microtherion / ScratchMonkey

Arduino software programmer sketch, supporting ISP, HVSP, and HVPP
67 stars 25 forks source link

CMD_ENTER_PROGMODE_ISP fails with multiple calls to avrdude #18

Open Ho-Ro opened 11 months ago

Ho-Ro commented 11 months ago

Used programmer HW: Arduino Nano (HW mod: capacitor from RESET to GND to suppress the bootloader activation when opening the serial connection) with original ScratchMonkey firmware from GitHub.

Error: After a 1st successful flash writing the 2nd write always fails (the error doesn't exist after eeprom writing):

avrdude_Ho-Ro -pt85 -U flash:w:t85_flash.hex -c scratchmonkey -vvvvv 2> log1
avrdude_Ho-Ro -pt85 -U flash:w:t85_flash.hex -c scratchmonkey -vvvvv 2> log2

Both logs are identical up to the CMD_ENTER_PROGMODE_ISP, the 1st returns STATUS_CMD_OK (0x00), the 2nd fails with STATUS_CMD_FAILED (0xC0):

--- log1_890    2023-10-15 18:21:38.686714240 +0200
+++ log2_890    2023-10-15 18:21:44.730747275 +0200
@@ -880,11 +880,11 @@
 0x0e 
 avrdude_Ho-Ro: recv: . [10] 
 0x10 
-avrdude_Ho-Ro: recv: . [00] 
-0x00 
-avrdude_Ho-Ro: recv: . [01] 
-0x01 
-STK500V2: stk500v2_command() received content: [ 0x10 0x00 0x64 0x19 0x20 0x00 0x53 0x03 0xac 0x53 0x00 0x00 ], length 12
+avrdude_Ho-Ro: recv: . [c0] 
+0xc0 
+avrdude_Ho-Ro: recv: . [c1] 
+0xc1 
+STK500V2: stk500v2_command() received content: [ 0x10 0xc0 0x64 0x19 0x20 0x00 0x53 0x03 0xac 0x53 0x00 0x00 ], length 12
  = 8
-pgm_default_rdy_led( 1 )
-avrdude_Ho-Ro: AVR device initialized and ready to accept instructions
+avrdude_Ho-Ro stk500v2_command() [stk500v2.c:894] error: command failed
+avrdude_Ho-Ro main() [main.c:1391] error: initialization failed, rc=-1

DEBUG output: Then I enabled the DEBUG_ISP and did the same test. The 1st line shows the correct response ![53] to CMD_ENTER_PROGMODE_ISP:

SPI AC [0] 53 [0] 0 ![53] 0 [0] 
SPI 30 [0] 0 [30] 0 [0] 0 ![1E] 
SPI 30 [0] 0 [30] 1 [0] 0 ![93] 
SPI 30 [0] 0 [30] 2 [0] 0 ![B] 

Here's the point in the SPI debug where the error shows up with bad response ![0], regardless of the spi speed:

SPI AC [0] 53 [0] 0 ![0] 0 [0] 
Retrying in limp mode 2 (62.50kHz).
SPI AC [0] 53 [0] 0 ![0] 0 [0] 
Retrying in limp mode 3 (31.25kHz).
SPI AC [0] 53 [0] 0 ![0] 0 [0] 
Retrying in limp mode 4 (15.63kHz).
SPI AC [0] 53 [0] 0 ![0] 0 [0] 
Retrying in limp mode 5 (7.81kHz).
SPI AC [0] 53 [0] 0 ![0] 0 [0] 
Retrying in limp mode 6 (3.91kHz).
SPI AC [0] 53 [0] 0 ![0] 0 [0] 
Retrying in limp mode 7 (1.95kHz).
SPI AC [0] 53 [0] 0 ![0] 0 [0] 

Affected AVR parts: My example uses a t85, but also a m328p behaves identical.

Error prevention: In the beginning I worked around this issue by pressing the reset button before each use of the programmer. So it looks to me that after a flash write the programmer is in a different internal state as before, and is not able to enter the prog mode again. Desired fix: Initialise the programmer correctly before each switch to prog mode. Current "fix": Reset the programmer automatically with the help of the watchdog timer (last line in SMoISP::LeaveProgmode(), this requires also #include <avr/wdt.h>):

void
SMoISP::LeaveProgmode()
{
    SMoHWIF::ISP::StopClock();
    SMoHWIF::ISP::StopSPI();
    digitalWrite(ISP_RESET, HIGH);
    SMoCommand::SendResponse();
    wdt_enable( WDTO_8S ); // Ho-Ho: Reset with wd timeout after 8 s
}