FreeCalypso > hg > fc-usbser-tools
comparison doc/FTDI-EEPROM-tools @ 34:f5fbcf1ff032
doc: initial import from freecalypso-hwlab
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sat, 09 Sep 2023 21:28:02 +0000 |
| parents | |
| children | f548ae912622 |
comparison
equal
deleted
inserted
replaced
| 33:df284688d0c8 | 34:f5fbcf1ff032 |
|---|---|
| 1 Mother Mychaela has developed a set of Linux command line tools for manipulating | |
| 2 configuration EEPROMs that are attached to FT2232x devices and accessed in-band | |
| 3 via USB. This document describes these tools. | |
| 4 | |
| 5 Supported FTDI chips and EEPROMs | |
| 6 ================================ | |
| 7 | |
| 8 The present tools work with 93C46, 93C56 and 93C66 EEPROMs attached behind | |
| 9 FT2232x dual-channel UART/FIFO/MPSSE/etc chips, both FT2232C/D and FT2232H. | |
| 10 We can read these EEPROMs for examination or backup, and we can program them | |
| 11 with new bits, either restoring a previously saved backup or creating a new | |
| 12 from-scratch configuration. These EEPROM configurations (which we can save, | |
| 13 restore or create from scratch) set the USB VID:PID and the textual strings | |
| 14 naming the manufacturer, the product model and an optional serial number, | |
| 15 select whether each FT2232x channel will come up in the default UART mode or | |
| 16 one of the other EEPROM-configurable modes (245 FIFO, CPU-style FIFO or fast | |
| 17 opto-isolated serial), and allow a few other obscure chip settings to be | |
| 18 tweaked. | |
| 19 | |
| 20 Some work has also been done toward the goal of being able to program the | |
| 21 internal EEPROM in FT232R chips (a very popular single-channel USB to UART | |
| 22 converter needing no external components), but this work should be considered | |
| 23 experimental: the tools appear to work on an UB232R module from Digi-Key | |
| 24 (presumably containing a genuine FT232RQ chip) and on a no-name FT232RL adapter | |
| 25 where the chip is uncertain, but because we have no real production use case | |
| 26 yet, we are not ready to truly vouch for FT232R support. | |
| 27 | |
| 28 More generally: | |
| 29 | |
| 30 * our fteeprom-read tool should be able to read out the EEPROM content from | |
| 31 just about any FTDI chip; | |
| 32 | |
| 33 * our fteeprom-prog tool should be able to program a user-supplied set of bits | |
| 34 into any FTDI+EEPROM combo where the EEPROM is a separate chip, or into FT232R | |
| 35 internal EEPROM - but it most likely won't work for newer FT-X chips; | |
| 36 | |
| 37 * if the goal is to generate a new EEPROM config from scratch, as opposed to | |
| 38 restoring a saved backup, we currently have generators only for FT2232C/D, | |
| 39 for FT2232H and for FT232R, with the last one considered experimental and not | |
| 40 proven. | |
| 41 | |
| 42 libftdi dependency | |
| 43 ================== | |
| 44 | |
| 45 We use libftdi (which is in turn layered on libusb) to issue the special USB | |
| 46 control pipe commands to FTDI chips which are needed to read and write their | |
| 47 EEPROMs. We use old-style libftdi-0.x (-lftdi on the link line) as opposed to | |
| 48 libftdi1 (-lftdi1) because the new versions took away the ability to write to | |
| 49 the EEPROM directly with ftdi_write_eeprom_location() calls, forcing users to | |
| 50 go through libftdi1's own EEPROM smarts, which we don't want to do - our tools | |
| 51 are all about more direct user empowerment at the lowest level. | |
| 52 | |
| 53 Selecting the device to operate on | |
| 54 ================================== | |
| 55 | |
| 56 Our fteeprom-read, fteeprom-prog and fteeprom-erase tools take a device selector | |
| 57 argument, selecting the device to operate on. This required argument is the | |
| 58 string to be passed to the ftdi_usb_open_string() function in libftdi, allowing | |
| 59 the device to be operated on to be selected in one of several ways. Copying | |
| 60 from libftdi documentation, the available formats are: | |
| 61 | |
| 62 d:<devicenode> - path of bus and device-node (e.g. "003/001") within usb device | |
| 63 tree (usually at /proc/bus/usb/) | |
| 64 | |
| 65 i:<vendor>:<product> - first device with given vendor and product id, ids can | |
| 66 be decimal, octal (preceded by "0") or hex (preceded by "0x") | |
| 67 | |
| 68 i:<vendor>:<product>:<index> - as above with index being the number of the | |
| 69 device (starting with 0) if there are more than one | |
| 70 | |
| 71 s:<vendor>:<product>:<serial> - first device with given vendor id, product id | |
| 72 and serial string | |
| 73 | |
| 74 If you have only one FTDI device connected to your PC or laptop at the time of | |
| 75 your EEPROM manipulation session (generally a good idea to avoid hitting the | |
| 76 wrong device by mistake) and if that FTDI device has some sensible starting | |
| 77 USB VID:PID (either from the previous EEPROM config or the chip's sans-EEPROM | |
| 78 default) that doesn't clash with anything else, then the i: form will probably | |
| 79 be the most convenient, e.g.: | |
| 80 | |
| 81 i:0x0403:0x6001 for single-channel FT232x devices running with the default ID | |
| 82 i:0x0403:0x6010 for dual-channel FT2232x devices running with the default ID | |
| 83 i:0x0403:0xPPPP for custom PIDs assigned out of FTDI's VID range | |
| 84 i:0xVVVV:0xPPPP for totally custom USB IDs | |
| 85 | |
| 86 Or if the current device config is totally hosed (the EEPROM has a passing | |
| 87 checksum, but sets some completely bogus USB ID), then the d: form will | |
| 88 probably be required for recovery. | |
| 89 | |
| 90 Reading the EEPROM | |
| 91 ================== | |
| 92 | |
| 93 The basic EEPROM read command is as follows: | |
| 94 | |
| 95 fteeprom-read <device-selector> | |
| 96 | |
| 97 See the previous section for the device selector argument. In this default | |
| 98 form the tool will read the first 64 EEPROM words, which is appropriate for | |
| 99 93C46 external EEPROMs or for the internal 1024-bit EEPROM in the FT232R chip. | |
| 100 However, if you are working with an FT2232x board with an external EEPROM and | |
| 101 that EEPROM is of a larger variety (93C56 or 93C66), this basic form with give | |
| 102 you an incomplete (truncated) read, and you will need one of the following | |
| 103 extended forms to read the complete EEPROM: | |
| 104 | |
| 105 fteeprom-read -b <device-selector> -- read 128 EEPROM words (93C56) | |
| 106 fteeprom-read -B <device-selector> -- read 256 EEPROM words (93C66) | |
| 107 | |
| 108 (If you use one of the extended forms on a smaller EEPROM, you will get 2 or 4 | |
| 109 copies of the same bits.) | |
| 110 | |
| 111 The output of fteeprom-read is in the same format as the input to fteeprom-prog, | |
| 112 thus you can redirect the output to a file and get a restorable backup copy of | |
| 113 your EEPROM. | |
| 114 | |
| 115 It also needs to be noted that if the FTDI device has the kernel's ftdi_sio | |
| 116 driver attached to it (ttyUSB device present) when you run fteeprom-read (same | |
| 117 for fteeprom-prog and fteeprom-erase), the act of running any of our EEPROM | |
| 118 tools will cause it to unbind, i.e., the ttyUSB device will disappear. If the | |
| 119 device being operated on is a dual-channel FT2232x, then only the ttyUSB device | |
| 120 corresponding to Channel A will disappear, while the Channel B ttyUSB device | |
| 121 will stay. | |
| 122 | |
| 123 Programming the EEPROM | |
| 124 ====================== | |
| 125 | |
| 126 In terms of the primitives provided over USB, writing to EEPROMs sitting behind | |
| 127 FTDI chips is accomplished by writing one 16-bit word at a time: the | |
| 128 SIO_WRITE_EEPROM_REQUEST command writes a user-supplied word at a user-supplied | |
| 129 EEPROM address. However, our fteeprom-prog tool currently supports only writing | |
| 130 complete EEPROMs (64 or 128 or 256 16-bit words starting at address 0) and we | |
| 131 do not currently provide any kind of "random access write" utility; the primary | |
| 132 reason for this design decision is practical usefulness: FTDI's EEPROM structure | |
| 133 includes a checksum over the first 64 words for 1024-bit EEPROMs or over the | |
| 134 first 128 words for larger ones, and if this checksum fails to match, the entire | |
| 135 structure is deemed to be invalid - hence there is no practical use case for | |
| 136 selectively rewriting individual words. The only exception may be with 93C66 | |
| 137 EEPROMs: on these giants only the first half would be subject to the checksum, | |
| 138 and the second half could be used arbitrarily. However, we have not yet | |
| 139 encountered any boards out in the wild with such big EEPROMs, and we have no | |
| 140 plans to use such in any of our own hardware designs either, hence there is no | |
| 141 business case at the present moment to develop tooling support for them. | |
| 142 | |
| 143 There are two primary modes of usage for our fteeprom-prog tool: restoring a | |
| 144 saved EEPROM backup or writing a new EEPROM config which you generate yourself. | |
| 145 To restore a saved EEPROM backup, run the tool as follows: | |
| 146 | |
| 147 fteeprom-prog <device-selector> <eeprom-image-file> | |
| 148 | |
| 149 To program a new EEPROM config of your own, run a pipeline of this form: | |
| 150 | |
| 151 <generator-tool> | fteeprom-prog <device-selector> | |
| 152 | |
| 153 fteeprom-prog reads the EEPROM image from stdin if no image file is named on | |
| 154 the command line; the image format is the same in both cases, and the length of | |
| 155 this EEPROM image tells the tool how many words need to be programmed - there | |
| 156 are no -b or -B options to fteeprom-prog. | |
| 157 | |
| 158 Generator tools | |
| 159 =============== | |
| 160 | |
| 161 Unfortunately FTDI never documented the format of their EEPROM configuration | |
| 162 structure - apparently they consider it a proprietary trade secret just like | |
| 163 the wire protocol spoken over USB between their chips and their closed-source | |
| 164 proprietary drivers. All FOSS community support for these chips is based on | |
| 165 reverse engineering, and that includes the EEPROM format. | |
| 166 | |
| 167 The present suite of tools includes ftee-gen2232c and ftee-gen2232h EEPROM image | |
| 168 generators, meant for use with FT2232C/D and FT2232H chips, respectively. These | |
| 169 tools are based on the knowledge extracted from other (pre-existing) community | |
| 170 tools, primarily the EEPROM config code built into various libftdi versions - | |
| 171 we haven't done any FTDI RE of our own, instead the goal of this project has | |
| 172 been to create a set of tools that are better fit for production use. | |
| 173 | |
| 174 Our ftee-gen2232c and ftee-gen2232h tools are invoked as follows: | |
| 175 | |
| 176 ftee-gen2232[ch] [-b|-B] <config-file> [serial-num] | |
| 177 | |
| 178 The output of these generator tools is meant to be piped directly into | |
| 179 fteeprom-prog. | |
| 180 | |
| 181 The philosophy of which settings are given in the config file vs. which ones | |
| 182 are given on the command line reflects configuration management and factory | |
| 183 production line operations. In the envisioned usage there would be a config | |
| 184 file for each product, giving the USB VID:PID, textual manufacturer and product | |
| 185 ID strings and possibly other config settings which need to be changed from the | |
| 186 defaults, but the optional serial number string is given on the command line | |
| 187 because it would be different for each individual unit being programmed. | |
| 188 | |
| 189 The EEPROM size selection is also made on the command line, so that the same | |
| 190 config can be programmed into a smaller EEPROM or a bigger one. By default our | |
| 191 tools generate an image suitable for a 93C46 EEPROM: the generated image is 64 | |
| 192 words long, with a checksum in word 63, and the EEPROM type byte in FTDI's | |
| 193 structure is set to 0x46. Running with -b produces an image for a 93C56 EEPROM: | |
| 194 the EEPROM type byte is set to 0x56, and the checksum-covered image length is | |
| 195 extended to 128 words. Finally, -B sets things up for a 93C66 EEPROM: the | |
| 196 EEPROM type byte is set to 0x66, but the generated checksum-covered image is | |
| 197 still 128 words long just like with -b, as that is what FT2232x chips apparently | |
| 198 expect. I said "apparently" because I don't have any FT2232x hardware with | |
| 199 93C66 EEPROMs and I don't plan on acquiring or building any, hence this minimal | |
| 200 93C66 support is completely untested - use at your own risk. | |
| 201 | |
| 202 It also needs to be noted that with our current RE-based understanding of FTDI's | |
| 203 undocumented EEPROM structure, using a bigger EEPROM does NOT provide more room | |
| 204 for strings: all that happens with -b and -B options is that a gap of 64 unused | |
| 205 EEPROM words is inserted between the end of the fixed structure and the | |
| 206 beginning of strings. The exact same arrangement has been observed in all 93C56 | |
| 207 EEPROM images found in the wild, presumably produced with FTDI's official tools, | |
| 208 including FTDI's own USB-COM232-PLUS2 board - thus it is not clear at all if | |
| 209 FT2232x chips actually support longer strings with bigger EEPROMs, and if not, | |
| 210 what does one need a bigger EEPROM for... | |
| 211 | |
| 212 For the format of config files read by our ftee-gen2232[ch] tools and what | |
| 213 settings can be tweaked, read the source code. | |
| 214 | |
| 215 Erasing the EEPROM (making it blank) | |
| 216 ==================================== | |
| 217 | |
| 218 If you are playing with a "generic" FT2232x breakout board that is made for | |
| 219 tinkering, as opposed to a more finished product, such boards are typically | |
| 220 shipped with their EEPROMs completely blank. In that case restoring the EEPROM | |
| 221 to its "pristine" state after playing around would mean erasing it, i.e., | |
| 222 bringing it into a blank (all ones) state. FT2232x chips provide two ways to | |
| 223 do so: one can explicitly write 0xFFFF into each individual EEPROM word with | |
| 224 SIO_WRITE_EEPROM_REQUEST, or one can send a SIO_ERASE_EEPROM_REQUEST command to | |
| 225 the chip, and the chip then erases the entire EEPROM. But we don't know how | |
| 226 the latter SIO_ERASE_EEPROM_REQUEST operation is implemented by FT2232x chips: | |
| 227 does the FT2232x chip go through and erase each word individually, or does it | |
| 228 issue an "erase full chip" opcode to the serial EEPROM? If the latter, then | |
| 229 according to some EEPROM datasheets that operation may not work if the EEPROM | |
| 230 is powered from a 3.3V rail rather than the full USB 5V - may be an issue in | |
| 231 FT2232H-based designs. | |
| 232 | |
| 233 In any case our tools provide both ways. To perform the "automatic full chip | |
| 234 erase" operation, run the following command: | |
| 235 | |
| 236 fteeprom-erase <device-selector> | |
| 237 | |
| 238 To blank the EEPROM by writing 0xFFFF into each word, run one of the following | |
| 239 pipelines: | |
| 240 | |
| 241 ftee-mkblank | fteeprom-prog <device-selector> -- blank a 93C46 EEPROM | |
| 242 ftee-mkblank -b | fteeprom-prog <device-selector> -- blank a 93C56 EEPROM | |
| 243 ftee-mkblank -B | fteeprom-prog <device-selector> -- blank a 93C66 EEPROM |
