ATtiny2313 se niega a programarse después de configurar el reloj de la CPU a 500 kHz

El otro día estaba escribiendo un programa para un ATtiny2313 . Una vez que funcionó, decidí probarlo a las distintas velocidades de reloj disponibles y programadas configurando el LFUSE como se describe en la página 159.

  • La velocidad de reloj predeterminada es 1 MHz;
  • así que probé 8 MHz a continuación y todo funcionó bien;
  • Luego configuré la velocidad del reloj en 4 MHz con el preescalador /8, lo que resultó en un reloj de 500 kHz.

Aunque el controlador ejecuta el programa a la velocidad esperada, mi programador se niega a reprogramar el controlador desde entonces. avrdude(5.11.1) simplemente arroja el conocido: '¡Yikes!':

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

Intenté agregar la -Fbandera, pero por supuesto eso tampoco.

Aquí hay algunos fragmentos de código que usé y cambié la velocidad del reloj como se esperaba:

// 0.5MHz
FUSES = { .low = 0x62   , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };


// 1MHz (default)
FUSES = { .low = 0x64   , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };

// 8MHz
FUSES = { .low = 0xe4   , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };

Para la programación, utilizo un Arduino con el boceto ArduinoISP (versión 04m3) que viene con Arduino IDE 1.0.1.

Este es el comando para programar flash:

avrType=attiny2313
avrFreq=1000000
programmerDev=/dev/ttyUSB003
programmerType=arduino
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U flash:w:$(src).flash.hex

Este es el comando para programar los fusibles:

avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U lfuse:w:$(src).lfuse.hex

Mi pregunta es doble:

  1. ¿Cuál es la razón por la que no puedo programar el controlador después de configurarlo en un reloj de 500 kHz (mientras que el programa en el controlador parece funcionar bien);
  2. ¿Cuáles son mis opciones para reprogramar los fusibles sin usar un programador HV? ¿Quizás me perdí alguna bandera útil para avrdude?

Por cierto: Tuve el mismo problema una vez con un ATtiny45 @ 128kHz. La programación HV lo resuelve, pero quiero evitar la situación HV.

¿A qué frecuencia intenta programar el programador? Recuerdo que tuve problemas similares cuando traté de programar AVR con frecuencia SPI, que es demasiado alta en comparación con el reloj principal. Reducir la frecuencia SPI resolvió el problema para mí.
Estuve pensando en eso, pero no tengo idea. Arduino se ejecuta en 16 MHz, pero no sé acerca de los pines de programación. Todo sucede demasiado rápido para medir la línea del reloj, por ejemplo. Podría intentarlo más tarde hoy, después del trabajo. Tampoco tengo idea de cómo reducir la frecuencia del programador.
No puedo ayudarte mucho allí. No he usado Arduino, así que no sé cómo se ve exactamente el boceto. El programador que utilicé tenía una configuración especial solo para este caso. Algunas búsquedas iniciales me dieron estos resultados: arduino.cc/forum/index.php?topic=71973.0 github.com/rsbohn/ArduinoISP/pull/2 Desafortunadamente, no tengo tiempo en este momento para investigar más sobre este tema. . ¡Buena suerte!
No uso Arduino, así que no sé mucho al respecto, pero a veces he tenido que alterar la velocidad de SPI cuando intento programar un dispositivo AVR que tiene un reloj más lento. Hay una opción -B para controlar la velocidad que funciona con el programador USBtiny, pero no parece que lo estés usando. Se menciona aquí: tom-itx.dyndns.org:81/~webpage/usbtiny_programmer/… Así como en los enlaces del comentario anterior.

Respuestas (4)

El problema, como se explicó, es una frecuencia de reloj SPI demasiado alta. Existe una versión fija de ArduinoISP que puede programar a una frecuencia más baja disponible aquí . Algunas discusiones sobre el tema están disponibles aquí .

Revisé el enlace de github y pude actualizar el controlador nuevamente en el primer intento. De hecho, permite cambiar entre SPI (demasiado rápido como se explica en electronics.stackexchange.com/a/65019/8627 para algunas configuraciones de fusibles) y bit banging (que parece funcionar). Aunque logré reprogramar el controlador, la versión original de ArduinoISP es más estable. El nuevo a veces falla y luego funciona en un segundo intento.

Como regla general, no puede elegir una velocidad de ISP superior a la cuarta parte de la velocidad de su MCU de destino. En su caso, 500/4 = 125 KHz debería ser la velocidad máxima del ISP. Si no puede cambiar la velocidad SPI de su Arduino como se describe en angelatlarge, es posible que necesite un programador externo.

Si no puede gestionar la disminución de la velocidad SPI de ArduinoISP, otra solución puede ser un código de programador personalizado. Puede cambiar ArduinoISP para usar un SPI de software y calcular los retrasos adecuados para disminuir a 100 KHz o tal vez velocidades personalizadas. Eche un vistazo a http://little-scale.blogspot.com/2007/07/spi-by-hand.html para la implementación de software de SPI.

Voy a buscar la insignia de Capitán Obvio aquí y sugeriré que la velocidad de ATtiny2313 es demasiado baja para ser programada por ArduinoISP ahora. De la hoja de datos ATtiny2313:

Los períodos mínimos bajo y alto para la entrada del reloj serial (SCK) se definen de la siguiente manera: Bajo:> 2 ciclos de reloj de la CPU para f C k < 12 MHz, 3 ciclos de reloj de CPU para f C k >= 12 MHz Alto:> 2 ciclos de reloj de CPU para f C k < 12 MHz, 3 ciclos de reloj de CPU para f C k >= 12 MHz

Su arduino probablemente funciona al menos a 16Mhz. Aquí está la línea relevante de ArduinoISP.ino:

SPCR = 0x53;

Esto establece la velocidad Arduino SPI en f O S C /64, o 250Khz si el SPI2Xbit está programado en el SPSRregistro . Si esto es correcto A 500 kHz de reloj, esto no es más de 2 ciclos de reloj de CPU como recomienda la hoja de datos. Si esta hipótesis es correcta, la solución es configurar el divisor de reloj SPI en 128 asegurándose de que SPI2Xesté apagado en spi_init()función en ArduinoISP.ino:

SPSR &= ~(1<<SPI2X);
lamentablemente mi versión de ArduinoISP ya está en /256 :(

Actualmente estoy trabajando en ScratchMonkey, un boceto de Arduino como programador que implementa un respaldo de software para SPI, retrocediendo gradualmente a velocidades tan bajas como 1kHz.

Todavía es un trabajo en progreso, pero puedes obtenerlo de github