FreeCalypso > hg > fc-usbser-tools
view doc/CP2102-EEPROM-format @ 104:866eae65dbea
LICENSE: same as other FreeCalypso tools
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 Sep 2023 18:20:04 +0000 |
parents | 29bff463402e |
children |
line wrap: on
line source
The classic CP2102 single-channel USB-serial chip from Silabs (original CP2102, not CP2102N and not CP2105) features an internal 1024-byte EEPROM, readable and writable over USB via vendor-specific commands. Note that it is 1024 bytes, not bits, thus the internal EEPROM of CP2102 is 8 times bigger than that of its direct competitor FT232R. Compared to FTDI EEPROMs, the internal EEPROM of CP2102 exhibits these most obvious differences: * The all-important baud rate remapping table (the signature feature of CP2102) is included here; * All USB descriptors are stored in full in the big EEPROM; * Each of the 3 string descriptors (manufacturer, product, serial number) has a fixed area allocated for it, no pointer-to-string scheme like in FTDI's EEPROMs; * Unlike FTDI EEPROMs, CP2102 EEPROM is most certainly NOT optional - a blank or garbage-filled EEPROM will result in a non-functional chip; * There is no checksum - because there is nothing for the chip to "fall back" on when the EEPROM is bad, there is no point in checking the EEPROM content for validity; * The logical structure of CP2102 EEPROM is byte-oriented - no 16-bit words as elementary units. Intel HEX format ================ Our FreeCalypso tools for working with CP2102 EEPROM are intended as a replacement for a Python-language tool from 2014 named cp210x-program-1.0. This original Python tool exhibits a rather peculiar format for reading and writing raw EEPROM byte images: it is a variant of Intel HEX format with a peculiar base address. The size of the EEPROM is 1024 or 0x400 bytes, thus if one were to represent an image of this EEPROM in Intel HEX with 16 bytes per data record, the "obvious" address span would be from 0x0000 to 0x03F0. However, the records that comprise EEPROM images written by the Python tool and included as examples in the source tarball exhibit a different address range, spanning from 0x3600 to 0x39F0 - the base address is 0x3600. As there is no obvious place where this 0x3600 base address could have come from, it is my (Mother Mychaela's) educated guess that the hex format adopted by the author of the Python tool could have originated from Silabs' own vendor tools, which are Windows-only and thus forbidden-ware in Themyscira temples. Our fc-usbser-tools CP2102 EEPROM tools use the same Intel HEX format for EEPROM images, with the same 0x3600 base address - thus we are consistent with the Python tool which we are directly replacing, and _possibly_ consistent with whatever sight-unseen, untouchable Windows tools might use. EEPROM image analysis ===================== An EEPROM image that has been read out of a CP2102 chip that appears to be pristine (not modified after the chip left Silabs) is captured in artifacts/CP2102-std-baud, in the variant of Intel HEX described above. Starting from the notes included in doc/cp210x.txt in the cp210x-program-1.0 package and looking further at the EEPROM image with our own eyes, we get the following picture of EEPROM structure: Address 0x3600, 320 or 0x140 bytes: The baud rate table resides here, 32 entries of 10 bytes each. Each entry has the following format: 2 bytes: BRG reload value from Silabs AN205, big-endian 2 bytes: timeout reload value from Silabs AN205, big-endian 1 byte: prescaler value from Silabs AN205 1 byte: reserved 4 bytes: intended baud rate, little-endian It is not clear if the "intended baud rate" field is actually used by the chip for anything - it may be a sort of comment. Address 0x3740, 0xBF bytes: Seems to be an unused area, all 00 bytes. Address 0x37FF, 1 byte: Part number code 0x02 for CP2102. The chip returns this EEPROM byte when queried (via CP210x family-specific command) for its part number, as in cp2102-read-partno. Address 0x3800, 4 bytes: USB string descriptor 0, as in USB 2.0 spec Table 9-15. Address 0x3804, 4 bytes: Seems to be an unused area, all 00 bytes. It is possible that Silabs may have left extra room here to allow a longer string descriptor 0, listing more than one language code, but it does not make sense to me (Mother Mychaela) to list more than one supported language when there is no mechanism to return different strings in response to different language requests. Address 0x3808, 255 or 0xFF bytes: USB string descriptor for product ID string, in the full format of USB 2.0 spec Table 9-16. The maximum possible length of this string is 126 UCS-2 characters. Address 0x3907, 128 or 0x80 bytes: USB string descriptor for serial number string, in the full format of USB 2.0 spec Table 9-16. The maximum possible length of this string is 63 UCS-2 characters. Address 0x3987, 1 byte: Byte with value 0x02, purpose unknown. Address 0x3988, 18 or 0x12 bytes: USB device descriptor, as in USB 2.0 spec Table 9-8. Address 0x399A, 9 bytes: USB configuration descriptor, as in USB 2.0 spec Table 9-10. Address 0x39A3, 9 bytes: USB interface descriptor, as in USB 2.0 spec Table 9-12. Address 0x39AC, 7 bytes: USB endpoint descriptor, as in USB 2.0 spec Table 9-13. Address 0x39B3, 7 bytes: USB endpoint descriptor, as in USB 2.0 spec Table 9-13. Address 0x39BA, 9 bytes: Seems to be an unused area, all 00 bytes. Address 0x39C3, 60 or 0x3C bytes: USB string descriptor for manufacturer ID string, in the full format of USB 2.0 spec Table 9-16. The maximum possible length of this string is 29 UCS-2 characters. Address 0x39FF, 1 byte: 0xFF is the value I find here, in the EEPROMs of CP2102-based devices I have on hand. Python cp210x package notes say that this byte is lock status, with 0xFF meaning unlocked and 0xF0 meaning locked.