Skip to main content

ftdi-ft232h

The ftdi-ft232h driver runs an FTDI FT232H USB adapter in its Multi-Protocol Synchronous Serial Engine (MPSSE) mode. One adapter gives you an SPI controller and up to 16 GPIO pins at the same time. Any channel, on any of the three chips, can run as a UART instead (see UART channels).

PropertyValue
kindftdi-ft232h
Interfacesspi, gpio, relay, uart, tty
locationusb:<vid>:<pid>[:<serial>|@<usb_path>]

Example​

mpsse:
kind: ftdi-ft232h
name: "FTDI FT232H"
description: "MPSSE adapter for SPI + GPIO bring-up"
location: usb:0403:6014:FT4ABC123
interfaces:
- type: spi
channel: 0
- type: gpio
channel: 0
config:
pins:
- { pin: 4, name: GPIOL0, direction: output, initial: low }
- { pin: 5, name: GPIOL1, direction: input }
- { pin: 12, name: reset_n, direction: output, active_level: low, initial: low }
- { pin: 13, name: shared_irq, direction: output, drive_mode: open_drain, initial: high }
- { pin: 14, name: boot_sense, direction: input }

Location​

The location identifies the adapter by its USB vendor and product ID, written as four hex digits each:

FormMatches
usb:0403:6014The first FT232H the bench finds.
usb:0403:6014:FT4ABC123The FT232H with serial number FT4ABC123.
usb:0403:6010@1-2.1The FT2232H at USB port 1-2.1.

Use the serial-number form whenever the adapter has one. It keeps pointing at the same adapter when you add a second one or move it to another USB port. mimick peripheral list shows the location of every FT232H the bench detects.

note

If you attach more than one FT232H, give each one a serial number. Without one, the bench opens the first FT232H it finds. If a chip has no serial number, use the USB port form to tell it from the others.

The FT232H has a single MPSSE channel, so every interface uses channel 0.

UART channels​

Declare a channel as uart to run it as a serial port. You can do this on any channel of any of the three chips, including FT4232H channels C and D. A UART channel can't also run spi, i2c, or gpio, but the other channels of the same chip can. The bench opens the chip directly, so no /dev/ttyUSB* device appears.

ft2232h:
kind: ftdi-ft232h
name: "Dual UART"
location: usb:0403:6010@1-2.1
interfaces:
- type: uart
channel: 0
config: { baud_rate: 115200 }
- type: tty
channel: 0
backed_by: { type: uart, channel: 0 }
- type: uart
channel: 1
config: { baud_rate: 115200, latency_ms: 1, initial_dtr: released }

The uart config takes the same baud_rate, data_bits, parity, stop_bits, and flow_control keys as linux-tty. The chip supports 7 or 8 data bits. It also takes:

KeyDefaultMeaning
latency_ms1How long the chip holds a partial packet before it reaches the bench, from 1 to 255.
initial_dtr, initial_rtsreleasedasserted or released. Applied on every open, before the first byte moves.
log_delimiter, log_delimiter_hex\n with a tty, none withoutText or hex bytes that end a row of the data recorder, such as "\r\n" or "7e". Set one, not both.
queued_writestrue with a tty on the channel, else falsetrue returns a console or exec write once it is queued. false returns after the chip took it.
queue_depth64How many writes can wait. Used only when queued_writes is true. Must be above 0.

The data recorder logs every byte the channel receives or sends. A row ends at the delimiter, after 2 ms with no new bytes, or at 4 KiB, whichever comes first. A row that arrives with a framing, parity, overrun or break error carries it as uart.flags.

A full queue makes the next write wait for room instead of losing it. uart write always reports the chip's own result.

A low latency_ms keeps each request and response fast. Set initial_dtr or initial_rts to asserted if your board holds its MCU in reset or in its bootloader while a line is asserted.

You can change the baud rate, data bits, parity, stop bits, and flow control on an open port without reopening it. A tty interface must use backed_by with the uart of the same channel.

A MIMICK HWI v2 board is built on an FT2232H too. Declare it as mimick-hwi instead, which serves its DUT console with the same uart keys.

Multi-channel chips​

The FT2232H (0403:6010) has channels A and B, and the FT4232H (0403:6011) has A to D. Set channel on an interface to 0 for A, 1 for B, 2 for C, and 3 for D. SPI, I2C, and GPIO run on the channels with an MPSSE engine: A and B on both chips. The bench rejects the file if you name a channel the chip doesn't have, or use one of those protocols on FT4232H channel C or D.

Declare every channel of a chip under the one peripheral that owns its location. Each channel works on its own, so a long SPI transfer on channel A doesn't hold up channel B.

A board whose EEPROM is blank has no serial number. Address it by the USB port instead, with usb:<vid>:<pid>@<usb_path>, as in the example below.

hwi:
kind: ftdi-ft232h
location: usb:0403:6010@1-2.1
interfaces:
- type: spi
channel: 0
- type: gpio
channel: 1
config:
pins:
- { pin: 4, name: boot, direction: output, initial: low }

If you unplug the chip, every channel of it goes absent, and plugging it back in restores them. A relay interface drives the peripheral's one gpio interface, so you can't combine relay with gpio on more than one channel.

SPI​

The spi interface takes no settings in the file. It runs in SPI mode 0 at 1 MHz.

Declaring spi claims pins 0 through 3 (SCK, MOSI, MISO, and CS), so those pins aren't available to the gpio interface.

mimick spi mpsse.spi0 transfer badf00d

GPIO​

The gpio interface takes a pins list. Each entry configures one pin.

KeyRequiredDefaultAllowed values
pinYes0 to 15 (see Pin numbers)
directionYesinput or output
nameNoChip nameAny label. The CLI accepts it in place of the number.
initialNolowhigh or low. Outputs only.
active_levelNohighhigh or low. Outputs only.
drive_modeNopush_pullpush_pull, open_drain, or open_source. Outputs only.

Each pin appears at most once. Setting initial, active_level, or drive_mode on an input is an error.

initial is a logical level, applied through active_level and drive_mode. In the example, reset_n starts deasserted, so the pin drives high. shared_irq starts released, so the pin floats at high impedance.

Pin numbers​

pin is the MPSSE bit index, not the package pin on the datasheet. The package pins below are the FT232H's, and other chips report 0. On channel B the names start with BDBUS instead of ADBUS. The FT4232H has only pins 0 to 7 on each channel:

pinSignalPackage pin
0 to 3ADBUS0 to ADBUS3 (SCK, MOSI, MISO, CS with SPI)13 to 16
4 to 7GPIOL0 to GPIOL317 to 20
8GPIOH021
9 to 15GPIOH1 to GPIOH725 to 31

mimick gpio list shows all three for every pin.

Open-drain and open-source outputs​

The FT232H has no native open-drain output, so the bench releases the pin to an input for the level it doesn't drive. A released pin is pulled toward VCCIO by a weak internal resistor (about 75 kΩ), except pin 15, which pulls down to ground. Fit an external pull-up for open_drain or a pull-down for open_source, sized for your bus.

Reading a released pin samples the line, so it can differ from the level you last wrote. That tells you whether something else is holding the line.

Relay channels over pins​

A relay interface presents output pins as on/off relay channels. It takes the same channels list as the other relay drivers, except each path is GPIO: followed by the name or number of a pin listed under the gpio interface's pins:

- type: relay
channel: 0
config:
channels:
- { number: 1, name: "Reset", path: "GPIO:reset_n" }

The pin can't be declared as an input, and two channels can't share a pin. A channel is on while its pin is at the pin's active_level. With a relay interface present, address the GPIO as -p mpsse.gpio0 and the relay as -p mpsse.relay0.

Use it​

mimick gpio list -p mpsse.gpio0
mimick gpio write -p mpsse.gpio0 reset_n on
mimick gpio watch -p mpsse.gpio0 boot_sense

In the web UI, select Open GPIO controls on the peripheral's row in the bench's Inventory tab.