PIC32MX210F016C: The USB Descriptors Are The Product

Plug a USB device into a host and the host asks three questions in the first second: who are you, what are you, how do you talk. The answers come from descriptor tables in the device’s flash, and on a PIC32MX210F016C those tables are not plumbing — they are the product. Recovering a USB product without its descriptors yields a firmware image that boots and says nothing.

What Lives In The Tables

The descriptor set holds the vendor and product IDs, the class and interface definitions, the endpoint structure, the string table with product and manufacturer names, and for HID-class devices the report descriptor — the byte-level grammar that defines every field the device ever sends. A report descriptor is authored once and approved by a host stack; it is compact, idiosyncratic, and utterly specific. Two competing mice with identical silicon are separated, at the protocol level, by their report descriptors and nothing else.

On the 210F016C those tables occupy flash alongside the code, typically near the top of the 16 KB array. They are constant data, copied or referenced by the USB stack at enumeration time. The peripheral itself is a full-speed USB 2.0 controller with device, host and OTG modes, backed by dedicated DMA channels so descriptor transfers do not starve the CPU. The M4K core runs to 50 MHz; SRAM is 4 KB; the package is 36-pin VTLA, the pin count that gives fixture builders pause — the 150F128C page covers that logistics problem in its own right.

Why Descriptors Are Intellectual Property

Code can be rewritten by anyone with the protocol documentation. The report descriptor cannot, because it encodes decisions: report IDs, field widths, padding choices, usage pages. Rebuilding it from observed traffic is reverse engineering with a sample rate problem — every field that only appears under rare conditions is a field the reconstruction gets wrong. Recovering the original table removes the guesswork. The same holds for the string table, which carries product names and revision strings that production documents rarely record accurately.

That is why a recovery report for this part separates the descriptor region from application code instead of shipping one flat HEX. The customer rebuilding or supporting the product needs both, but needs them labeled: here is the array’s code, here is the boot bank with its 3 KB and its DEVCFG words, here are the descriptors at these addresses. The firmware extraction page describes the packaging standard.

The Descriptor Hierarchy, Briefly

USB descriptors nest: one device descriptor, configurations inside it, interfaces inside those, endpoints and class-specific tables — the HID report descriptor among them — at the leaves. The nesting is declared in the bytes, so a reconstruction can validate its own reading: lengths must sum, counts must match, and a dump that violates the structure is either misaligned or from a different product than assumed. That self-check is free, and it catches capture errors before they become support errors. On a 4 KB SRAM part the descriptors are also some of the largest constants in flash, which makes them easy to locate once the region boundaries are known.

Endpoint zero handles enumeration itself; the interface descriptors declare what the other endpoints do. For HID products the report descriptor is the document that matters — it is the grammar of every field the device ever sends — and hosts cache it at enumeration, which is why a rebuilt device with the wrong descriptor fails in ways users notice instantly.

Capture And Verification

The mechanical read is family-standard: two independent captures of the 16 KB program array from 0x1D000000 to 0x1D003FFF and the 3 KB boot flash from 0x1FC00000 to 0x1FC00BFF, compared word for word, with the device ID read back to confirm the die — the C package shares its silicon with B and D siblings of the same density, and the ID settles the flash size while the marking settles the lead count. Page geometry is 256-word erases and 32-word program rows.

Code protect sits in DEVCFG0 bit 28, active low; armed, it blocks external reads of both partitions, and the only documented exit is a chip erase that destroys the image. Write-protect fields do not block reads. The configuration words are read before anything else for exactly this reason — they answer the security question before the effort is spent. The reading process page details the sequence.

Who Needs This

The recurring callers are three: the product owner who lost source and needs the device to keep enumerating as itself after a firmware rebuild; the support team reverse-documenting a legacy product line; and the engineer porting the product to a successor part, who needs the descriptors byte-exact because hosts remember them. All three jobs start the same way — the part, the board, or both — under the terms on the NDA page. The capture is routine; the value is in knowing that on a USB product, identity is data, data is in flash, and flash yields to a competent reader before it yields to anything else.

Part numbers across the branch are collected on the PIC32MX family page, each with its page size and pin count.