Devices

FTDI has made a great variety of devices. Here we attempt to categorize all of them.

Note that, at one point, FTDI has spun off its MCU division as a new company, Bridgetek. There are many device that exist with both FTDI (FTxxx) and Bridgetek (BTxxx) naming and branding. To simplify things, we just consider all Bridgetek devices to be FTDI devices as well.

Usually, the last letter of a full part name (eg. Q in FT2232HQ) represents the package type (SSOP / QFP / QFN / etc). We usually skip this letter when describing the devices, as it doesn't affect their behavior in any way.

D2xx devices

D2xx devices are USB peripherial devices that implement the D2xx protocol, originally created for USB—UART bridging. They come in several varieties:

  • the "proper" fixed-function D2xx devices implementing the D2xx protocol in hardware
    • FT8U232A, FT232B, FT232R, FT230X, FT231X, FT234X: single-channel USB—UART bridge
    • FT8U245A, FT245B, FT245R, FT240X: single-channel USB—FIFO bridge
    • FT200X, FT201X: single-channel USB—I2C peripherial bridge
    • FT220X, FT221X: single-channel USB-SPI/FT1248 bridge
    • FT2232, FT2232H: dual-channel USB—multiprotocol bridge
    • FT4232H: quad-channel USB—multiprotocol bridge
    • FT232H: single-channel USB-multiprotocol bridge
  • preprogrammed MCUs implementing the D2xx protocol in fixed firmware
    • FT4222H: quad-channel USB—SPI/I2C bridge
    • UMFT4222PROG: programmer board for FT4222H (based on FT51A)
    • UMFTPD3A: programmer board for FT260/FT4222H (based on FT51A)
  • programmable MCUs with FTDI-provided libraries that can be used to implement the D2xx protocol in firmware
    • FT8U100A: ???-based MCU
    • FT51: 8051-based MCU
    • FT900 series: FT32-based MCU (custom RISC-like 32-bit Harvard architecture)
    • FT930 series: FT32B-based MCU (a revision of FT32)

D2xx devices come with one or more "channel"s, which are essentially independent bidirectional data pipes. They correspond to USB interfaces with one IN endpoint and one OUT endpoint. On the host side, they can be opened and used independently by distinct applications.

The fixed-function D2xx devices as well as FT4222H can be configured through non-volatile memory — some device types use an external EEPROM for that purpose, while others come with on-chip EEPROM or OTP memory.

Almost all D2xx devices allow the designer to provide custom USB vendor and product IDs (as well as string descriptors), making fully reliable detection impossible. However, once something is known to be a D2xx device, the bcdDevice field of device descriptor can be used to determine its exact type:

bcdDevicedefault VID:PID# channelsdevice
00010403:83721FT8U100A UART "applet"
02000403:60011FT8U232A or FT8U245A
0400 or 02000403:60011FT232B or FT245B
0400 or 02000403:60041FT232B (alternate PID strap)
0400 or 02000403:60051FT245B (alternate PID strap)
05000403:60102FT2232C, FT2232D
06000403:60011FT232R or FT245R
06000403:60491FT232RN or FT245RN
07000403:60102FT2232H
08000403:60114FT4232H
09000403:60141FT232H
10000403:60151FT-X series
14000403:601b1FT4222 mode 3 (unreleased)
15000403:601b2FT4222 mode 0 (unreleased)
16000403:601b4FT4222 mode 1 or 2 (unreleased)
17000403:601c1FT4222H mode 3
18000403:601c2FT4222H mode 0
19000403:601c4FT4222H mode 1 or 2
21000403:0fec1?UMFT4222PROG
24000403:60311FT90x (1 channel)
24000403:60322FT90x (2 channels)
24000403:60333FT90x (3 channels)
25000403:60341FT93x (1 channel)
25000403:60352FT93x (2 channels)
25000403:60363FT93x (3 channels)
25000403:60374FT93x (4 channels)
25000403:60385FT93x (5 channels)
25000403:60396FT93x (6 channels)
25000403:603a7FT93x (7 channels)
27000403:603e1?UMFTPD3A
28000403:60402FT2233HP
29000403:60414FT4233HP
30000403:60422FT2232HP
31000403:60434FT4232HP
32000403:60441FT233HP
33000403:60451FT232HP
35000403:60472FT2232HA
36000403:60484FT4232HA

FT8U232A and FT8U245A

These are the first-generation fixed-function D2xx devices. FT8U232A is a USB—UART bridge, while FT8U245A is a USB—FIFO bridge. They look exactly the same from the software perspective, and in fact may or may not be the same silicon.

They are configured by an optional external 93C46 (64×16-bit word) EEPROM. If no EEPROM is present, or the EEPROM is unprogrammed, the device will use a default configuration.

devicepackage
FT8U232AM32-pin MQFP
FT8U245AM32-pin MQFP

FT232B and FT245B

These are a second-generation revision of FT8U2xxA. They are largely software-compatible, but introduce a few new features:

  • configurable latency timer
  • bitbang mode
  • serial number descriptor
  • support for larger 93C56 (128×16) and 93C66 (256×16) EEPROMs in addition to 93C46

They are mostly, but not completely pin compatible with FT8U2xxA in the QFP packages.

devicepackage
FT232BM32-pin LQFP
FT232BL32-pin lead-free LQFP
FT232BQ32-pin QFN
FT245BM32-pin LQFP
FT245BL32-pin lead-free LQFP

FT2232C/D/L

A third-generation D2xx device. This device features two largely-independent channels (called A and B), which can be independently configured through EEPROM in several modes:

  • UART (like FT232B)
  • FIFO (like FT245B)
  • CPU FIFO (new mode, meant for use as a peripherial on an 8051-style MCU bus)
  • fast opto-isolated serial (custom serial protocol, optimised for low pin count and speed)

In addition, the device can also dynamically switch either of the two channels into alternate modes:

  • async bitbang mode: like FT232B/FT245B
  • MPSSE mode: implements a fast controller for SPI, JTAG, and similar protocols (channel A only)
  • sync bitbang mode: new, variation of the async bitbang mode
  • MCU bus: uses pins of both channels; makes the device capable of controlling an 8051-style MCU bus and driving MCU peripherials

Like FT2xxB, the device can be configured by a 93C46/93C56/93C66 external EEPROM.

devicepackagewhat is
FT2232C48-pin LQFPbase version
FT2232L48-pin lead-free LQFPbase version
FT2232D48-pin lead-free LQFPrevised version

FT232R/FT245R

A fourth-generation D2xx device. The FT232R and FT245R are, in fact, the same chip, and it seems that they can be converted into one another via an EEPROM change. They are an enhanced version of FT2xxB, with the following new features:

  • internal 32×32-bit EEPROM for configuration (instead of external 93C*), plus 8×32-bit factory-programmed area with unique per-chip ID
    • whether the device is FT232R or FT245R is stored in the user-programmable area and can be changed, though vendor tools go out of their way not to do so
  • internal oscillator
  • configurable CBUS pins with multiple functions (FT232R only)
  • CBUS GPIO mode (allows putting individual CBUS pins under software control while continuing to use other pins for their normal UART purpose)
  • adds the synchronous bitbang mode (ported from FT2232C)

The FT2xxRN is a variant of the device that makes the internal oscillator work with 3.3V VCC.

devicepackage
FT232RL28-pin TSSOP
FT232RQ32-pin QFN
FT245RL28-pin TSSOP
FT245RQ32-pin QFN
FT232RNL28-pin TSSOP
FT232RNQ32-pin QFN
FT245RNL28-pin TSSOP
FT245RNQ32-pin QFN

FT2232H and FT4232H

Fifth-generation D2xx devices. FT2232H and FT4232H are the same silicon, and are differentiated by a fuse programmed in the factory.

FT2232H is an enhanced version of FT2232C, with the following new features:

  • USB 2.0 high-speed interface
  • max UART speed bumped from 3Mbaud to 12Mbaud
  • max FIFO speed bumped from 1MB/s to 8MB/s
  • adds new synchronous FIFO submode, which further increases FIFO speed to 40MB/s
  • MPSSE mode is available on both channels
  • each channel now has 16 pins instead of 13 (additional pins can be used as GPIO in MPSSE mode)

FT4232H is a variant with the following differences:

  • four channels (A, B, C, D) instead of two, each of which includes 8 pins instead of 16
  • modes requiring more than 8 pins are not supported (FIFO, CPU FIFO, MCU bus)
  • fast opto-isolated serial mode is also not supported
  • only channels A and B support MPSSE (C and D are limitted to UART and bitbang)

Later on, variants of these devices were made with USB-PD support. They have the same core functionality as the base version, but they require a 93C66 EEPROM to fit the extra configuration required for USB-PD.

devicepackagewhat
FT2232HL64-pin LQFPbase FT2232H
FT2232HQ56-pin VQFNbase FT2232H
FT4232HL64-pin LQFPbase FT4232H
FT4232HQ56-pin VQFNbase FT4232H
FT2233HPQ76-pin QFNFT2232H with two USB-PD ports
FT4233HPQ76-pin QFNFT4232H with two USB-PD ports
FT2232HPQ68-pin QFNFT2232H with one USB-PD port
FT4232HPQ68-pin QFNFT4232H with one USB-PD port
FT2232HAQ64-pin QFNFT2232H automotive version
FT4232HAQ64-pin QFNFT4232H automotive version

FT232H

A single-channel variant of FT2232H, with some FT232R features merged in. Features include:

  • USB 2.0 high-speed interface
  • a single channel, with 18 pins
  • supports all FT2232H modes except for the MCU bus mode (which would require more than 16 pins)
  • adds FT232R-style configurable CBUS pins, as well as the CBUS bitbang mode
  • continues to require external EEPROM; only 93C56 and 93C66 are supported
  • adds a new FT1248 mode

Like FT2232H and FT4232H, this device also got USB-PD variants later on.

devicepackagewhat
FT232HL48-pin LQFPbase FT232H
FT232HQ48-pin QFNbase FT232H
FT233HPQ64-pin QFNFT232H with two USB-PD ports
FT232HPQ56-pin QFNFT232H with one USB-PD port

FT-X series

A single-channel D2xx device. Essentially an enhanced version of FT232R, with the following changes:

  • internal 2048-byte MTP memory for configuration, including some immutable factory pre-programmed data
  • the device comes in several variants; the variant is selected by the factory-programmed MTP area and cannot be changed
    • FT200X and FT201X: USB to I2C peripherial bridge
    • FT220X and FT221X: USB to FT1248 bridge
    • FT230X, FT231X, FT234X: USB to UART bridge (like FT232R)
    • FT240X: USB to FIFO bridge (like FT245R)
  • adds battery charger detection
devicepackagebusiness endbusiness end pins
FT200XD10-pin DFNI2C peripherial2×I2C + 1×CBUS
FT201XS16-pin SSOPI2C peripherial2×I2C + 6×CBUS
FT201XQ16-pin QFNI2C peripherial2×I2C + 6×CBUS
FT220XS16-pin SSOP4-bit FT12487×FT1248 + 1×CBUS
FT220XQ16-pin QFN4-bit FT12487×FT1248 + 1×CBUS
FT221XS20-pin SSOP8-bit FT124811×FT1248 + 1×CBUS
FT221XQ20-pin QFN8-bit FT124811×FT1248 + 1×CBUS
FT230XS16-pin SSOPbasic UART4×UART + 4×CBUS
FT230XQ16-pin QFNbasic UART4×UART + 4×CBUS
FT231XS20-pin SSOPfull UART8×UART + 4×CBUS
FT231XQ20-pin QFNfull UART8×UART + 4×CBUS
FT234XD12-pin DFNbasic UART4×UART + 1×CBUS
FT240XS24-pin SSOPFIFO13×FIFO + 2×CBUS
FT240XQ24-pin QFNFIFO13×FIFO + 2×CBUS

FT4222H

The FT4222H is a high-speed USB to QSPI/I2C + GPIO bridge. Internally, it is based on an MCU (unknown, but likely FT32).

The device is configured using internal OTP memory.

The device has four channel configurations, selectable by two configuration pins:

modechannel countchannel 0channel 1channel 2channel 3
02SPIC / SPIP / I2CC / I2CPGPIO--
14SPIC (CS0)SPIC (CS1)SPIC (CS2)GPIO
24SPIC (CS0)SPIC (CS1)SPIC (CS2)SPIC (CS3)
31SPIC / SPIP / I2CC / I2CP---

The device has four modes, selected at runtime:

  • SPIC: SPI controller; depending on channel configuration, can use up to four CS lines, and thus control 4 peripherials; every peripherial is controlled by a dedicated channel
  • SPIP: SPI peripherial (not available in modes 1 and 2)
  • I2CC: I2C controller (not available in modes 1 and 2)
  • I2CP: I2C peripherial (not available in modes 1 and 2)

The device comes in 4 revisions, which differ in firmware version:

devicepackagefirmware
FT4222HQ-A32-pin VQFNrev A
FT4222HQ-B32-pin VQFNrev B
FT4222HQ-C32-pin VQFNrev C
FT4222HQ-D32-pin VQFNrev D

D3xx devices

D3xx devices are USB super-speed peripherial devices that implement the D3xx protocol. There are several variants:

  • FT600 and FT601: USB—FIFO bridge
    • FT600: up to 16-bit FIFO
    • FT601: up to 32-bit FIFO
  • FT602: USB—FIFO bridge implementing the UVC protocol

All of these devices are internally based on an FT32-based MCU.

default VID:PIDdevice
0403:601eFT600
0403:601fFT601
TODOFT602

FT260

FT260 is a USB—UART/I2C bridge implementing the HID device class. It is internally based on an unknown MCU (FT32? FT51?). It can be configured using internal eFUSE memory or external EEPROM.

devicedefault VID:PIDpackage
FT260Q0403:603028-pin WQFN
FT260S0403:603028-pin TSSOP

FT12 series

FT12 series devices are, essentially, completely customizable USB peripherial devices meant to be controlled by an external MCU. The FT12 acts as a PHY and endpoint FIFO controller, while the MCU is supposed to implement all USB endpoint logic, including control requests.

Note that the internal VID:PID listed in the table is actually presented to the MCU as FT12's identification, not to the host. The actual USB VID:PID is provided by the MCU.

devicemax endpointsMCU interfaceinternal VID:PIDpackage
FT120T6MCU parallel busnone28-pin TSSOP
FT121T16SPI0403:601816-pin TSSOP
FT121Q16SPI0403:601816-pin QFN
FT122T16MCU parallel bus0403:601828-pin TSSOP
FT122Q16MCU parallel bus0403:601828-pin QFN

MCU devices

FT8U100A

FT8U100A is an MCU based on an unknown 8-bit architecture (8051?). It implements a USB hub, with 1 upstream port and 7 physical downstream ports, as well as virtual downstream ports for internal devices. It also has a variety of peripherials, such as UART, PS/2 keyboard/mouse host, IrDA, I2C controller, and GPIO. It comes with ready-made firmware that can be used to expose these peripherials as USB devices (including SIO UART, the first device in the D2xx family).

devicepackage
FT8U100AX100-pin PQFP
VID:PIDinternal device
0403:8370USB hub
0403:8371PS/2 keyboard and mouse
0403:8372UART (D2xx protocol)

TODO: list incomplete

FT51

FT51 is an 8051-based MCU that has a programmable USB peripherial interface, as well as a USB hub. It is used in the UMFTPD3A and UMFT4222PROG boards. It comes in several variants, all of which are the same silicon and only differ in the number of pins:

devicepackageGPIO
FT51AQ48-pin QFN16×DIO + 16×AIO
FT51AL44-pin LQFP16×DIO + 16×AIO
FT51BQ32-pin QFN16×DIO + 8×AIO
FT51CS28-pin SSOP12×DIO + 8×AIO

FT900 series

FT900 is an MCU based on FTDI's custom FT32 RISC-like architecture. It comes in several variants, all of which are actually the same silicon:

deviceethernetCANGPIO pinsSD hostSPI peripherialI2CI2Spackage
FT900Qyesyes66yes22yes100-pin QFN
FT900Lyesyes66yes22yes100-pin LQFP
FT901Qyesno66yes22yes100-pin QFN
FT901Lyesno66yes22yes100-pin LQFP
FT902Qnoyes66yes22yes100-pin QFN
FT902Lnoyes66yes22yes100-pin LQFP
FT903Qnono66yes22yes100-pin QFN
FT903Lnono66yes22yes100-pin LQFP
FT905Qyesyes44no11no76-pin QFN
FT905Lyesyes44no11no80-pin LQFP
FT906Qyesno44no11no76-pin QFN
FT906Lyesno44no11no80-pin LQFP
FT907Qnoyes44no11no76-pin QFN
FT907Lnoyes44no11no80-pin LQFP
FT908Qnono44no11no76-pin QFN
FT908Lnono44no11no80-pin LQFP

FT900 comes with (device-side) libraries that can implement the D2xx protocol in software.

FT930 series

FT930 is an MCU based on FT32B, a revision of the FT32 architecture used in the FT900 series. It comes in several variants, all of which are actually the same silicon:

deviceDACADCPWMSD hostRTCUARTGPIOpins
FT930Q×2×3×8yesyes×44068-pin QFN
FT931Q×2×3×4yesyes×22856-pin QFN
FT932Q×2×3×4yesno×22448-pin QFN
FT933Qno×2×4nono×21648-pin QFN

In addition to the main FT32B core that is advertised in the datasheet, FT930 also contains a secondary MCU (unknown architecture, but likely also FT32). The "hardware D2xx engine" advertised in the datasheet is actually implemented in software on the other MCU core.

VNC1

VNC1, also known as Vinculum, is an MCU with USB host and peripherial interfaces. It is based on a custom 8-bit Harvard architecture, known as FT8. It has a cute 32-bit integer numeric coprocessor for complex arithmetic tasks such as "handling the FAT filesystem".

devicepackage
VNC1L48-pin LQFP

VNC2

VNC2, also known as Vinculum-II, is an MCU with USB host and peripherial interfaces. It is based on a custom Harvard 16-bit architecture, known as FT16.

devicepackageGPIO
VNC2-48L48-pin LQFP28
VNC2-48Q48-pin QFN28
VNC2-32L32-pin LQFP12
VNC2-32Q32-pin QFN12

FT311 and FT312

FT311 and FT312 are Android Open Accessory host devices. They are USB full-speed hosts that accept a single peripherial that should support the AOA protocol. They will then expose UART or other interface to the Android device.

The device has internal flash memory which stores, among other things, the descriptor strings presented to the Android device. It can be modified via an FTDI null-modem cable and a configuration utility.

Both of these devices are actually just VNC2 chips with preprogrammed firmware.

devicepackageinterfaces
FT311D-32Q1C32-pin QFNone of: UART, GPIO, PWM, I2C controller, SPI controller, SPI peripherial
FT311D-32L1C32-pin LQFPone of: UART, GPIO, PWM, I2C controller, SPI controller, SPI peripherial
FT312D-32Q1C32-pin QFNUART
FT312D-32L1C32-pin LQFPUART

FT313

FT313 is an EHCI controller meant to be connected as a peripherial to 8051-style MCU bus. It has 24kiB of internal buffer memory and DMA support.

devicepackage
FT313HQ64-pin QFN
FT313HL64-pin LQFP
FT313HP64-pin TQFP

EVE display controllers

EVE (Embedded Video Engine) aka FT8xx aka BT8xx is a series of display controllers. They are meant to be driven by an external MCU, and provide parallel or LVDS video output (and, in some cases, input), audio output, and a resistive or capacitive touch controller.

EVE aka FT80x

The first generation of EVE. Both chips are the same silicon. It features:

  • SPI peripherial or I2C peripherial interface exposing internal RAM and registers, meant to be controlled by the MCU host
  • 256kiB of internal RAM
  • parallel 18-bit RGB video output, up to 480×272 resolution
  • display list based graphics engine driving the video output
    • basic rendering features
    • JPEG decode
    • zlib decompression
    • ROM and RAM fonts
  • backlight control
  • one-channel PWM audio output, playing PCM audio or predefined sound effects from ROM wave table
  • touch controller
    • resistive version: directly controls the touchscreen via analog pins
    • capacitive version: has an I2C controller interface meant to be connected to the capacitive touchscreen
devicetouch interfacepackage
FT800Qresistive48-pin VQFN
FT801Qcapacitive48-pin VQFN

EVE2 aka FT81x and BT88x

The second generation of EVE. FT81x has the following differences from FT80x:

  • MCU interface is SPI or QSPI peripherial
  • 1MiB of internal RAM
  • different memory map
  • video output supports up to 800×600 resolution
  • video output is 24-bit instead of 18-bit (on FT812 and FT813 only)

The BT88x is a smaller variant of EVE2. It has the following differences from FT81x:

  • only 256kiB of internal RAM
  • video output resolution is limitted to 131072 pixels total
devicevideo outputtouch interfaceinternal RAMpackage
FT810Q18-bit RGBresistive1MiB48-pin VQFN
FT811Q18-bit RGBcapacitive1MiB48-pin VQFN
FT812Q24-bit RGBresistive1MiB56-pin VQFN
FT813Q24-bit RGBcapacitive1MiB56-pin VQFN
BT880Q18-bit RGBresistive256kiB48-pin VQFN
BT881Q18-bit RGBcapacitive256kiB48-pin VQFN
BT882Q24-bit RGBresistive256kiB56-pin VQFN
BT883Q24-bit RGBcapacitive256kiB56-pin VQFN

All of the FT81x devices are the same silicon. FT810 and FT811 are pin-compatible with FT800 and FT801.

Likewise, all BT88x devices are the same silicon. They are pin-compatible with their corresponding FT81x devices.

EVE3 aka BT815/BT816

The third generation of EVE. It has switched to the BT (Bridgetek) device name prefix. It has the following differences from EVE2:

  • added QSPI controller interface meant for connecting an external flash chip with preprogrammed graphics or audio data
  • sigma-delta audio output instead of PWM
devicetouch interfacepackage
BT815Qcapacitive64-pin VQFN
BT816Qresistive64-pin VQFN

Both BT815 and BT816 are the same silicon.

EVE4 aka BT817/BT818

The fourth generation of EVE. It has the following differences from EVE3:

  • video output supports up to 1920×480, 1440×540, or 1280×800 resolution
devicetouch interfacepackage
BT817Qcapacitive64-pin VQFN
BT817AQcapacitive64-pin VQFN
BT818Qresistive64-pin VQFN

BT817A is an automotive variant of BT817.

All EVE4 devices are the same silicon.

EVE5 aka BT820

The fifth generation of EVE, with major changes. It has the following features:

  • QSPI peripherial interface for the MCU host
  • QSPI controller interface for flash
  • memory controller for DDR3/DDR3L/LPDDR2 working memory
  • SD card host interface
  • dual-channel FPD-link video output
    • with backlight control
  • dual-channel FPD-link video input
  • I2C controller interface for capacitive touch
  • audio output through stereo delta-sigma or I2S
  • 16 GPIO pins
  • display list based graphics engine
    • PNG and JPG decode support
    • deflate decode support
    • ROM and RAM fonts
  • render engine for memory-to-memory drawing
    • ASTC decode support
devicepackage
BT820B329-pin BGA

D2xx protocol

D2xx is the name of protocol used by most FTDI USB devices. It was originally made for the UART function of the FT8U100A, and remains quite UART-oriented. However, FTDI has reused it for all kinds of stream-based interfaces.

Channels and interfaces

A D2xx device can have one or more channels. A channel is, at the core, a bidirectional byte-oriented stream of data.

Channels are often identified by single letters, in order (A, B, C, D, ...).

Each channel is exposed as a separate USB interface. Each interface has two bulk endpoints: IN and OUT. In addition, a channel also makes use of D2xx-specific control requests on the default config pipe (endpoint 0).

Some devices have an undocumented option to use isochronous endpoints instead of bulk endpoints. That options is undoubtedly broken in some completely hilarious ways.

Identifying a D2xx device

Since all D2xx devices can have custom VIDs and PIDs programmed, there is no sure-fire way to identify a USB device as a D2xx device — you need to know what VID:PID you are looking for. However, there are some predefined VID:PID combinations that will be used by default. They are listed in the table on the devices page.

As you can see, FTDI used to reuse its VID:PID combinations for groups of similar devices for some time, but then decided to just start assigning new IDs for every new device.

Once something is known to be a FTD2xx device, further identification can be obtained from the bcdDevice field of USB descriptor. The bcdDevice values are likewise listed on the devices page. It is not clear whether the bcdDevice field may be overriden via EEPROM.

Even putting VID:PID and bcdDevice together, it is still not always possible to uniquely identify the device. Usually, one can just live with the uncertainty. However, there are some more checks that can be done for further identification:

  • FT8U2xxA and FT2xxB can be told apart by attempting the GET_LATENCY_TIMER request — a failure implies A-series device, while a success implies B-series device
  • FT232R and FT245R can be told apart by a field in the internal EEPROM, which the vendor claims to not be modifiable by the user
  • likewise, FT-X series devices can be told apart to some extent by another EEPROM field

Stream protocol

Note: FT2xxR devices have configurable wMaxPacketSize field in the bulk endpoint descriptors. There are devices in the wild where people have programmed the (invalid) value of 0 in that field. In case a device is encountered with such value, it should be overriden in the driver to 64 bytes.

IN endpoint

The IN endpoint of a channel is used to transfer byte stream data from the device to the user. It involves a framing protocol: every packet transferred on the endpoint includes a header with modem and line status. Packets are always at least 2 bytes long. The packet format is as follows:

  • byte 0: modem status (shows the most recent state of the modem status input pins)
    • bit 0: always 1?
    • bit 1: always 0?
    • bit 2: always 0?
    • bit 3: always 0?
    • TODO: allegedly high-speed devices have 0010 in low bits?
    • bit 4: CTS
    • bit 5: DSR
    • bit 6: RI
    • bit 7: DCD
  • byte 1: line status
    • bit 0: data ready (???)
    • bit 1: overrun error (device received data on the business end when there was no more space in IN endpoint FIFO)
    • bit 2: parity error
    • bit 3: framing error
    • bit 4: break interrupt
    • bit 5: TX holding register (???)
    • bit 6: TX (OUT endpoint) FIFO is empty
    • bit 7: FIFO error (???)
  • bytes 2 and up (if any): actual stream data

As can be seen, the protocol is very UART-oriented. The modem and line status bytes are present even for D2xx devices that have nothing to do with UART, though they are mostly dummied out in that case. The TX FIFO empty bit is, however, generally useful.

TODO: kernel driver alleges that parity/framing errors are always associated with the last byte in the packet. Check this.

To avoid excessive load on the host, the device doesn't always transmit packets on the IN endpoint as soon as data is available. Instead, the device will send a packet in the following circumstances:

  • a full-sized packet has been filled
  • a special "event" character has been received (if enabled by driver)
  • data is available and the latency timer has expired
    • on FT8U2xxA (and FT8U100A?), the latency timer is always 16ms
    • on newer devices, the default latency timer is 16ms, but it can be configured to any value between 2ms and 255ms
  • TODO: line errors / modem status changes too? kernel alleges device will send an update packet every 40ms even with no activity

OUT endpoint

There are two variants of the protocol with respect to OUT endpoint handling.

The original variant is present on the FT8U100A only. In this variant, every OUT endpoint packet has to be prefixed with a header. The packet then has the following format:

  • byte 0: header
    • bit 0: must be 1
    • bit 1: must be 0
    • bits 2-7: length of payload (ie. length of packet, not including the header byte)
  • bytes 1 and up: actual stream data

Since the header is completely useless, it has been done away with in later devices. In every device other than FT8U100A, the OUT endpoint is completely headerless and packets contain just the raw stream data.

Control requests

The protocol includes the following control requests:

requestbmRequestTypebRequestwValuewIndexdata
RESET0x400x00reset kindchannel-
SET_MODEM_CTRL0x400x01DTR + RTS statechannel-
SET_FLOW_CTRL0x400x02XON / XOFF charschannel + mode-
SET_BAUD_RATE0x400x03divisor low bitschannel + divisor high bits-
SET_DATA_CHARACTERISTICS0x400x04data format + break statechannel-
GET_MODEM_STATUS0xc00x050channel2 bytes
SET_EVENT_CHAR0x400x06event char + enablechannel-
SET_ERROR_CHAR0x400x07error char + enablechannel-
SET_LATENCY_TIMER0x400x09latency timerchannel-
GET_LATENCY_TIMER0xc00x0a0channel1 byte
SET_BITMODE0x400x0bbit mode + output maskchannel-
GET_PIN_STATE0xc00x0c0channel1 byte
VENDOR_CMD_GET0xc00x20requestchannelup to 0x80 bytes
VENDOR_CMD_SET0x400x21request + datachannelup to 0x80 bytes
READ_EEPROM0xc00x900word address2 bytes
WRITE_EEPROM0x400x91word valueword address-
ERASE_EEPROM0x400x9200-

Most control requests operate on a channel. The channel is specified as follows:

  • for single-channel devices: channel is 0
  • for multi-channel devices: the channel indices start at 1 (ie. channel number in control request is USB interface index + 1)
    • TODO: allegedly, specifying 0 means "all channels"?

The channel is usually stuffed directly into wIndex. However, there are variations to keep you on your toes.

RESET

Resets the device or purges IN/OUT endpoint buffers on device.

  • applicable to: all D2xx devices
  • bmRequestType: 0x40
  • bRequest: 0x00
  • wValue: kind of reset to perform
    • 0: reset the serial engine
      • purge both IN and OUT endpoints
      • disable event char and set it to 0x0d ('\r')
      • disable flow control
      • clear DTR and RTS
    • 1: purge OUT endpoint (nuke all buffered data)
    • 2: purge IN endpoint
  • wIndex: channel

TODO: determine exactly what the reset actually resets; the above list is according to the kernel sources.

TODO: libftd2xx seems to always send resets with wIndex set to 0; is this a bug?

SET_MODEM_CTRL

Changes the state of DTR and RTS lines.

  • applicable to: all D2xx devices (but may be a no-op in non-UART modes)
  • bmRequestType: 0x40
  • bRequest: 0x01
  • wValue:
    • bit 0: new DTR value
    • bit 1: new RTS value
    • bit 8: change DTR (if not set, DTR will be unchanged)
    • bit 9: change RTS
  • wIndex: channel

SET_FLOW_CTRL

Changes hardware flow control mode.

  • applicable to: all D2xx devices (but may be a no-op in non-UART modes)
  • bmRequestType: 0x40
  • bRequest: 0x02
  • wValue:
    • bits 0-7: XON character
    • bits 8-15: XOFF character
  • wIndex:
    • bits 0-7: channel
    • bit 8: enable RTS/CTS flow control
    • bit 9: enable DTR/DSR flow control
    • bit 10: enable XON/XOFF flow control

TODO: make double-sure of wIndex encoding

TODO: check if XON/XOFF is applicable to eg. FIFO mode

SET_BAUD_RATE

Sets the baud rate, and also the clock for bitbang and MPSSE modes.

  • applicable to: all D2xx devices (but may be a no-op on MCU-based ones)
  • bmRequestType: 0x40
  • bRequest: 0x03
  • wValue: bits 0-15 of the divisor value
  • wIndex:
    • for single-channel device:
      • bits 0-1: bits 16-17 of the divisor
    • for multi-channel device:
      • bits 0-7: channel
      • bits 8-9: bits 16-17 of the divisor

The format of the divisor varies depending on the exact device.

FT8U100A

For FT8U100A, the divisor is an enum, selecting the baud rate from the following fixed list:

  • 0: 300 baud
  • 1: 600
  • 2: 1200
  • 3: 2400
  • 4: 4800
  • 5: 9600
  • 6: 19200
  • 7: 38400
  • 8: 57600
  • 9: 115200

FT8U232A, FT8U245A

These devices run on 48MHz base clock. The base clock is divided by a fractional divisor to obtain the channel clock. The channel clock is then further divided by 16 to obtain the baud rate.

The divisor is encoded into a 16-bit number as follows:

  • bits 0-13: integer part (must be at least 2, except for the special case below)
  • bits 14-15: fractional part, encoded
    • 0: .0
    • 1: .5
    • 2: .25
    • 3: .125

There is also a special divisor with dedicated encoding:

  • 0x0000 encodes a special divisor of 1 (corresponding to 3000000 baud rate)

FT232B, FT245B, FT232R, FT245R, FT2232[CDL], FT-X series

These devices are similar to FT8U2xxA, with minor extensions. The encoding scheme is backwards-compatible.

The divisor is encoded into a 17-bit number (with top bit overflowing into the wIndex field) as follows:

  • bits 0-13: integer part (must be at least 2, except for the special cases below)
  • bits 14-16: fractional part, encoded
    • 0: .0
    • 1: .5
    • 2: .25
    • 3: .125
    • 4: .375
    • 5: .675
    • 6: .75
    • 7: .875

There are also two special divisors with dedicated encoding:

  • 0x0000 encodes a special divisor of 1 (corresponding to 3000000 baud rate)
  • 0x0001 encodes a special divisor of 1.5 (corresponding to 2000000 baud rate)

In addition to providing the UART baud rate, the channel clock (not divided by 16) is also used for other modes such as bitbang and MPSSE.

FT2232H, FT4232H, FT232H (and all their variants)

These devices are USB high-speed peripherials, and support a higher baud rate and channel clock range. The base clock of the device is 120MHz. The divisor encoding is an extension of the one used in FT232B, and is backwards compatible.

The divisor is encoded into an 18-bit number (with top two bits overflowing into the wIndex field) as follows:

  • bits 0-13: integer part (must be at least 2, except for the special cases below)
  • bits 14-16: fractional part, encoded
    • 0: .0
    • 1: .5
    • 2: .25
    • 3: .125
    • 4: .375
    • 5: .675
    • 6: .75
    • 7: .875
  • bit 17: divisor and UART mode
    • 0: low-speed, FT232B compatible:
      • base 120MHz clock is pre-divided by 2.5 into a 48MHz clock before being put through the divisor
      • baud rate is channel clock divided by 16
    • 1: high-speed:
      • base 120MHz clock is fed directly into the divisor
      • baud rate is channel clock divided by 10

There are also two special divisors with dedicated encoding:

  • 0x00000 or 0x20000 encodes a special divisor of 1 (corresponding to low-speed 3000000 or high-speed 12000000 baud rate, respectively)
  • 0x00001 or 0x20001 encodes a special divisor of 1.5 (corresponding to low-speed 2000000 or high-speed 8000000 baud rate, respectively)

In addition to providing the UART baud rate, the channel clock (not divided by 10 or 16) is also used for other modes such as bitbang and MPSSE.

Note that, while the new high-speed divisor mode is usually preferable due to more precision, it cannot represent some of the lowest baud rates (600 baud and below). The low-speed mode should be used for those.

SET_DATA_CHARACTERISTICS

Sets the UART data format and break state.

  • applicable to: all D2xx devices (but will be a no-op in non-UART mode)
  • bmRequestType: 0x40
  • bRequest: 0x04
  • wValue:
    • bits 0-7: number of data bits (7-8; allegedly FT8U100A can also do 5-6)
    • bits 8-10: parity mode
      • 0: none
      • 1: odd
      • 2: even
      • 3: mark
      • 4: space
    • bits 11-13: stop bits
      • 0: 1 bit
      • 1: 1.5 bits (support status unclear)
      • 2: 2 bits
    • bit 14: transmitter in break state if set
  • wIndex: channel

GET_MODEM_STATUS

Returns current modem status and line status. This is the same information that is transmitted in the packet header bytes on the IN endpoint.

  • applicable to: all D2xx devices
  • bmRequestType: 0xc0
  • bRequest: 0x05
  • wValue: 0
  • wIndex: channel
  • wLength: 2
  • data:
    • byte 0: modem status (shows the most recent state of the modem status input pins)
      • bit 0: always 1?
      • bit 1: always 0?
      • bit 2: always 0?
      • bit 3: always 0?
      • TODO: allegedly high-speed devices have 0010 in low bits?
      • bit 4: CTS
      • bit 5: DSR
      • bit 6: RI
      • bit 7: DCD
    • byte 1: line status
      • bit 0: data ready (???)
      • bit 1: overrun error (device received data on the business end when there was no more space in IN endpoint FIFO)
      • bit 2: parity error
      • bit 3: framing error
      • bit 4: break interrupt
      • bit 5: TX holding register (???)
      • bit 6: TX (OUT endpoint) FIFO is empty
      • bit 7: FIFO error (???)

TODO: allegedly FT8U100A only returns the first byte?

SET_EVENT_CHAR

Sets the special "event" character. Whenever a matching byte is received on the business end of the device, a packet will be sent on the IN endpoint immediately, instead of waiting for the buffer to fill completely or for the latency timer to expire. This can be eg. set to 0x0d (CR) to immediately present received lines to the host.

  • applicable to: all D2xx devices
  • bmRequestType: 0x40
  • bRequest: 0x06
  • wValue:
    • bits 0-7: event character
    • bit 8: event character enable (if unset, no event character processing is done)
  • wIndex: channel

SET_ERROR_CHAR

Sets the special "error" character that will be inserted into the receive FIFO in place of parity and framing errors.

  • applicable to: all D2xx devices (but will be a no-op in non-UART mode)
  • bmRequestType: 0x40
  • bRequest: 0x07
  • wValue:
    • bits 0-7: error character
    • bit 8: error character enable (if unset, parity and framing errors do not insert anything into the FIFO)
  • wIndex: channel

SET_LATENCY_TIMER

Sets the latency timer (see IN endpoint description).

  • applicable to: everything except FT8U100A, FT8U232A, FT8U245A
  • bmRequestType: 0x40
  • bRequest: 0x09
  • wValue: latency timer, in units of 1ms (2 to 255)
  • wIndex: channel

Note: on FT232R and FT245R this command is also used as EEPROM write unlock. The latency timer has to be set to 0x77 to enable EEPROM writes. Otherwise, the write commands get ignored.

GET_LATENCY_TIMER

Reads back the latency timer (see IN endpoint description). Also useful for telling FT8U2xxA and FT2xxB apart.

  • applicable to: everything except FT8U100A, FT8U232A, FT8U245A
  • bmRequestType: 0xc0
  • bRequest: 0x0a
  • wValue: 0
  • wIndex: channel
  • wLength: 1
  • data: latency timer (1 byte)

SET_BITMODE

Sets a special mode on the channel, overriding whatever base mode it has.

  • applicable to: FT232B, FT245B, FT232R, FT245R, FT2232[CDL], FT2232H, FT4232H, FT232H, FT-X series
    • async bitbang: all of the above devices
    • MPSSE: FT2232[CDL] (channel A only), FT2232H, FT4232H (channel A and B only), FT232H
    • sync bitbang: FT232R, FT245R, FT2232[CDL], FT2232H, FT4232H, FT232H, FT-X series
    • MCU host bus: FT2232[CDL], FT2232H
    • fast opto-isolated serial: FT2232[CDL], FT2232H, FT232H
    • CBUS bit-bang: FT232R, FT232H, FT-X series
    • synchronous 245-style FIFO: FT2232H, FT232H
    • FT1248: FT232H maybe?!?
  • bmRequestType: 0x40
  • bRequest: 0x09
  • wValue:
  • wIndex: channel

TODO: figure out the details of this cursed thing

TODO: why are FT1248 and fast opto-isolated serial set both here and in the EEPROM

TODO: CBUS bit-bang has special semantics and can be combined with base mode?!? figure that out

GET_PIN_STATE

Reads current raw state of the channel's DBUS pins.

FTDI calls this request GET_BITMODE. However, this naming decision is a crime against catgirlkind, and we shall not respect it.

  • applicable to: FT232B, FT245B, FT232R, FT245R, FT2232[CDL], FT2232H, FT4232H, FT232H, FT-X series
  • bmRequestType: 0xc0
  • bRequest: 0x0c
  • wValue: 0
  • wIndex: channel
  • wLength: 1
  • data: pin state

TODO: allegedly this reads CBUS state instead of DBUS state when in CBUS bit-bang mode

VENDOR_CMD_GET

Does a vendor-specific operation with get semantics. Corresponds to FT_VendorCmdGet and FT_VendorCmdGetEx.

You may be asking yourself why FTDI saw fit to create a space for vendor-defined requests within its vendor-defined requests space as defined by USB, given that it is the defining vendor in both cases. The answer is that I have no meowing idea. However, this seems to be where they stuff a bunch of subcommands specific to their weirder devices.

  • applicable to: FT4222H, allegedly UMFTPD3A
  • bmRequestType: 0xc0
  • bRequest: 0x20
  • wValue: request type
  • wIndex: channel (or not, it's vendor-defined after all)
  • wLength: up to 0x80

The request set appears to be specific to the exact device. For the FT4222H request list, see [TODO].

VENDOR_CMD_SET

Does a vendor-specific operation with set semantics. Corresponds to FT_VendorCmdSet.

  • applicable to: FT4222H, allegedly UMFTPD3A
  • bmRequestType: 0x40
  • bRequest: 0x21
  • wValue:
    • bits 0-7: request type
    • bits 8-15: data, if a single byte of data is transferred
  • wIndex: channel (or not, it's vendor-defined after all)
  • wLength: up to 0x80

If exactly 1 byte is sent to the device, it is put in the high byte of wValue, and wLength is set to 0. If more than 1 byte is sent to the device, they are all put in the data payload, and the high byte of wValue is unused.

The request set appears to be specific to the exact device. For the FT4222H request list, see [TODO].

READ_EEPROM

Reads a 16-bit word from the EEPROM.

  • applicable to: FT8U100A?, FT8U232A, FT8U245A, FT232B, FT245B, FT232R, FT245R, FT2232[CDL], FT2232H, FT4232H, FT232H, FT-X series
  • bmRequestType: 0xc0
  • bRequest: 0x90
  • wValue: 0
  • wIndex: word address to read; note that the address is counted in 16-bit words, not bytes
  • wLength: 2
  • data: word from EEPROM (little-endian)

The format of the EEPROM depends on the device. See the documentation for the particular device.

WRITE_EEPROM

Writes a 16-bit word into the EEPROM.

  • applicable to: FT8U100A?, FT8U232A, FT8U245A, FT232B, FT245B, FT232R, FT245R, FT2232[CDL], FT2232H, FT4232H, FT232H, FT-X series
  • bmRequestType: 0x40
  • bRequest: 0x91
  • wValue: word to write to the EEPROM
  • wIndex: word address to write; note that the address is counted in 16-bit words, not bytes

Note: on FT232R and FT245R this command is only accepted when the latency timer is set to the magic 0x77 value.

Note that the EEPROM on FT232R and FT245R devices is 32-bit dword oriented, not 16-bit. This is completely transparent on reads, but is significant for writes: FT2xxR EEPROM must always be written one aligned dword at a time, with the lower-address word written first.

TODO: what about FT-X series?

ERASE_EEPROM

Erases the entire EEPROM.

  • applicable to: FT8U100A?, FT8U232A, FT8U245A, FT232B, FT245B, FT2232[CDL], FT2232H, FT4232H, FT232H
  • bmRequestType: 0x40
  • bRequest: 0x92
  • wValue: 0
  • wIndex: 0

FIFO modes

TODO

Bitbang modes

TODO

MPSSE mode

TODO

MCU host bus mode

TODO

FT1248 mode

TODO

Fast opto-isolated serial mode

TODO

I2C peripherial mode

TODO

FT8U232A and FT8U245A

The first generation of fixed-function D2xx devices. The devices are:

  • FT8U232AM: UART mode, 32-pin MQFP
  • FT8U245AM: FIFO mode, 32-pin MQFP

Both devices look exactly the same from the software perspective, and in fact may or may not be the same silicon.

Features:

  • is a full-speed USB 1.1 peripherial
  • single channel D2xx device, hardwired to either UART or FIFO mode
    • no alternate bit modes
  • 384-byte IN FIFO, 128-byte OUT FIFO
  • 48MHz internal base clock, generated from 6MHz crystal
  • 5V VCC supply (used for internal circuitry and business-end IO)
  • separate AGND and AVCC supply for the clock multiplier
  • internal 3.3V LDO
  • required external support circuitry:
    • USB D+ pullup
    • power-on reset circuit
    • decoupling capacitor for internal LDO
    • RC timer for oscillator bootstrap
    • 6MHz crystal
    • optionally, a 93C46 64×16-bit EEPROM

The default VID:PID of the device is 0403:6001, unless configured otherwise by the EEPROM. The bcdDevice value is 0x0200.

Pinout

MQFP pincategoryFT8U232AFT8U245A
1EEPROMEESKEESK
2EEPROMEEDATAEEDATA
3powerVCCVCC
4controlRESET#RESET#
5controlTESTTEST
6power3V3OUT3V3OUT
7USBUSBDPUSBDP
8USBUSBDMUSBDM
9powerGNDGND
10IOSLEEP#EEGNT#
11IORXLED#EEREQ#
12IOTXLED#RXF#
13powerVCCVCC
14IOPWRCTLTXE#
15IOUSBENWR
16IOTXDENRD#
17powerGNDGND
18IORI#D7
19IODCD#D6
20IODSR#D5
21IODTR#D4
22IOCTS#D3
23IORTS#D2
24IORXDD1
25IOTXDD0
26powerVCCVCC
27clockXTINXTIN
28clockXTOUTXTOUT
29powerAGNDAGND
30powerAVCCAVCC
31clockRCCLKRCCLK
32EEPROMEECSEECS

UART-mode IO pins have the following functions:

  • TXD, RXD, RTS#, CTS#, DTR#, DSR#, DCD#, RI#: standard UART pins
  • SLEEP#: device output, goes low when in USB suspend mode
  • RXLED#, TXLED#: active-low LED outputs
  • PWRCTL: device input, used to generate USB descriptors when EEPROM not present or not functional
    • 0: bus-powered
    • 1: self-powered
  • TXDEN: device output, high while TXD is actively transmitting data; can be used as transmitter enable for RS485 transceivers
  • USBEN: device output, high after the host configures the device

FIFO-mode IO pins have the following functions:

  • D0-D7, TXE#, RXF#, RD#, WR: standard FIFO-mode pins
  • EEREQ#: device input, requests access to EEPROM via data bus
  • EEGNT#: device output, grants access to EEPROM via data bus

The semantics of EEREQ# and EEGNT# are unclear. They were removed from all subsequent devices.

TODO: wtf is this exactly

The EEPROM interface is 3-pin at the FTDI chip, while the EEPROM itself has a 4-pin interface. This is because the FTDI device uses a single tied data line. To connect the EEPROM, connect the FTDI EEDATA pin directly to the ROM's data input, and to the data output via a 2.2kΩ resistor.

EEPROM data format

  • word 0x00: always 0
  • word 0x01: idVendor (USB VID)
  • word 0x02: idProduct (USB PID)
  • word 0x03: bcdDevice (should be 0x200)
  • word 0x04: USB config (goes straight to configuration descriptor)
    • bits 0-7: bmAttributes
      • bit 5: remote wakeup enabled
      • bit 6: self-powered
      • bit 7: always set to 1
    • bits 8-15: bMaxPower (max power in units of 2mA)
  • words 0x05, 0x06: always 0
  • word 0x07: manufacturer string pointer
  • word 0x08: product description string pointer
  • word 0x09: serial number string pointer
  • words 0x0a..0x3f: string / user area
  • word 0x3f: checksum

String pointers are formatted as follows:

  • bits 0-6: pointer to descriptor within EEPROM (counted in bytes)
  • bit 7: always set to 1
  • bits 8-15: total length of descriptor in bytes

The string descriptors are stored in ROM with the descriptor header included, as follows:

  • word 0: header
    • bits 0-7: total length of descriptor in bytes (includes header)
    • bits 8-15: descriptor type (always 3 — string)
  • words 1 and up: string in UTF-16

The checksum can be computed as follows:

#![allow(unused)]
fn main() {
fn checksum(eeprom: &[u16; 0x40]) -> u16 {
    let mut res: u16 = 0xaaaa;
    for pos in 0..0x3f { // checksum word is NOT included — we're calculating it
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    res
}
}

FT232B and FT245B

The second generation of fixed-function D2xx devices, an upgrade to FT8U232A and FT8U245A. The devices are:

  • FT232BM: UART mode, 32-pin LQFP
  • FT232BL: UART mode, 32-pin LQFP (lead-free version)
  • FT232BQ: UART mode, 32-pin QFN
  • FT245BM: FIFO mode, 32-pin LQFP
  • FT245BL: FIFO mode, 32-pin LQFP (lead-free version)

Both FT232B and FT245B look exactly the same from the software perspective, and in fact may or may not be the same silicon.

Features:

  • is a full-speed USB 1.1 peripherial
  • single channel D2xx device, hardwired to either UART or FIFO base mode
  • 384-byte IN FIFO, 128-byte OUT FIFO
  • 48MHz internal base clock, generated from 6MHz crystal
  • 5V VCC supply for internal circuitry
  • separate 3.3V or 5V VCCIO supply for business-end IO
  • separate AGND and AVCC 5V supply for the clock multiplier
  • internal 3.3V LDO
  • internal power-on reset circuit
  • required external support circuitry:
    • USB D+ pullup
    • decoupling capacitor for internal LDO
    • 6MHz crystal or external clock
    • optionally, a 93C46 64×16-bit EEPROM; a 93C56 or 93C66 is also acceptable, but the device will not be able to access the extra space

On reset, the device samples the value of the EESK pin to determine the default VID:PID that will be used unless configured otherwise by the EEPROM. The default VID:PID is:

  • 0403:6001 if EESK is high (or left floating, as the device has weak internal pullup)
  • 0403:6004 if EESK is low and the device is an FT232B
  • 0403:6005 if EESK is low and the device is an FT245B

The bcdDevice value for the device is 0x0200 (same as FT8U2xxA) if no serial number has been configured, or 0x0400 if a serial number has been configured.

Pinout

The pinout is mostly, but not quite, compatible with FT8U2xxA.

LQFP / QFN pincategoryFT8U232AFT8U245A
1EEPROMEESKEESK
2EEPROMEEDATAEEDATA
3powerVCCVCC
4controlRESET#RESET#
5controlRSTOUT#RSTOUT#
6power3V3OUT3V3OUT
7USBUSBDPUSBDP
8USBUSBDMUSBDM
9powerGNDGND
10IOSLEEP#PWREN#
11IORXLED#SI/WU#
12IOTXLED#RXF#
13powerVCCIOVCCIO
14IOPWRCTLTXE#
15IOPWREN#WR
16IOTXDENRD#
17powerGNDGND
18IORI#D7
19IODCD#D6
20IODSR#D5
21IODTR#D4
22IOCTS#D3
23IORTS#D2
24IORXDD1
25IOTXDD0
26powerVCCVCC
27clockXTINXTIN
28clockXTOUTXTOUT
29powerAGNDAGND
30powerAVCCAVCC
31controlTESTTEST
32EEPROMEECSEECS

UART-mode IO pins have the following functions:

  • TXD, RXD, RTS#, CTS#, DTR#, DSR#, DCD#, RI#: standard UART pins
  • SLEEP#: device output, goes low when in USB suspend mode
  • RXLED#, TXLED#: active-low LED outputs
  • PWRCTL: device input, used to generate USB descriptors when EEPROM not present or not functional
    • 0: bus-powered
    • 1: self-powered
  • TXDEN: device output, high while TXD is actively transmitting data; can be used as transmitter enable for RS485 transceivers
  • PWREN#: device output, low when the device has been configured by the host and is not in suspend mode (can be used to gate power to the rest of the board)

FIFO-mode IO pins have the following functions:

  • D0-D7, TXE#, RXF#, RD#, WR, SI/WU#: standard FIFO-mode pins
  • PWREN#: like in UART mode

The EEPROM interface is 3-pin at the FTDI chip, while the EEPROM itself has a 4-pin interface. This is because the FTDI device uses a single tied data line. To connect the EEPROM, connect the FTDI EEDATA pin directly to the ROM's data input, and to the data output via a 2.2kΩ resistor.

EEPROM data format

The format is backwards-compatible with the one used by FT8U2xxA devices.

  • word 0x00: always 0
  • word 0x01: idVendor (USB VID)
  • word 0x02: idProduct (USB PID)
  • word 0x03: bcdDevice (should be 0x400 or 0x200 when serial number not present)
  • word 0x04: USB config (goes straight to configuration descriptor)
    • bits 0-7: bmAttributes
      • bit 5: remote wakeup enabled
      • bit 6: self-powered
      • bit 7: always set to 1
    • bits 8-15: bMaxPower (max power in units of 2mA)
  • word 0x05: device control
    • bit 0: IN endpoint is isochronous
    • bit 1: OUT endpoint is isochronous
    • bit 2: IO pulldown in suspend
    • bit 3: serial number enabled
    • bit 4: bcdUSB is present
  • word 0x06: bcdUSB
  • word 0x07: manufacturer string pointer
  • word 0x08: product description string pointer
  • word 0x09: serial number string pointer
  • words 0x0a..0x3f: string / user area
  • word 0x3f: checksum

String pointers are formatted as follows:

  • bits 0-6: pointer to descriptor within EEPROM (counted in bytes)
  • bit 7: always set to 1
  • bits 8-15: total length of descriptor in bytes

The string descriptors are stored in ROM with the descriptor header included, as follows:

  • word 0: header
    • bits 0-7: total length of descriptor in bytes (includes header)
    • bits 8-15: descriptor type (always 3 — string)
  • words 1 and up: string in UTF-16

The checksum can be computed as follows:

#![allow(unused)]
fn main() {
fn checksum(eeprom: &[u16; 0x40]) -> u16 {
    let mut res: u16 = 0xaaaa;
    for pos in 0..0x3f { // checksum word is NOT included — we're calculating it
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    res
}
}

FT2232[CDL]

The third generation of fixed-function D2xx devices, now with two channels. The devices are:

  • FT2232C: first revision; 48-pin LQFP package
  • FT2232L: first revision; 48-pin LQFP package (lead-free version)
  • FT2232D: second revision, fixed CPU FIFO mode; 48-pin LQFP package (lead-free version)

The FT2232H is an entirely different device, and is not described here.

Features:

  • is a full-speed USB 1.1 peripherial
  • dual-channel D2xx device
  • each channel can be independently configured to one of several supported modes:
  • 384-byte IN FIFOs, 128-byte OUT FIFOs (per channel)
  • 48MHz internal base clock, generated from 6MHz crystal
  • 5V VCC supply for internal circuitry
  • separate 3.3V or 5V VCCIOA supply for channel A business-end IO
  • separate 3.3V or 5V VCCIOB supply for channel B business-end IO
  • separate AGND and AVCC 5V supply for the clock multiplier
  • internal 3.3V LDO
  • internal power-on reset circuit
  • required external support circuitry:
    • USB D+ pullup
    • decoupling capacitor for internal LDO
    • 6MHz crystal or external clock
    • optionally, a 93C46 (64×16-bit), 93C56 (128×16-bit), or 93C66 (256×16-bit) EEPROM

The default VID:PID of the device is 0403:6010, unless configured otherwise by the EEPROM. The bcdDevice value is 0x0500.

Pinout

pincategoryfunction
1EEPROMEESK
2EEPROMEEDATA
3powerVCC
4controlRESET#
5controlRSTOUT#
6power3V3OUT
7USBUSBDP
8USBUSBDM
9powerGND
10IO-ASI/WUA
11IO-AACBUS3
12IO-AACBUS2
13IO-AACBUS1
14powerVCCIOA
15IO-AACBUS0
16IO-AADBUS7
17IO-AADBUS6
18powerGND
19IO-AADBUS5
20IO-AADBUS4
21IO-AADBUS3
22IO-AADBUS2
23IO-AADBUS1
24IO-AADBUS0
25powerGND
26IO-BSI/WUB
27IO-BBCBUS3
28IO-BBCBUS2
29IO-BBCBUS1
30IO-BBCBUS0
31powerVCCIOB
32IO-BBDBUS7
33IO-BBDBUS6
34powerGND
35IO-BBDBUS5
36IO-BBDBUS4
37IO-BBDBUS3
38IO-BBDBUS2
39IO-BBDBUS1
40IO-BBDBUS0
41controlPWREN#
42powerVCC
43clockXTIN
44clockXTOUT
45powerAGND
46powerAVCC
47controlTEST
48EEPROMEECS

Pin functions per mode

pinUARTFIFOCPU FIFObitbang (U)bitbang (F)MPSSEMCU busopto-isolated
ADBUS0TXDD0D0D0D0TCK/SKAD0-
ADBUS1RXDD1D1D1D1TDI/DOAD1-
ADBUS2RTS#D2D2D2D2TDO/DIAD2-
ADBUS3CTS#D3D3D3D3TMS/CSAD3-
ADBUS4DTR#D4D4D4D4GPIOL0AD4-
ADBUS5DSR#D5D5D5D5GPIOL1AD5-
ADBUS6DCD#D6D6D6D6GPIOL2AD6-
ADBUS7RI#D7D7D7D7GPIOL3AD7-
ACBUS0TXDENRXF#CS#-WR#GPIOH0I/O0-
ACBUS1SLEEP#TXE#A0-RD#GPIOH1I/O1-
ACBUS2RXLED#RD#RD#WR#-GPIOH2IORDY-
ACBUS3TXLED#WRWR#RD#-GPIOH3OSC-
SI/WUASI/WUSI/WU- (?)SI/WUSI/WUN/A--
BDBUS0TXDD0D0D0D0N/AA8FSDI
BDBUS1RXDD1D1D1D1N/AA9FSCLK
BDBUS2RTS#D2D2D2D2N/AA10FSDO
BDBUS3CTS#D3D3D3D3N/AA11FSCTS
BDBUS4DTR#D4D4D4D4N/AA12-
BDBUS5DSR#D5D5D5D5N/AA13-
BDBUS6DCD#D6D6D6D6N/AA14-
BDBUS7RI#D7D7D7D7N/AA15-
BCBUS0TXDENRXF#CS#-WR#N/ACS#-
BCBUS1SLEEP#TXE#A0-RD#N/AALE-
BCBUS2RXLED#RD#RD#WR#-N/ARD#-
BCBUS3TXLED#WRWR#RD#-N/AWR#-
SI/WUBSI/WUSI/WU- (?)SI/WUSI/WUN/A-SI/WU

Note: for bitbang modes, the pin assignments in the "bitbang (U)" column apply when the base mode of the channel is UART, and the "bitbang (F)" column applies otherwise.

EEPROM data format

The device will accept 64-word, 128-word, and 256-word EEPROMs. In case of 256-word EEPROMs, only first half is covered by the checksum. The other half can still be used to store user data.

  • word 0x00:
    • bits 0-2: channel A mode
    • bit 3: channel A enable bind to VCP driver
    • bit 4: channel A high current output drive
    • bits 8-10: channel B mode (see above)
    • bit 11: channel B enable bind to VCP driver
    • bit 12: channel B high current output drive
  • word 0x01: idVendor (USB VID)
  • word 0x02: idProduct (USB PID)
  • word 0x03: bcdDevice (0x500)
  • word 0x04: USB config (goes straight to configuration descriptor)
    • bits 0-7: bmAttributes
      • bit 5: remote wakeup enabled
      • bit 6: self-powered
      • bit 7: always set to 1
    • bits 8-15: bMaxPower (max power in units of 2mA)
  • word 0x05: device control
    • bit 0: channel A IN endpoint is isochronous
    • bit 1: channel A OUT endpoint is isochronous
    • bit 2: IO pulldown in suspend
    • bit 3: serial number enabled
    • bit 4: bcdUSB is present
    • bit 5: channel B IN endpoint is isochronous
    • bit 6: channel B OUT endpoint is isochronous
  • word 0x06: bcdUSB
  • word 0x07: manufacturer string pointer
  • word 0x08: product description string pointer
  • word 0x09: serial number string pointer
  • word 0x0a: EEPROM type
    • 0x46: 93C46 (64-word)
    • 0x56: 93C56 (128-word)
    • 0x66: 93C66 (256-word)
  • for 64-word EEPROM:
    • words 0x0b..0x3f: string / user area
    • word 0x3f: checksum
  • for 128-word and 256-word EEPROM:
    • words 0xb..0x4b: user area
    • words 0x4b..0x7f: string / user area
    • word 0x7f: checksum
  • words 0x80..0x100 (256-word EEPROM only): user area (not covered by checksum)

String pointers are formatted as follows:

  • for 64-word EEPROM:
    • bits 0-6: pointer to descriptor within EEPROM (counted in bytes)
    • bit 7: always set to 1
  • for 128-word or 256-word EEPROM:
    • bits 0-7: pointer to descriptor within EEPROM (counted in bytes); note that FTDI tools will only store string descriptors in the area starting at word 0x4b, ensuring the high bit is always set
  • bits 8-15: total length of descriptor in bytes

TODO: figure out wtf it is with the always-set high bit

The string descriptors are stored in ROM with the descriptor header included, as follows:

  • word 0: header
    • bits 0-7: total length of descriptor in bytes (includes header)
    • bits 8-15: descriptor type (always 3 — string)
  • words 1 and up: string in UTF-16

The checksum can be computed as follows:

#![allow(unused)]
fn main() {
fn checksum(eeprom: &[u16]) -> u16 {
    let checksum_word = match eeprom.len() {
        0x40 => 0x3f,
        0x80 | 0x100 => 0x7f,
    };
    let mut res: u16 = 0xaaaa;
    for pos in 0..checksum_word { // checksum word is NOT included — we're calculating it
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    res
}
}

FT232R and FT245R

The fourth generation of fixed-function D2xx devices, an upgrade to FT232B and FT245B. The devices are:

  • FT232RL: UART mode, 28-pin TSSOP
  • FT232RQ: UART mode, 32-pin QFN
  • FT245RL: FIFO mode, 28-pin TSSOP
  • FT245RQ: FIFO mode, 32-pin QFN
  • FT232RNL: revised version, UART mode, 28-pin TSSOP
  • FT232RNQ: revised version, UART mode, 32-pin QFN
  • FT245RNL: revised version, FIFO mode, 28-pin TSSOP
  • FT245RNQ: revised version, FIFO mode, 32-pin QFN

FT232R and FT245R are the exact same device, and differ only in a configuration bit in the internal EEPROM. That bit can just be reprogrammed by the user. Likewise, FT232RN and FT245RN are the exact same device.

The FT2xxRN is a minor revision of FT2xxR, making the internal oscillator work when powered by 3.3V VCC.

Features:

  • is a full-speed USB 1.1 peripherial
  • single channel D2xx device, set to either UART or FIFO base mode by EEPROM
  • in UART mode, the device has 5 CBUS pins that can be programmed (via EEPROM) to a variety of functions
  • added EEPROM-programmable signal inversion on all UART pins
  • dynamically-selectable alternate modes include:
  • 256-byte IN FIFO, 128-byte OUT FIFO
  • internal EEPROM, replacing the external EEPROM interface of FT2xxB
    • pre-programmed factory area in EEPROM, including a unique chip ID
  • 48MHz internal base clock, generated from either internal 12MHz oscillator or external 12MHz crystal
    • external oscillator has to be selected through EEPROM configuration
    • internal oscillator doesn't work on 3.3V VCC on the original FT2xxR
    • ... leading to a fun factory programming procedure if you wish to use the device on 3.3V VCC, which likely further motivated the FT2xxRN revision
  • 3.3V or 5V VCC supply for internal circuitry
  • separate 1.8V to 5V VCCIO supply for business-end IO
  • internal 5V-to-3.3V LDO
  • internal D+ pullup resistor
  • internal power-on reset circuit
  • required external support circuitry:
    • just the decoupling capacitors

The default VID:PID of the device is 0403:6001 (FT2xxR) or 0403:6049 (FT2xxRN), unless configured otherwise by the EEPROM. The bcdDevice value is 0x0600.

Pinout

QFN32TSSOP28categoryFT232RFT245R
14powerVCCIOVCCIO
25IO-DBUSRXDD1
36IO-DBUSRI#D7
47powerGNDGND
58NC?--
69IO-DBUSDSR#D5
710IO-DBUSDCD#D6
811IO-DBUSCTS#D3
912IO-CBUSCBUS4PWREN#
1013IO-CBUSCBUS2RD#
1114IO-CBUSCBUS3WR
12-NC--
13-NC--
1415USBUSBDPUSBDP
1516USBUSBDNUSBDN
1617power3V3OUT3V3OUT
1718powerGNDGND
1819controlRESET#RESET#
1920powerVCCVCC
2021powerGNDGND
2122IO-CBUSCBUS1TXE#
2223IO-CBUSCBUS0RXF#
2324NC?--
2425powerAGNDAGND
25-NC--
2626controlTESTTEST
2727clockOSCIOSCI
2828clockOSCOOSCO
29-NC--
301IO-DBUSTXDD0
312IO-DBUSDTR#D4
323IO-DBUSRTS#D2

TODO: FT245R datasheet and FT_PROG claim that CBUS pins are not programmable on the FT245R and perform fixed functions. This is most likely to be a lie.

CBUS pins

The device has 5 CBUS pins. They can be configured through the EEPROM to do the following functions:

EEPROM valuevalid on pinsfunction
0x0allUART TXDEN
0x1allPWREN#
0x2allUART RXLED#
0x3allUART TXLED#
0x4allUART TXRXLED#
0x5allSLEEP#
0x6allCLK48
0x7allCLK24
0x8allCLK12
0x9allCLK6
0xaCBUS0-CBUS3I/O (for CBUS bitbang mode)
0xbCBUS0-CBUS3bitbang WR#
0xcCBUS0-CBUS3bitbang RD#
0xdCBUS0FIFO RXF#
0xdCBUS1FIFO TXE#
0xdCBUS2FIFO RD#
0xdCBUS3FIFO WR

TODO: this list (particularly "valid on pins" and everything relating to FT245R) should be deemed extremely suspicious, as it seems to differ a lot between the datasheet, FT_PROG, and libftd2xx, and also doesn't seem to make all that much sense. The above is merely a least-squares approximation assembled from multiple lying sources.

The factory-programmed defaults are as follows:

pinFT232RFT245R
CBUS0TXLED#RXF#
CBUS1RXLED#TXE#
CBUS2TXDENRD#
CBUS3PWREN#WR
CBUS4SLEEP#PWREN#

The TXDEN, TXLED#, RXLED#, PWREN# and SLEEP# functions perform the same role as corresponding FT232B pins. TXRXLED# is a composite LED output, showing both TX and RX activity. CLK* functions provide a clock output of the selected frequency (6 to 48MHz).

EEPROM format

The device has a 40×32-bit internal EEPROM. However, it pretends to be a 80×16-bit word EEPROM on the USB interface. Words 0x00..0x40 are user-programmable, while words 0x40..0x50 contain factory-programmed data and are (allegedly) immutable. Note that the factory area is not covered by the checksum (or maybe has its own checksum).

The device introduces a simple "EEPROM write lock" mechanism: the EEPROM can only be programmed when the current latency timer is set to 0x77.

The "erase EEPROM" request is not supported on FT2xxR (presumably because, if supported, it'd erase the entire EEPROM along with factory data).

The 32-bit dword internal organization of the EEPROM is completely transparent on reads: the device will read the whole dword and reply to the USB request with just the relevant half of it. However, writes need to be handled specially:

  • when the device receives a "write EEPROM word" request for an even-address word, the data is stored in an internal register, but EEPROM is not modified
  • when the device receives a "write EEPROM word" request for an odd-address word, the data is combined together with the last data word previously stored in the register by an even-address write, and the whole 32-bit dword is written into EEPROM

This effectively means that EEPROM writes always have to be issued in aligned word pairs to work properly. In an infamous incident, FTDI Windows drivers abused this subtle behavior (which FT2xxR clones generally didn't replicate) to selectively brick clone devices.

The EEPROM format is:

  • word 0x00:
    • bit 0: device kind
      • 0: FT232R
      • 1: FT245R
      • NOTE: the vendor programming tools go out of their way to preserve the value of this bit. However, using the raw control requests, it can be modified just fine, turning an FT232R device into an FT245R or vice-versa.
    • bit 1: use external oscillator
    • bit 2: high-current IO
    • bit 3: enable bind to VCP driver
    • bit 4: regulator on during suspend
    • bit 8-15: bulk endpoint max packet size (0x40 by default)
      • note: badly-programmed devices exist with this field set to 0; this needs to be worked around in the driver
      • TODO: it is unclear whether this applies to IN, OUT, or both
  • word 0x01: idVendor (USB VID)
  • word 0x02: idProduct (USB PID)
  • word 0x03: bcdDevice (0x600)
  • word 0x04: USB config (goes straight to configuration descriptor)
    • bits 0-7: bmAttributes
      • bit 5: remote wakeup enabled
      • bit 6: self-powered
      • bit 7: always set to 1
    • bits 8-15: bMaxPower (max power in units of 2mA)
  • word 0x05: device control
    • bit 2: IO pulldown in suspend
    • bit 3: serial number enabled
    • bit 8: invert TXD (FT232R only)
    • bit 9: invert RXD (FT232R only)
    • bit 10: invert RTS (FT232R only)
    • bit 11: invert CTS (FT232R only)
    • bit 12: invert DTR (FT232R only)
    • bit 13: invert DSR (FT232R only)
    • bit 14: invert DCD (FT232R only)
    • bit 15: invert RI (FT232R only)
  • word 0x06: bcdUSB (always 2.0?)
  • word 0x07: manufacturer string pointer
  • word 0x08: product description string pointer
  • word 0x09: serial number string pointer
  • word 0x0a:
    • bits 0-3: CBUS0 function (see table above)
    • bits 4-7: CBUS1 function
    • bits 8-11: CBUS2 function
    • bits 12-15: CBUS3 function
  • word 0x0b:
    • bits 0-3: CBUS4 function
  • words 0x0c..0x3f: string / user area
  • word 0x3f: checksum
  • words 0x40..0x50: factory data (mostly unknown)
    • word 0x42:
      • bit 1: is FT2xxRN
    • word 0x43: low word of unscrambled chipid (unique per-device ID)
    • word 0x44: high word of unscrambled chipid

String pointers are formatted as follows:

  • bits 0-6: pointer to descriptor within EEPROM (counted in bytes)
  • bit 7: always set to 1
  • bits 8-15: total length of descriptor in bytes

The string descriptors are stored in ROM with the descriptor header included, as follows:

  • word 0: header
    • bits 0-7: total length of descriptor in bytes (includes header)
    • bits 8-15: descriptor type (always 3 — string)
  • words 1 and up: string in UTF-16

The checksum can be computed as follows:

#![allow(unused)]
fn main() {
fn checksum(eeprom: &[u16; 0x50]) -> u16 {
    let mut res: u16 = 0xaaaa;
    for pos in 0..0x3f { // checksum word is NOT included — we're calculating it
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    res
}
}

For unknown reasons, the libftchipid library returns the chipid in scrambled form, computed as follows:

#![allow(unused)]
fn main() {
fn scramble_byte(b: u8) -> u8 {
    (b & 1) << 1 |
    (b & 2) << 5 |
    (b & 4) >> 2 |
    (b & 8) << 4 |
    (b & 0x10) >> 1 |
    (b & 0x20) >> 1 |
    (b & 0x40) >> 4 |
    (b & 0x80) >> 2
}

fn scramble_chipid(eeprom_chipid: u32) -> u32 {
    let scrambled_b0 = scramble_byte((unscrambled_chipid & 0xff) as u8);
    let scrambled_b1 = scramble_byte((unscrambled_chipid >> 8 & 0xff) as u8);
    let scrambled_b2 = scramble_byte((unscrambled_chipid >> 16 & 0xff) as u8);
    let scrambled_b3 = scramble_byte((unscrambled_chipid >> 24 & 0xff) as u8);
    // note the byte reversal
    let word = 
        (scrambled_b0 as u32) << 24 |
        (scrambled_b1 as u32) << 16 |
        (scrambled_b2 as u32) << 8 |
        (scrambled_b3 as u32);
    word ^ 0xa5f0f7d1
}
}

FT2232H and FT4232H

The fifth generation of fixed-function D2xx devices, an upgrade to FT2232D. There are two base devices:

  • FT2232H: has two channels with 16 IO pins each and a large selection of operating modes
  • FT4232H: has four channels with 8 IO pins each and a smaller selection of operating modes

Both of these devices are actually the same silicon, and are thus highly similar. Whether a device is FT2232H or FT4232H is determined by a fuse programmed at the factory. Note that the FT232H is not another variant of the same silicon, but a completely distinct device with different capabilities.

The devices have automotive variants, known as FT2232HA and FT4232HA. It is not known what their functional differences are, if any.

The devices also have USB-PD variants, which integrate a power delivery core into the same die. The D2xx function and the power delivery function are largely separate and operate independently, but they do share the same configuration EEPROM. The USB-PD variants are:

  • FT2233HP and FT4233HP: two USB-PD ports
  • FT2232HP and FT4232HP: one USB-PD port (actually identical to FTx233HP with the extra port unbonded)

All USB-PD variants are the same silicon (which is distinct from the "base" FT2232H silicon).

This document will use the name FT2232H to refer to FT2232HA/FT2232HP/FT2233HP as well, unless otherwise specified. The same applies for FT4232H.

Features:

  • is a high-speed USB 2.0 peripherial
    • supports higher UART baud rates and bitbang/FIFO/MPSSE speeds thanks to the extra oomph
    • integrated D+ pullup resistor
  • dual-channel (FT2232H) or quad-channel (FT4232H) D2xx device
  • each channel can be independently configured to one of several supported modes:
    • FT232B-like UART mode (default)
    • FT245B-like FIFO mode (selected in EEPROM; FT2232H only)
    • new synchronous FIFO mode (dynamically selected variant of FIFO mode; FT2232H only)
      • available on channel A only
      • NOTE: channel B cannot be used while this mode is active, as it reuses channel B's buffer resources
    • FT2232D-like CPU FIFO mode (selected in EEPROM; FT2232H only)
    • FT2xxB-like async bitbang mode (dynamically selected)
    • FT2232C-like sync bitbang mode (dynamically selected)
    • FT2232C-like MPSSE mode (dynamically selected)
      • on FT2232H, supported on both channels (an improvement from FT2232C)
      • on FT4232H, supported on channels A and B only
    • FT2232C-like fast opto-isolated serial mode (selected in EEPROM; FT2232H only)
    • FT2232C-like MCU bus controller mode (dynamically selected; FT2232H only, uses both channels)
  • FT2232H: 4kiB IN FIFO and 4kiB OUT FIFO for each channel
  • FT4232H: 2kiB IN FIFO and 2kiB OUT FIFO for each channel
  • 120MHz internal base clock, generated from 12MHz crystal
  • internal 3.3V to 1.8V LDO
  • 1.8V VCORE power supply for internal logic; can be connected to internal LDO
  • 3.3V VCCIO power supply for business-end IO
  • 3.3V VPHY power supply for USB PHY
  • 3.3V separate AGND and VPLL power supply for PHY PLL
  • internal power-on reset circuit
  • required external support circuitry:
    • precision resistor for PHY current reference
    • VBUS to 3.3V LDO (or other 3.3V power source)
    • decoupling capacitor for internal LDO
    • 12MHz crystal
    • optionally, a 93LC46 (64×16-bit), 93LC56 (128×16-bit), or 93LC66 (256×16-bit) EEPROM

For USB-PD devices, the USB-PD function is described on the USB-PD page.

The full list of devices is:

devicechannelsUSB-PD portsdefault VID:PIDbcdDevicepackage
FT2232HL2-0403:60100x070064-pin LQFP
FT2232HQ2-0403:60100x070064-pin QFN
FT2232H-56Q2-0403:60100x070056-pin VQFN
FT4232HL4-0403:60110x080064-pin LQFP
FT4232HQ4-0403:60110x080064-pin QFN
FT4232H-56Q4-0403:60110x080056-pin VQFN
FT2233HPQ220403:60400x280076-pin QFN
FT4233HPQ420403:60410x290076-pin QFN
FT2232HPQ210403:60420x2a0068-pin QFN
FT4232HPQ410403:60430x2b0068-pin QFN
FT2232HA?2-0403:60470x3500???
FT4232HAQ4-0403:60480x360064-pin QFN

Note: while FT2232HA is supported by the drivers, there is no datasheet available, thus packaging options are unknown. However, "same as FT4232HA" is probably a good bet.

Pinout — base and automotive devices

LQFP64 or QFN64 pinVQFN56 pincategoryFT2232HFT4232H
1-powerGNDGND
23clockOSCIOSCI
34clockOSCOOSCO
45powerVPHYVPHY
5-powerGNDGND
66referenceREFREF
77USBDMDM
88USBDPDP
99powerVPLLVPLL
10-powerAGNDAGND
11-powerGNDGND
12-powerVCOREVCORE
1310controlTESTTEST
1411controlRESET#RESET#
15-powerGNDGND
1612IO-AADBUS0ADBUS0
1713IO-AADBUS1ADBUS1
1814IO-AADBUS2ADBUS2
1915IO-AADBUS3ADBUS3
2016powerVCCIOVCCIO
2117IO-AADBUS4ADBUS4
2218IO-AADBUS5ADBUS5
2319IO-AADBUS6ADBUS6
2420IO-AADBUS7ADBUS7
2521powerGNDGND
2622IO-BACBUS0BDBUS0
2723IO-BACBUS1BDBUS1
2824IO-BACBUS2BDBUS2
2925IO-BACBUS3BDBUS3
3026IO-BACBUS4BDBUS4
31-powerVCCIOVCCIO
3227IO-BACBUS5BDBUS5
3328IO-BACBUS6BDBUS6
3429IO-BACBUS7BDBUS7
35-powerGNDGND
3630IO-sharedSUSPEND#SUSPEND#
3731powerVCOREVCORE
3832IO-CBDBUS0CDBUS0
3933IO-CBDBUS1CDBUS1
4034IO-CBDBUS2CDBUS2
4135IO-CBDBUS3CDBUS3
4236powerVCCIOVCCIO
4337IO-CBDBUS4CDBUS4
4438IO-CBDBUS5CDBUS5
4539IO-CBDBUS6CDBUS6
4640IO-CBDBUS7CDBUS7
4741powerGNDGND
4842IO-DBCBUS0DDBUS0
4943powerVREGOUTVREGOUT
5044powerVREGINVREGIN
5145powerGNDGND
5246IO-DBCBUS1DDBUS1
5347IO-DBCBUS2DDBUS2
5448IO-DBCBUS3DDBUS3
5549IO-DBCBUS4DDBUS4
5650powerVCCIOVCCIO
5751IO-DBCBUS5DDBUS5
5852IO-DBCBUS6DDBUS6
5953IO-DBCBUS7DDBUS7
6054IO-sharedPWREN#PWREN#
6155EEPROMEEDATAEEDATA
6256EEPROMEECLKEECLK
631EEPROMEECSEECS
642powerVCOREVCORE

Pinout — USB-PD devices

QFN76QFN68categoryFT2232HFT4232H
11EEPROMEECLKEECLK
22EEPROMEEDATAEEDATA
33controlTESTTEST
44controlRESET#RESET#
55IO-PDGPIO3GPIO3
6-IO-PDGPIO4GPIO4
7-IO-PDGPIO5GPIO5
86IO-AADBUS0ADBUS0
97IO-AADBUS1ADBUS1
108powerVCOREVCORE
119powerGNDGND
1210powerVCCIOVCCIO
1311IO-AADBUS2ADBUS2
1412IO-AADBUS3ADBUS3
1513IO-AADBUS4ADBUS4
1614IO-AADBUS5ADBUS5
1715IO-AADBUS6ADBUS6
1816IO-AADBUS7ADBUS7
1917IO-BACBUS0BDBUS0
2018IO-BACBUS1BDBUS1
2119IO-BACBUS2BDBUS2
2220IO-BACBUS3BDBUS3
2321IO-BACBUS4BDBUS4
2422IO-BACBUS5BDBUS5
2523IO-BACBUS6BDBUS6
2624IO-BACBUS7BDBUS7
2725powerVCOREVCORE
2826powerVCCIOVCCIO
2927clockOSCIOSCI
3028clockOSCOOSCO
3129powerGNDGND
3230powerVREGINVREGIN
3331powerVREGOUTVREGOUT
3432powerFSOURCEFSOURCE
3533powerVPPVPP
3634IO-CBDBUS0CDBUS0
3735IO-CBDBUS1CDBUS1
3836IO-CBDBUS2CDBUS2
3937IO-CBDBUS3CDBUS3
4038IO-CBDBUS4CDBUS4
4139powerVCCIOVCCIO
4240IO-CBDBUS5CDBUS5
4341IO-CBDBUS6CDBUS6
4442IO-CBDBUS7CDBUS7
4543IO-sharedSUSPEND#SUSPEND#
46-IO-PDGPIO6GPIO6
4744powerVCOREVCORE
4845IO-DBCBUS0DDBUS0
4946IO-DBCBUS1DDBUS1
5047IO-DBCBUS2DDBUS2
5148IO-DBCBUS3DDBUS3
5249IO-DBCBUS4DDBUS4
5350IO-DBCBUS5DDBUS5
5451powerVCCIOVCCIO
55-powerGNDGND
5652IO-DBCBUS6DDBUS6
5753IO-DBCBUS7DDBUS7
58-IO-PDGPIO7GPIO7
5954IO-PDGPIO2GPIO2
6055IO-PDGPIO1GPIO1
6156IO-PDGPIO0GPIO0
6257powerVCC_USBVCC_USB
6358USBDMDM
6459USBDPDP
6560referenceREFREF
6661powerVCC_PDVCC_PD
6762PDPD1_CC2PD1_CC2
6863PDPD1_SVBUSPD1_SVBUS
6964PDPD1_VCONNPD1_VCONN
7065PDPD1_CC1PD1_CC1
71-PDPD2_CC1PD2_CC1
72-PDPD2_SVBUSPD2_SVBUS
73-PDPD2_CC2PD2_CC2
7466powerVCOREVCORE
7567IO-sharedPWREN#PWREN#
7668EEPROMEECSEECS

Pin functions per mode — FT2232H

pinUARTFIFOsync FIFOCPU FIFObitbangMPSSEMCU busopto-isolated
ADBUS0TXDD0D0D0D0TCK/SKAD0-
ADBUS1RXDD1D1D1D1TDI/DOAD1-
ADBUS2RTS#D2D2D2D2TDO/DIAD2-
ADBUS3CTS#D3D3D3D3TMS/CSAD3-
ADBUS4DTR#D4D4D4D4GPIOL0AD4-
ADBUS5DSR#D5D5D5D5GPIOL1AD5-
ADBUS6DCD#D6D6D6D6GPIOL2AD6-
ADBUS7RI#D7D7D7D7GPIOL3AD7-
ACBUS0TXDENRXF#RXF#CS#-GPIOH0A8-
ACBUS1-TXE#TXE#A0WR#GPIOH1A9-
ACBUS2-RD#RD#RD#RD#GPIOH2A10-
ACBUS3RXLED#WRWRWR#-GPIOH3A11-
ACBUS4TXLED#SI/WUSI/WUSI/WUSI/WUGPIOH4A12-
ACBUS5--CLKOUT--GPIOH5A13-
ACBUS6--OE#--GPIOH6A14-
ACBUS7-----GPIOH7A15-
BDBUS0TXDD0N/AD0D0TCK/SKCS#FSDI
BDBUS1RXDD1N/AD1D1TDI/DOALEFSCLK
BDBUS2RTS#D2N/AD2D2TDO/DIRD#FSDO
BDBUS3CTS#D3N/AD3D3TMS/CSWR#FSCTS
BDBUS4DTR#D4N/AD4D4GPIOL0IORDY-
BDBUS5DSR#D5N/AD5D5GPIOL1CLKOUT-
BDBUS6DCD#D6N/AD6D6GPIOL2I/O0-
BDBUS7RI#D7N/AD7D7GPIOL3I/O1-
BCBUS0TXDENRXF#N/ACS#-GPIOH0--
BCBUS1SLEEP#TXE#N/AA0WR#GPIOH1--
BCBUS2RXLED#RD#N/ARD#RD#GPIOH2--
BCBUS3TXLED#WRN/AWR#-GPIOH3--
BCBUS4SI/WUSI/WUN/ASI/WUSI/WUGPIOH4-SI/WU
BCBUS5--N/A--GPIOH5--
BCBUS6--N/A--GPIOH6--
BCBUS7PWRSAV#PWRSAV#N/APWRSAV#PWRSAV#GPIOH7PWRSAV#PWRSAV#

NOTE: The pin mapping is changed from FT2232C/D for many modes.

PWRSAV# is a device input that, if enabled in EEPROM, will force the device into suspend mode when low. It can be connected to VBUS/GND via a resistor ladder to force-suspend a self-powered device when not connected to USB.

Pin functions per mode — FT4232H

pinUARTbitbangMPSSE
*DBUS0TXDD0TCK/SK
*DBUS1RXDD1TDI/DO
*DBUS2RTS#D2TDO/SI
*DBUS3CTS#D3TMS/CS
*DBUS4DTR#D4GPIOL0
*DBUS5DSR#D5GPIOL1
*DBUS6DCD#D6GPIOL2
*DBUS7RI# or TXDEN (selected in EEPROM)D7GPIOL3

EEPROM data format

The device will accept 64-word, 128-word, and 256-word EEPROMs. In case of 256-word EEPROMs, only first half is covered by the checksum. The other half can still be used to store user data.

For USB-PD devices, a 256-word EEPROM is required for the USB-PD part of the device to function. The second half of the EEPROM is used to store the USB-PD configuration data, and it has its own, separate checksum. It is described on the USB-PD page.

  • word 0x00 (FT2232H):
    • bits 0-2: channel A mode
    • bit 3: channel A enable bind to VCP driver
    • bits 8-10: channel B mode (see above)
    • bit 11: channel B enable bind to VCP driver
    • bit 15: enable PWRSAV# function on BCBUS7
  • word 0x00 (FT4232H):
    • bit 3: channel A enable bind to VCP driver
    • bit 7: channel C enable bind to VCP driver
    • bit 11: channel B enable bind to VCP driver
    • bit 15: channel D enable bind to VCP driver
  • word 0x01: idVendor (USB VID)
  • word 0x02: idProduct (USB PID)
  • word 0x03: bcdDevice (see table)
  • word 0x04: USB config (goes straight to configuration descriptor)
    • bits 0-7: bmAttributes
      • bit 5: remote wakeup enabled
      • bit 6: self-powered
      • bit 7: always set to 1
    • bits 8-15: bMaxPower (max power in units of 2mA)
  • word 0x05: device control
    • bit 2: IO pulldown in suspend
    • bit 3: serial number enabled
    • bit 12 (FT4232H only): ADBUS7 function in UART mode
      • 0: RI
      • 1: TXDEN
    • bit 13 (FT4232H only): BDBUS7 function in UART mode
    • bit 14 (FT4232H only): CDBUS7 function in UART mode
    • bit 15 (FT4232H only): DDBUS7 function in UART mode
  • word 0x06: controls electrical characteristics of channel IO pins; the IO-* names match the pin categories in the pinout table above. on FT4232H, they correspond directly to channels, while on FT2232H, CBUS and DBUS of each channel can be controlled independently
    • bits 0-1: IO-A pin drive strength
      • 0: 4mA
      • 1: 8mA
      • 2: 12mA
      • 3: 16mA
    • bit 2: IO-A pin slow slew rate
    • bit 3: IO-A pin schmitt trigger
    • bits 4-5: IO-B drive strength
    • bit 6: IO-B slow slew rate
    • bit 7: IO-B schmitt trigger
    • bits 8-9: IO-C drive strength
    • bit 10: IO-C slow slew rate
    • bit 11: IO-C schmitt trigger
    • bits 12-13: IO-D drive strength
    • bit 14: IO-D slow slew rate
    • bit 15: IO-D schmitt trigger
  • word 0x07: manufacturer string pointer
  • word 0x08: product description string pointer
  • word 0x09: serial number string pointer
  • word 0x0a: always 0
  • word 0x0b:
    • bits 3-4: TPRDRV (an obscure undocumented trim parameter for the USB HS PHY)
  • word 0x0c: EEPROM type
    • 0x46: 93LC46 (64-word)
    • 0x56: 93LC56 (128-word)
    • 0x66: 93LC66 (256-word)
  • for 64-word EEPROM:
    • words 0x0d..0x3f: string / user area
    • word 0x3f: checksum
  • for 128-word and 256-word EEPROM:
    • words 0xd..0x4d: user area
      • word 0x2b: for some reason, set to 0x302 by default (concidentally or not, this corresponds to a header of an empty string descriptor)
    • words 0x4d..0x7f: string / user area
    • word 0x7f: checksum

String pointers are formatted as follows:

  • for 64-word EEPROM:
    • bits 0-6: pointer to descriptor within EEPROM (counted in bytes)
    • bit 7: always set to 1
  • for 128-word or 256-word EEPROM:
    • bits 0-7: pointer to descriptor within EEPROM (counted in bytes); note that FTDI tools will only store string descriptors in the area starting at word 0x4d, ensuring the high bit is always set
  • bits 8-15: total length of descriptor in bytes

TODO: figure out wtf it is with the always-set high bit

The string descriptors are stored in ROM with the descriptor header included, as follows:

  • word 0: header
    • bits 0-7: total length of descriptor in bytes (includes header)
    • bits 8-15: descriptor type (always 3 — string)
  • words 1 and up: string in UTF-16

The checksum can be computed as follows:

#![allow(unused)]
fn main() {
fn checksum(eeprom: &[u16]) -> u16 {
    let checksum_word = match eeprom.len() {
        0x40 => 0x3f,
        0x80 | 0x100 => 0x7f,
    };
    let mut res: u16 = 0xaaaa;
    for pos in 0..checksum_word { // checksum word is NOT included — we're calculating it
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    res
}
}

FT232H

The sixth generation of fixed-function D2xx devices. This is essentially half of an FT2232H with some improvements.

The base device is FT232H. However, just like FT2232H, it also has two USB-PD variants:

  • FT233HP: two USB-PD ports
  • FT232HP: one USB-PD port (actually identical to FT233HP with the extra port unbonded)

Both USB-PD variants are the same silicon (which is distinct from the "base" FT232H silicon).

Features:

  • is a high-speed USB 2.0 peripherial
    • integrated D+ pullup resistor
  • single-channel D2xx device
  • can be configured to one of several supported modes:
  • 1kiB IN FIFO and 1kiB out FIFO
  • 120MHz internal base clock, generated from 12MHz crystal or external oscillator
  • internal 5V to 3.3V
  • internal 5V/3.3V to 1.8V LDO
  • 1.8V VCORE power supply for internal logic from internal LDO
  • 3.3V VCCIO power supply for business-end IO
  • 3.3V VPHY power supply for USB PHY
  • 3.3V separate AGND and VPLL power supply for PHY PLL
  • internal power-on reset circuit
  • required external support circuitry:
    • precision resistor for PHY current reference
    • decoupling capacitor for internal LDO
    • 12MHz crystal or oscillator
    • optionally, a 93LC56 (128×16-bit) or 93LC66 (256×16-bit) EEPROM

For USB-PD devices, the USB-PD function is described on the USB-PD page.

The full list of devices is:

deviceUSB-PD portsdefault VID:PIDbcdDevicepackage
FT232HL-0403:60140x090048-pin LQFP
FT232HQ-0403:60140x090048-pin QFN
FT233HPQ20403:60440x320064-pin QFN
FT232HPQ10403:60450x330056-pin QFN

Pinout — base device

LQFP48 and QFN48categoryfunction
1clockXCSI
2clockXCSO
3powerVPHY
4powerAGND
5referenceREF
6USBDM
7USBDP
8powerVPLL
9powerAGND
10powerGND
11powerGND
12powerVCCIO
13IO-DBUSADBUS0
14IO-DBUSADBUS1
15IO-DBUSADBUS2
16IO-DBUSADBUS3
17IO-DBUSADBUS4
18IO-DBUSADBUS5
19IO-DBUSADBUS6
20IO-DBUSADBUS7
21IO-CBUSACBUS0
22powerGND
23powerGND
24powerVCCIO
25IO-CBUSACBUS1
26IO-CBUSACBUS2
27IO-CBUSACBUS3
28IO-CBUSACBUS4
29IO-CBUSACBUS5
30IO-CBUSACBUS6
31IO-CBUSACBUS7
32IO-CBUSACBUS8
33IO-CBUSACBUS9
34controlRESET#
35powerGND
36powerGND
37powerVCCA
38powerVCCCORE
39powerVCCD
40powerVREGIN
41powerAGND
42controlTEST
43EEPROMEEDATA
44EEPROMEECLK
45EEPROMEECS
46powerVCCIO
47powerGND
48powerGND

Pinout — USB-PD devices

QFN64QFN56categoryfunction
11EEPROMEECS
22EEPROMEECLK
33EEPROMEEDATA
44controlTEST
55powerVCCIO
66controlRESET#
77IO-PDGPIO0
88IO-PDGPIO1
99IO-PDGPIO2
1010IO-PDGPIO3
11-IO-PDGPIO4
12-IO-PDGPIO5
1311powerVCORE
1412powerGND
1513powerVCCIO
16-IO-PDGPIO6
17-IO-PDGPIO7
1814powerVCCIO
1915clockOSCI
2016clockOSCO
2117powerGND
2218powerVREGIN
2319powerVREGOUT
2420powerFSOURCE
2521powerVPP
2622powerVCORE
27-NC-
2823IO-DBUSADBUS0
2924IO-DBUSADBUS1
3025IO-DBUSADBUS2
3126IO-DBUSADBUS3
3227IO-DBUSADBUS4
3328powerVCCIO
3429IO-DBUSADBUS5
3530IO-DBUSADBUS6
3631IO-DBUSADBUS7
3732IO-CBUSACBUS0
3833IO-CBUSACBUS1
3934IO-CBUSACBUS2
4035IO-CBUSACBUS3
4136powerVCORE
4237IO-CBUSACBUS4
4338IO-CBUSACBUS5
4439IO-CBUSACBUS6
4540powerVCCIO
4641powerGND
4742IO-CBUSACBUS7
4843IO-CBUSACBUS8
4944IO-CBUSACBUS9
5045NC?-
5146powerVCORE
5247powerVCC_USB
5348USBDM
5449USBDP
5550referenceREF
5651powerVCC_PD
5752PDPD1_CC2
5853PDPD1_SVBUS
5954PDPD1_VCONN
6055PDPD1_CC1
61-PDPD2_CC1
62-PDPD2_SVBUS
63-PDPD2_CC2
6456powerVCORE

Pin functions per mode

pinUARTFIFOsync FIFOCPU FIFObitbangMPSSEopto-isolatedFT1248
ADBUS0TXDD0D0D0D0TCK/SKFSDICIOPIO0
ADBUS1RXDD1D1D1D1TDI/DOFSCLKCIOPIO1
ADBUS2RTS#D2D2D2D2TDO/DIFSDOCIOPIO2
ADBUS3CTS#D3D3D3D3TMS/CSFSCTSCIOPIO3
ADBUS4DTR#D4D4D4D4GPIOL0-CIOPIO4
ADBUS5DSR#D5D5D5D5GPIOL1-CIOPIO5
ADBUS6DCD#D6D6D6D6GPIOL2-CIOPIO6
ADBUS7RI#D7D7D7D7GPIOL3-CIOPIO7
ACBUS0[CBUS0]RXF#RXF#CS#[CBUS0]GPIOH0[CBUS0]SCLK
ACBUS1[CBUS1]TXE#TXE#A0WR#GPIOH1[CBUS1]CS#
ACBUS2[CBUS2]RD#RD#RD#RD#GPIOH2[CBUS2]CIPO
ACBUS3[CBUS3]WRWRWR#[CBUS3]GPIOH3[CBUS3][CBUS3]
ACBUS4[CBUS4]SIWU#SIWU#SIWU#SIWU#GPIOH4SIWU#[CBUS4]
ACBUS5[CBUS5][CBUS5]CLKOUT[CBUS5][CBUS5]GPIOH5[CBUS5][CBUS5]
ACBUS6[CBUS6][CBUS6]OE#[CBUS6][CBUS6]GPIOH6[CBUS6][CBUS6]
ACBUS7PWRSAV#PWRSAV#PWRSAV#PWRSAV#PWRSAV#GPIOH7PWRSAV#PWRSAV#
ACBUS8[CBUS8][CBUS8][CBUS8][CBUS8][CBUS8][CBUS8][CBUS8][CBUS8]
ACBUS9[CBUS9][CBUS9][CBUS9][CBUS9][CBUS9][CBUS9][CBUS9][CBUS9]

Note: the function of the pins labeled with square brackets is determined by the configuration in EEPROM when the relevant mode is active.

CBUS pins

The device has 10 CBUS pins. They can be configured through the EEPROM to do the following functions:

EEPROM valuevalid on pinsfunction
0x0alltristate
0x1all but CBUS7UART TXLED#
0x2all but CBUS7UART RXLED#
0x3all but CBUS7UART TXRXLED#
0x4all but CBUS7PWREN#
0x5all but CBUS7SLEEP#
0x6all but CBUS7const-0 output
0x7CBUS[05689]const-1 output
0x8CBUS[5689]I/O (for CBUS bitbang mode)
0x9all but CBUS7UART TXDEN
0xaCBUS[05689]CLK30
0xbCBUS[05689]CLK15
0xcCBUS[05689]CLK7.5

TODO: valid pin set far from certain.

Note that the EEPROM-configured CBUS pin function may be overriden by whatever mode is currently active.

EEPROM data format

The device will accept 128-word and 256-word EEPROMs. In case of 256-word EEPROMs, only first half is covered by the checksum. The other half can still be used to store user data.

Note that 64-word EEPROMs are not supported for unknown reasons. This may be related to the funny fixed word at address 0x45. Since this is in the same address range as the FT232R uses for factory-programmed data, it is somewhat likely that it is an accidental bit of leftover FT232R circuitry.

The EEPROM format is:

  • word 0x00:
    • bits 0-3: mode
      • 0: UART
      • 1: 245-style FIFO
      • 2: CPUFIFO
      • 4: opto-isolated
      • 8: FT1248
    • bit 4: enable bind to VCP driver
      • 0: low
    • bit 9: FT1248 bit order
      • 0: MSB first
      • 1: LSB first
    • bit 10: FT1248 flow control enable
      • TODO: the polarity of this bit is not clear, it might be a disable
    • bit 15: enable PWRSAV# function on ACBUS7
  • word 0x01: idVendor (USB VID)
  • word 0x02: idProduct (USB PID)
  • word 0x03: bcdDevice (see table)
  • word 0x04: USB config (goes straight to configuration descriptor)
    • bits 0-7: bmAttributes
      • bit 5: remote wakeup enabled
      • bit 6: self-powered
      • bit 7: always set to 1
    • bits 8-15: bMaxPower (max power in units of 2mA)
  • word 0x05: device control
    • bit 2: IO pulldown in suspend
    • bit 3: serial number enabled
  • word 0x06:
    • bits 0-1: ADBUS drive strength
      • 0: 4mA
      • 1: 8mA
      • 2: 12mA
      • 3: 16mA
    • bit 2: ADBUS slow slew rate
    • bit 3: ADBUS schmitt trigger
    • bits 4-5: ACBUS drive strength
    • bit 6: ACBUS slow slew rate
    • bit 7: ACBUS schmitt trigger
  • word 0x07: manufacturer string pointer
  • word 0x08: product description string pointer
  • word 0x09: serial number string pointer
  • word 0x0a: always 0
  • word 0x0b: always 0
  • word 0x0c:
    • bits 0-3: CBUS0 function (see table above)
    • bits 4-7: CBUS1 function
    • bits 8-11: CBUS2 function
    • bits 12-15: CBUS3 function
  • word 0x0d:
    • bits 0-3: CBUS4 function
    • bits 4-7: CBUS5 function
    • bits 8-11: CBUS6 function
    • bits 12-15: CBUS7 function (lol has to be 0?)
  • word 0x0e:
    • bits 0-3: CBUS8 function
    • bits 4-7: CBUS9 function
  • word 0x0f: EEPROM type
    • 0x56: 93LC56 (128-word)
    • 0x66: 93LC66 (256-word)
  • words 0x10..0x40: user area
    • word 0x2e: set to 0x302 by default (concidentally or not, this corresponds to a header of an empty string descriptor)
  • words 0x40..0x50: reserved area for unclear reason (stuff copied over from FT232R?)
    • word 0x45: always set to 0x48
  • words 0x50..0x7f: string / user area
  • word 0x7f: checksum

String pointers are formatted as follows:

  • bits 0-7: pointer to descriptor within EEPROM (counted in bytes); note that FTDI tools will only store string descriptors in the area starting at word 0x50, ensuring the high bit is always set
  • bits 8-15: total length of descriptor in bytes

TODO: figure out wtf it is with the always-set high bit

The string descriptors are stored in ROM with the descriptor header included, as follows:

  • word 0: header
    • bits 0-7: total length of descriptor in bytes (includes header)
    • bits 8-15: descriptor type (always 3 — string)
  • words 1 and up: string in UTF-16

The checksum can be computed as follows:

#![allow(unused)]
fn main() {
fn checksum(eeprom: &[u16]) -> u16 {
    let mut res: u16 = 0xaaaa;
    for pos in 0..0x7f { // checksum word is NOT included — we're calculating it
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    res
}
}

FT-X series

The seventh generation of fixed-function D2xx devices, an upgrade to FT232R and FT245R. There are four kinds of FT-X series devices:

  • the FT20xX series, USB to I2C peripherial bridges (effectively a new mode of operation)
  • the FT22xX series, USB to FT1248 bridges (based on the FT1248 mode introduced in FT232H)
  • the FT23xX series, USB to UART bridges (a sequel to FT232R)
  • the FT240X, USB to FIFO bridge (a sequel to FT245R)

Note: FT22xX claims to be an "FT1248/SPI bridge". In reality, it has nothing to do with SPI. It could at most be charitably described as "SPI fanfic with little regard for canon".

All FT-X series devices are actually the same silicon, differentiated through mode selection in the factory-programmed area of its EEPROM memory and packaging.

Features:

  • is a full-speed USB 1.1 peripherial
  • single channel D2xx device
  • set to one of four base modes depending on factory configuration:
  • dynamically-selectable alternate modes include:
  • 512-byte IN FIFO, 512-byte OUT FIFO
  • internal 2048-byte EEPROM
    • pre-programmed factory area in EEPROM
    • in FT1248 and I2C peripherial modes, the EEPROM can be accessed from the business end too
  • USB battery charger detection
  • 48MHZ internal base clock, generated from an internal 12MHz oscillator
  • 3.3V or 5V VCC supply for internal circuitry
  • separate 1.8V to 3.3V VCCIO supply for business-end IO
  • internal 5V-to-3.3V LDO
  • internal 3.3V/5V-to-1.8V LDO
  • internal D+ pullup resistor
  • internal power-on reset circuit
  • required external support circuitry:
    • just the decoupling capacitors

The default VID:PID of the device is 0403:6015, unless configured otherwise by the EEPROM. The bcdDevice value is 0x1000.

The devices are:

devicepackagebusiness endbusiness end pins
FT200XD10-pin DFNI2C peripherial2×I2C + 1×CBUS
FT201XS16-pin SSOPI2C peripherial2×I2C + 6×CBUS
FT201XQ16-pin QFNI2C peripherial2×I2C + 6×CBUS
FT220XS16-pin SSOP4-bit FT12487×FT1248 + 1×CBUS
FT220XQ16-pin QFN4-bit FT12487×FT1248 + 1×CBUS
FT221XS20-pin SSOP8-bit FT124811×FT1248 + 1×CBUS
FT221XQ20-pin QFN8-bit FT124811×FT1248 + 1×CBUS
FT230XS16-pin SSOPbasic UART4×UART + 4×CBUS
FT230XQ16-pin QFNbasic UART4×UART + 4×CBUS
FT231XS20-pin SSOPfull UART8×UART + 4×CBUS
FT231XQ20-pin QFNfull UART8×UART + 4×CBUS
FT234XD12-pin DFNbasic UART4×UART + 1×CBUS
FT240XS24-pin SSOPFIFO13×FIFO + 2×CBUS
FT240XQ24-pin QFNFIFO13×FIFO + 2×CBUS

Pinout — FT20xX, FT22xX, FT23xX

QFN20SSOP20QFN16SSOP16DFN12DFN10FT20xXFT22xXFT23xX
1424108SDAMIOSI1RXD
25-----MIOSI7RI#
3635-9GNDGNDGND
47-----MIOSI5DSR#
58-----MIOSI6DCD#
694611-CBUS4MIOSI3CTS#
71057--CBUS2MISOCBUS2
811681210USBDPUSBDPUSBDP
9127911USBDMUSBDMUSBDM
1013810333V3OUT3V3OUT3V3OUT
111491122RESET#RESET#RESET#
1215101244VCCVCCVCC
131613135-GNDGNDGND
14171114--CBUS1CS#CBUS1
1518121565CBUS0CLKCBUS0
16191416--CBUS3CBUS3CBUS3
17201517-CBUS5MIOSI0TXD
181-----MIOSI4DTR#
19216286SCLMIOSI2RTS#
2031397VCCIOVCCIOVCCIO
[pad][pad]-[pad][pad]GNDGNDGND

Pinout — FT240X

QFN24SSOP24FT240X
14DATA1
25DATA7
36GND
47DATA5
58DATA6
69DATA3
710SI/WU#
811RD#
912WR
1013USBDP
1114USBDM
12153V3OUT
1316RESET#
1417VCORE
1518VCC
1619GND
1720TXE#
1821RXF#
1922CBUS6
2023CBUS5
2124DATA0
221DATA4
232DATA2
243VCCIO

CBUS pins

The device has up to 6 CBUS pins. They can be configured through the EEPROM to do the following functions:

EEPROM valuevalid on pinsfunction
0x00alltristate
0x01allUART TXLED#
0x02allUART RXLED#
0x03allUART TXRXLED#
0x04allPWREN#
0x05allSLEEP#
0x06allconst-0 output
0x07allconst-1 output
0x08all (everything but FT20xX), CBUS[0-3] (FT20xX)I/O (for CBUS bitbang mode)
0x09allUART TXDEN
0x0aallCLK24
0x0ballCLK12
0x0callCLK6
0x0dallBCD_CHARGER
0x0eallBCD_CHARGER#
0x0fallI2C TXE#
0x10allI2C RXF#
0x11allVBUS_SENSE (previously known as PWRSAV#)
0x12allbitbang WR#
0x13allbitbang RD#
0x14allTIMESTAMP
0x15allKEEP_AWAKE

The two new functions are:

  • TIMESTAMP (device output, toggles on every USB SOF frame)
  • KEEP_AWAKE (device input, prevents device from entering suspend state when unplugged)

EEPROM format

The FT-X series has an internal EEPROM of 2048 bytes. It can be accessed from the USB host side like on previous devices, where it is instead viewed as an array of 1024 16-bit words. On the FT20xX and FT22xX, it can also be accessed from the I2C/FT1248 side through special requests, where it is viewed as a 2048-byte array.

Note that the vendor calls the EEPROM "MTP memory" on this device. The difference, if any, is unknown.

The EEPROM format is (viewed as 1024×16-bit words, like from the host):

  • word 0x00:
    • bit 0: battery charge detect: enable
    • bit 1: battery charge detect: force PWREN# low when charger detected
    • bit 2: battery charge detect: disable sleep mode when charger detected
    • bit 3: RS485 echo suppression (FT23xX only)
    • bit 4: use external oscillator (?!? how? unbonded pads?)
    • bit 5: external oscillator feedback resistor enable
    • bit 6: USB suspend VBUS (set if one of CBUS is allocated as VBUS sense)
    • bit 7: enable bind to VCP driver
  • word 0x01: idVendor (USB VID)
  • word 0x02: idProduct (USB PID)
  • word 0x03: bcdDevice (0x1000)
  • word 0x04: USB config (goes straight to configuration descriptor)
    • bits 0-7: bmAttributes
      • bit 5: remote wakeup enabled
      • bit 6: self-powered
      • bit 7: always set to 1
    • bits 8-15: bMaxPower (max power in units of 2mA)
  • word 0x05: device control
    • bit 2: IO pulldown in suspend
    • bit 3: serial number enabled
    • bit 4: FT1248 clock polarity (CPOL) (FT22xX only)
      • 0: low
      • 1: high
    • bit 5: FT1248 bit order (FT22xX only)
      • 0: MSB
      • 1: LSB
    • bit 6: FT1248 flow control enable (FT22xX only)
    • bit 7: I2C disable schmitt trigger (FT20xX only)
    • bit 8: invert TXD (FT23xX only)
    • bit 9: invert RXD (FT23xX only)
    • bit 10: invert RTS (FT23xX only)
    • bit 11: invert CTS (FT23xX only)
    • bit 12: invert DTR (FT23xX only)
    • bit 13: invert DSR (FT23xX only)
    • bit 14: invert DCD (FT23xX only)
    • bit 15: invert RI (FT23xX only)
  • word 0x06:
    • bits 0-1: DBUS drive strength
      • 0: 4mA
      • 1: 8mA
      • 2: 12mA
      • 3: 16mA
    • bit 2: DBUS slow slew rate
    • bit 3: DBUS schmitt trigger
    • bits 4-5: CBUS drive strength
    • bit 6: CBUS slow slew rate
    • bit 7: CBUS schmitt trigger
  • word 0x07: manufacturer string pointer
  • word 0x08: product description string pointer
  • word 0x09: serial number string pointer
  • word 0x0a: I2C slave address (FT20xX only)
  • word 0x0b: I2C device ID low word (FT20xX only)
  • word 0x0c: I2C device ID high word (FT20xX only)
  • word 0x0d:
    • bits 0-7: CBUS0 function
    • bits 8-15: CBUS1 function
  • word 0x0e:
    • bits 0-7: CBUS2 function
    • bits 8-15: CBUS3 function
  • word 0x0f:
    • bits 0-7: CBUS4 function
    • bits 8-15: CBUS5 function
  • word 0x10:
    • bits 0-7: CBUS6 function
  • words 0x12..0x40: user area (not checksummed)
  • words 0x40..0x50: factory configuration area
    • word 0x49:
      • bits 8-15: device type
        • 0: UART (FT23xX)
        • 1: FIFO (FT24xX)
        • 2: FT1248 (FT22xX)
        • 3: I2C (FT20xX)
  • words 0x50..0x7f: string area
  • word 0x7f: checksum
  • word 0x80..0x400: user area (not checksummed)

String pointers are formatted as follows:

  • bits 0-7: pointer to descriptor within EEPROM (counted in bytes)
  • bits 8-15: total length of descriptor in bytes

The string descriptors are stored in ROM with the descriptor header included, as follows:

  • word 0: header
    • bits 0-7: total length of descriptor in bytes (includes header)
    • bits 8-15: descriptor type (always 3 — string)
  • words 1 and up: string in UTF-16

The checksum can be computed as follows:

#![allow(unused)]
fn main() {
fn checksum(eeprom: &[u16; 0x400]) -> u16 {
    let mut res: u16 = 0xaaaa;
    for pos in 0..0x12 {
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    for pos in 0x40..0x7f { // checksum word is NOT included — we're calculating it
        res ^= eeprom[pos];
        res = res.rotate_left(1);
    }
    res
}
}

FT4222H

TODO

USB-PD devices

The FT2232H, FT4232H, and FT232H devices have variants with USB-PD support. They essentially consist of the base device and a USB-PD controller core put together with some super glue. The USB-PD part is described here.

The devices are:

  • FT2233HP: FT2232H with two USB-PD ports
  • FT4233HP: FT4232H with two USB-PD ports
  • FT2232HP: FT2232H with one USB-PD port
  • FT4232HP: FT4232H with one USB-PD port
  • FT233HP: FT232H with two USB-PD ports
  • FT232HP: FT232H with one USB-PD port

TODO

EEPROM data format

A 256-word EEPROM is required for the USB-PD part of the device to function. The second half of the EEPROM is used to store the USB-PD configuration data.

TODO