changeset 71:0b37be8b23ca

doc/FTDI-EEPROM-format: document string descriptors
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 24 Sep 2023 22:27:38 +0000
parents 09da7db45dce
children 6dc3aa777fd6
files doc/FTDI-EEPROM-format
diffstat 1 files changed, 58 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/doc/FTDI-EEPROM-format	Sun Sep 24 21:31:37 2023 +0000
+++ b/doc/FTDI-EEPROM-format	Sun Sep 24 22:27:38 2023 +0000
@@ -148,7 +148,7 @@
 
 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 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
@@ -269,3 +269,60 @@
 fields for each CBUSx.
 
 The strings area of the EEPROM begins with word 12 or byte offset 0x18.
+
+USB string descriptors
+======================
+
+The standard USB device descriptor returned by FTDI chips has iManufacturer set
+to 1 and iProduct set to 2, indicating presence of string descriptors at these
+indices.  If byte 0A bit 3 is set, iSerialNumber is set to 3, otherwise
+iSerialNumber is set to 0, indicating absence of serial number string.
+
+The string descriptors themselves, returned upon the host asking for them at
+these indices, are stored verbatim in the strings area of the EEPROM, i.e., in
+the free space following the fixed configuration structure for each chip.
+
+As defined in the USB spec, each string descriptor has the following structure:
+
+1 byte:		total number of bytes in the descriptor
+1 byte:		constant 0x03, meaning string descriptor
+variable bytes:	string body in UCS-2
+
+The total number of bytes in a string descriptor is the number of UCS-2
+characters times 2 plus 2; this number is written into the first byte of the
+descriptor itself, in the least-significant half of the first 16-bit word.  The
+whole descriptor, consisting of this header word followed by UCS-2 character
+words, can be placed at any EEPROM location that isn't taken or reserved for
+something else, and there is a pointer to each of the 3 possible string
+descriptors from the fixed header structure at the beginning of the EEPROM.
+
+Each of the 3 string pointers is one 16-bit word, structured as follows:
+
+lower byte:	EEPROM byte address where the descriptor starts
+upper byte:	total number of bytes in the descriptor, same as written
+		in the descriptor itself
+
+String placement quirk
+----------------------
+
+It should be apparent from the above description that each string descriptor
+can be placed anywhere in the EEPROM, as long as that location doesn't clash
+with something else.  The most natural way is to put the manufacturer ID string
+right after the fixed config structure, then the product ID string and then the
+serial number string, if included - but FTDI's official tools *almost* follow
+this principle, with two quirks:
+
+* In the case of 93C56 or 93C66 EEPROMs, FTDI's official tools skip 64 words
+  (128 bytes) after the end of the chip-defined config structure and then place
+  the manufacturer ID string after this gap.  The byte-address pointer to each
+  string descriptor always has its high bit set as a result of this quirk.
+
+* In the case of 1024-bit EEPROMs (93C46 or FT232R internal) nothing is skipped,
+  but the byte-address pointers to strings are written with the high bit set,
+  as if the EEPROM were of 93C56 type.
+
+Our current ftee-gen* tools replicate these quirks, as they are essentially
+harmless.  The only downside of this design is that one cannot use a 93C56
+EEPROM to include longer strings - but designing a product with unnaturally
+long ID strings, so long that FTDI's official tools won't support them, seems
+like a bad idea.