Wednesday, February 1, 2012

AVR development with the Amtel AVR Dragon under OS-X

I've recently become interested in development with Amtel's AVR microprocessors.  After starting out with prebuilt Arduino boards I decided it was time to get closer to the metal. The primary motivation for this was cost: an AVR uC costs only a few bucks, while an Arduino Uno runs about $34. With this in mind, I picked up an Amtel AVR Dragon since my primary development machine is a MacBook without serial or parallel ports. The AVR dragon has a nice list of features, among them a small size for tossing in a bag and the ability to program over USB. However it takes a bit of work to get everything working properly, so I am posting this for others. It might also help me remember in case I forget. To get started, you need some software installed. I installed AVRDude via Homebrew. Make sure to include the --with-usb flag as this is needed for the AVR Dragon and is not set by default.$ brew install avrdude --with-usb

In my case, this command failed because of a conflict with MacPorts.  To work around this, I simply commented out the MacPorts changes to the $PATH environment variable set in my ~/.profile during the install. After AVRDude was installed, I reverted these changes and everything seems to be fine. I also installed AVRCrossPack, which provides an easy way to generate test projects and makefiles. After it is installed, simply type:$ avr-project  ProjectName

and it will generate the project and makefiles for you in the current directory.  These makefiles will not work with the AVR Dragon without editing. To set them up for the AVR Dragon, you need to set the programmer type.  Find this line in the makefile:

PROGRAMMER = ......

and change it to this:

PROGRAMMER = -c dragon_isp -P usb

to get AVRDude to use the AVR Dragon over USB.  You will also probably need to change the the line (nearby):

CHIP = .....

to match the chip you're actually trying to program, in my case the ATMega328p:

CHIP = atmega328p

You also need something to compile.  I changed the default main.c in the firmware directory of the project to this:

#include<avr/io.h>
#include<util/delay.h>

int main(void)
{

DDRD  = 0b00000001;
for(;;){
PORTD = 0b00000001;
_delay_ms(50);
PORTD = 0b00000000;
_delay_ms(50);
}
return 0;
}

which should flash an LED connected between Pin 2 and ground if the chip is successfully programmed.

Next, you need a bit of hardware to get going.  For this, I build a small programmer/prototyping board, effectively a *very* stripped down Arduino.  This board simply connects every pin from a 28-pin DIP socket and a 10-pin ICP socket to adjacent female headers.  The two centered rows of headers provide +5V and GND connections, and the whole mess is jumpered together.  Cheap, easy and versatile.  I also added a power LED just for kicks.

Given this hardware, I connect the power connections and make the appropriate connections for programming.  So far I haven't been able to get the 10-pin programming header working with the Dragon, but the beauty of this setup is that I can rewire it for the 6-pin header without any problems.

I used the following programming connections, you can find all of this in a variety of places:

ICSP Pin 1 (MISO) to ATMega328 pin 18
ICSP Pin 2 (VCC)  to ATMega328 pin7
ICSP Pin 3 (SCK) to ATMega328 pin 19
ICSP Pin 4 (MOSI) to ATMega328 pin 17
ICSP Pin 5 (RESET) to ATMega328 pin 1
ICSP Pin 6 (GND) to ATMega328 pin 8

Note that this only uses the first six pins of my 10-pin connector.  On the Dragon, these first six pins are connected to the six-pin ICSP header, with the remaining four pins hanging off in space.  If you use a six-pin ribbon cable and connectors, this can be avoided.

In addition to the programming connections, ATMega328 pin 22 must be connected to GND and pin 20 connected to +5V.  With this done and everything connected together, you should be able to program your chip.  Note that you need to provide +5V and GND connections to the board, the AVR Dragon does not power the board.  Open a terminal in the project directory and type the following:

$make avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=atmega328p -c main.c -o main.o avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=atmega328p -o main.elf main.o rm -f main.hex avr-objcopy -j .text -j .data -O ihex main.elf main.hex$ make flash
avrdude -c dragon_isp -P usb -p atmega328p -U flash:w:main.hex:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.15s

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: writing flash (174 bytes):

Writing | ################################################## | 100% 0.26s

avrdude: 174 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 174 bytes

Reading | ################################################## | 100% 0.15s

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

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

If all goes well, you should see something like the above. and the LED should start flashing.

As you can see, since the Dragon comes in a fancy box with no case, I, like others, just cut the cardboard to allow the USB and ICSP connections to be made and use the box as a case.

Hope this is helpful, it took me a number of tries to get all this to work properly, but now that it does I don't think I'll be using Arduinos as much anymore.