tigard-tools / tigard

An FTDI FT2232H-based multi-protocol tool for hardware hacking
Other
619 stars 75 forks source link
Tigard PCB Render

Tigard

An FTDI FT2232H-based multi-protocol tool for hardware hacking.

Objectives

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.

Contents

Software Features

In general, Tigard was designed to work as-is with several tools and libraries that already support the x232H family of chips. This includes:

Hardware Features

Highlights:

Usage

Hardware Hookup

Starting with the board completely disconnected:

  1. Connect board to target system with clips or jumper wires
  2. Select the correct mode either SPI/JTAG or SWD/I2C
  3. Ensure that the voltage switch is in VTGT mode
  4. Plug in the USB cable. The PWR and EN LEDs will illuminate
  5. Power on your target.
  6. If you connected VTGT to your target, the VTGT LED will illuminate. If not, you can now select your voltage with the voltage switch

Switches

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:

Voltage Switch

This switch chooses the reference voltage for the level shifters and the target system:

This results in 3 distinct use cases:

  1. Target-Powered: Set the switch to VTGT and connect the VTGT wire to the powered target. The target powers the level shifters.
  2. Tigard-Powered: Set the switch to a voltage, and connect the VTGT to the unpowered target. Tigard supplies power to the target.
  3. Self-Powered: Set the switch to a voltage, but do NOT connect the VTGT wire. Tigard powers its own level shifters. Target powers itself.

Mode Switch

This switch controls how some of the I/O pins are connected for specific uses:

UART

Hookup:

Software:

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

SPI

Hookup:

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.

Software:

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()

I2C (on I2C, SPI, or JTAG header)

Hookup:

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:

Quirks:

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:

Hacks:

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.

Software:

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)

JTAG Debug (on JTAG or CORTEX header)

Hookup:

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.

Software:

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

JTAG Boundary Scan (on JTAG or CORTEX header)

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).

Hookup:

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.

Software:

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:

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.

SWD (on CORTEX header)

Hookup:

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.

Software:

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

iCE40 Programming

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.

Hookup:

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:

Software:

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.

AVR ISP

To program AVR microcontrollers including many Arduino boards, use avrdude with a custom configuration file.

Hookup:

Be sure to select JTAG/SPI on the mode selection switch. Use SRST as your reset.

Software:

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

Debugging

PWR LED:

This will turn on when the board has USB power and should turn on immediately when the USB cable is connected.

EN LED:

This will turn on when the FTDI chip is operation and should turn on a moment after the usb power LED is on.

VTGT LED:

This will turn on when the level shifters are properly powered, either by your target or by the onboard level selector

ALL LEDS ON:

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:

Pinouts

There are way too many choices of 'standard' pinouts for all of these interfaces. Pinouts were chosen for ease of use, specificially:

UART

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

SWD

This is a standard pinout. In order to accomodate both SWD and JTAG, the mode switch:

  1. Combines DI and DO to create SWDIO for SWD mode
  2. Selects between SWDIO and TMS for pin 2
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

JTAG

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

SPI

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:

  1. Combines DI and DO to create SDA for I2C mode
  2. Disconnects pin 2 in I2C mode for devices that use it as an address signal
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 --

LA

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

I2C

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

iCE40

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.

AVR ISP

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

Stripes and Tails

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.

Dens

Tigard is supplied as a bare board, but there are several options for 3d printing mounts and cases - 'dens' - for your Tigard.:

Serial Numbers

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

Allocated

Getting Tigard

Where to Buy

Tigard 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

DIY Tigards

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.