Please do also take a look at AVRDebug, which can be used to adjust voltage levels.
Here's a file you'll find in the firmware-archive, too:
avrdev -- AVR programmer and debug helper
Jens Wilhelm Wulf, 2005
1. Purpose
There already are some programmers around, but I wanted to have additional
features:
- Provide several interfaces to the target hardware with adjustable
voltage levels: SPI, UART, TWI.
- Use any of these interfaces to connect to the target hardware while it
is up and running in order to read/write variables (debug helper).
- Modular software to make using different hardware implementations easy.
Porting to another hardware should touch not touch a large number of
files.
2. Origin
Lots of things (protocol for AVR109 and AVR910) have been taken from
Klaus Leidinger's avr910_2313_v37e.asm.
3. Usage
Use avrdude with -c butterfly for flash and eeprom, -c avr910 for the
rest. Some devices (8535) need to leave reset state and resync after memory
erase. Therefore use avrdude in two steps: first erase using -D, program
in a second step using -e to inhibit auto erase.
The application avrdebug can be used to adjust voltage levels.
4. Hardware
The simple variable voltage output is made using PWM output, an opamp and
transistors. At 5.0V supply voltage, the PWM outputs are able to provide
nearly 5V, but the opamp may not. I used a LM358, which gives 3.8V. However,
this is sufficient for an AVR, which recognizes high level at 0.6*VCC and
above. At VCC_max=5.5V it would be sufficient to provide 0.6*5.5V=3.3V. Use
a rail-to-rail type or the jumper to get higher voltages.
5. Debugging
Both the firmware on the adapter and the software on the host PC are not
designed to debug via SPI, UART and SELF at the same time.
I thought that
this will rarely be neccessary.
6. Optimization for speed in debug mode
Some things have been tweaked especially for usb<->serial converters, but
offer an enhancement with standard serial ports, too (see below). One can read a
range of addresses in one command and it is possible to send a set of
commands which are not answered before the whole block of commands has been
received. Using such a usb<->serial converter, exchanging a little number of
big packets is faster than a high number of small packets (half duplex mode).
Stateless communication is not used because the hardware is not able to
receive/send on its (hardware) uart and doing a software uart or spi at the
same time.
For example, my prototype has a buffer of 128 bytes to receive commands from
the host (PC). I tested writing 512 bytes on the target, which takes 512
single commands. Baudrate is only 19200 baud. The is no real communication
to a target (uDebugMode==DEBUG_SELF). The host PC runs linux 2.6.8. I measured
the complete runtime of the program, which includes some additional
communication not included in the calculation below (syncing to adapter,
reading status information).
commands: 512*6 Bytes (plus 25*6 Bytes when using command blocks)
replies: 512*2 Bytes
4096 Byte -> 2.13 seconds at 19200 baud
4246 Byte -> 2.21 seconds at 19200 baud
using a usb-serial converter:
time with command blocks : 2.8 s
time without command blocks : 8.6 s
using standard serial port:
time with command blocks : 2.6 s
time without command blocks : 4.0 s