changeset 82:2c135bde4dd0

doc/CP2102-EEPROM-format: new article
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 27 Sep 2023 01:44:27 +0000
parents 8b0a01b19fb9
children b3989befca98
files doc/CP2102-EEPROM-format
diffstat 1 files changed, 139 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/CP2102-EEPROM-format	Wed Sep 27 01:44:27 2023 +0000
@@ -0,0 +1,139 @@
+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;
+
+* 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:
+
+	Python cp210x package notes indicate that this byte holds the part
+	number, presumably the one returned by the vendor-specific command that
+	retrieves it.  This aspect remains to be tested at FreeCalypso HQ.
+
+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.
+
+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.
+
+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 0x39BC, 7 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.
+
+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.