SkillAgentSearch skills...

Tigard

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

Install / Use

/learn @tigard-tools/Tigard
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<img alt="Tigard PCB Render" width="320" align="right" src="https://raw.githubusercontent.com/tigard-tools/tigard/master/tigard-render.png">

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:

  • USB-Serial drivers for UART access
  • OpenOCD and URJTAG for JTAG
  • Flashrom, libmpsse, pyftdi and other tools for SPI interfaces
  • libmpsse and pyftdi for I2C interfaces
  • iceprog for ice40 FPGAs
  • avrdude for AVR microcontrollers

Also, users have used Tigard with BMDA, Mitou jtag, VSCode, and SPI via FTDI

Hardware Features

Highlights:

  • Dual-port, with one dedicated to UART and the second shared with other interfaces
  • High-performance directional level shifters for 1.8 to 5.5v operation
  • Switch to choose between on-board 1.8, 3.3, and 5.0v supplies and vTarget
  • Switch to choose between SPI/JTAG and I2C/SWD modes
  • Logic analyser port to observe device-level signals (v1.0 and later)
  • Indicator lights to aid debugging

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:

  • 1V8, 3V3, and 5V all apply a voltage to the VTGT pin.
  • VTGT disconnects the VTGT pin from supplies, and depends on the wire connected to the target to set the level shifter voltage.

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:

  • When set to JTAG/SPI mode:
    • All signals run straight through
    • CORTEX and JTAG headers are wired for normal JTAG
    • JTAG and SPI headers can be used for SPI
  • When set to SWD/I2C mode:
    • DO and DI are wired together to create SWDIO or SDA
    • CORTEX and JTAG headers can be used for SWD
    • JTAG and SPI headers can be used for I2C

UART

Hookup:

  • In most cases, you need pins 2,3,and 4 of the UART header - Ground, TX, and RX. Connect these to your target
  • If you have a VCC header on your target, connect pin 1 - VTGT to it, and slide the voltage selector to VTGT
  • If you don't have a VCC header, leave the VTGT wire disconnected, and choose your target voltage with the selector

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.

  • Select SPI/JTAG on the mode selection switch
  • Connect your clip or socket to the header. Pay attention to pin 1, which is usually marked on sockets or has a red/highlighted wire on ribbon cables
  • Connect your clip to the target or insert your chip into the socket
  • If you're doing this in-circuit, you must take extra precautions to make sure no other device is communicating with the SPI device.
  • If you're using a clip in-circuit and the target is powered on, choose the VTGT option on the voltage slider
  • If you're using a zif socket, or clip with a powered-off target, choose the voltage on the voltage slider.

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:

  • Connect a 4-pin JST SH compatible cable into the I2C connector
  • Connect the other end to your STEMMA QT, Qwiic, or other I2C device

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:

  • Connect your clip or socket to the header. Pay attention to pin 1, which is usually marked on sockets or has a red/highlighted wire on ribbon cables
  • Connect your clip to the target or insert your chip into the socket

Finally, the JTAG header can also be used to get the I2C signals on .1" individual pins:

  • Connect the 8-wire JTAG harness to the JTAG connector
  • Connect the white SCL and grey SDA wires to your target's I2C pins

In either case, you need to set the Tigard switches properly:

  • Select I2C on the mode selection switch
  • If you're attaching to a device in-circuit and the target has its own power, choose the VTGT option on the voltage slider
  • If you're attaching a standalone sensor, socket, or clip with a powered off target, choose the correct voltage on the voltage slider

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:

  • Only controller operation is supported, not Device
  • Tigard may not play nice if there are other controllers present on the I2C interface
  • Clock stretching is not supported
  • The I2C switch ties the DI and DO lines together so that it can do bidirectional communication
  • The pullup resistors are not included since they are usually located on the target, and the weak pullups on the level shifters are sufficient

Hacks:

To accomodate both I2C and SWD, the DI and DO lines are combined through resistor R16. This is required for SWD and generally acceptable for 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 b

View on GitHub
GitHub Stars808
CategoryDevelopment
Updated4h ago
Forks92

Security Score

80/100

Audited on Mar 27, 2026

No findings