RaccoonBoard #1 Diseñando un sistema empotrado Linux

Hace un par de semanas que empecé uno de los proyectos personales más complejos a los que me he enfrentado, pero de momento está siendo más sencillo de lo que me esperaba gracias a toda la información que hoy en día se puede encontrar en innumerables fuentes en internet. Después de leer el increible artículo de Jay Carlson «So you want to build an enbedded Linux system», y de leer algo más sobre los procesadores mencionados en el mismo, me animé a diseñar una placa de desarrollo para uno de ellos, y meterme de lleno en el diseño de uno de estos sistemas. De mano parece algo bastante intimidante. Un sistema con una CPU a cientos de megahertzios, con memoria dinámica, buses modernos como USB y ethernet, configurar, compilar y conseguir arrancar uBoot y Linux… Muchos retos a nivel de hardware y software. Pero al empezar a leer la documentación existente, muchas cosas parecían asequibles. Así que dedidí tirarme a la piscina. Para empezar elegí uno de los procesadores que de entrada parecía más sencillo, un NUC980 de Nuvoton. Una de las ventajas de este procesador es que lleva RAM DDRII integrada (64MB), con lo que de un plumazo se elimina una de las mayores complejidades de un sistema moderno con microprocesador, el bus de DRAM con sus señales de longitudes e impedancias controladas. Además como comenta Jay Carlson en su blog, esta plataforma tiene otras ventajas para un principiante, como un sistema Buildroot simplificado por el fabricante, un encapsulado TQFP con sus pines en vez de un array BGA, y también importante, un precio especial para prototipos con un gran descuento para las 5 primeras unidades del integrado. Leyendo sobre los problemas que Jay Carlson tuvo con la versión de 64 pines (básicamente la selección del modo de arranque por no estar todas las señales de configuración del chip en pines externos), me decidí por la version de 128 pines que si tiene todas estas señales presentes. Así que mi selección final fue el Nuvoton NUC980DK61YC, en formato TQFP de 128 pines y con 64MB de DDRII integrados. Esta CPU tiene un núcleo ARM926EJ-S hasta 300MHz, y viene cargada de periféricos propios de un sistema empotrado, 2 puertos USB 2.0 y varios 1.1, dos puertos de tarjeta MMC/SD, 20 canales DMA, interfaz de entrada de vídeo digital, 8 canales de ADC de 12 bits, y varios puertos de I2C, PWM, SPI, UART, CAN…  de todo.

Una vez elegido el microprocesador, lo siguiente es empezar a leer la documentación del fabricante. Básicamente me basé en dos documentos, su datasheet principal, y su guia de diseño de hardware. Aunque al principio diseñar un sistema de este tipo desde cero pueda parecer muy intimidante, normalmente contaremos con bastante información de los fabricantes. Guias concisas sobre que necesitaremos para hacer funcionar nuestro sistema, incluyendo información sobre como conectar cada periférico, requisitos de alimentación, reset, desacople, reloj, etc, incluyendo muchas veces además de los esquemas de ejemplo consejos sobre el enrutado del PCB. Así que me puse a analizar toda esta documentación para empezar a diseñar que quería en mi placa, que componentes necesitaría, y cómo conectarlos.

Alimentación y desacople
Alimentación y desacople

Empezamos con la alimentación. Una CPU de este tipo suele tener ciertos requerimientos de alimentación que a veces son complicados y se dejan en manos de un PMIC (Power Management IC), que se encarga de generar los voltajes necesarios en el orden correcto. En el caso del NUC980 esto se simplifica un poco ya que no son necesarias complejas sincronizaciones de los diferentes voltajes en cascada ni nada de eso, así que nos ahorramos el PMIC y podemos usar reguladores normales. Eso si, en este caso necesitaremos tres: 1.2V para el núcleo de la CPU, 1.8 para la memoria DDRII, y 3.3V para los periféricos y la I/O. Por disponibilidad (la mayoría de componentes los compré en Aliexpress por decenas para asi ir teniendo stock de ciertas cosas), seleccioné reguladores 1117 de 3.3V y 1.2V, y para los 1.8V que sólo requerían unos pocos mA, usé el LP2985.  Respecto a la alimentación no mucho más, los condensadores que recomiendan los fabricantes de cada regulador, y eso si, todos los condensadores de desacople que exige el NUC980 que son un montón, básicamente uno de 100nF en cada pin de alimentación y alguno extra , unos 20 en total sólo para la CPU. Teniendo en cuenta esta cantidad enorme de condensadores, me decidí a usar el tamaño 0402 para los mismos, y aunque sabía que luego serían complicados de soldar (nunca había usado menos de 0603 en diseños propios, aunque si los había soldado en reparaciones o kits), esto haría más fácil seguramente el enrutamiento del PCB.

Además necesitamos un pequeño circuito para la pila si queremos que el RTC de la CPU no pierda la hora al apagar el sistema, con sus diodos para prevenir que la pila reciba alimentación cuando la placa está enchufada, y el circuito de reset, el típico pulsador con resistencia pullup y condensador. También tenemos unas cuantas señales de configuración de la CPU. Básicamente definen el dispositivo principal de arranque (NAND, Flash SPI, SD, USB…), si tenemos mensajes de debug en el UART0, si el USB0 es Host o Device (que puede funcionar como un interfaz de debug del fabricante), la activación del watchdog, etc. Para esto defino en el esquema unos puentes de soldadura que me permitirán ponerlos a 0 o a 1 mientras testeo el software para la placa.

Respecto al reloj, muy sencillo, un simple cristal de 12MHz con sus condensadores de carga (valores recomendados por el fabricante) y otro de 32.768KHz para el RTC con igualmente sus condensadores de carga.

Tarjeta SD
Ejemplo de conexión de la tarjeta SD

Luego he seleccionado los periféricos base que quería tener en el sistema, una tarjeta SD como dispositivo de arranque y almacenamiento (usaré la MMC/SD0) , los dos puertos USB 2.0, el puerto serie UART0 que servirá como consola de debug y arranque de Linux, y el puerto ethernet 0. Para este último, el NUC980 sólo tiene MAC (Media Access Control o capa de enlace de datos), así que nos hace falta ponerle un integrado que implemente el PHY (Physical layer o medio físico, en mi caso un LAN8720A de SMSC), y teniendo en cuenta que hay que añadir también los transformadores,  seleccioné un conector RJ45 con ellos integrados.

El resto del esquema es básicamente seleccionar todas las señales de los GPIO y sacarlas a un par de tiras de pines en el orden más sencillo para enrutar, que por suerte en la mayoría de casos es un orden bastante lógico ordenado por puertos. Al final añado unos puntos de prueba para los diferentes voltajes, un conector USB C para la alimentación (con sus resistencias de configuración), un LED de encencido… y listo.

Y ahora empieza lo mejor, el enrutado. La verdad es que hice dos diseños del PCB. Uno en dos capas y otro en cuatro. No cabe decir que el diseño con cuatro capas ha sido considerablemente más sencillo. El disponer de un plano de tierra y otro de alimentación en las capas intermedias hace el enrutado mucho más fácil al poder bajar con vias directamente desde los pines donde necesite una de estas dos señales, y además para las pistas que tengan que tener impedancia controlada (USB, ETH…), el tener un plano de tierra directamente debajo de la capa superior sin ninguna señal atravesándola, hace el trabajo mucho más sencillo. Aunque logré enrutar la PCB con el diseño de dos capas y tengo un prototipo funcionando con ella, la verdad es que se hizo bastante más difícil e incluso tuve que dejar tres GPIOs sin enrutar ya que se me hacía imposible.

Con el diseño de cuatro capas la verdad es que se simplificó mucho el tema y terminé el enrutado en mucho menos tiempo (y pudiendo enrutar todos los GPIO). Igualmente para ambos diseños  lo primero fue posicionar los componentes en una disposición lógica (las posiciones son las mismas en ambas placas), primero la CPU en el centro y luego en función de la conexión a sus pines los periféricos alrededor de ella. Como es una placa de desarrollo y no tenía limitaciones en cuanto a forma, tamaño o disposición de los diferentes puertos, pues lo fui poniendo todo buscando el menor lio de conexiones posibles. Lo primero definir varios anchos de pista, 0.203mm (8mil) para la mayoría de señales, y 0.5mm y 0.75mm para señales de alimentación. También definí las separaciones de las señales y los anchos y separación de las señales diferenciales que tenemos que enrutar (más info sobre esto a continuación). Una vez listo esto empiezo por posicionar y enrutar los condensadores de desacople, intentando dejarlos lo más cerca de los pines que los necesitan. Luego los dos cristales y sus condensadores correspondientes, los pines del UART0, y luego los periféricos que deben tener salidas en los bordes de la PCB, ordenados según los pines a los que están conectados. Primero el más complejo, el IC del PHY de ethernet, que requiere de su propio espacio en el PCB ya que tiene sus propios condensadores de desacople y resistencias de polarización además de su propio cristal, resistencias de terminación, y el propio conector de ethernet.

Longitud de la pista y el segmento seleccionado.

Luego por posición de las señales y en el mismo lado del PCB, posiciono los dos puertos USB. Hay que tener en cuenta que estos USB 2.0 tienen que enrutarse con pares diferenciales y que son líneas de impedancia controlada. Por suerte KiCAD tiene una herramienta para ello, sólo tenemos que definir los grosores y separación de las líneas (podemos usar la calculadora de KiCAD para ver la impedancia, en el caso de USB las señales tienen que ser de 90 ohm) y nombrar las señales diferenciales con nombres acabados en +/- ó _P/_N. Luego al seleccionar la herramienta de enrutado diferencial, KiCAD ya nos llevará las dos señales a la vez hasta su destino, sólo teniendo luego que ajustar el «skew» (la diferencia de longitud entre las dos pistas) con una herramienta también disponible en el enrutado de KiCAD. También las señales finales del ethernet son diferenciales, esta vez de 100 ohm de impedancia, otra cosa a tener en cuenta.

Ejemplo de meandros en las señales de la tarjeta SD

Y para terminar con lo complejo y en el otro lado del PCB, la tarjeta SD. Aunque no son pares diferenciales, si que tenemos las cuatro señales de datos que son un bus paralelo a alta velocidad, así que lo mejor es igualar la longitud de las pistas para que las señales tengan una alta sincronización y evitarnos problemas. Para ello también tenemos una herramienta en KiCAD. Al seleccionar una pista, nos dirá la longitud de la misma (no confundir con la longitud del segmento) en la barra inferior de la pantalla, recordaremos la longitud más larga de las señales a igualar, y usando la herramienta «Tune track lenght» con esa esa longitud iremos igualando el resto de señales. Lo que hace KiCAD es ir añadiendo «meandros» a la pista hasta que iguala la longitud a la que le hemos definido. Normalmente es algo que no tenemos en cuenta cuando diseñamos circuitos para Arduino y similares que como mucho se mueven en pocas decenas de megahertzios, pero si nos adentramos en los 300MHz como este caso o más, ya hay que tener en cuenta el tiempo de propagación e igualar las longitudes de las señales que tienen que viajar a la vez (buses de datos, de dirección, pares diferenciales, etc), nos ahorrará muchos dolores de cabeza.

Por último posiciono al lado de la tarjeta SD el botón de reset, y al otro lado todos los componentes de alimentación, junto con el conector USB C que nos proporcionará los 5V para alimentar la placa. En el espacio que queda encajo el soporte para la pila del RTC y los pasivos que necesita, los puentes de soldadura para las señales de configuración de la CPU en la cara inferior, y ya solo queda el tedioso paso de enrutar todos los GPIOs externos a las tiras de pines que van a los lados del PCB. En previsión había girado la CPU 45º lo que nos deja las señales bastante ordenadas para ir sacándolas hacia los pines, auque en algunas de ellas  no queda otra que usar la cara inferior para enrutarlas. Una vez enrutado y comprobadas las reglas de diseño.

Una cosa que suelo hacer es imprimir el diseño de la PCB en papel, para posicionar encima todos los componentes y asegurarme que todo encaja, sobretodo si he tenido que crear alguna huella. Después de comprobar varias veces todo el enrutado y las reglas de diseño, DRC y demás, exporto los gerbers y a fabricar. En este caso las envié a JLCPCB por que tiene un proceso de 4 caras bastante barato. 5 PCBs de 59x92mm con envío incluido por 20€ (y 15€ son de envío!!!). En poco más de una semana tenía las flamantes PCBs en mi buzón, y ya sólo quedaba soldarlas y a funcionar! (o eso pensaba yo). La mayoría de componentes los pude soldar sin problema usando un estañador, en mi caso una estación T12 (que por cierto recomiendo encarecidamente, tecnología de soldadura moderna a un precio estupendo, y con muchas puntas para elegir). Sólamente tuve que usar aire caliente para los componentes sin pines laterales, el PHY de ethernet (QFN24) y los tres cristales. Los condensadores 0402 si que tuve que ser cuidadoso para soldarlos a ojo, pero con una punta fina en el estañador y algo de flux, acabé soldándolos sin demasiado problema (salvo alguno que salió disparado y nunca más apareció). El resultado…

Primer mensaje de la CPU, no puede arrancar desde la SD porque no tiene ni conector soldado :)

En ese momento todavía no me habían llegado todos los componentes, faltaba el conector de ethernet y el de la tarjeta SD, el portapilas, los diodos y el cristal del RTC, algunas resistencias… pero tenía lo suficiente para inciar la placa con el debug activado y ver que pasaba. Después de comprobar que que no había ningún cortocircuito en las alimentaciones, y enchufarla a 5V y comprobar que todos los voltajes eran correctos, soldé los puentes de configuración para activar el debug por el puerto serie 0, boot desde la SD, USB 0 en modo device para depuración, conecté un conversor USB-Serie a mi PC (cuidado que son señales de 3.3V) y lancé un programa de terminal serie,  pulsé reset y… respuesta de la CPU!!! Por lo menos estaba viva, así que sólo quedaría instalar las herramientas de software del fabricante y cocinar un sistema linux adaptado para la misma, mientras a esperar al resto de componentes para poder terminar el PCB y así probar todos los periféricos. Pero voy a dejar el tema del software para otro post, porque va a ser un artículo largo por si mismo.

Teneis disponible el diseño del PCB en mi Github: https://github.com/ladecadence/RaccoonBoard-PCB, pero aviso desde ya que es un prototipo y no está todo probado, así que no recomiendo a nadie fabricarla, pero para echarle un vistazo al esquema y el PCB puede valer. En unos días espero tener probados todos los periféricos de la placa desde Linux (de momento la SD, los USB y los GPIO funcionan!) y escribiré el post sobre todo el tema del software, mientras os dejo mi twitter donde iré comentando avances:  https://twitter.com/davidpello

Un saludo.

ViejuLCD USB

Ya tengo el prototipo del ViejuLCD versión USB, he preparado el PCB y todo correcto a la primera. Ahora mandaré un par de ellos a un par de compas de vieju.net para que desarrollen software del lado del PC.

viejulcd-protousb-2La idea es hacer un servidor de datos al LCD, que implemente una cola y a la que las aplicaciones que quieran hablar con el LCD se conecten por sockets y dejen el stream de texto/comandos que quieran mandar. Asi no habra conflictos de bloqueo entre las aplicaciones si dos toman el control del puerto al mismo tiempo. Luego tenemos pensado desarrollar varios clientes,  para datos del sistema, notificaciones, etc.

En el lado XT, la idea de JoJo, es hacer un programa residente de DOS (TSR), que capture ciertas interrupciones para recabar datos del sistema y asi enviarla al LCD. Con esta técnica se podria incluso usar el LCD de pantalla externa, capturando las interrupciones necesarias.

Yo he estado haciendo un pequeño demo, para probar los comandos implementados en el firmware del LCD, y la verdad, ha sido un éxito.

Lo programé en ruby, toma el control directamente del puerto, y hace una serie de pruebas del firmware, texto, scroll, niveles de brillo, activacion/desactivación, etc.

Podeis ver un video del demo a continuación:

Cartucho MSX-DOS2

Desde hace un tiempo tengo un MSX2, un Phillips VG8235. Me lo donaron en GP32Spain, no le funcionaba la disquettera y el dueño buscaba algumsxdos2-cartien que le diera un hogar y lo arreglara. Asi hice. Le adapté un disquetera de PC (cambia completamente el cableado, y hay que sacar un par de señales de otros conectores), y asi puede leer discos de 720K (la original es de 360K). Estuve estos dias trasteando con CP/M y con MSX-DOS, incluyendo compilar cosas en C nativamente con el compilador de hitech para CP/M (que funciona en MSX-DOS tambien).

Como el MSX-DOS 1 es bastante limitado, estuve buscando información y vi que se puede meter la bios del MSX-DOS2 en un cartucho externo, como ocupa 64K, con una EPROM 27C512, parecería suficiente, pero no, como el MSX sólo puede direccionar directamente esos 64K, tiene que usar paginación para poder tener  en memoria,  la bios, el sistema y ram libre, así que hay que añadir algo de lógica para que pueda paginar esa bios de MSX-DOS2. Está todo muy bien explicado en varias páginas, asi que me fue bastante fácil diseñar el cartucho.

Más fotos, esquemas y PCBs a continuación…

Continuar leyendo «Cartucho MSX-DOS2»

Nuevo miembro en el taller

El taller crece, con la llegada de mi nueva estación de soldadura de aire caliente, una Soldtec 830c, que es una estación básica, pero más que suficiente para mi uso. Viene con tres boquillas redondas de diferentes diámetros, y hay una buena gama de ellas para elegir, además muy barata. Tiene una cosa que me hace gracia, cuando la apagas, se queda como un minuto o asi lanzando aire frio para refrigerar el equipo antes de apagarse sola. Ya la he estado probando y desoldar cosas con ella es una pasada. A ver que pida un poco de pasta y pruebe a soldar SMDs. Ahi queda instalada en mi rincón de trabajo.

Insoladora con LEDs UV y temporizador.

Estoy haciéndome una insoladora de PCB’s con LEDs UV. La idea me la dieron los chicos de http://radikaldesig.com/, que estuvieron trabajando en una. Después de hacer el PCB con los LEDs en una protoboard de tiras, pensé que sería interesante tener un temporizador que se encargara de apagar automáticamente la insoladora para no pasarme si se me olvida encendida. Asi que cojí otros trozos de protoboard y me he hecho uno, basado en un attiny2313, un 4511 para gestionar un display LED de 7 segmentos, un relé, y poco más. Podeis ver un video con un test del temporizador a continuación. El temporizador cuenta minutos, pero para hacer las pruebas esta muy acelerado como se puede ver en el video:

En siguientes entradas publicaré el esquema y el código de este temporizador por si os interesa.

EDIT: Os dejo el esquema del temporizador:

Y el código del micro; incluyo un makefile para compilarlo (make), flashearlo (make flash) y flashear los fuses (make fuses). seguramente tendreis que adaptarlo a vuestro programador, puertos, etc:

temporizador1

PCBs de los cartuchos 32Mbit Flash, 1Mbit SRAM.

Ayer me llegaron los PCBs del prototipo de cartucho flash para la gameboy en que estuve trabajando estos meses. Es un cartucho MBC5, con hasta 32MBit de FLASH (soporta chips de 16 ó 32Mbit), y 1Mbit de SRAM (128KB), con pila para poder guardar partidas. Con esta configuración se puede usar un 99% del software disponible para la gameboy (juegos y apps homebrew), incluyendo el LittleSoundDJ y el NanoLoops.

Ayer mismo monté uno de ellos, y parece funcionar correctamente; además de un programa hecho por mi que somete al cartucho a unos tests (bancos de ROM y salvado en la SRAM), probé a meter el ZELDA DX (8MBit), a jugar una partida, guardarla, sacar el cartucho y meterlo en otra gameboy y comprobar el guardado de la partida. Todo perfecto.

Solo tiene un pequeño fallo, el condensador de abajo del todo (C4) choca con la tapa y hay que hacerce a esta una pequeña muesca para que cierre, nada, en el diseño final lo subiré un poco y listo. Me quedaré con uno o dos, y el resto están adjudicados a seguidores del proyecto, en unos dias los montaré y empezaré a mandarlos, y dentro de poco pediré mas placas para seguir construyéndolos para los interesados. :-)

Cart Flasher

El programador está funcionando perfectamente. Tuve unos problemas programando el microcontrolador, pero ya está todo solucionado. Acabo de hacer unas pruebas y está todo correcto. Ahora a seguir depurando todo, he movido un par de componentes para el PCB final, pero el diseño es bueno, asi que ya solo quedan los cartuchos para tener todo listo para ponernos manos a la obra.

PCBs del CartFlasher

Me acaban de llegar los PCBs del programador de cartuchos flash de GameBoy en el que estoy trabajando. De momento visualmente están perfectos, y los conectores y los componentes encajan a la perfección, además han quedado muy bonitos.

Esta noche o mañana montaré uno para probarlo, a ver que tal va. Ya solo queda que me llegen los PCBs de los prototipos finales de los cartuchos, con 128KB de SRAM, que los tengo fabricando ahora mismo.

A la que lleguen y esté todo probado, ya podremos poner en marcha esos pedidos conjuntos de los que muchos estais deseosos.

Saludos!

PCBs de cartuchos flash

PCBs_CartuchoMe han llegado los primeros prototipos del PCB del cartucho flash para gameboy que estoy diseñando. Después de montarlo me di cuenta que había interpretado mal un dato del datasheet del mm1134, el chip que se encarga de alimentar la sram cuando apagas la consola para poder conservar los datos de partidas guardadas y demás, y no funcionaba bien. Ya está corregido el diseño y probado puenteando las pistas que estaban mal con cables, asi que ahora el diseño ya es definitivo.

Ahora voy a modificar el diseño para incluir un chip de sram de 128K en lugar del de 32K que tiene ahora, para asi poder usarlo con software como el LittleSoundDJ que requiere esta capacidad para guardar canciones.

También he pedido fabricar los primeros prototipos del programador en diseño SMD, dentro de un mes postearé los resultados.

Producción Masiva

produccion_masiva.jpgNunca había hecho tantos PCB’s de una vez. Estoy preparando el material para un taller que realizaré para la LABoral junto con el proyecto de ocio juvenil Abierto hasta el amanecer del Ayuntamiento de Gijón.

supersensor.jpgEl taller, titulado «La ciudad invisible» consistirá en la realización de unos pequeños circuitos que nos permiten escuchar los campos electromagnéticos que nos rodean. Los participantes soldarán y construirán los circuitos para luego moverse por diferentes entornos escuchando las reacciones del dispositivo a los campos electromagnéticos de su alrededor, grabándolos y elaborando mapas y apuntes de zonas que consideren de interés.

A ver que tal sale, tengo ganas.