Si hablara, ella te diría que me conoce desde chico, y yo te digo que la conozco muy bien. A ella le debo parte de mi interés por la ciencia, por las cosas técnicas. Fue tal el revuelo en casa cuando apareció, que algo adentro de mi muy joven yo hizo clic. Con ella podía jugar, dibujar, explorar, hacer mi propio mundo ahí adentro, pero no era simple. Había que aprender, había que probar, pero había que tenerle respeto para no romperla, que ya era una herramienta esencial de trabajo. Fuera del horario laboral éramos yo y ella. No podía molestar cada vez que quería hacer algo, tuve que aprender yo mismo como usarla, como invocar las cosas que quería, como salir de ese menú raro que se había puesto y no había visto nunca.
Ella, es mi PC 486 de 1997. Cyrix DX2 a 66Mhz en sus orígenes, hoy un DX4 a 100Mhz después de que esa batería asesina le comiera su placa madre original. No importa, sigue siendo ella, con su hermoso gabinete y un disco duro que al día de hoy tiene los mismos dibujos y savegames que le hice cuando tenía 7 años, más o menos. Para mi siempre fue todo pc speaker; era una PC de trabajo. Ya de adolescente un amigo me regaló su vieja SoundBlaster CT2230, y descubrí todo lo que me había estado perdiendo. De vez en cuando juego algún que otro juego, como los legendarios Monkey Island que nunca jugué de chico, le vuelvo a dar una pasada a los niveles de Jill of the Jungle que tanto conozco, o instalo algún que otro software interesante que hoy en día gracias a los archivos online están al alcance de la mano.
En fin, ella me acompañó toda mi vida. Siempre en su propio mueble y hoy en día en escritorio compartido con mi setup moderno; comparte monitor y parlantes con mi Lenovo Yoga 720 de 2017 utilizando un conversor de VGA a HDMI. Solo tengo que estirarme, encenderla, tocar dos botones en el monitor y ¡pum!, nos fuimos a 1997. ¿Nos jugamos YA un Indianápolis 500? Dale. Acordate que la carpeta se llama INDI y está en C:\JUEGOS\. Si más vale, cómo olvidarlo, dejame que en Norton Commander uso las flechas del teclado y ya lo pong… ¡Ah!, el teclado. Beige, enorme, crujiente pero de muy buenas teclas y un enter que daba placer, engorroso y con un cable largo. Saco mi moderno y práctico teclado Bluetooth que uso con la 720 y me dispongo a cambiarlo por ese bicho, ¡si solo pudiera usar el mismo teclado para mis dos PCs!
De toda necesidad salen planes y de esos planes, soluciones. No encontré nada en internet que resuelva mi problema, parecía que nadie lo había intentado y ninguna empresa le vió potencial comercial como para ponerse a fabricar un adaptador que permita conectar un teclado Bluetooth a un sistema con puerto PS/2. Ahí nomás se me prendió la lamparita y acepté el desafío, de la misma manera que acepté el desafío de aprender computación cuando era joven. Tenía que poner a uso práctico mis modestos conocimientos de C++ y hacer un proyecto con alguna de esas placas de desarrollo que tan famosas son hoy en día. Arduino tiene una gran comunidad pero su hard está un poco anticuado ya. Así descubrí la ESP-32 de EspressIF, este pequeño gigante tiene WiFi, Bluetooth, un IO completísimo y un procesador de núcleos duales a 240Mhz, todo a un precio accesible, ¡casi está para reemplazar la PC entera!
Nunca lo hubiera logrado de no ser porque encontré dos librerías para ESP-32 que la comunidad ya había pre-cocinado, o al menos hubiera tardado muchísimo más que la semana y media que me llevó. La primera es PS2dev, que maneja toda la interfaz PS/2 y emula ser un teclado. PS2dev estaba muy verde, poco desarrollada, solo encontré un usuario que la había usado exitosamente en un sistema no-PC-compatible y un montón más que se quejaban de que no servía para nada. Entonces empecé a debugearla y me encontré con que el problema estaba en el tiempo.
PS/2 (o PC-AT si nos remontamos a sus orígenes), es un protocolo serial bidireccional, donde la PC (el host) y el teclado periférico se turnan para comunicarse por un único cable de datos, regidos por una señal de reloj. El teclado envía las teclas presionadas y las ya no presionadas como códigos de uno o dos bytes de largo llamados make codes y break codes, correspondientes a una tabla que los asignaba a cada símbolo y letra a la que IBM llamó Scan Codes. Normalmente el teclado envía estos códigos y no pasa más nada, la computadora recibe el mensaje y actúa como esperamos. Pero hay ciertas ocasiones donde la comunicación hace uso de su carácter bidireccional, es decir que el host se comunica con el teclado, por ejemplo para solicitarle información, apagar o prender sus LEDs, etc. Para esto la computadora envía mensajes, llamados Mensajes de Comandos PS/2, y espera para cada uno al menos una respuesta de confirmación proveniente del teclado, llamada ACK (por acknowledge o “confirmación” en inglés). Entonces si queremos emular un teclado real tenemos que responder en tiempo y forma a estos mensajes de comandos. PS2dev lo hacía, pero resulta que las BIOS (sistema básico que controla el arranque e IO de una PC compatible) suelen ser muy exquisitas con sus tiempos y encontré varios sistemas donde la actuación de PS2dev no podía superar el encendido de la máquina, haciendo que la BIOS ignorara totalmente a nuestro “teclado”. En una Toshiba 205CDS respondía muy rápido a la pregunta “¿sos un mouse o un teclado?” ocasionando que la BIOS no recibiera el mensaje y configurara el periférico por defecto a un mouse, porque su puerto PS/2 es combinado. En mi 486 respondía muy rápido al mensaje “¡prendé tu LED de Num Lock!”, la BIOS no lo recibía y terminaba ignorando el teclado, asumiendo que estaba funcionando mal. Solo solucioné todos estos errores agregando los delays específicos en el preciso momento que eran necesarios, antes y después de cada ACK. ¡Y estoy hablando de microsegundos!
Con PS2dev finalmente funcionando nos quedaba la otra mitad; la comunicación Bluetooth. Mi teclado es BLE o Bluetooth Low Energy, un nuevo protocolo mucho más eficiente que hoy en día coexiste con el ultra-archi-conocido Bluetooth Classic. Otra librería me dió el dominio para esta interfaz, bt_keyboard, hecha por un usuario de la comunidad que usó el ejemplo publicado por el mismísima fabricande del ESP32, EspressIF, usando su API para Bluetooth HID recién salida del horno.
Bt_keyboard funcionaba, reconocía mi teclado, se conectaba, ¡recibía los códigos! No podía ser mejor, pero pasaba algo. Al igual que PS2dev, estaba muy verde y EspressIF no se había molestado en incluir entre sus rutinas todas las que se encargaban de reconectar el teclado una vez que había sido emparejado, entonces había que reiniciar y emparejar el teclado con cada encendido. Fue así como investigué sobre BLE y como el ESP32 guarda en su memoria flash las claves permanentes que nos permiten reconectar a un dispositivo previamente emparejado, hice las rutinas que escanean y detectan la presencia del teclado y nos salvan de tener que emparejarlo de nuevo. Ahora sí, ¡practicidad al fin!
Solo un pasito más. Los teclados Bluetooth transmiten códigos para cada tecla, como los que creó IBM para su PC en los 80. Decime que son los mismos. No, ¡claro que no!, no puede ser tan fácil. Los códigos que transmiten los teclados modernos, sea por Bluetooth o algo más conocido como USB, son precisamente códigos HID creados por el consorcio USB. Y no son uno para presionadas (make) y otro para liberadas (break), sino sólo uno que está presente (o no) dependiendo si la tecla está apretada (o no), que se comunica en un paquete de datos cada vez que hay algún cambio en las teclas. Así que el reto estuvo en hacer rutinas que detecten la presencia o no de la tecla en base a los códigos HID, traduzcan esto al respectivo código make o break, y finalmente lo envíen mediante PS2dev al la computadora host.
El último detalle lo tuvo una característica que quizás es la más interesante en lo que refiere a la interfaz PS/2; el llamado comportamiento Typematic o “tipomático”. Si lo traducimos literalmente, una combinación de la palabra “tipo” y “automático”. Por si no te diste cuenta, te lo explico, “tipo”es el nombre que se le da a una letra o símbolo, así que estamos haciendo referencia a: aaaaaaaaaaaaaaaa. Si, a cuando se repiten las letras automáticamente si mantenés apretada una tecla, a eso. Acordate cada vez que lo uses, “miren, ¡estoy tipomatiqueandooooooo!”. USB HID no provee un mecanismo explícito para detectar si una tecla está mantenida apretada y actuar al respecto, hoy en día es la computadora quien lleva el registro de que la última tecla no se soltó y empieza a repetirla internamente para lo que sea que estemos haciendo. En los viejos teclados PS/2 era el mismo teclado el que entraba en modo Typematic después de cierto tiempo de mantener apretada la tecla, usualmente unos 500 milisegundos, para luego enviar una y otra vez el mismo código make de la última tecla presionada, usualmente unas 20 veces por segundo. Esa fue la última cosa que le faltaba a mi proyecto.
Una vez emulado PS/2, solucionados los problemas de conexión de Bluetooh, traducidos los mensajes USB HID a los Scan Codes de IBM, y emulado el comportamiento Typematic, mi proyecto estaba terminado al fin. Un simple cable a ficha DIN-5 o Mini DIN-6 permite conectarlo al sistema, y le pedí a un amigo que me haga una cajita en 3D para protegerlo.
¿Funciona? Si, y muy bien. Pueden encontrar el código fuente en mi sitio de GitHub. De hecho todo este post lo escribí con ella, mi 486, pero no le digas que con un teclado Bluetooth, ¡porque no se dio cuenta y piensa que es PS/2! Ahora si, disfrutar del Indi 500 a simplemente dos botones, y un switch de distancia.