Author Topic: New findings - avrdude error: program enable: target doesn't answer (0x01)  (Read 1471 times)

0 Members and 1 Guest are viewing this topic.

Offline eblc1388Topic starter

  • Frequent Contributor
  • **
  • Posts: 400
  • Country: gb
When using avrdude+usbasp on programming avr chips, often one would get:

avrdude error: program enable: target doesn't answer (0x01)

This is a very common error and there are tons of messages related to it on the Internet. Typical answers/suggestions are:

- check programmer pins/wiring connection
- MCU's fuses were previously programmed to use external crystal
- programmer default speed (375KHz usbasp) too fast for MCU with internal Oscillator
- bad avr chip

However, what happens to me really did not appear to belong to any one of the above. I moved to Linux (MX 23, Debian 12) from Windows and is using new tool chains for AVR. To upload the object HEX file to the AVR, I use AVRDUDE. The hardware programmer is a common Ali express Usbasp I bought 5 years ago. The target MCU is ATMega16 with a crystal of 7.3728MHz and fuses set up accordingly.

The first object hex file upload operation using avrdude was fast and completed without any issues. However, starting from the second and subsequent operations, the avrdude interface was consistently reporting the above dreaded "Target does not answer" error message. I unplugged the usbasp and plug it back in again. Same thing happens with successful first operation and subsequent failures. I tried reading only the Fuses but its just the same. (Screen capture terminal log)




The part that intrigues me most is why it all went so well in the first operation using the default SCK programming clock speed, but failed consistently afterwards. I need to find out what part of the system is at fault. Being a hardware guy I dug out my logic analyser(LA) and connected up four channels directly on the following (reset, SCK, MISO, MOSI) AVR pins, right on the AVR chip itself. With the Usbasp plugged in and the LA trigger set on falling reset level, I issue the first command to Avrdude and got the following response. You can clearly see the 4-bytes "enable programming mode" request(0xAC, 0x53, 0x00, 0x00) on MOSI line and AVR echo back 0x53 on the MISO line as an acknowledgment. This is in perfect agreement with what the data sheet recommended for serial programming. So far so good as it is expected. (First run screen capture)



Now, what will the situation be like on issuing subsequent commands? This is what I've got on the LA. It is completely different from the initial capture. I got a lot of activity on SCK and MOSI line, and they were all the 4-byte "enable programming" request sequences. Sadly the AVR does not acknowledge any of them. But wait, what happens to the first few bytes of the request? Looking carefully, instead of the usual 4-bytes, it is only 3 bytes long. The 0x53 bytes was missing. To be absolutely sure I did the capture again the third time and no, byte 0x53 is still missing.( second run screen capture)



No wonder the AVR does not answer. After taking the Reset pin low, AVR is expecting a 4-byte data packet. Giving it only three would just means the following byte will be taken as the fourth byte. After issuing many many "out of sync" 4-byte enable programming packets to the AVR, usbasp finally gave up and report failure to avrdude.  This is the reason why we get the "Target does not answer" error.

My next trial was to reduce the programming speed manually to see what happens. The 0x53 byte is still missing at SCK=94KHz bit but it suddenly reappears at SCK=32KHz. I tried many operations at SCK=32KHz and all were successful. This indicates to me that the problem lies entirely on the "missing 0x53" byte. If we can figure out why it is missing, then we can solve the above error.



This is new to me. The same code producing different result when run for a second time. This type of software troubleshooting is out of my depth. I look at the most recent Source Code of usbasp "usbasp.2011-05-28.tar.gz (519 kB)" from the Thomas Fischl website and find the following code inside the isp.c file, relating to the output of these four bytes, but everything seems in good order and I couldn't figure out why 0x53 is missing. Also in reality I didn't observed any pulsing on the reset line when the program enable check fails, which it should.

Code: [Select]
uchar ispEnterProgrammingMode() {
uchar check;
uchar count = 32;

while (count--) {
ispTransmit(0xAC);
ispTransmit(0x53);
check = ispTransmit(0);
ispTransmit(0);

if (check == 0x53) {
return 0;
}

spiHWdisable();

/* pulse RST */
ispDelay();
ISP_OUT |= (1 << ISP_RST); /* RST high */
ispDelay();
ISP_OUT &= ~(1 << ISP_RST); /* RST low */
ispDelay();

if (ispTransmit == ispTransmit_hw) {
spiHWenable();
}

}

return 1; /* error: device dosn't answer */
}
   

Finally, it dawns on me that even I couldn't figure out why byte 0x53 is missing, I can patch up the situation by forcefully inserting one extra byte such that the byte packet length returns to 4 again. I did it by doing one more "ispTransmit(0x00)" if the enable check fails.(see image) I built the usbasp firmware from source with the patched isp.c file and flash it to the usbasp programmer. The resulting LA capture confirms that the patch works and AVR responded by the next enable programming request.  Now I can issue commands to avrdude and I do not get that dreaded error message again. Also the up/down load speed is about 375KHz instead of the slow 32KHz which everything works. I even try the option of "-B 0.5" on the command line, which increase the SCK speed to 1.5MHz.  Reading the whole flash feels like a breeze compares to the 32KHz speed before.

If your are currently still using "-B 32kHz" in your avrdude command line because of the dreaded error above, I hope this post can offer the needed help.



Remaining questions: (probably no one would want to answer)

1. Why 0x53 is missing in second and subsequent trials, but magically reappears if SCK is reduced down to 32KHz?

2. How would one troubleshoot such situation and find out the real cause?
« Last Edit: July 09, 2024, 11:53:27 pm by eblc1388 »
 

Offline eblc1388Topic starter

  • Frequent Contributor
  • **
  • Posts: 400
  • Country: gb
I have mentioned in my above post, " Also in reality I didn't observed any pulsing on the reset line when the program enable check fails, which it should."

I looked into the MCU board that I've used for this test and located a 10uF smd capacitor shunting the reset line to ground. This is the reason that no reset pulsing could be observed on the reset line when the "enable programming" check fails. After removing this capacitor, pulse can be seen on the reset line.

Although the first handshake is still only 3 bytes long instead of 4, the presence of the reset pulse do manage to reset the AVR internal SPI engine so the next 4-byte handshake give a success result.



The reason why it suddenly works with SCK=32KHz is due to the changing of the programming algorithm from hardware SPI to bit-banged software SPI when the speed is 32KHz or lower.

I spent many hours trying to look into why 0x53 is missing and there are only three bytes in the first round of handshake but to no avail. I even disassembled the object file and looked at the assembly instructions. I've tried different versions of avr-gcc but still the same result. Because of the reset pulse, AVR managed to re-sync its SPI engine so the second packet of 4-byte handshake works as expected.

I guess I will never know the answer. Thanks for reading.

 
 

Offline coromonadalix

  • Super Contributor
  • ***
  • Posts: 6329
  • Country: ca
check on the web  usb asp has a new FW or an small update ??

https://forum.arduino.cc/t/usbasp-improved/1107037
https://github.com/dioannidis/usbasp/releases/tag/v1.11

not sure it helps ?

or this one

https://github.com/dioannidis/usbasp   there was some code changes
or
https://github.com/nerdralph/usbasp   ??
« Last Edit: July 10, 2024, 04:32:26 pm by coromonadalix »
 
The following users thanked this post: eblc1388

Offline eblc1388Topic starter

  • Frequent Contributor
  • **
  • Posts: 400
  • Country: gb
I spent many hours trying to look into why 0x53 is missing and there are only three bytes in the first round of handshake

I have finally located the reason why the second byte 0x53 is missing, by placing a software counter inside the spi subroutine that outputs each byte. The counter value indicates that the routine has actually been called 4 times, with the correct data to be sent out.

Then the only question remains, why didn't the avr hardware SPI outputs the second byte? Simple answer, it is busy sending out the first byte. Although a wait loop has been implemented in the subroutine to check for the SPIF flag being set before subroutine returns, a previously set SPIF flag has led to no wait loop and resulted in the second byte 0x53 being immediately written to SPDR register while avr spi is busy sending out the first byte. This byte(0x53) has thus been ignored by avr.

Solution is simple, clear all the pending SPI flags before sending the first byte, by reading the SPDR and SPSR SPI registers. After placing these instructions in the source code and rebuild the firmware, results from Logic Analyser proved that the missing 0x53 byte is now back and handshake succeeded everytime after the first 4 bytes is sent, first trial and every trial afterwards.




 

Offline madires

  • Super Contributor
  • ***
  • Posts: 8033
  • Country: de
  • A qualified hobbyist ;)
Solution is simple, clear all the pending SPI flags before sending the first byte, by reading the SPDR and SPSR SPI registers.

IIRC, this is explained in the datasheet. Classic RTFM! ;) When sending data you should read SPDR after each byte to clear SPIF:
Code: [Select]
void SPI_Write_Byte(uint8_t Byte)
{
  /* send byte */
  SPDR = Byte;                     /* start transmission */
  while (!(SPSR & (1 << SPIF)));   /* wait for flag */
  Byte = SPDR;                     /* clear flag by reading data */
}
 

Offline eblc1388Topic starter

  • Frequent Contributor
  • **
  • Posts: 400
  • Country: gb
I completely agree to what you've said, but the code in the original firmware did actually read the SPDR register afterwards.

Code: [Select]
uchar ispTransmit_hw(uchar send_byte) {

SPDR = send_byte;             
while (!(SPSR & (1 << SPIF)));
  return SPDR;
}

;----- Disassembled listing of bin file ------

00341:   ..     b98f     OUT    SPDR, r24 ; r24 contains data to sent
Lbl_00342
00342:   w.    9b77    SBIS   SPSR, 7 ; Skip if Bit 7 in SPSR Reg is Set
00343:   ..     cffe       RJMP   Lbl_00342 ; -2 0x00342 Relative Jump
00344:   ..     b18f      IN       r24, SPDR ; Read SPDR to r24 as return value
00345:   ..     9508     RET                    ; Return from Subroutine





 

Offline madires

  • Super Contributor
  • ***
  • Posts: 8033
  • Country: de
  • A qualified hobbyist ;)
So, whoever wrote that code missed the first part, but got the second right.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf