Burning a Atmega 328 Bootloader with an Arduino Leonardo

Hi guys,
I am at the point where I can't figure out how to get it running =(
I bought myself an Arduino Leonardo and tried to burn a Atmega 328 on a breadboard-installation. I followed the instruction from http://arduino.cc/en/Tutorial/ArduinoToBreadboard but everytime I try to install the bootloader the commandline gives me a

avrdude: stk500_getsync(): not in sync: resp=0x00

I already measured all input voltages, changed the 16Mhz Oscillator, changed both 18pF C's to 22pF one's and rechecked all pin-connections.

What am I doing wrong? Thank you so much for your help!

Regards,
Stevil

Perhaps you need to disable auto-reset on the Leonardo. See: http://arduino.cc/en/Tutorial/ArduinoISP

"Note for Arduino 1.0: you need to make one small change to the ArduinoISP code. Find the line in the heartbeat() function that says "delay(40);" and change it to "delay(20);".

"An Arduino board serving as an ISP to program the ATmega on another Arduino board. On the Arduino Uno, you'll need to connect a 10 uF capacitor between reset and ground (after uploading the ArduinoISP sketch). Note that you need access to the reset pin on the target board, which isn't available on NG or older boards.

Hi John,

thanks for your answer. You mean a 10µF between RST and GND on the Leonardo or on the breadboard?
Anyway I tried both ways - no solution. Same error :frowning:

It looks like that is using SPI on both the source Arduino and the target Arduino / 328 chip.

If you're using pins 10, 11, 12 and 13 on the Leonardo, you are using the wrong pins. On the Leonardo, SPI only exists on its own ICSP port, not on any of the normal Arduino headers. A further possible problem is that the internal SPI function of pin '10' on the Uno (SPI SS) is not connected to anything on the Leonardo. (Well it's the RX Led but it's not anything you can use directly.)

Edited to add: Mapping the SPI pins from the regular headers to the ICSP, Uno pin 13 (SCK) is on pin 3 of the ICSP header, Uno pin 12 (MISO) is pin 1 of the header, and Uno pin 11 (MOSI) is pin 4 of the icsp header. For pin 10, you can probably leave that one where it is on the Leonardo, it's the other three that are more critical.

Hi Steph,

that are great thoughts and I already thought that that was the solution for my problem. I connected the MOSI, MISO and SCLK to the ICSP-header - but with no success =( Same error message

Could it be the missing /SS-Pin? I'm afraid of cutting the signal-line to try it.
Any other solution in mind?

Serial Programming doesn't use the Slave Select signal. It uses the Reset pin. The ArduinoISP sketch uses Pin 10 to control the Reset pin of the target.

The ICSP header on any Arduino (including the Leonardo) will be connected to MOSI, MISO, SCK, Vcc, Ground, and Reset. You want to hook MOSI, MISO, SCK, Vcc, and Ground to the same pins on the target device. Then connect Pin 10 on the Arduino running ArduinoISP to the Reset pin on the target device.

Looking at the ArduinoISP sketch I think I see how you can make it go - the first #define statement is "#define RESET SS" if you change that to "#define RESET 10" then use your Leonardo's pin 10 as the /SS pin that might just do it. Leave the other SPI pins connected to the ICSP on the leonardo, and everything ought to be ok.

Good luck!

Hi John, hi Steph,

tried everything - just won't work. Seems like I'll have to get a Arduino Uno for that kind of stuff =( Seems like no one has ever tried to flash a Atmega328 with an Arduino Leonardo :frowning: - I spent hours on google and tried to get some information.

Maybe tomorrow at work I'll check the SPI signals with a Scope.

Thanks for your help anyway dudes

The problem is similar to the auto-reset issues when running ArduinoISP on uno, duemilenove...
Whenever avrdude opens the serial port it toggles DTR (and RTS) signals. On these 'classic' arduino's, DTR pulls low the RESET of the programming arduino, causing it to reset. Avrdude then starts communicating with the arduino which may not yet have booted and you get these 'not in sync' errors.

The difference on the leonardo is that when avrdude toggles DTR, this just boils down to an usb control message being sent to the leonardo's usb driver.
I will try to find out what the driver does in response to this message. Anyway the behavior is very similar to what I observe (on my Sanguino) when I install the auto-reset enable jumper: the ide burns a bootloader by calling avrdude twice. The first command succeeds, but the second one fails with a 'not in sync' error.

In meantime I tested two alternative ways to burn a bootloader using a leonardo:

  1. Use Nick Gammon's "Atmega_Board_Programmer" sketch. It works out of the box if your target is in the list of supported processors.
    This method works because this sketch is stand alone (i.e. it does not download the images over the serial line, they are compiled in, in the sketch)

  2. Use ArduinoISP via the leonardo's real uart: Serial1:

  • In the ArduinoISP example change all occurrences of "Serial" into "Serial1".
  • Also don't forget to change the RESET define into #define RESET 10, as reported by Steph.
  • Download the sketch to the leonardo.
  • Hookup an ftdi cable or similar to the leonardo's tx1, rx1 and gnd lines.
  • In the ide, select the target processor as board type.
  • In the ide, Select the port corresponding to the ftdi cable.
  • In the ide, select "burn bootloader".

All atmega chips are set in factory to 1MHz internal clock, so a standard programming may not work. You have to set the programming speed to the lowest one possible, and reflash the fuses to the external crystal mode..

pito:
All atmega chips are set in factory to 1MHz internal clock, so a standard programming may not work. You have to set the programming speed to the lowest one possible, and reflash the fuses to the external crystal mode..

I think this was meant for thread: http://arduino.cc/forum/index.php/topic,110321.30.html?

Hi there I'm also having the same problem! I'm new to micro controllers so any help would be appreciated. I have done everything that the previous posts have said and still no luck.

Jared, what microcontroller are you trying to burn a bootloader into?
Can you provide more detail about what goes wrong (output of avrdude(set verbose output for upload in the preferences panel...)). What schematic are you using?

Nick Gammon's board programmer should really work but I forgot to mention you should add

while(!Serial)
    ;

as the first line of the setup() routine, otherwise you don't see the messages in the serial console and this is confusing.

In meantime I succeeded to burn a bootloader using the leonardo an ArduinoISP, using the usb cable, not the real uart.

To do this, I increased SERIAL_BUFFER_SIZE to 150 in CDC.cpp and provided a mechanism to disable autoreset in software (on the leonardo this is all software!). This requires more investigation, not sure the autoreset disable is needed. I will write about this later.

Hi Peter, thanks for the reply. I'm using the atmega 328 on a breadboard. I don't have access to a crystal as yet so i was attempting to burn it without the crystal present. When using the Arduino ISP (with all the recommended changes) i got the "avrdude: stk500_getsync(): not in sync: resp=0x00" message. When using Nick Gammon's i get the following:

Atmega chip programmer.
Written by Nick Gammon.
Entered programming mode OK.
Signature = 0x1E 0x95 0x14
Unrecogized signature.
LFuse = 0x62
HFuse = 0xD9
EFuse = 0xFF
Lock byte = 0xFF
Clock calibration = 0xAA

With regards to the setup on the breadboard, Im using the icsp headers on the Leo. The reset pin I connected to pin 10 of the Leo.
Thanks so Much
Jared

Hi all, think i found the problem... The chip Im using is the 328-pu, not the 328p-pu, so i think that's why the program was not recognizing it. I changed the hex code in Nick's program to the signature of the 328-pu but got this message:

Atmega chip programmer.
Written by Nick Gammon.
Entered programming mode OK.
Signature = 0x1E 0x95 0x14
Processor = ATmega324P
Flash memory size = 32768 bytes.
LFuse = 0x62
HFuse = 0xD9
EFuse = 0xFF
Lock byte = 0xFF
Clock calibration = 0xBD
No bootloader support for this device.
Type 'C' when ready to continue with another chip ...

Look carefully at the signatures array: it has entries that are completely initialized and there are ones for which the bootloader and subsequent fields are left uninitialized (in which case they are guaranteed to be all zero's).

You modified an entry of the second type: one without bootloader support.
More precisely the ATmega324P entry. But you have a 328PU. So I think you were lucky it did not write anything, if it had written incorrect fuses, the chip could become unrecoverable for ArduinoISP.

I would create a new entry in the table by copying the one for 328P. But consult the datasheet for the AT328PU and check wether the fuse settings are correct (for the crystal you wish to use).

@Jared: the optiload program has support for the 328-PU. It uses the same fuse settings for the 328P-PU and the 328-PU.

I have further investigated the problems when running ArduinoISP on leonardo. There are indeed two of them: first is an unintentional auto reset and a second one is a loss of serial data.

The unintentional autoreset is a funny one. The leonardo only autoresets when DTR gets set when the speed at that time is 1200 baud. So normally, avrdude can toggle DTR as much as it wants: as long as the speed is not 1200 baud the leonardo won't reboot.

But guess what happens if you first upload the ArduinoISP sketch to the leonardo:

  1. The ide resets the leonardo by "touching" the serial port: it sets DTR when the speed is 1200 baud.
    It does not use avrdude to do this.
  2. Avrdude downloads the sketch at the baudrate specified in boards.txt. When it is done, avrdude nicely sets the speed back to what it was before: 1200 baud.
    Then you decide to burn a bootloader to your target:
    3.The ide makes its first call to avrdude. Again, when avrdude is done, just before it closes the port it sets the speed back to what it was: 1200 baud. Closing the port toggles DTR and the leoardo reboots!
  3. The ide makes its second call to avrdude, but the leonardo is not yet up and you get the 'not in sync' error.

Moreover the behavior is timing dependent: if there is little time between 3. and 4. (a fast pc) it may be that the autoreset is cancelled by the second call to avrdude. (See autoreset cancellation code in CDC.cpp).

I'll issue a change request. A possible solution is that the ide sets the baud rate back to what it was, when it is done resetting the leonardo (or at least sets it to another value than 1200). Otherwise this is a recipe for spurious autoresets.

In mean time there is a simple workaround: after uploading the sketch, briefly open the serial monitor and set the baudrate to a value different from 1200. Close the serial monitor again. Then burn the bootloader to your target.

Loss of serial data. When flashing, avrdude provides 128 bytes in one command. USB provides the data so fast that the device cannot keep up. Changing SERIAL_BUFFER_SIZE to say 150 (in CDC.cpp!), allows you to burn a bootloader. But that is a poor work around. No bytes should be lost even with a buffer of 64 bytes: USB has built in handshaking: if a device cannot accept more data it should send NAK's to the host (the pc) and the host will retry later. The USB controller in the device (leonardo) should do this by itself. I modified the code in CDC.cpp such that it only takes data from the controller's fifo when there is room in its serial buffer. Apparently the USB device controller does the rest.

in CDC.cpp:

void Serial_::accept(void)
{
        ring_buffer *buffer = &cdc_rx_buffer;
       
        int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE;

        // if we should be storing the received character into the location
        // just before the tail (meaning that the head would advance to the
        // current location of the tail), we're about to overflow the buffer
        // and so we don't write the character or advance the head.

        // while we have room to store a byte
        while (i != buffer->tail) {
                int c = USB_Recv(CDC_RX);
                if (c == -1)
                        break;  // no more data, we're done
                buffer->buffer[buffer->head] = c;
                buffer->head = i;

                i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE;
        }
}

And in USBCore.cpp:

...
#ifdef CDC_ENABLED
                USB_Flush(CDC_TX);                              // Send a tx frame if found
                if (USB_Available(CDC_RX))      // Handle received bytes (if any)
                        Serial.accept();
#endif
...

With these changes in place, ArduinoISP on the leonardo works nicely. Any sketch that reads serial data can benefit from this change (of coarse more testing is needed).

I tried this on kubuntu/linux, with avrdude 5.10 as well as 5.11.

PeterVH:
The difference on the leonardo is that when avrdude toggles DTR, this just boils down to an usb control message being sent to the leonardo's usb driver.
I will try to find out what the driver does in response to this message. Anyway the behavior is very similar to what I observe (on my Sanguino) when I install the auto-reset enable jumper: the ide burns a bootloader by calling avrdude twice. The first command succeeds, but the second one fails with a 'not in sync' error.

I think that this is actually good news. (in that it may escalate things to actually get fixed)
It is an avrdude bug/issue that I reported a while back. It never got any attention because it seemed
to be so narrow as it was an issue when primarily using an AVR dragon.
Here is the link to the Arduino bug report
http://code.google.com/p/arduino/issues/detail?id=650
Here is the link to the Savannah bug report for Avrdude:

There are several small/easy work arounds that can be done in
the IDE or the Makefiles. The simplest is to do the full bootloader burn in a
single avrdude command vs 2 commands.
The real solution is a small patch for AVRdude.

Too bad the IDE update didn't get done for 1.0.1

--- bill

Hi all

Managed to finally burn the bootloader. I changed the hex as i said above, but this time of the code relating to the p-pu and (with alot of luck XD) got it right! I assumed that the settings would be the same after a bit of reading up than the 2 chips and turns out it worked fine!

Thanks for all the help

Jared