[SOLVED] Burning bootloader to Arduino Uno

Hey all.

Just got my first Arduino today, which was working fine until I decided to mess around with it :grin:

I set up the Arduino IDE which worked fine. Then I decided to try flashing it with an STK500 which I've used to flash other AVR's, this also worked fine. I connected the 6-pin ISP of the STK500 to the Uno and it flashed as expected. But when I wanted to reburn the bootloader I ran into problems...

I'm using Ubuntu, avr-gcc and avr-dude to play with my AVR's. Basically my problem is that I'm having trouble finding information about the correct lock bits and fuse settings for the atmega328p-pu that is plugged in my Uno board. As I've understood the correct bootloader to use is the file optiboot_atmega328.hex that exists in the $ARDUINO_HOME/hardware/arduino/bootloaders/optiboot directory.

I've read http://arduino.cc/en/Hacking/Bootloader?from=Main.Bootloader but the page doesn't list the 328-specific details. I tested with different settings, but something is wrong and I can't get the Uno programmed through the arduino IDE again. Presumably this is because the bootloader or some settings aren't as they should.

Here's what things look like at the moment:

  • Fuse and lock bits:
$ avrdude -p m328p -P /dev/ttyS0 -c stk500 -U efuse:r:-:h -U hfuse:r:-:h -U lfuse:r:-:h -U lock:r:-:h

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x1e950f
avrdude: reading efuse memory:

Reading | ################################################## | 100% 0.01s

avrdude: writing output file "<stdout>"
0x5
avrdude: reading hfuse memory:

Reading | ################################################## | 100% 0.01s

avrdude: writing output file "<stdout>"
0xcc
avrdude: reading lfuse memory:

Reading | ################################################## | 100% 0.01s

avrdude: writing output file "<stdout>"
0xdf
avrdude: reading lock memory:

Reading | ################################################## | 100% 0.01s

avrdude: writing output file "<stdout>"
0x3f

avrdude: safemode: Fuses OK

avrdude done.  Thank you.
  • parms and part info:
$ avrdude -p m328p -P /dev/ttyS0 -c stk500 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x1e950f
avrdude> parms
>>> parms 
Vtarget         : 5.1 V
SCK period      : 10.9 us
Varef           : 5.0 V
Oscillator      : 3.686 MHz
avrdude> part
>>> part 

AVR Part                      : ATMEGA328P
Chip Erase delay              : 9000 us
PAGEL                         : PD7
BS2                           : PC2
RESET disposition             : dedicated
RETRY pulse                   : SCK
serial program mode           : yes
parallel program mode         : yes
Timeout                       : 200
StabDelay                     : 100
CmdexeDelay                   : 25
SyncLoops                     : 32
ByteDelay                     : 0
PollIndex                     : 3
PollValue                     : 0x53
Memory Detail                 :

                         Block Poll               Page                       Polled
  Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
  ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
  eeprom        65     5     4    0 no       1024    4      0  3600  3600 0xff 0xff
  flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
  lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
  hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
  efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
  lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
  calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
  signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
  • I use the following command to try burning the bootloader on the 328:
$ avrdude -p m328p -P /dev/ttyS0 -c stk500 -U flash:w:optiboot_atmega328.hex 

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "optiboot_atmega328.hex"
avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
avrdude: writing flash (32748 bytes):

Writing | ################################################## | 100% 0.73s

avrdude: 32748 bytes of flash written
avrdude: verifying flash memory against optiboot_atmega328.hex:
avrdude: load data flash data from input file optiboot_atmega328.hex:
avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
avrdude: input file optiboot_atmega328.hex contains 32748 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 42.38s

avrdude: verifying ...
avrdude: 32748 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Flashing 32748 bytes for the bootloader seems a bit odd as I thought it was supposed to be 512 bytes, but the filesize is 1,4K:

$ ls -lh optiboot_atmega328.hex 
-rw-r--r-- 1 erichax erichax 1.4K 2011-04-06 22:46 optiboot_atmega328.hex

Can anyone please help me understand what I'm doing wrong here? For starters, info about correct fuse and lockbit settings and what bootloader file to use would be very helpful. I'm assuming that using the ISP on the STK500 with avrdude to flash the Uno with a bootloader is actually possible, am I correct about this?

Have you tried burning the bootloader through the Arduino IDE?

I don't have a programmer, so no. Now my atmega328 is busted anyway after I messed up the fuses. I set hfuse to 0b11011000 and lfuse 0b11000000, and i can't seem to do anything with it any more.. :~

erichax:
I don't have a programmer, so no

I suspect you misunderstand what I mean by "a programmer"...

I decided to try flashing it with an STK500

Do you have an STK500?

I set hfuse to 0b11011000 and lfuse 0b11000000, and i can't seem to do anything with it any more

With those values...

hfuse = 0b11011000 = 0xD8
lfuse = 0b11000000 = 0xC0

...run through my favourite fuse calculator...

http://www.engbedded.com/fusecalc/

...these two are still enabled (which is good)...

[X] Serial program downloading (SPI) enabled; [SPIEN=0]
[ ] Reset Disabled (Enable PC6 as i/o pin); [RSTDISBL=0]

But the clock is this (which is certainly inconvenient)...

    Ext Clock; Start-up time...

Do you have another processor? You could enable the clock-output and feed that to the errant processor.

Thanks for the help! I just managed to reset fuses to what I think is correct settings:

hfuse = DA
lfuse = FF
efuse = 05
unlock = 3F
lock = 0F

(from http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html#mega8_328)

I used an atmega8515L in another socket on the stk500. Got the working mcu to output 0 and 1 continuously on a pin, connected that pin to PB6 (XTAL1, external clock input pin) on the 328p, and could continue using avrdude as before!

I don't have a programmer, so no

I suspect you misunderstand what I mean by "a programmer"...

To burn the bootloader using the Arduino IDE, don't you need some sort of ISP or parallel programmer? I only have an stk500 and the Arduino w/ USB. The stk500 can do ISP, but is that compatible with the IDE?

Nevertheless, I still can't burn the bootloader correctly using avrdude/stk500. This is what i do:

$ avrdude -p m328p -P /dev/ttyS0 -c stk500 -U flash:w:optiboot_atmega328.hex 

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "optiboot_atmega328.hex"
avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
avrdude: writing flash (32748 bytes):

Writing | ################################################## | 100% 0.72s

avrdude: 32748 bytes of flash written
avrdude: verifying flash memory against optiboot_atmega328.hex:
avrdude: load data flash data from input file optiboot_atmega328.hex:
avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
avrdude: input file optiboot_atmega328.hex contains 32748 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 42.26s

avrdude: verifying ...
avrdude: 32748 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

[15:43:07]:[eric@eric-desktop ~]$ avrdude -p m328p -P /dev/ttyS0 -c stk500 -U lock:w:0x0F:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x1e950f
avrdude: reading input file "0x0F"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.03s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0F:
avrdude: load data lock data from input file 0x0F:
avrdude: input file 0x0F contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lock verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Everything looks fine as far as I can tell from the commands/output, but i can't upload sketches with Arduino IDE. Should I be using another bootloader? And why does avrdude think it contains 32K bytes, it obviously is a smaller file (1,388 KB).

Finally found the solution!

First I compiled and flashed optiboot+fuse&lock-bits using the makefile in $ARDUINO_HOME/hardware/arduino/bootloaders/optiboot (command 'make atmega328_isp') . When I still was having issues uploading sketches, I checked the ~/.arduino/preferences.txt-file, where I previously had changed the line 'upload.using=bootloader' to 'upload.using=stk500'. I thought I had changed it back to bootloader, but I hadn't.. So I changed it to use the bootloader and everything is now aok :grin:

So thanks for the help Coding Badly!

And if anyone else needs the commands and bits, this is how to upload the bootloader to the atmega328p using stk500, the right way:

  • set fuses and lock bits:
avrdude -c stk500 -p atmega328p -P /dev/ttyS0 -b 115200 -e -u -U lock:w:0x3f:m -U efuse:w:0x05:m -U hfuse:w:0xDE:m -U lfuse:w:0xFF:m
  • burn bootloader, and set lock bits to lock bootloader section:
avrdude -c stk500 -p atmega328p -P /dev/ttyS0 -b 115200 -U flash:w:optiboot_atmega328.hex -U lock:w:0x0f:m

And voila, you can use the Arduino IDE again!

So thanks for the help Coding Badly!

You are welcome and thank you for the follow-up.