Replicate Locked IC LPC2141FBD64 Heximal: The Port That Introduces Itself
Most locked devices say nothing about themselves. This one is different, because it has a USB port, and a USB device cannot be anonymous. Before any application code runs in a meaningful sense, the product has already told the host what it is, what class it belongs to, how many endpoints it has, and what each of them is for.
That handshake is a genuine head start on a replication job, and it is also the source of a persistent misunderstanding. Teams capture the descriptors, conclude that they have the device, and discover later that they have only its business card.
What the host learns without asking permission
On connection the device is enumerated: the host resets it, reads the device descriptor, assigns an address, then reads the configuration, interface and endpoint descriptors, and finally requests the string descriptors that carry the manufacturer and product names.
All of that is plaintext on the bus, and all of it can be recorded with a passive capture. What it establishes:
| Descriptor | Information | Value to a replication job |
|---|---|---|
| device | vendor and product identifiers, class, revision | tells you which driver the host binds |
| configuration | power draw, number of interfaces | tells you whether the product is bus powered |
| interface | class, subclass, protocol | tells you whether it is a standard class or vendor specific |
| endpoint | address, type, packet size, interval | tells you the traffic shape before you see any traffic |
| string | manufacturer, product, serial format | tells you what the serial number looks like |
The last row is worth attention. Products that derive a serial number from a unique identifier or from flash content produce a string with a recognisable structure, and seeing that structure is often enough to establish that the firmware reads something per-unit at start-up.
What the descriptors do not tell you
They do not tell you what any of the vendor-specific requests do, and on a device that is not implementing a standard class, that is the entire protocol.
They also do not tell you the meaning of the data in either direction. A report of sixty-four bytes is sixty-four bytes; whether the first two are a setpoint and the next two a measurement, or the other way round, is decided by code that lives in the array.
They do not tell you the endpoint behaviour under load: whether double buffering is used, whether the transfer is interrupted mid-packet, whether an error causes a stall or a retry. That is all configured in the controller registers from constants in flash.
What descriptors do give you is a skeleton to hang the recovered code on. When the image is available, the descriptor block appears in it as a byte table — usually early in the code section, in the same order the host read it. Matching the captured descriptors against the byte table locates the table, and the code that references that address is the code that handles enumeration.
The identifier trap
A replicated device that behaves identically but presents a different vendor or product identifier will not load the same driver on the host. Operating systems bind drivers to that pair, and a clone with a new identifier is a different product to the operating system even though it is the same board.
If the replication is intended for internal repair or for a second source of the same product, the identifiers must be preserved, which is legally a different proposition from copying them. If it is intended as a new product, the identifiers must be changed, and then the host-side software has to be changed with them.
Establishing which case applies is a commercial question, and it is worth asking before any work begins. It changes the deliverable from an exact image to a modified one, and it changes what the customer can legally do with it.
There is no USB bootloader here
A reasonable assumption on a part with a USB port is that firmware can be updated over that port by default. On this family it cannot: the factory loader lives in flash and speaks a UART protocol, not USB. There is no ROM-resident USB loader to fall back on.
The consequence for a locked device is direct. The USB port is an interface to the application, not to the boot loader, so a device that has stopped enumerating cannot be recovered through that port. Recovery goes through the UART loader described in LPC2102FBD48 data recovery, or through the debug port, or through the package.
That distinction catches people who are used to later generations of parts where a USB boot mode exists, and it is worth stating plainly in any quotation.
Where the memory budget lands
Thirty-two kilobytes of flash and eight kilobytes of SRAM is a tight budget for a USB product. The controller itself needs buffer space, the descriptors take a few hundred bytes, and the application has to do something useful with what remains.
Practically, this means the firmware does not contain a USB stack so much as a hand-rolled subset of one. That is good news for reading it: a hand-written implementation is compact and its state machine is visible in the code, where a vendor stack would be an opaque library with a documented API. The recovered image frequently reads like a description of the protocol written in C.
The replication checklist
- captured descriptors, transcribed exactly
- vendor-specific request codes, recovered from the code that dispatches them
- endpoint buffer configuration, recovered from the controller initialisation
- the string descriptors, including the format of any serial number
- the whole array, trimmed, with the reserved region excluded
- clock and bus configuration, since USB timing depends on both
Six items, and the last two are the ones that are forgotten. A replicated USB device with a slightly wrong bus clock enumerates intermittently, which is the worst possible failure mode: it works on the bench and fails at the customer site.
A closing note on layered identity
A USB product has three identities: what it announces, what it does, and how it does it. Capture gives you the first in a minute, the recovered image gives you the third, and the second is the work.
The other end of the family, where the array is large enough to carry a full protocol stack rather than a hand-rolled one, is covered in LPC2138FBD64 locked flash work. What travels with an image besides the code is set out in LPC2134FBD64 firmware extraction, and the clock dependency that governs USB timing is treated in LPC2136FBD64 duplication.