AT89LP51ED2 SPI ISP: el primer intento de ingresar al modo ISP después del reinicio arroja datos incorrectos, pero el segundo intento funciona

Tengo una placa que usa un AT89LP51ED2 de Atmel; este es un derivado 8051 con memoria de programa Flash integrada y una interfaz SPI ISP, que estoy usando mi Bus Pirate para controlar (velocidad de 30 kHz, pullups ENCENDIDO y cableado a la placa Vcc, configuración SPI predeterminada de lo contrario, el pin AUX conduce /RESET). El protocolo ISP está documentado por Atmel, tanto en la hoja de datos como en esta nota de la aplicación Atmel ; en general, es superficialmente similar a AVR SPI ISP excepto por el uso de 2 bytes de prefijo (lo que lo hace incompatible con avrdude). El modo de programación requiere un comando de entrada: los dos bytes de prefijo 0xAA 0x55seguidos de 0xAC 0x53y un dummy 0x00, que debería regresar 0x53para indicar que el dispositivo está en modo ISP.

Por lo tanto, me propuse implementar el protocolo yo mismo, utilizando el modo binario SPI de Bus Pirate, su módulo Python asociado y un poco de secuencias de comandos Python personalizadas en mi propio extremo; sin embargo, noté que mi secuencia de comandos Python solo ingresaría al modo ISP. intermitentemente Pude reproducir la falla manualmente usando la interfaz de terminal de Bus Pirate, comenzando desde un arranque en frío de la placa:

SPI>a
AUX LOW
SPI>{ 0xaa 0x55 0xac 0x53 0x00 ]
/CS ENABLED
WRITE: 0xAA READ: 0xFF 
WRITE: 0x55 READ: 0xFF 
WRITE: 0xAC READ: 0xFF 
WRITE: 0x53 READ: 0xFF 
WRITE: 0x00 READ: 0xA7 
/CS DISABLED
SPI>{ 0xaa 0x55 0xac 0x53 0x00 ]
/CS ENABLED
WRITE: 0xAA READ: 0xFF 
WRITE: 0x55 READ: 0xAA 
WRITE: 0xAC READ: 0x55 
WRITE: 0x53 READ: 0xAC 
WRITE: 0x00 READ: 0x53 
/CS DISABLED
SPI>

La falla en particular es que en el primer comando, la interfaz ISP repite 0xA7 en lugar del 0x53 que debería. Restablecer la placa me permitió reproducirla nuevamente y capturar la secuencia en mi osciloscopio, incluida una falla BAJA durante medio reloj al final del último 0xFF que se desplaza:

Captura general de 2 ms/div del paquete ISP defectuoso Byte 1 -- 0xAA de salida, 0xFF de vuelta Byte 2 -- 0x55 de salida, 0xFF de vuelta Byte 3 -- 0xAC de salida, 0xFF de vuelta Byte 4 -- 0x53 fuera, 0xFF atrás pero con un fallo BAJO durante medio ciclo al final Byte 5 -- 0x00 de salida, 0xA7 de vuelta en lugar de 0x53

Entonces, ¿ qué estoy haciendo mal? ¿Es esto un problema de protocolo de mi parte? ¿O debería estar sospechando un microcontrolador defectuoso, o peor aún, una errata en la implementación de la programación? ¿Debería solucionar esto simplemente en el script de mi ISP?

Creé el caso de soporte de Atmel #36278 para esto, por cierto (esta Q también está vinculada en el caso)
Atmel no pudo reproducirse en el caso de soporte: superó esto usando una solución alternativa en mi secuencia de comandos ISP pero dejando esto en caso de que alguien finalmente resuelva este misterio.

Respuestas (1)

Parece que puede estar recibiendo un pulso de reloj adicional antes del último bit del cuarto byte. El esclavo cree que se han enviado los 8 bits y comienza a generar un 0 en la línea MISO en el último bit porque lo percibe como el primer bit del siguiente byte.

Entonces, como resultado, todos los datos se desplazan uno por uno.

Creo que no puede ver este pulso de reloj adicional porque su frecuencia de reloj es tan lenta que tiene que alejar mucho el zoom del osciloscopio. Intente hacer zoom en esa área entre el bit 7 y 8, y ajuste el visor para que pueda ver el pulso más pequeño.

Es difícil decir si esto es causado por el hardware o el software, pero supongo que el software: busque algo que pueda causar una pequeña falla en el reloj.