En la parte anterior de este artículo habíamos visto como diseñar la placa tenía sus retos y decisiones complejas, pero no se iba a quedar ahí. El proceso de construir la Kelboy 2.0 tiene muchas otras cosas a tener en cuenta para que funcione bien el sistema, hoy vamos a ver en esta última parte algunas de ellas, que como veréis nos son pocas. Al final, una placa compleja tiene retos complejos.
Figura 33: LemonCrest: Una historia de emprendedores Makers & Gamers (4 de 4)
Teníamos que plantear los retos a mitigar. Los detalles son importantes para poner las mejores características al producto. Nos pusimos en marcha y se consiguió funcionalmente:
- Fuel-Gauge por I2C proporcionando el control absoluto del consumo, la batería y su estado.
- WiFi/BT de última generación por SDIO, la base de estos drivers fue facilitada por Panasonic en versión GPL, de manera que somos capaces de mejorarlos y adaptarlos al sistema.
- Audio por I2S, un sistema de audio digital en formato 384 kbps y 32 bits de alta calidad que hacen que los juegos suenen mejor que el primer día.
- Memoria EEPROM interna por I2C accesible por el driver para el espacio de usuario.
Figura 34: Configurando la pantalla de la Kelboy 2.0
El problema de este apartado es que está cerrado y las empresas no quieren perder el control sobre las pantallas, por lo que nos quedamos atascados en los DPI timmings. Estos tiempos son los que utiliza el protocolo CSI-MIPI para enviar la información de vídeo y que el driver de la pantalla lo entienda correctamente para visualizarlo. No abandonamos esta alternativa en otros proyectos, pero pensando en la salida del prototipo de Kelboy 2.0, sacar los tiempos por ingeniería inversa como estamos haciendo consumía un tiempo elevado y el proyecto debía continuar.
Figura 35: "Raspberry Pi para Hackers & Makers: PoCs & Hacks Just For Fun" de 0xWord |
Por lo tanto, se decidió reducir la complejidad e irnos a un RGB TTL, donde nuevamente nos encontramos con el problema de los tiempos. Dicen que la experiencia es siempre un grado y esta vez con lo aprendido del CSI-MIPI se obtuvieron unos tiempos óptimos con el resultado de una pantalla con una nitidez espectacular. Se buscaba alcanzar la sensación a nivel usuario de pixel perfecto y se consiguió el reto.
Figura 36: FullHD DPI Test
Una vez conseguida la pantalla, pasamos al siguiente punto, y no menos importante, los periféricos como el sonido y GamePad. Para poder avanzar con todo esto debíamos comprender y conocer los drivers, un conocimiento que fue adquirido a cabezazos y el libro de Alberto Liberal de los Ríos “Linux Driver Development for Embedded Processors“.
Pero nuevamente, se nos planteó otro problema. Al utilizar la pantalla con un bus RGB-TTL que es paralelo, necesitamos un GPIO por cada bit de cada color más el GPIO de sincronización vertical, sincronización horizontal y el reloj que marca cuando se debe leer la señal.
Figura 38: Valores GPIO
Por lo tanto, debíamos modificar a nivel de descriptor hardware el entendimiento del kernel de Linux de qué es cada pin. Para ello contamos con la ayuda del foro de Raspberry Pi y pudimos mover el bus I2S y el I2C a GPIOS que estuviesen libres, puesto que todos los GPIOs iniciales de la Raspberry Pi estaban en uso. Este punto tiene cierta dificultad ya que, aunque Raspbery Pi quiera ser abierta, Broadcom tiene muchas partes ocultas que no lo permiten, con lo que el funcionamiento difiere bastante de una plataforma no tan privativa.
Figura 39: Tabla de Funciones Alternativas del banco 1 de GPIO
Como se puede observar en la imagen estos eran los pines que nos quedaron libres. El resultado fue del 28 al 32 para el I2S, del 34 al 40 para el SDIO, y del 44 al 45 para I2C nos quedaron libres 4 pines. Ahora bien, nos quedaba por gestionar las interrupciones del bus I2C y el backlight. Lo bueno es que a nivel de driver podemos escoger los GPIO o cargarlos desde un descriptor hardware dando versatilidad. Quedándonos la friolera de dos pines libres teníamos que decidir bien su uso. Control del hardware, uno para detectar pulsación de apagado y el otro para poder resetear los periféricos.
Figura 40: Testeo de la Kelboy 2.0
Por último, nos queda el apartado del GamePad, la forma más simple de abordar un dispositivo de estas características que cumpliese nuestra dificultad en cuanto a “ocupación” de los GPIOS del procesador era el USB. Esto nos introducía en un campo de mucha complejidad, el stack HID del USB.
Nuevamente abordar esto no era sencillo, y aunque no esté cerrado en su totalidad no hay una documentación en si misma que explique cómo poder programar a bajo nivel los drivers y enfrentarse a ello. Bienvenido al mundo del hardware. Para entenderlo se inició con dos documentaciones antiguas pero muy conocida “USB in a nutshell” y “USB made simple”. Una vez entendido se inició a abordar con microprocesadores como el STM32, pero nuevamente otra losa en el camino... necesitábamos más de un USB Device al mismo tiempo, lo que nos situaba en un USB Device Composite.
Para variar en este mundo del bajo nivel las empresas potentes no dan soporte a este tipo de funcionalidades, y si las quieres hay que pagar por stacks privativos unas sumas de dinero considerables además de la firma de licencias restrictivas, lo que nuevamente nos situaba en una posición donde no podíamos avanzar.
¿Cómo realizamos un USB Device Composite en STM32? ¿Programamos el driver? Cómo no esta tarea implicaba un largo recorrido y con muchos interrogantes. Tras llegar a este punto se decide por buscar algún framework que dé soporte a este punto, encontrándonos negativas en los frameworks Mbed y HAL de STM32 pero con una muy buena noticia, el USB_Plugable.h del framework de Arduino sí contemplaba estas situaciones.
Figura 41: "Arduino para Hackers: PoCs & Hacks Just for Fun" |
Con la ayuda del creador de Teensy y empresas tan valiosas como Adafruit y Sparkfun parecía que el framework de Arduino iba a ser el camino, y así ha sido. Gracias a leer las múltiples librerías de ejemplo y lo aprendido anteriormente conseguimos describir el HID que queríamos fielmente al detalle, un Gamepad embebido.
Lo bueno de todo esto es que las librerías del framework de Arduino facilitan todo el apartado de cabeceras necesarias para el stack del USB y uno se puede centrar en el descriptor de su dispositivo, pudiendo así realizar el dispositivo que se quiera, tanto sea un ratón, un teclado..... o incluso un dispositivo Raw, es decir, sin funcionalidad conocida pero que con el driver adecuado realiza la función programada.
Figura 43: Descriptor del Gamepad
Finalmente, solo era necesario rellenar el descriptor que posteriormente empaquetaría las funciones del framework del Arduino, dando como resultado un USB Device Composite funcional de una manera tan simple comparada con otras soluciones que es increíble, aquí es donde se ve nuevamente la fuerza que tiene la comunidad y el movimiento Open Source. El resultado y felicidad al ver este mensaje saliendo por la consola de log de Linux fue y será indescriptible.
Figura 44: Log de Linux con el Gamepad cargado
Pudiendo así redondear un sistema completo. ¿El siguiente reto? Dar soporte y crear paquetes de distribución Debian para que podamos integrarnos al gestor de paquetes APT, que el usuario pudiera manejar de manera sencilla. Lo bueno de todos estos cabezazos es que tenemos en la palma de la mano un dispositivo abierto, donde se enseñan las tripas de manera completa y que nos da la posibilidad de tocar y modificar a voluntad pudiendo así obtener múltiples funcionalidades. El objetivo de ser abiertos se cumple.
Figura 45: Kelboy 2.0 con Mario Kart64
Saludos,
***************************************************************************************
***************************************************************************************
No hay comentarios:
Publicar un comentario