Saturday, January 30, 2010

Bootloader woes!

I have some AVR 328s that I'd like to upgrade to LadyAda's bootloader. Which has a couple of features for homemade arduino boards:

1. Three flashes on reset. Her bootloader flashes pin 13 when reset occurs.
2. Upload flicker on pin 13.

Although not absolutely necessary, it sure is nice to get the positive feedback that things are working when any number of things can go wrong with a home build duino.

The MegaISP seemed to work ok, but requires 2 arduinos to program a new Mega chip: one to run MegaISP, and one to house the chip to be programmed. I thought I could simplify things by buying this programmer, but it has been difficult to get this working.

Here is how I got it working on my Linux box.

1. Power the chip. The programmer does not supply the power to the chip as I discovered. So I was beating a dead horse for a day not knowing this simple fact.

2. Disconnect anything from the board. When I powered the board, I still got the same error. avrdude stk_500v2 not responding. I had an LED connected to pin 13 that I guess was sapping the signal from the micro back to the computer.

3. Plug programmer into usb port. You should see a device /dev/ttyACM0 or similar. That is the programmer. Green light on programmer should be on. If you are an avrdude guru, you probably already know to use the -P /dev/ttyACM0 option. I had trouble getting avrdude to write the efuse, so I tried using Arduino IDE to write the bootloader.

4. Unplug arduino from usb, power it with a 9v or otherwise through VIN. We are going to program the chip through /dev/ttyUSB0 and we don't want to figure out if USB0 is the programmer or the duino. Just unplug it from the usb all together and use external power.

5. Arduino IDE expects to see the programming sitting at /dev/ttyUSBX and it is actually at /dev/ttyACM0. The solution here is so simple I never thought it would work. Use a soft link. I don't remember where I found this solution, but it works.
> sudo ln -s /dev/ttyACM0 /dev/ttyUSB0

6. Select Tools->Burn Bootloader->w/AVRISP mkii. After a couple of minutes the bootloader is loaded.

7. Upload blink.pde. If this loaded congratulations. This worked for me with the standard bootloader: ATmegaBOOT_168_atmega328.hex.

8. Move standard bootloader for safekeeping, cd to Arduino/hardware/bootloaders/atmega/
> mv ... /bootloaders/atmega/ATmegaBOOT_168_atmega328.hex /bootloaders/atmega/ATmegaBOOT_168_atmega328.hex-orig

9. Copy AdaBoot to expected bootloader location
>mv ATmegaBOOT_xx8_adaboot328.hex /bootloaders/atmega/ATmegaBOOT_168_atmega328.hex

10. Tools->Burn Bootloader->w/AVRISP mkii (again)

11. Upload blink.pde. This is where I am stuck. Blink will not upload. I see this in the output window after I see the 3 blink reset (so I know adaboot is running):
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding

Manual reset (at different delays from upload click) makes no difference.

UPDATE!
LadyAda suggested that perhaps the baud rate for the hex file I was using was 19200. This turned out to be the case. I modified */hardware/boards.txt by changing

atmega328.upload.speed=57600

to
atmega328.upload.speed=19200

and got blink.pde to upload and run. Thanks LadyAda! The real fix is to upload the 57600 hex adaboot file. Look for an uplate when I get this to run.

UPDATE:
I recompiled LadyAda's AdaBoot with the baudrate changed to 57600. Download the hex file here.

Or, to compile it yourself:

Download and unzip AdaBoot.

Change the baudrate in the C source code will do the trick. Line 90 of the source code reads:
#define BAUD_RATE 19200

Change this to
#define BAUD_RATE 57600

Then from the command line:
> make adaboot328

If you have all everything you need installed you will generate a hex file. Or you can use this 57600 hex file if you don't.

To upload with avrdude only try just talking to the chip first:
> avrdude -c stk500v2 -p m328p -P /dev/ttyACM0
(change -P as necessary)

If that works, this script will upload the hex file using only avrdude
#!/bin/sh
# change -P as necessary
#
# find extended, high, low, lock, and unlock bits on hardware.txt
OPTS="-c stk500v2 -p m328p -P /dev/ttyACM0"
avrdude $OPTS -U efuse:w:0x05:m
avrdude $OPTS -U
hfuse:w:0xda:m
avrdude $OPTS -U lfuse:w:0xff:m

avrdude $OPTS -U lock:w:0x3f:m
avrdude $OPTS -U flash:w:ATmegaBOOT_xx8_adaboot328.hex:i
avrdude $OPTS -U lock:w:0x0f:m



Here is a picture of the programming setup.  I had to stack several 2 x 14 DIL sockets to make room for the 6 pin programming cable.  The green socket has a lever that releases the chip... handy.

AdaBoot: Succeed!

6-22-2010 Update:
I am pleased to confirm that this process works with fresh ATMEGA 328 chips (no previous bootloader installed).

May 30, 2011 UPDATE:
I just got a new set of MEGAs from digikey with a different device signature.
The old signature that avrdude expected is
"0x1e950f".

The chips I received with the same part number had a signature of
"0x1e9514".

There are two ways to handle this.  The easiest is to use the -F option with avrdude to force it into action regardless of the signature.  The second is to change the device signature in avrdude.conf (mine was located in /etc/avrdude.conf).  Search for 328, then search again for signature.  I commented out the existing line and modified it like so
# signature = 0x1e950f
signature =0x1e9514

This works like a charm until you need to program older chips in which case you need to revert to the original version.


No comments: