Nav:  [home][elec][pdev][usb-atmelprg] > [software]
Go:  [index] [circuit] [firmware] [software] [levelcv] [openocd]

USB-AtmelPrg: Host Software for Flashing AVRs and Executing JTAG/SVF

USB-AtmelPrg is the native host software for the USB-AtmelPrg interface cable. It allows to in-system program ("flash") AVR (RISC) microcontrollers via SPI and can be used to program other parts like CPLDs by sending SVF files over the JTAG port.


Mar 2009: Version 1.4
Added support for ATMega644, ATMega164P, ATMega324P, ATMega644P. Now supports writing and reading flash and EEPROM with page-aligned offset (e.g. to flash a bootloader at 0x1c00). Minor bugfixes.
Nov 2007: Version 1.2
A new version with many new features: JTAG support improved; JTAG speed selection between 1MHz and 4kHz; support for arbitrary bitfield size in SVF files (required to program e.g. XC95144XL), new delay command to delay execution, added support for ATMega32, ATTiny13, ATTiny24 (and untested for ATTiny44, ATTiny84); minor bug fixes and enhancements. I'm sorry but there is again a new firmware (Rev 2.3) required for newly introduced JTAG speed selection.
May 2007: Version 1.0
Changed build system to use configure, added devices ATMega162 and ATTiny26, now needs 16MHz crystal and new firmware (Rev 2.2) on the interface cable size, new "extreme" speed grade for AVRs at 8 MHz and above (flash read 15kb/s), new command cmpflash speeds up verification for small firmware in large memories, JTAG ID scan.
May 2006: Version 0.9
New firmware Rev 2.0 implements pipelining and allows JTAG programming (e.g. of CPLDs) via SVF files.
Mar 2006: Version 0.7
New firmware Rev 1.2 fixes timing problems and allows IO speed selection. Other minor changes.
Jan 2006: Version 0.6
New firmware Rev 1.1 improves programming speed by a factor of 6; lots of minor changes improving usability.
Jan 2006: Version 0.5
Full support for ATTiny2313 implemented, added command sequencing via semicolon. Among minor other changes: Note that lock/fuse bit dump order is now reversed (compared to v0.4) now following common style in data sheets (highest bit first).
Oct 2005: Version 0.4
Support for ATMega8 added; full fuse/lock programming implemented.
Jul 2005: Version 0.3
Apart from fixing one diagnosis bug, this version adds support for the AT90S2313 device.
Jul 2005: Version 0.2: Initial release
This is the initial release of the software and I've used the USB-based programmer presented on these pages to successfully program an ATMega8515-based device.

Host Software for AVR Programming and Limited JTAG Support

I developed a host-side software for the interface cable which covers all functionality required to program AVR microcontrollers (erase, write, read flash and eeprom, read and write fuse bits; see below). Furthermore, the software allows to scan a JTAG chain for IDs and to execute SVF files (currently only for chains of length 1); see further down. The program features an interactive readline-based command line user interface with tab completion.

Note: Always use the latest software together with the latest firmware. If the software complains about an "unknown board", you need to update the firmware on the programmer. (Due to changes in the transfer protocol, recent software versions don't support old firmware versions.)
Firmware updates should be rare; Rev 2.2 should be considered mature.

Download and Build

The program is distributed as source code, only. It should compile without problems on any Linux-ix86 platform using the GNU C++ compiler (gcc). Note that you need the specified support libraries as well.

Source: usb-atmelprg-1.4.tar.gz   [151kb gzipped source tarball]
Version:1.4   (2009-03-24)
Author:Wolfgang Wieser   (report bugs here)
License:GNU GPL (Version 2)
Requires:(GNU readline,) libusb-0.1.12, libftdi-0.11

NOTE: The program is known to not operate correctly with some earlier versions of these libraries (libftdi, libusb). I try to keep it compatible to recent versions of the libraries.

Supported AVR Microcontrollers

Support for additional AVR controllers will be added as soon as I need it. Currently, the usb-atmelprg host software supports the following controllers:

  • AT90S2313 (2kb flash, 128b RAM, 15 IO; no fuse/lock access via SPI!)
  • ATTiny2313 (2kb flash, 128b RAM, max. 18 IO)
  • ATTiny13 (1kb flash, 64b RAM, max. 6 IO)
  • ATTiny26 (2kb flash, 128b RAM, max. 16 IO)
  • ATTiny24 (2kb flash, 128b RAM, max. 12 IO)
  • ATTiny44 (4kb flash, 256b RAM, max. 12 IO)
  • ATTiny84 (8kb flash, 512b RAM, max. 12 IO)
  • ATMega8 (8kb flash, 512b RAM, 22 (+1) IO)
  • ATMega8515 (8kb flash, 512b RAM, 35 IO)
  • ATMega162 (16kb flash, 1kb RAM, 35 IO)
  • ATMega32 (32kb flash, 2kb RAM, 32 IO)
  • ATMega644 (64kb flash, 4kb RAM, 32 IO)
  • ATMega164P (16kb flash, 1kb RAM, 32 IO)
  • ATMega324P (32kb flash, 2kb RAM, 32 IO)
  • ATMega644P (64kb flash, 4kb RAM, 32 IO)

Note that generally no change in the firmware is required for support of additional controllers, but instead the corresponding driver/description has to be added in the host software. The required additions to the host source code are not very hard; just take an existing similar controller and enter the right flash sizes and fuse/lock descriptions. If you added support for a new controller, please send me a patch so that I can include it in the official source code distribution.

Known Bugs and Limitations

  • Issue: You cannot use file/buffer names with spaces or semicolon inside.
    Solution: Don't do that or implement a fancy command parser which can handle these things. In my opinion, the required efford is not worth it.
  • Issue: Readline completion is not perfect.
    Solution: Send me a patch which corrects the problems :)
  • Issue: Pipelining is implemented on the host side for flash reads and JTAG SVF downloads but not yet for flash writes.
    Solution: Flash writes are fully functional just slightly slower. Relax. Or send me a patch.

First Steps for AVR Programming

So, if you have built the programmer board, configured the USB chip and downloaded the firmware (both described on the firmware page) and successfully compiled the program above, you can do the first steps:

First, re-connect the USB cable to the programmer, switch it on (i.e. put S1 into state 3; you should see the LED MAINPWR going on) and watch the syslog output: You should see that the USB device is recognized by the kernel. But in particular, no module should be loaded and claim the device (especially not ftdi-sio) because in that case the usb-atmelprg program will no longer be able to access the USB connection. (If you used the USB IDs described on the firmware page, you should not get any trouble with that.)

Next, become root and start usb-atmelprg. If you did not chose to use the standard 0403:6002 USB IDs, you need to set the FTDI_USB env var first.

bash# # normally not needed: export FTDI_USB=0403:6002
bash# ./usb-atmelprg
Opened USB connection to 0403:6002:
  Hardware: USB-AtmelPrg, Rev. 2/1
USB Atmel Programmer 1.0 by Wolfgang Wieser. Try `?' for help, ^D to quit.
atmelprg> _

Now, the first step is to check if a programmer is connected. You normally need not issue the ident command since it is done automatically when needed but it comes handy for initial testint:

atmelprg> ident
Connected to 0403:6002 (USB-AtmelPrg, Rev. 2/1):
  Device: USB AtmelPrg Rev 2.2
  Vendor: Wolfgang WIESER, 04/2007
  Firmware version: 0x202
  Protocol version: 5
atmelprg> _

If you see something like that (note that these strings except those in the first line are compiled into the firmware and not into the USB controller), then this is already a good sign.

Next, connect an AVR-based device to the 9-pin SUB-D connector and set the switch S2 correctly (see circuit page). The LED DEVPWR should be illuminated. Try to connect to the chip there. I assume the RESET pin is not externally controlled:

atmelprg> connect
Atmel chip:
  Name: ATMega8515  (Vendor: Atmel)
  Flash:    8192 bytes  [0x1000 words]   Pages: 64 bytes
  EEPROM:    512 bytes
atmelprg> _

Note also that it is normally not necessary to use the connect command since it is executed automatically when needed. However, some mostly older AVRs (like the AT90S2313) may have trouble entering the programming mode if the RESET line is not pulsed high and low before; in this case you may need to use 2 commands to connect: rh, then connect ("rh" is the short form for "r h"; this works because the connect command will automatically set the RESET line LOW; it is assumed that the RESET line is not externally controlled).

If the RESET pin is externally controlled (i.e. the programmer device cannot simply tie it low or high), use the command set ext_reset 1 before doing connect and make sure to get RESET LOW before trying to connect (otherwise it will fail).

Now, we can e.g. read the flash content, dump it, load a file to program, erase the chip download the flash content and so on... The commands would be (with output omitted):

atmelprg> readflash
atmelprg> dump flash
atmelprg> load firmware.bin
atmelprg> erase
atmelprg> writeflash firmware.bin
atmelprg> _

(Make sure to program the flash content binary and not an Intel HEX file (ihx) and also not an ELF format file; see compiling AVR firmware.) Finally, when done, or when the device with the new firmware needs to be tested, you must explicitly disconnect the programmer. This is done using the dc command.

atmelprg> dc
Programmer status:
  SCK: in:HIGH (P)     MOSI: in:HIGH (P)     RESET: in:HIGH (Z)
  D6:  in:HIGH (Z)     D7:   in:HIGH (Z)     D8:    in:HIGH (Z)
  LED: off             MISO: LOW
atmelprg> _

You can explicitly set the RESET pin LOW, HIGH and into High-Z state using the commands r l, r h and r z, respectively. This can come handy to manually reset the device to be programmed.

Finally note that there is tab completion, i.e. pressing tab should do completion on things which make sense (does not yet work perfectly) and that you can get a short online help using the ? command. To quit, just use Control-D as usual.

Now, let us quickly program the fuse bits to migrate from the 1MHz internal RC oscillator to the 8MHz one. The fuseL value used here is for the ATMega8515 (and ATMega8); other chips use similar fuse bit values; check the data sheet to be sure.
We begin with querying the current fuse/lock bits:

atmelprg> getfl
Lock bits: 0xff  (programmed=0)
  BLB1 2,1: 11   (see p.177)
  BLB0 2,1: 11   (see p.177)
  LB   2,1: 11   (unrestricted memory access)
Fuse low bits: 0xe1  (programmed=0)
  BODLEVEL:   1    (brown-out level 2.7V, see p.45)
  BODEN:      1    (brown-out detector disabled)
  SUT   1,0:  10
  CKSEL 3..0: 0001 (internal RC osc at 1 MHz)
Fuse high bits: 0xd9  (programmed=0)
  S8515C:     1    (AT90S4414/8515 compat mode disabled)
  WDTON:      1    (WDT off)
  SPIEN:      0    (SPI enabled)  [readonly]
  CKOPT:      1    (small output swing, see p.34)
  EESAVE:     1    (EEPROM erased at chip erase)
  BOOTSZ 1,0: 00   (boot size 1024 bytes, see p.175)
  BOOTRST:    1    (reset vector at address 0)
atmelprg> _

What we need to do is to change the CKSEL value from 0001 to 0100 leaving all other values unchanged. You may use setfl help for more information.
We first simulate (without writing; by specifying no exclamation mark) to be sure. Hence, we do:

atmelprg> setfl fuseL=0b11100100
Fuse low bits: 0xe4  (programmed=0)
  BODLEVEL:   1    (brown-out level 2.7V, see p.45)
  BODEN:      1    (brown-out detector disabled)
  SUT   1,0:  10
  CKSEL 3..0: 0100 (internal RC osc at 8 MHz)
Not actually writing anything ("!" not specified).
atmelprg> setfl fuseL=0b11100100 !
Fuse low bits: 0xe4  (programmed=0)
  BODLEVEL:   1    (brown-out level 2.7V, see p.45)
  BODEN:      1    (brown-out detector disabled)
  SUT   1,0:  10
  CKSEL 3..0: 0100 (internal RC osc at 8 MHz)
Writing: [fuseL]
atmelprg> _

Note that by writing improper fuse/lock bits (like wrong clock select, disabling reset pin, disabling SPI [should not be possible via SPI]) you can render your microcontroller inaccessible by the programmer. It is therefore highly recommended to first simulate and double-check the settings.

Similarly, one would use 0b11101000 for external clock but after that you cannot go on talking to the controller unless you actually have an external clock connected to the Atmel controller you wish to program.

Command sequencing: Since version 0.5, you can use the semicolon to separate commands. Like that, you can re-execute a set of commands simply by pressing up-arrow (previous command in readline history) and enter/return. Common example:

 atmelprg> load firmware.bin ; erase ; writeflash firmware.bin ; cmpflash firmware.bin ; dc

If you experience trouble with sequencing for commands which work when executed one-by-one, it may help to add a delay with optional delay time in msec:

 atmelprg> load firmware.bin ; erase ; delay ; writeflash firmware.bin ; ...

SPI: IO Speed Selection

Since software version 0.7 and firmware Rev 1.2, you can select different IO speeds for communication between the programmer and the device to be programmed. These are set using the set io_speed command, e.g.

atmelprg> set io_speed normal

It is important to understand the theory behind serial IO speed: The controller to be programmed runs at a certain internal frequency f. (In case things like "clock division by 8" (e.g. ATtiny2313) are activated, the internal clock is the divided/slower clock.) In order for serial communication to work, the LOW and HIGH pulses of the SCK signal pin must be several clock cycles wide at least (2 for most AVRs at 1MHz, see data sheet). Hence, LOW and HIGH times must be at least 2/f (seconds).

set io_speedSCK L/H timeExamples
extreme 0.562 usec AVR running at 8MHz or faster (4Mhz may work as well)
fast 1.125 usec AVR running at 2MHz or faster
normal 2.125 usec AVR running at 1MHz internal RC (or 8MHz and clock div. by 8)
20 20 usec ATtiny2313 running at 125kHz (1MHz int. RC with clock div. by 8)
80 80 usec AVR running on 32.768kHz standard clock crystal

The set io_speed command accepts an argument which is the time in microseconds (usec) to keep SCK LOW/HIGH. This must be at least 3. For faster operation, use the special keywords normal (default), fast and extreme; see table above. Note: The numerical value specifies a delay in usec, hence larger values make things go slower.

NOTE that you should always be on the safe side and make the timings slightly longer than required especially since the internal RC oscillators are not very precise. This is also the reason for the 1/8usec safety margin in the normal and fast modes.

If you change the IO speed while being connected to the AVR, the software will request a re-connect to be sure that the communication works with the selected speed. If you have trouble connecting to a device, try a slower IO speed (i.e. larger number).

Note: If you didn't understand everything, memorize that if you buy a recent AVR (like ATMegaXXX or ATtinyYYY) with an internal RC oscillator, it will run at 1MHz as of factory defaults and the default setting for the IO speed (normal) should work just fine.

First Steps for JTAG/SVF Programming

First, after connecting the cable to the JTAG port of the device to be programmed, we may want to see what device is connected. To read the so-called IDCODE, use jid. If the software knows the IDCODE, it will display additional information, e.g:

atmelprg> jid
JTAG ID code: 0x59604093 = 01011001011000000100000010010011
  Version:   5
  Manufact:  0x049   (Xilinx)
  Part num:  0x9604  (XC9572XL)
  Marker:    1       (should be 1)
atmelprg> _

Note that for SVF downloading it is not necessary that the usb-atmelprg software "knows" the connected device.

SVF (serial vector format) is a JTAG output specification. SVF files can be generated by CPLD/FPGA design/programming software as supplied by the respective vendors of such devices (such as ISE WebPACK from XILINX and similar tools from Altera or Lattice).

In order to execute an SVF file, first connect the CPLD (or whatever you wish to program) to the USB-AtmelPrg interface cable and then issue the svfprog command in the host software. Example:

atmelprg> svfprog test.svf
Programming SVF file: 186450 bits in 808 blocks...
Elapsed: 7927 msec (slept 2761 msec); rate: 9.810644 msec/pack
atmelprg> _

JTAG/SVF: Bugs and Limitations

Not all the SVF functionality is supported currently:

  • JTAG chaining: The JTAG port allows you to chain several devices so that only one port is needed to progam all the devices sequentially. Device chains can be scanned using the jscanid command but chaining is not yet supported for SVF files. (The software does not interprete the TIR/HIR/TDR/HDR commands from the SVF file which specify prefix and postfix bits. Support could be implemented in (software part) if the need arises.)
  • Defective cells: During SVF file downloading, the readback code from the JTAG port is checked against expected values thereby failing if they don't match. The standard allows to re-program individual cells if the check for one cell fails during programming but this feature is not supported. (So, the software will complain about the error but not try to correct it.) However, it does not seem to be a major flaw these days; during testing, I re-programmed my XC9500XL at least 100 times without getting a single error of that sort. So, why worry? If that unlikely thing really happens to you, download the file again and you're done.
    [Note that the program verification (which can usually be enabled when creating the SVF file) is correctly performed by USB-AtmelPrg's software since it's encoded in expected readback values for SVF commands.]

[home] [site map] [Impressum] [Datenschutz/privacy policy]
Valid HTML 4.01!
Copyright © 2005-2009 by Wolfgang Wieser
Last modified: 2009-04-04 17:39:38