Un lector e-ink se convierte en impresora IPP con solo 400 KB de RAM
Nishant Joshi ha logrado que un lector Xteink X3 aparezca como impresora en macOS vía IPP. Para superar la falta de memoria, procesa las páginas en streaming y usa la pantalla como buffer.

Nishant Joshi, un desarrollador con predilección por los dispositivos de tinta electrónica, ha convertido un lector Xteink X3 en una impresora IPP que macOS detecta sin necesidad de controladores. Para lograrlo ha tenido que resolver un problema de memoria aparentemente imposible: las páginas a 300 dpi no caben en los 400 KB de RAM del chip. Lo ha conseguido procesando las imágenes en streaming y escribiendo cada fila directamente en el buffer de la pantalla, que hace las veces de almacenamiento intermedio. El código está en GitHub.
El punto de partida fue un Xteink X3, un lector que ya usa una versión del firmware CrossPoint. Joshi quería una pantalla programable para añadir animaciones, dados y códigos QR, pero pronto le frustró el método de transferencia de archivos, basado en un hotspot y un portal web. Entonces razonó: si un lector parece papel, debería comportarse como papel, así que investigó el protocolo IPP para emular una impresora.
La implementación requirió anunciar el dispositivo con Bonjour y el subtipo _universal, usando el API mDNS de ESP-IDF porque el wrapper de Arduino no lo exponía. El servidor IPP acepta formatos Apple raster y PWG raster, y anuncia monochrome, 300 dpi, una copia y una sola cara. Cuando el Mac envía una página, la recibe por HTTP y la procesa.
El quebradero de cabeza era la memoria. Una página Letter a 300 dpi y un byte por píxel ocupa unos 8,4 MB, pero el chip ESP32-C3 solo tiene 400 KB, de los cuales 16 KB están reservados como caché. Con Wi-Fi activo y el buffer de pantalla, quedaban 6,8 KB libres. Joshi pensó en mmap y en usar la tarjeta SD como memoria virtual, pero la MMU del C3 solo mapea flash, no ficheros. Así que recurrió a la pantalla: ¿por qué no construir la página directamente sobre el buffer de imagen del display? Escribió un pipeline de decodificación, escalado y tramado que entrega filas ya listas a la región de memoria de la pantalla, reutilizando el espacio. Al pasar a escribir fila a fila, el uso de memoria se redujo de ~113 KB a ~62 KB, dejando margen para el stack de red.
El resultado fue que una página tarda cerca de un segundo en aparecer, dice Joshi. Al principio hacía actualizaciones parciales cada medio segundo, visible en bandas, pero optó por mostrar la página entera cuando está lista. También guarda los trabajos como BMP en la tarjeta SD, así que hay una "bandeja de salida" real: una carpeta donde se puede navegar desde el lector.
La utilidad práctica es limitada, pero demuestra que conociendo los protocolos y con un poco de ingeniería se puede sacar partido a hardware con recursos ajustados. El proyecto, bautizado 'literate-penguin', se puede consultar en el fork de CrossPoint, junto con la implementación de la impresora. Para quien quiera profundizar, la referencia de IPP y la hoja de datos del SoC son buenos puntos de partida.
