FreeCalypso > hg > fc-usbser-tools
comparison doc/CP2102-EEPROM-format @ 82:2c135bde4dd0
doc/CP2102-EEPROM-format: new article
| author | Mychaela Falconia <falcon@freecalypso.org> | 
|---|---|
| date | Wed, 27 Sep 2023 01:44:27 +0000 | 
| parents | |
| children | b3989befca98 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 81:8b0a01b19fb9 | 82:2c135bde4dd0 | 
|---|---|
| 1 The classic CP2102 single-channel USB-serial chip from Silabs (original CP2102, | |
| 2 not CP2102N and not CP2105) features an internal 1024-byte EEPROM, readable and | |
| 3 writable over USB via vendor-specific commands. Note that it is 1024 bytes, | |
| 4 not bits, thus the internal EEPROM of CP2102 is 8 times bigger than that of its | |
| 5 direct competitor FT232R. Compared to FTDI EEPROMs, the internal EEPROM of | |
| 6 CP2102 exhibits these most obvious differences: | |
| 7 | |
| 8 * The all-important baud rate remapping table (the signature feature of CP2102) | |
| 9 is included here; | |
| 10 | |
| 11 * All USB descriptors are stored in full in the big EEPROM; | |
| 12 | |
| 13 * Each of the 3 string descriptors (manufacturer, product, serial number) has a | |
| 14 fixed area allocated for it, no pointer-to-string scheme like in FTDI's | |
| 15 EEPROMs; | |
| 16 | |
| 17 * The logical structure of CP2102 EEPROM is byte-oriented - no 16-bit words as | |
| 18 elementary units. | |
| 19 | |
| 20 Intel HEX format | |
| 21 ================ | |
| 22 | |
| 23 Our FreeCalypso tools for working with CP2102 EEPROM are intended as a | |
| 24 replacement for a Python-language tool from 2014 named cp210x-program-1.0. | |
| 25 This original Python tool exhibits a rather peculiar format for reading and | |
| 26 writing raw EEPROM byte images: it is a variant of Intel HEX format with a | |
| 27 peculiar base address. The size of the EEPROM is 1024 or 0x400 bytes, thus if | |
| 28 one were to represent an image of this EEPROM in Intel HEX with 16 bytes per | |
| 29 data record, the "obvious" address span would be from 0x0000 to 0x03F0. | |
| 30 However, the records that comprise EEPROM images written by the Python tool and | |
| 31 included as examples in the source tarball exhibit a different address range, | |
| 32 spanning from 0x3600 to 0x39F0 - the base address is 0x3600. | |
| 33 | |
| 34 As there is no obvious place where this 0x3600 base address could have come | |
| 35 from, it is my (Mother Mychaela's) educated guess that the hex format adopted | |
| 36 by the author of the Python tool could have originated from Silabs' own vendor | |
| 37 tools, which are Windows-only and thus forbidden-ware in Themyscira temples. | |
| 38 | |
| 39 Our fc-usbser-tools CP2102 EEPROM tools use the same Intel HEX format for EEPROM | |
| 40 images, with the same 0x3600 base address - thus we are consistent with the | |
| 41 Python tool which we are directly replacing, and _possibly_ consistent with | |
| 42 whatever sight-unseen, untouchable Windows tools might use. | |
| 43 | |
| 44 EEPROM image analysis | |
| 45 ===================== | |
| 46 | |
| 47 An EEPROM image that has been read out of a CP2102 chip that appears to be | |
| 48 pristine (not modified after the chip left Silabs) is captured in | |
| 49 artifacts/CP2102-std-baud, in the variant of Intel HEX described above. | |
| 50 | |
| 51 Starting from the notes included in doc/cp210x.txt in the cp210x-program-1.0 | |
| 52 package and looking further at the EEPROM image with our own eyes, we get the | |
| 53 following picture of EEPROM structure: | |
| 54 | |
| 55 Address 0x3600, 320 or 0x140 bytes: | |
| 56 | |
| 57 The baud rate table resides here, 32 entries of 10 bytes each. Each | |
| 58 entry has the following format: | |
| 59 | |
| 60 2 bytes: BRG reload value from Silabs AN205, big-endian | |
| 61 2 bytes: timeout reload value from Silabs AN205, big-endian | |
| 62 1 byte: prescaler value from Silabs AN205 | |
| 63 1 byte: reserved | |
| 64 4 bytes: intended baud rate, little-endian | |
| 65 | |
| 66 It is not clear if the "intended baud rate" field is actually used by | |
| 67 the chip for anything - it may be a sort of comment. | |
| 68 | |
| 69 Address 0x3740, 0xBF bytes: | |
| 70 | |
| 71 Seems to be an unused area, all 00 bytes. | |
| 72 | |
| 73 Address 0x37FF, 1 byte: | |
| 74 | |
| 75 Python cp210x package notes indicate that this byte holds the part | |
| 76 number, presumably the one returned by the vendor-specific command that | |
| 77 retrieves it. This aspect remains to be tested at FreeCalypso HQ. | |
| 78 | |
| 79 Address 0x3800, 4 bytes: | |
| 80 | |
| 81 USB string descriptor 0, as in USB 2.0 spec Table 9-15. | |
| 82 | |
| 83 Address 0x3804, 4 bytes: | |
| 84 | |
| 85 Seems to be an unused area, all 00 bytes. It is possible that Silabs | |
| 86 may have left extra room here to allow a longer string descriptor 0, | |
| 87 listing more than one language code, but it does not make sense to me | |
| 88 (Mother Mychaela) to list more than one supported language when there | |
| 89 is no mechanism to return different strings in response to different | |
| 90 language requests. | |
| 91 | |
| 92 Address 0x3808, 255 or 0xFF bytes: | |
| 93 | |
| 94 USB string descriptor for product ID string, in the full format of | |
| 95 USB 2.0 spec Table 9-16. | |
| 96 | |
| 97 Address 0x3907, 128 or 0x80 bytes: | |
| 98 | |
| 99 USB string descriptor for serial number string, in the full format of | |
| 100 USB 2.0 spec Table 9-16. | |
| 101 | |
| 102 Address 0x3987, 1 byte: | |
| 103 | |
| 104 Byte with value 0x02, purpose unknown. | |
| 105 | |
| 106 Address 0x3988, 18 or 0x12 bytes: | |
| 107 | |
| 108 USB device descriptor, as in USB 2.0 spec Table 9-8. | |
| 109 | |
| 110 Address 0x399A, 9 bytes: | |
| 111 | |
| 112 USB configuration descriptor, as in USB 2.0 spec Table 9-10. | |
| 113 | |
| 114 Address 0x39A3, 9 bytes: | |
| 115 | |
| 116 USB interface descriptor, as in USB 2.0 spec Table 9-12. | |
| 117 | |
| 118 Address 0x39AC, 7 bytes: | |
| 119 | |
| 120 USB endpoint descriptor, as in USB 2.0 spec Table 9-13. | |
| 121 | |
| 122 Address 0x39B3, 7 bytes: | |
| 123 | |
| 124 USB endpoint descriptor, as in USB 2.0 spec Table 9-13. | |
| 125 | |
| 126 Address 0x39BC, 7 bytes: | |
| 127 | |
| 128 Seems to be an unused area, all 00 bytes. | |
| 129 | |
| 130 Address 0x39C3, 60 or 0x3C bytes: | |
| 131 | |
| 132 USB string descriptor for manufacturer ID string, in the full format of | |
| 133 USB 2.0 spec Table 9-16. | |
| 134 | |
| 135 Address 0x39FF, 1 byte: | |
| 136 | |
| 137 0xFF is the value I find here, in the EEPROMs of CP2102-based devices | |
| 138 I have on hand. Python cp210x package notes say that this byte is lock | |
| 139 status, with 0xFF meaning unlocked and 0xF0 meaning locked. | 
