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.