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
}
}