USB-AtmelPrg: Interface Cable Circuit
About this Design
Since I had the opportunity to have PCBs manufactured the next day (while the next chance would have been weeks later), this is pretty much a one-afternoon design:
I wanted a USB connection, so I mounted an already-designed USB8Bit board with minor modifications. In order to handle all the handshaking etc., the easiest thing was to mount another microcontroller, so I chose an ATMega8: It has 8kb of flash (which should suffice), an internal RC oscillator and can be bought in a narrow 28-pin DIL package which allows to easily put it on a socket which is done because the microcontroller is directly connected to the 9-pin SUB-D port.
The USB interface is a slightly unmodified version of the USB8Bit board.
The power enable (_PWREN) and send immediate/wake up (SI/WU) pins are connected to a pin header for external connection if needed; but in this case they are simply left unconnected.
The USB reset pin (USB-RESET) should be left unconnected as well. It is suitably internally biased using R13 and R16.
One feature design intent was versatility concerning power supply. In short, the interface cable supports USB-powered operation, 5V supply, 8-30V supply and supply by the device to be programmed. Furthermore, it can itself provide a 5V supply the device to be programmed.
The main power switch is S1 which should be an "on-off-on" type with a stable middle "off" state. Power connection to the device to be programmed is controlled via S2 which should be an "on-on" type without middle state. The main power indicators are the LEDs MAINPWR (in series with R6) which is supposed to be a green LED indicating power being applied to the programmer and DEVPWR (in series with R2) which signals power on the device side (i.e. the 9-pin SUB-D connector).
There are several power hubs/connectors (SUPPLY, EXTSUP, PWR-HUP and SUP-HUP) which are not all needed for operation but they may come handy at one point to attach external circuits or just ground returns.
NOTE: You must not switch S2 into state 1 if both the device to be programmed and the cable itself are supplied by their own power sources. Otherwise, huge compensation currents will flow.
Interface to Device to be Programmed
The connection to the device to be programmed is all done via a 9-pin SUB-D connector. The USB-AtmelPrg interface cable should have a male connector attached and the devices to be programmed either a female SUB-D or a 6-port linear pin header (see below). The SUB-D ports can either be directly connected or using a standard 1:1 9-pin SUB-D expansion cable (I'm using 1.5 meter).
The pinout of the SUB-D connector is fixed and includes the 3 SPI lines
(serial programming interface of the Atmel AVR RISC controllers:
MOSI, MISO, SCK), the RESET line to be able to control the reset from
the programmer and 2 supply lines (see above).
The pins D6, D7, D8 are general-purpose diagnosis I/O lines which do not have to be connected at all. They can, however, to ease debugging of microcontroller-based circuits.
The RESET pin in the 9-pin SUB-D connector normally controls the RESET line to the AVR-RISC controller to be programmed. This line should be pulled high in the device using a 100k resistor so that the device is running (and not reset) in normal operation when no programmer is connected. You can also (although this is not recommended) use an "externally controlled" RESET pin, i.e. control the RESET line using some other means (e.g. by a switch in the device). In this case, the programmer must be informed to keep the RESET line in High-Z state. (The software supports that.) In JTAG mode, the RESET pin changes its meaning to TDO and D8 is an additional open-drain-like microcontroller reset used by OpenOCD.
The common 6-pin SPI or JTAG connector (pin header style) used by me has the following fixed pinout:
About the Controller in the Circuit and How To Program It
Apart from the low-level USB handling, all work is done by the Atmega8 AVR RISC mounted on the USB-AtmelPrg board. I chose a 28-pin DIL package mounted on a socket so that the chip can easily be replaced in case it gets destroyed due to improper use of the programming interface (i.e. the 9-pin SUB-D connector).
The connection to the USB controller is done via a 4-bit "nibble" bus. This means that in order to transmit one byte from the host to the ATMega8, 2 nibbles need to be transferred and hence there are also 2 bytes on the USB wire. Only the bits 4,5,6,7 from each byte transferred via the USB are used. There are 2 reasons for that: Firstly, the ATMega8 simply does not have enough free pins to connect all 8 bits. And secondly, I wanted to have the option to directly program the firmware onto the ATMega8 wihtout an external programmer device ("bitbang self-programming"), see below.
Additionally, I mounted a (red) LED (LEDRED) and a push button (SW-PRESS) to be used arbitrarily by the firmware. In order to provide a clock for the programmer, the internal RC oscillator (at 1,2,4 or 8 MHz) can be used. Optionally, one can mount the crystal and its 2 ancillary capacitors near pins 9 and 10 of the ATMega8. Note that if you do so, you need to program the CKSEL fuse bits accordingly and note also that the firmware needs to be designed specifically for the chosen clock. The current firmware requires the external 16MHz crystal and fuse settings which make the ATMega8 run at its full speed (16MHz).
The ATMega8 must be programmed with suitable firmware before the programmer can operate. Initially, the plan was to allow the ATMega8 to be programmed directly from the USB by putting the FT245BM into "bit-bang" mode at a suitable baud rate and use the bits 0,1,2 of the USB data bus (UD) connected to the SPI interface of the ATMega8. Since the FT245BM even has the possibility to query the status of all its pins, one can do status readback as well. It is supposed to be quite slow but should work in theory. Unfortunately (since I did have a parport-based programmer initially and two USB-AtmelPrg cables nowadays), I went the easier way to get the firmware onto the ATMega8. Hence, this approach has not been tested yet and there is no software for that purpose. (If you succeeded, please let me know! You need to put a jumper between pins 4 and 5 of the 6-pin SPI pin header.)
The 6 pins of the SPI connector provide all the lines which are necessary to do in-system programming of the ATMega8. The pinout is the same as that of the "common 6-pin SPI connector" described above. A second USB-AtmelPrg can easily be used to program the ATMega8 on the first one.
Interface Cable Board