Archivo por días: 26 septiembre, 2022

Problemas tecladiles (4)

EDITADO: actualizados los fuses.

Como ya comenté, decidí reemplazar el cargador original del Atmega32U4, llamado DFU y que se puede descargar desde la página de Atmega, por Ubaboot, un bootloader reducido que sólo ocupa 512 bytes y que es muy sencillo de utilizar. A mayores envié dos parches para simplificarlo aún más:

Para instalar Ubaboot, lo primero que hay que hacer es editar el fichero config.h y configurar los parámetros de nuestra placa. En el caso de mi teclado, hay que descomentar OSC_MHZ_16 (pues el reloj es de 16MHz), y USB_REGULATOR:

Una vez hecho esto, hay que programar los fuses del microcontrolador para un bootloader de 512bytes, además de asegurarnos de configurar bien el resto. En el caso de mi teclado, la configuración es la siguiente:

Fuse LOW: 0x5E

  • CKDIV8 0
  • CKOUT 1
  • SUT1/0 = 0x01
  • CKSEL3/0 = 0x0E

En este bloque básicamente no tocamos nada.

Fuse HIGH: 0xDE

  • OCDEN 1 (desactivado)
  • JTAGEN 1 (JTAG desactivado)
  • SPIEN 0 (programación por SPI activada)
  • WDTON 1 (watchdog desactivado)
  • EESAVE 1 (preservar EEPROM al borrar la memoria)
  • BOOTSZ1/0 0x11 (bootloader de 512 bytes)
  • BOOTRST 0 (vector de reset apunta al bootloader)

En este bloque básicamente desactivamos el JTAG, pues no lo necesitamos para nada, ponemos la dirección de inicio del cargador a 512 bytes antes del final de la memoria, y por último configuramos el vector de reset para que salte al cargador directamente. Esto último es muy importante, pues el propio cargador detecta si estamos arrancando «en frío» (en cuyo caso saltará a nuestro código directamente) o si hemos pulsado el botón de reset (en cuyo caso entrará en modo programación).

Fuse EXTRA: 0xFE

  • RESERVADO 7/4 tienen que estar todos a 1 (0xF)
  • HWBE 1
  • BODLEVEL2/0 0x1 (EDITADO)

El entorno de Arduino me había cambiado el BODLEVEL a 110 (1,8 a 2,2 voltios), en lugar del original 011 (2,4 a 2,8 voltios). Tras algunas pruebas, y en base a mi experiencia, he decidido que es más seguro ponerlo a 001 (3,3 a 3,7 voltios). Esto es algo que he cambiado en este artículo después de haberlo publicado.

El siguiente paso es conectar un programador SPI al teclado a través de los pines correspondientes. Yo uso un BusPirate que me prestaron, para lo cual tuve que editar el fichero Makefile y sustituir usbtiny -B10 por buspirate -P /dev/ttyUSB0 -b 115200, además de instalar AVRdude y el resto de utilidades de AVR. Con esto ya sólo me queda conectarlo al teclado y ya puedo leer el estado con

avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4

borrar todo el estado para desprotegerlo con

avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -e

grabar los fusibles con

avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -U efuse:w:0xFE:m
avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -U hfuse:w:0xDE:m
avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -U lfuse:w:0x5E:m

y hacer make y make program para grabar el Ubaboot. Con él grabado, sólo tengo que pulsar el boton de RESET del teclado y se pone automáticamente en modo programación por USB, con lo que ya no necesito más el BusPirate.

Y ya, por último, instalé Arduino y Teensyduino para disponer de las bibliotecas de USB. Sin embargo, hice un pequeño cambio para integrar la programación mejor. Los cambios concretos están descritos en el fichero README del segundo parche que envié a Ubaboot.

Y con esto escribí la primera versión del software de mi teclado, pero eso lo comentaré con calma en otra entrada.