Free USB JTAG Interface (FUJI)
The aim of this project is to create a free (as in free speech) JTAG interface which can be connected to all modern computers via USB. Several alternatives exist, but they're either proprietary (you can only buy it from a certain vendor at a made-up price) or require some $30+ part to be ordered from a US supplier. More information about the alternatives can be found in the appropriate section.
FUJI provides an interface between a USB port and the 25-pin D-sub parallel port interface of Digilent Inc. (JTAG3), because it's distributed for free with some FPGA boards (for example the Xilinx Spartan-3 Starter Kit) and it can be constructed easily (and quite frankly, because we already have one).
Current version
The current version interfaces with the PC natively (eg. without external circuitry) using V-USB under GPL license. FUJI presents itself as a low-speed (1,5 Mbps) HID device, but not as mouse, keyboard or joystick. This setup has the following advantages:
- The USB IDs allocated for V-USB can be used with zero cost.
- Communication is easy using the hid-data example of the vusb code.
- It can be used under Windows without external DLLs and the "Insert driver disc" window popping up all the time, and avoids the problem of the identification string being cached.
Most of the USB related code was copy-pasted from the V-USB hid-data example code for both the firmware and the host-side co
Our hardware implementation is based on the level conversion example of V-USB, and the firmware compiles fine and works using Atmega 168 clocked ad 16 MHz. Most of the settings are defined in firmware/usbconfig.h and firmware/Makefile, so if you'd like to give it a try using another MCU, this is where to find it.
Schematic
The following schematic connects to an Arduino like a shield, using the following pin headers.
- J1 (POWER): power headers, pin1 = 5V, pin2 = GND
- J2 (ANALOG): analog headers, pin1 = analog5 ... pin4 = analog2
- J3 (DIGITAL): digital headers, pin1 = digital2 ... pin3 = digital4
Board
The following board implements the schematic from the previous section in the form of an Arduino shield. This view reflects a viewpoint of looking from the point of the Arduino, so it'll be flipped horizontally if you look at it from above. At analog pin 3 it uses two vias and a jumper wire, because I couldn't route the wires any other way without sacrificing the opportunity to etch the board using cheap DIY methods.
Protocol
As of 7747457d the current version of FUJI uses a protocol that is an optimized version of the Arduino's. Because USB is synchronous and packet oriented (unlike RS-232 which is asynchronous and byte-oriented), sending a single bit of TDI in each packet would make the system very slow. To resolve this, the following optimizations had been implemented.
- If there is no need for reading (eg. bulk writes of bitfile uploads), the host caches write operations in 512 bit chunks.
- In a chunk, the last operation can be a read operation, thus one less packet is needed.
- In a byte, there is room for simple storage of two operations (2×3 data/control bits + 1 flag bit).
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
purpose | H_USED | HRX | HTMS | HTDI | - | LRX | LTMS | LTDI |
If the H_USED bit is set, the first operation is defined by the (higher) HRX, HTDI and HTMS bits. After this check, the operation defined by the (lower) LRX, LTDI and LTMS bits gets executed. The host packs the operations the same way, a 512 byte chunk can contain up to 1024 write or 1023 write + 1 read operations.
Results
The current version is still under development, but it's able to detect the chain and upload bitfiles. As USB is different in many ways from an UART connection, most of the ongoing development is about performance, as it can be seen in the following table.
Commit | Time needed to upload echo_out.bit | |||||||
3868dc92 | more than 1.5 hours | |||||||
e0920158 | 2m 17s | |||||||
18fe1cba | 1m 09s |
First Arduino version
The first version was developed as an Arduino sketch and communicated over RS-232 over USB at 115,200 bps. It served the purposes of experimentation and Arduino was chosen as a platform because of the advantages of fast prototyping. The protocol is very simple, one 8-bit byte is needed to be transferred over the serial connection for every JTAG cycle using the following pattern.
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
purpose | - | - | - | - | - | RX | TDI | TMS |
After a reception of a byte like the one above, the Arduino pulls TCK do ground, sets the TDI and TMS bits according to their respective bits in the packet and then pulls TCK to 5V again. The RX bit is set when a response is needed, and in that case, the Arduino replies with an 8-bit byte which has the LSB set according to the state of TDO. The byte is OR'd with 0x30 for the sake of easy debugging (results in ASCII 0s and 1s being sent back).
Results
This version had been tested with both chain detection and bitfile upload, and it worked for us, albeit a little bit slowly (because of the bandwidth and ineffective usage of the serial connection).
$ ./detectchain Waiting for Arduino to load the sketch... done IDCODE: 0x01414093 Desc: XC3S200 IR length: 6 IDCODE: 0xf5045093 Desc: PROM IR length: 8
Assembly
The Arduino version can be assembled pretty easily, the following parts are needed.- Arduino
- 25 pin female D-Sub connector
- wires (6 pieces of 10 cm)
D-Sub 25 pin | Arduino pin | Purpose | ||||||
2 | Digital 2 | TDI | ||||||
3 | Digital 3 | TCK | ||||||
4 | Digital 4 | TMS | ||||||
13 | Digital 5 | TDO | ||||||
16 | 5V | Power | ||||||
(case) | GND | Ground |
It's very important to connect the metal case of the LPT connector, because the Digilent JTAG3 cable uses it for grounding (which is not recommended in the specification in favor of pins 18-25).
After wiring up the connector, download the firmware from GitHub and upload it to the Arduino. After that, a modified version of xc3sprog can be used to detect the chain and upload bitfiles to an FPGA. Because of its "prototypeness" and structural reasons, the port name is hardcoded as /dev/ttyUSB0, if it's incorrect, it has to be edited in the appropriate .c file.
Alternatives
Product | Disadvandage | |||||||
Amontec JTAGkey | proprietary product for €129 | |||||||
Hubert Hoegl's USB to JTAG interfaces | needs FT2232C | |||||||
embedded projects GmbH JTAG interfaces | cheapest USB interface costs €34 | |||||||
Digilent Inc. JTAG USB cable | proprietary product for $47.95 |