An FTDI FT2232H-based multi-protocol tool for hardware hacking.
There are plenty of -232H series breakout boards, but they are generally designed to be an easy way to adapt it to a specific use, and not designed for regularly plugging in to all different target systems.
The two exceptions are the Exodus Intelligence Hardware Interface Board which is not open hardware or commercially available, and TIMEP which is the origin and heritage of this project.
In general, Tigard was designed to work as-is with several tools and libraries that already support the x232H family of chips. This includes:
Highlights:
Starting with the board completely disconnected:
There are two switches on Tigard to set the mode of operation. One controls voltage, one controls how several of the IO pins are wired. Both need to be set properly for a specific use mode. Details are in each of the interface sections further below, but here is a summary of the modes and their uses:
This switch chooses the reference voltage for the level shifters and the target system:
This results in 3 distinct use cases:
This switch controls how some of the I/O pins are connected for specific uses:
The first of the two ports is connected to the UART header. When you plug Tigard in, you will see two serial devices show up - the first one is the one you want. Start your software using the appropriate serial port. For example:
screen /dev/ttyUSB0 115200
The SPI/I2C header is laid out to be the same orientation as the pins on a standard 8-pin SPI flash chip, making it easy to attach clips or sockets.
flashrom is the most common tool for SPI flash dumps. However, while pervasive, it is very slow and inefficient.
flashrom -p ft2232_spi:type=2232H,port=B,divisor=4
libmpsse is a powerful library for controlling the MPSSE, or high speed serial pins of the x232H series. However, it is no longer recommended because of a large number of dependencies
pyftdi is a new and simple interface very similar to libmpsse:
from pyftdi.ftdi import Ftdi
Ftdi.show_devices()
from os import environ
ftdi_url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232:1:23f/2')
from spiflash.serialflash import SerialFlashManager
flash=SerialFlashManager.get_flash_device(ftdi_url)
print("Flash device: %s @ SPI freq %0.1f MHz" % (flash, flash.spi_frequency/1E6))
f=open("data.bin","wb")
f.write(flash.read(0,len(flash)))
f.close()
The I2C header (on hardware versions 1.0 and later) is compatible with Sparkfun's Qwiic and Adafruit's STEMMA QT system:
In addition, the SPI header is laid out to be the same orientation as the pins on most 8-pin I2C chips, making it easy to attach clips or sockets:
Finally, the JTAG header can also be used to get the I2C signals on .1" individual pins:
In either case, you need to set the Tigard switches properly:
The FT2232H has a very limited I2C implementation. I2C depends on shared I/O lines using open collector/open drain instead of push-pull-tristate I/O, but the FT2232H doesn't support that well. Therefore:
To accomodate both I2C and SWD, the DI and DO lines are combined through resistor R16. This is required for SWD and acceptable for I2C. For the best I2C performance with the tradeoff of breaking SWD functionality, bridge the HACK solder jumper on the bottom. This will bypass resistor R16, shorting DI and DO when the MODE switch is set to SWD/I2C.
Many I2C targets already have pullup resistors. In addition, all of Tigard's I/O pins have a weak 100K ohm pullup. In testing, this has been sufficient for both in-circuit and external use of most I2C devices. If you need stronger pullups on I2C, you can temporarily add them by pulling up COPI and SCK on the SPI header, or TCK and TDI on the JTAG header.
libmpsse is a powerful library for controlling the MPSSE, or high speed serial pins of the x232H series. However, it is no longer recommended because of a large number of dependencies
pyftdi is a new and simple interface very similar to libmpsse:
from pyftdi.ftdi import Ftdi
Ftdi.show_devices()
from os import environ
ftdi_url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232:1:23f/2')
from i2cflash.serialeeprom import SerialEepromManager
flash = SerialEepromManager.get_flash_device(ftdi_url,'24AA32A',0x50)
flash.write(5,10)
flash.read(0,32)
The JTAG header is laid out with pins in the same order as the FTDI I/O pins are labeled, in order to be consistent with many other x232H breakout boards.
In additon, the CORTEX header is also wired as a standard ARM 10-pin JTAG header.
Be sure to select JTAG on the mode selection switch. This makes sure that TDI and TDO are separated, and ensures that TMS is wired properly to the CORTEX header. Otherwise, the standard hookup sequence applies.
OpenOCD is a powerful tool for On-Chip Debugging of ARM, MIPS, and some other architectures.
The appropriate configuration file (make this a link to the file) should look like:
interface ftdi
ftdi_vid_pid 0x0403 0x6010
ftdi_channel 1
adapter_khz 2000
ftdi_layout_init 0x0038 0x003b
ftdi_layout_signal nTRST -data 0x0010
ftdi_layout_signal nSRST -data 0x0020
transport select jtag
To use it with openocd:
openocd -f tigard-jtag.cfg
Boundary scan can be used to take control of a device to set I/O pin state (EXTEST
), or to view the state of them during device operation (SAMPLE
).
The hookup is the same as described in section JTAG Debug (on JTAG or CORTEX header).
The pinout is compatible with the Olimex ARM-USB-OCD
running on the B
interface.
UrJTAG is open-source jtag control software geared toward low-level and boundary scan use.
We need to tell UrJTAG Tigard's VID and PID, as well as the fact that JTAG is on interface 1 (default is 0). Due to a bug it seems that TCK is miscalculated and is actually running 5 times what you select - 500khz in the case below.
jtag> cable ft2232 vid=0x403 pid=0x6010 interface=1
Connected to libftdi driver.
jtag> frequency 100000
Setting TCK frequency to 100000 Hz
jtag> detect
IR length: 5
Chain length: 1
Device ID: 00010110001101010010001001001111 (0x1635224F)
Unknown manufacturer! (00100100111) (/usr/share/urjtag/MANUFACTURERS)
jtag>
The TopJTAG software is one of the easier to use options, but is commercial ($100) and Windows-only. This includes a "waveform view" that allows you to view arbitrary pin states as if you had a logic analyzer on the device while it is running. If using TopJTAG, set the following as the JTAG connection:
Connection
: Generic FTDI FT2232Device
: Tigard V1.0 BStatic Pins
: Olimex ARM-USB-OCDTCK Freq
: 2 MHz (adjust as needed)An open-source option that supports Tigard is JTAG Boundary Scanner which offers a Windows GUI, but the backend library is cross-platform (however written in C). This library offers many features such as an ability to talk to SPI devices attached to the target chip, where the SPI interface is run using JTAG boundary scan (warning - slow!).
Alpha Python bindings for this library are available in PyJTAGBS. Using Tigard from Python for checking the scan chain for example:
from jtagbs import JTAGCore, JTAGBS
interface = JTAGCore()
jtag = JTAGBS(interface)
probes = jtag.list_available_probes()
print(probes)
jtag.open_probe('Tigard V1.0 B')
jtag.init_scanchain()
print(jtag.list_devids())
See the PyJTAGBS documentation for further examples of loading BSDL files required to toggle specific pins. The listed probes should be 'Tigard V1.0 A TG100065A'
and 'Tigard V1.0 B TG100065B'
if the correct drivers are loaded.
The SWD header a standard 10-pin header found on many SWD target boards. A short 'SWD' cable with the same header on both ends is the ideal way to hook up to most targets.
Be sure to select SWD on the mode selection switch. This connects the DI and DO pins with resistor R16 to make the bidirectional SWDIO pin, and connect it to pin 2 of the CORTEX header. Otherwise, the standard hookup sequence applies.
OpenOCD is a powerful tool for On-Chip Debugging of ARM, MIPS, and some other architectures. In order to use it for SWD with Tigard, you'll need to build it from source. The directions from the AND!XOR DC27 Badge cover it step-by-step.
The appropriate configuration file (make this a link to the file) should look like:
adapter driver ftdi
transport select swd
ftdi_vid_pid 0x0403 0x6010
ftdi_channel 1
adapter speed 2000
ftdi_layout_init 0x0028 0x002b
ftdi_layout_signal SWD_EN -data 0
ftdi_layout_signal nSRST -data 0x0020
To use it with openocd:
openocd -f tigard-swd.cfg
The Lattice iCE40 family of FPGAs are popular for small scale projects because of their low cost and the availability of an open toolchain. While this is a very specific target, Tigard is well suited for programming devices since it has all the necessary pins readily available.
All the necessary pins are on the JTAG header. The bonus "!?" pin is not populated by default. The JTAG !? pin and the UART RX pin are shorted in case you need to flash an iCE40 but don't want to solder your Tigard. See the pinouts table below for details.
Be sure to select JTAG/SPI on the mode selection switch. This makes sure that COPI and CIPO are separated.
If you are planning on programming SRAM instead of FLASH:
To program your target's nonvolatile FLASH, use iceprog:
iceprog -I B yourbitstream.bin
If you prefer to directly program the ice40's SRAM, make sure you adjust your wiring and again use iceprog:
iceprog -I B -S yourbitstream.bin
Remember that if you choose to program the SRAM, your bitstream will be lost on power cycle.
To program AVR microcontrollers including many Arduino boards, use avrdude with a custom configuration file.
Be sure to select JTAG/SPI on the mode selection switch. Use SRST as your reset.
Avrdude is an open-source AVR flashing utility. Avrdude 7.1 and later have built-in support for Tigard - all you need to do is:
avrdude -c tigard
For older versions, create the following tigard.conf
file in order to identify Tigard as an avrftdi-compatible device and specify which pins to use:
programmer
parent "avrftdi"
id = "tigard";
desc = "Tigard interface board";
usbdev = "B";
sck = 0;
mosi = 1;
miso = 2;
reset = 5;
;
Then, use -C +tigard.conf
to add the configuration file, and -c tigard
to indicate your programmer:
avrdude -C +tigard.conf -c tigard
This will turn on when the board has USB power and should turn on immediately when the USB cable is connected.
This will turn on when the FTDI chip is operation and should turn on a moment after the usb power LED is on.
This will turn on when the level shifters are properly powered, either by your target or by the onboard level selector
When all LEDS are on, then Tigard is probably working as intended. If you are still having trouble, there are a few possibilities. They are listed in order of likelihood, though it makes sense to test the easier cases first:
There are way too many choices of 'standard' pinouts for all of these interfaces. Pinouts were chosen for ease of use, specificially:
This pinout prioritizes putting the FT2232H pins in sequential order - similar to many x232H breakout boards
The coloring of the wiring harness is intended to match most common usb-serial cables
Pin Number | UART Signal | Color | FT2232H Pin |
---|---|---|---|
1 | VTGT | Red | -- |
2 | GDD | Black | -- |
3 | TX | Green | AD0 |
4 | RX | White | AD1 |
5 | RTS | -- | AD2 |
6 | CTS | -- | AD3 |
7 | DTR | -- | AD4 |
8 | DSR | -- | AD5 |
9 | DCD | -- | AD6 |
This is a standard pinout. In order to accomodate both SWD and JTAG, the mode switch:
Pin Number | SWD Signal | FT2232H Pin | JTAG Signal | FT2232H Pin |
---|---|---|---|---|
1 | VTGT | -- | VTGT | -- |
2 | SWDIO | BD1 BD2 | TMS | BD3 |
3 | GND | -- | GND | -- |
4 | SWDCLK | BD0 | TCK | BD0 |
5 | GND | -- | GND | -- |
6 | NC | -- | TDO | BD2 |
7 | KEY | -- | KEY | -- |
8 | NC | -- | TDI | BD1 |
9 | GND | -- | GND | -- |
10 | nSRST | BD5 | nSRST | BD5 |
This pinout prioritizes putting the FT2232H pins in sequential order - similar to many x232H breakout boards.
In general, set the mode switch to SPI/JTAG mode when using this connector.
The coloring of the wiring harness is what SecuringHardware.com used for their Adafruit FT232H wiring harness for several years. The colors were chosen because frequently black-brown-red-orange are used with logic analyzers in class, so unique colors were chosen for this wiring harness.
This header can also be used for I2C and SPI if the 8-pin header doesn't make sense in your application.
Pin Number | JTAG Pin | Color | FT2232H Pin |
---|---|---|---|
1 | VTGT | Red | -- |
2 | GND | Black | -- |
3 | TCK | White | BD0 |
4 | TDI | Grey | BD1 |
5 | TDO | Purple | BD2 |
6 | TMS | Blue | BD3 |
7 | TRST | Green | BD4 |
8 | SRST | Yellow | BD5 |
This header is designed specifically to match the pinout of most 8-pin SPI and I2C chips, so that a jumper to a chip clip or a socket would align properly.
In order to accomodate both SPI and I2C, the mode switch:
Chip Pin Number | Header Pin Number | SPI signal | FT2232H Pin |
---|---|---|---|
1 | 1 | CS | BD3 |
2 | 3 | CIPO | BD2 |
3 | 5 | WP | pullup |
4 | 7 | GND | -- |
5 | 8 | COPI | BD1 |
6 | 6 | SCK | BD0 |
7 | 4 | EN | pullup |
8 | 2 | VTGT | -- |
The LA port makes it easier to hook up a logic analyzer to monitoring push-pull signals between Tigard and your target hardware. It's tested and working well with UART, SPI and JTAG, and generally works with I2C.
While there is a driver allowing you to use the FT2232H as a makeshift logic analyzer, that's not the intended purpose - the expected use case is that you are using Tigard to communicate with a target, but need to debug that communication using an external logic analyzer.
The LA port may be used as a passive mechanical adapter although this usage is not supported. For best results, power the Tigard board but disconnect VTGT from the target. Additional effort will likely be required to ensure signal integrity.
This header is specifically designed to connect directly to the Bitmagic logic analyzer, or you could use the Bitmagic logic analyzer wiring harness to connect to any other tool.
The 8 most interesting signals are connected - 6 from the JTAG/SWD/SPI/I2C port, and 2 from the UART port.
Pin Number | Bitmagic Signal | FT2232 Pin | JTAG signal | SPI signal | SWD Signal | I2C Signal | UART Signal |
---|---|---|---|---|---|---|---|
1 | xPB0 | BD0 | TCK | SCK | SWCLK | SCL | |
2 | xPB1 | BD1 | TDI | COPI | SWDIO | SDA | |
3 | xPB2 | BD2 | TDO | CIPO | SWDIO | SDA | |
4 | xPB3 | BD3 | TMS | CS | |||
5 | xPB4 | BD4 | TRST | ||||
6 | xPB5 | BD5 | SRST | ||||
7 | xPB6 | AD0 | TX | ||||
8 | xPB7 | AD1 | RX | ||||
9 | GND | ||||||
10 | GND | ||||||
11 | xTRIG | ||||||
12 | xCLK | ||||||
13 | xTRIG2 | ||||||
14 | xIFCLK |
This header is designed specifically to match Sparkfun's Qwiic and Adafruit's STEMMA QT system.
Set the mode switch to I2C/SWD mode when using this connector.
Pin Number | I2C signal | FT2232H Pin |
---|---|---|
1 | GND | --- |
2 | VCC | --- |
3 | SDA | BD1 and BD2 |
4 | SCL | BD0 |
Use the JTAG header with the addition of the "!?" pin which is not populated by default.
Pin Number | Label | iCE40 Signal | FT2232 Pin |
---|---|---|---|
1 | VTGT | VTGT | --- |
2 | GND | GND | --- |
3 | TCK | CLK | BD0 |
4 | TDI/MOSI/SDA | MOSI/COPI | BD1 |
5 | TDO/MISO/-- | MISO/CIPO | BD2 |
6 | TMS/SS/-- | --- | --- |
7 | TRST/--/-- | CS/ICE_SS_B | BD4 |
8 | SRST/--/-- | CRESET | BD5 |
9 | !? | CDONE | BD6 |
JTAG !? pin and the UART RX pin are shorted in case you need to flash an iCE40 but don't want to solder your Tigard.
The common 6-pin ICSP header found on many AVR boards requires the following hookup:
Pin Number | Label | ISP Signal | ICSP Pin | FT2232 Pin |
---|---|---|---|---|
1 | VTGT | VTGT | 2 | --- |
2 | GND | GND | 6 | --- |
3 | TCK | SCK | 3 | BD0 |
4 | TDI/MOSI/SDA | MOSI | 4 | BD1 |
5 | TDO/MISO/-- | MISO | 1 | BD2 |
6 | TMS/SS/-- | --- | --- | --- |
7 | TRST/--/-- | --- | --- | --- |
8 | SRST/--/-- | RST | 5 | BD5 |
In order to support different interfaces, custom wiring harnesses or add-on boards might be useful. The preferred names are "Tigard Stripes" for add-on boards and "Tigard Tails" for wiring harnesses.
UART Tail
ships with Tigard and includes VTGT, GND, TX and RXJTAG Tail
ships with Tigard and includes labeled multipurpose JTAG, SPI, and I2C wiresSOIC8 Tail
refers to inexpensive SOIC-8 clips with ribbon cables and 2x4 connectors compatible with the SPI/I2C headerTigard is supplied as a bare board, but there are several options for 3d printing mounts and cases - 'dens' - for your Tigard.:
Tigard follows a convention for allocating serial numbers. If you decide to make and sell your own Tigards, please change the first two characters "TG" to something else.
Format: TGMmxxxx
TG
- constant indicates "tigard"M
- major version decimal numberm
- minor version decimal numberxxxx
- 0 padded lowercase hex serial starting at 0Tigard can be purchased directly from Crowd Supply, Mouser, or 1BitSquared
Tigard can be aquired in Europe via 1BitSquared's German store
10+ boards can be ordered at a discount direct from SecuringHardware.com
Tigard is published with the CC-BY-SA 4.0 License. This means you have permission and are encouraged to make your own devices, or make modifications to the Tigard design, as long as you attribute the project and share your changes.
If you choose to manufacture your own tigard boards, we recommend/request the following:
SecuringHardware.com tests, verifies, and supports every Tigard they manufacture and sell. Please let us know about any design issues while making your own devices, but if you're having hardware issues with a third-party Tigard that you bought, you will need to resolve that with the seller or manufacturer.