# HG changeset patch # User Mychaela Falconia # Date 1695594458 0 # Node ID 0b37be8b23ca34ac6bce04d94355b6daee0f8e45 # Parent 09da7db45dceee4042cfa5e6f41c380883b40e0c doc/FTDI-EEPROM-format: document string descriptors diff -r 09da7db45dce -r 0b37be8b23ca doc/FTDI-EEPROM-format --- 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.