# HG changeset patch # User Mychaela Falconia # Date 1694735785 0 # Node ID 065f68a94b6b9bb1968c24842ce75d2183bd97ae # Parent 5cbde3c80c240b8287ae646d2f5b5b18fab9a701 doc/FTDI-EEPROM-format: beginning of article diff -r 5cbde3c80c24 -r 065f68a94b6b doc/FTDI-EEPROM-format --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/FTDI-EEPROM-format Thu Sep 14 23:56:25 2023 +0000 @@ -0,0 +1,252 @@ +FTDI configuration EEPROM format +================================ + +Unfortunately FTDI never documented the format of their EEPROM configuration +structure - apparently they consider it a proprietary trade secret just like +the wire protocol spoken over USB between their chips and their closed-source +proprietary drivers. All FOSS community support for these chips is based on +reverse engineering, and that includes the EEPROM format. + +We (FreeCalypso) have not done any significant FTDI RE of our own - instead we +are taking the knowledge that already exists in the FOSS community (including +RE-based knowledge of FTDI EEPROM format) and using it to produce better tools. + +The present document summarizes the bits of knowledge we have collected +regarding FTDI's EEPROM configuration structure - this knowledge base is what +our generator and decoder tools are built on, as well as shipped EEPROM +programming in all physical hw products made by FreeCalypso. + +Word-based vs byte-based views +============================== + +Before FTDI started integrating the EEPROM inside their FT232R and FT-X chips, +their original design used external serial EEPROMs of 93C46, 93C56 or 93C66 +type. These EEPROMs are physically structured as an array of 16-bit words - or +more precisely, some EEPROM parts support both word and byte organization modes, +selected by pin strapping, but FTDI chips require word-structured EEPROMs. + +Given this physical organization, we tend to view the EEPROM structure as an +array of 16-bit words. For some parts of the configuration structure, such as +16-bit ID words and UCS-2 strings, this word-based view is ideal - however, +there are also times when the EEPROM structure needs to be viewed in terms of +bytes: + +* Some configuration parameters are given as bytes rather than words; + +* Pointers from the fixed structure at the beginning of the EEPROM to string + descriptors in the "user" area use byte-based addressing. + +The correspondence order between bytes and words is little-endian. + +Fixed header structure +====================== + +The first 10 words (20 or 0x14 bytes) of the EEPROM follow the same basic +structure across all known-to-us FTDI chips: + +Word 0 (bytes 0x00 and 0x01): this word is best viewed as two separate bytes, +and these bytes encode FTDI-specific functions detailed later in this document. + +Word 1 (bytes 0x02 and 0x03): USB vendor ID, called idVendor in the USB spec. + +Word 2 (bytes 0x04 and 0x05): USB product ID, called idProduct in the USB spec. + +Word 3 (bytes 0x06 and 0x07): originally allocated for the bcdDevice word in +the USB device descriptor, see Table 9-8 in the USB 2.0 specification. On older +FTDI chips such as FT2232D, the chip takes the value programmed in this EEPROM +word and actually reports this value in its device descriptor - thus if the +EEPROM is misprogrammed, all standard host software will be misled; see our +FTDI-chip-ID article. OTOH, FT232R ignores this word and always reports its +bcdDevice as 0x0600; in terms of FT232R EEPROM images captured in the wild, +some have zero in this word while others have 0x0600. FT2232H behaves like +FT232R (ignores this EEPROM word), but I haven't seen any EEPROM images with +this word zeroed out - it appears that FTDI's official tools still insert the +correct bcdDevice value. + +Word 4 (bytes 0x08 and 0x09): this word is best viewed as two separate bytes. +Both bytes go into the USB configuration descriptor: byte 0x08 is bmAttributes +and byte 0x09 is bMaxPower. See USB 2.0 specification Table 9-10 for the +detailed format. + +Word 5 (bytes 0x0A and 0x0B): this word is best viewed as two separate bytes, +and these bytes encode FTDI-specific functions detailed later in this document. + +Word 6 (bytes 0x0C and 0x0D): originally allocated for the bcdUSB word in the +USB device descriptor, indicating the version of the USB spec which the device +claims to support. Starting with FT2232H this word has been repurposed for +other functions, as detailed in the chip-specific sections below. + +Word 7 (bytes 0x0E and 0x0F): pointer to the manufacturer ID string; format +explained later in the string descriptors section. + +Word 8 (bytes 0x10 and 0x11): pointer to the product ID string. + +Word 9 (bytes 0x12 and 0x13): pointer to the serial number string if one is +present, otherwise 0. + +FTDI-specific bytes in the fixed header +======================================= + +Bytes 00, 01, 0A and 0B in the structure covered above are FTDI-specific (don't +correspond to any fields in any of the standard USB descriptors), and many of +the functions controlled by these bytes differ significantly from one FTDI chip +type to the next. + +FT2232x bytes 00 and 01 +----------------------- + +On FT2232x chips bytes 00 and 01 configure channels A and B, respectively. +The 3 least significant bits of each byte encode the channel mode as follows: + +0 = UART +1 = 245-style FIFO +2 = fast opto-isolated serial +4 = CPU-style FIFO + +Bit 3 (mask 0x08) appears to have no function in the chip itself, but is used +by FTDI's Losedows drivers: for each of the two channels, FTDI's VCP driver is +selected if the bit is set and D2XX driver is selected if the bit is cleared. + +On FT2232C/D only (not on FT2232H), bit 4 (mask 0x10) enables high current drive +on the respective A/B channel. + +On FT2232H only, byte 01 bit 7 (mask 0x80) turns on a feature that is misnamed +"Suspend on DBus 7 Low" in FTDI's official programming tool. It is misnamed +because the actual pin in question is BCBUS7, not "DBUS7". When this function +is enabled via this bit, BCBUS7 becomes PWRSAV# input, which is sufficiently +documented in the FT2232H datasheet. + +ftee-gen2232c and ftee-gen2232h default for both bytes is 0x08. + +FT232R byte 00 +-------------- + +This byte is conceptually similar to its counterpart on FT2232x, but not exactly +the same, and NOT compatible. FT232R byte 00 bit assignments are as follows: + +bit 0: 0 for FT232R, 1 for FT245R +bit 1: use external oscillator if set +bit 2: high current drive if set +bit 3: same VCP/D2XX nonsense as on other chips, but with reversed sense: + 0 means VCP, 1 means D2XX on this chip + +ftee-gen232r default for this byte is 0x00. + +FT232R byte 01 +-------------- + +This byte is unique to FT232R: it sets the maximum packet size the chip +advertises for its Data In endpoint, via wMaxPacketSize in the endpoint +descriptor. The standard value is 64 (0x40), and there does not seem to be +any need to change it. + +Byte 0A on all FTDI chips +------------------------- + +This byte has the same bit assignments across all FTDI chips we work with, +although newer chips don't support some of the older bits: + +bit 0: isochronous endpoint control on FT232BM and FT2232C/D +bit 1: isochronous endpoint control on FT232BM and FT2232C/D +Bit 2: enable suspend mode pull-down on I/O pins (all chips) +bit 3: 1 means serial number string present, 0 means serial # string absent +bit 4: set bcdUSB in device descriptor to EEPROM value (only up to FT2232C/D) +bit 5: isochronous endpoint control on FT2232C/D +bit 6: isochronous endpoint control on FT2232C/D + +See chip-specific sections below for the details on isochronous endpoint +control bits. + +ftee-gen* default for this byte is 0x00. + +Byte 0B: FT2232x +---------------- + +This byte appears to be unused on FT2232C/D and on FT2232H. + +Byte 0B: FT232R +--------------- + +This byte controls UART signal inversion. Bits 0 through 7 (lsb through msb) +correspond to DBUS0 through DBUS7: if a given bit is set, the corresponding +DBUS/UART signal is inverted. + +FT232BM specifics +================= + +We don't have much support for this chip as it predates FreeCalypso involvement +in the business of FTDI chip tinkering - however, we know the following bits: + +* The fixed part of the EEPROM config structure is just the 10 words described + above, and the strings area begins at byte offset 0x14. + +* Isochronous endpoint control via byte 0A appears to be the same as for + Channel A of FT2232C/D, described below. + +FT2232C/D specifics +=================== + +Words 0 through 9 (bytes up to 0x13) are as explained above. The only +additional FT2232C/D-specific word is 10: + +Byte 0x14 (low half of word 10) holds the EEPROM type: set to 0x46 for 93C46, +0x56 for 93C56 or 0x66 for 93C66. It is not clear if the chip actually uses +this byte for anything: it seems to me that FTDI's EEPROM read engine has to +determine the required number of address bits (presumably by asking to read +address 0 and looking for the position of the dummy 0 bit from the EEPROM) +before it can proceed with incrementing addresses. (The address bit order +in the serial EEPROM interface is big-endian, hence one needs to know the +correct number of address bits in order to increment linearly.) + +Byte 0x15 (high half of word 10) appears to be unused. + +The strings area of the EEPROM begins with word 11 or byte offset 0x16. + +Isochronous endpoint control +---------------------------- + +The 4 data endpoints on this chip (In and Out for each channel) are of type +Bulk by default, but each of these 4 endpoints is independently selectable +between bulk and isochronous via these 4 bits in byte 0A: + +bit 0: make Channel A data In endpoint isochronous +bit 1: make Channel A data Out endpoint isochronous +bit 5: make Channel B data In endpoint isochronous +bit 6: make Channel B data Out endpoint isochronous + +FT2232H specifics +================= + +On both FT2232H and FT4232H (which we don't support yet) EEPROM word 6 +(originally allocated for bcdUSB override) is repurposed for I/O electrical +interface configuration. The 16-bit word is divided into four 4-bit groups, +mapped to pins as follows: + +Group # FT2232H pins FT4232H pins +-------------------------------------------- +0 ADBUSx ADBUSx +1 ACBUSx BDBUSx +2 BDBUSx CDBUSx +3 BCBUSx DDBUSx + +Within each group the 4 bits are assigned as follows: + +Bits Function +---------------- +1:0 drive strength: + 00 = 4 mA + 01 = 8 mA + 10 = 12 mA + 11 = 16 mA +2 set to 1 for slow slew rate +3 set to 1 for Schmitt trigger + +Other EEPROM quirks on FT2232H: + +* Words 10 and 11, used on FT232R (chronologically between FT2232C and FT2232H) + for CBUS configuration, appear to be reserved and unused on FT2232H. + +* Word 12 on FT2232H is same as word 10 on FT2232C/D: EEPROM type code, even + though it still isn't clear what the chip does with it, if anything. + +* The strings area of the EEPROM begins with word 13 or byte offset 0x1A.