diff doc/FTDI-EEPROM-format @ 69:065f68a94b6b

doc/FTDI-EEPROM-format: beginning of article
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 14 Sep 2023 23:56:25 +0000
parents
children 09da7db45dce
line wrap: on
line diff
--- /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.