If you have our XCP1 JTAG adapter (which is usually used to program Xilinx CPLDs) you can also use it to program Atmel AVR microprocessors via JTAG (and you can use it for non-JTAG parts, as well). In fact, you could probably use our Altera-style JTAG interface for the same purpose, but the Xilinx board will easily plug directly into a solderless breadboard (if you have the female socket on the XCP1, you can simply insert some header pins to interface it to the breadboard).

There are two basic methods you can use. First, you can use the JTAG adapter for JTAG (but this only works on some AVR chips). Second, you can use a "universal" programmer like UISP that knows how to drive a Xilinx cable.

By the way, did you know it is easy to use our PAK coprocessors to offload tasks like floating point math when using gcc or AVR assembly? Read more about it here.

JTAG

Only certain AVR micros use JTAG and you can program their fuses to ignore the JTAG pins. However, a fresh chip will program using this method since the default setup is to allow JTAG. In particular, you can program ATMega16, ATMega162, ATMega169, ATMega32, ATMega64, and ATMega128 parts. Of course, some of these are surface mount, so you'll have to make your own connections to the JTAG port.

I used a 40 pin DIP ATMega162 part, so my instructions will assume that's what you are using. The basic steps are simple:

  1. Generate a hex file in the usual way.
  2. Convert the hex file to a Serial Vector Format (SVF) file.
  3. Convert the SVF file to a JAM file.
  4. Use a "JAM Player" to download the file to the processor.

The first thing you need is a hex file you want to program. I entered this simple program into AVR Studio (Atmel's free IDE and assembler):

;A simple program 
.include "m162def.inc" ;Includes the m162 definitions file

.def Temp = R16 ; Variables
.def delayer = R17

.org 0x0000 ;Places the following code from address 0x0000
rjmp RESET ;Take a Relative Jump to the RESET Label

RESET: 
ldi Temp,HIGH(RAMEND)
out SPH,Temp
ldi Temp,LOW(RAMEND) ; Set initial stack ptr location at ram end
out SPL,Temp

ldi Temp, 0xFF ;Store 255 in Temp
out DDRB, Temp ;Save in The PORTB DDR (make PORTB all outputs)
Loop: 
out PORTB, Temp ;Write Temp to PORTB
dec Temp ;Decrement Temp
rcall delay ; waste some time
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rjmp Loop ; Do some more

; This just kills some time
delay:
ldi delayer,0xFF
Dloop:
dec delayer
brne Dloop
ret 

Compiled, this generates a HEX file (here it is for download).

Next, you need a few programs -- avrsvf, svf2jam, and jam. The first program is from Atmel and the other two are from Altera. You can find all the files you need at this site (which includes some other interesting files) or try the Atmel Download Page and the Altera JAM Page.

Suppose you have a file called avrtest.hex and you want the fuse word to be 0x9962. Here are the commands you have to issue:

avrsvf -datmega162 -s -e -ifavrtest.hex -pf -vf -F -ovavrtest.svf -mp -f0x9962

svf2jam avrtest.svf avrtest.jam

This results in a file, avrtest.jam, that is ready for JTAG programming with the JAM player. The arguments to avrsvf are:

-d = Device type
-s = Verify signature
-e = Erase before program
-if = Input file
-pf = Program flash
-vf = Verify flash
-f = Set fuses
-F = Verify fuses
-ov = Output vector file
-mp = Use pageload mode (omit if more than one device in JTAG chain)

The final step is to use the JAM player to download the code. Place your ATMega162 into a solderless breadboard (or some other hookup method). Connect pin 40 to +5V and pin 20 to ground. You should also connect RESET to +5V or ground (it doesn't really matter which). Then you need to connect the JTAG adapter. The markings on the board will guide you. The first pin is +5V and the second pin is ground. Then you need to make the following connections:

XCP1 pin ATMega162 pin JTAG Pin
3 25 TCK
4 27 TDO
5 28 TDI
6 26 TMS

Next, issue this command line:

jam -v -cx -arun_file avrtest.jam

If you aren't using LPT1, add a -p option (so for LPT2, add -p2). The -cx is specific to the Xilinx-style interface, so if you are using the ACP1, you'll omit it. The output looks like this:

CRC matched: CRC value = 101C
NOTE "CREATOR" = "SVF2JAM Converter version: 2.2 "
NOTE "SVF_COMPLIANCE" = "SVF Revision E"
NOTE "DATE" = "2003/12/18"
NOTE "STAPL_VERSION" = "JESD71"
NOTE "MAX_FREQ" = "10000000"
SUCCESSFUL JAM EXECUTION, VERIFY PASS
Exit code = 0... Success
Elapsed time = 00:00:00
Jam STAPL Player Version 2.3
Copyright (C) 1997-2000 Altera Corporation

If you have the internal clock set (for example, if your fuse word is 0x9962) you can move RESET to +5V and the chip will start running. Put an LED on PORT B bit 7 (pin 8 of the chip) and you'll see it blink.

I made a batch file called program.bat that does all three steps in one piece:

avrsvf -datmega162 -s -e -if%1.hex -pf -vf -F -ov%1.svf -mp -f%2
svf2jam %1.svf %1.jam
jam -v -cx -arun_file %1.jam

Be sure to add the -p command if you are using a different LPT port. Then you just issue the command: program avrtest 0x9962

That's it! Now you can program AVR microprocessors with your XCP1 JTAG adapter.

UISP

You can use UISP (http://savannah.nongnu.org/projects/uisp/) to program an AVR chip with the XCP1 (or the ACP1). This is a more general-purpose method, but it doesn't use the JTAG adapter for JTAG -- it simply uses it as a parallel port interface. That means it will work with AVR parts that don't have a JTAG port. Of course, you need to connect +5 and Ground to the JTAG adapter and the AVR chip. Connect the rest of the pins like this:

XCP1 pin ATMega162 pin AVR Pin
3 8 SCK
4 7 MISO
5 6 MOSI
6 9 RESET

That's it! Here is a typical download command:

uisp -dprog=xil -dlpt=0x378 -dpart=atmega162 --erase --upload if=aaw.hex --wr_fuse_l=0x62 --wr_fuse_h=0x99 --verify

And the corresponding output:

Atmel AVR ATmega162 is found.
Erasing device ...
Reinitializing device
Atmel AVR ATmega162 is found.
Uploading: flash
Verifying: flash

Fuse Low Byte set to 0x62

Fuse High Byte set to 0x99

One thing to remember is that some AVR parts don't have an internal clock (or you may have the internal clock shut down). In that case, you'll need to put a clock source into the oscillator pins. For example, when programming an AT90S8515, I put an 8MHz crystal between pins 38 and 39. Otherwise, the programming will fail.

Other AVR Resources

AVR Assembly Language for PAK Interfacing

AVR gcc PAK Library


Site contents © 1997-2014 by AWC, 310 Ivy Glen, League City, TX 77573    (281) 334-4341