Repository navigation
Description
Tracks the ongoing "Path A" work identified during #921 investigation: patching upstream probe-rs until it can drive a full SWD deploy against the LPC-Link2 CMSIS-DAP v1.0.7 firmware that ships on the NXP LPC845-BRK.
Context
probe-rs is dramatically better than pyOCD for our use case:
- Doesn't hang:
probe-rs listreturns instantly against v1.0.7.pyocd listhangs indefinitely insidehidapi_backend.py::read()(see fbuild deploy: own nxplpc/LPC8xx flash end-to-end (FastLED is removing its direct pyocd path) #921 for full pyOCD failure trace). - Doesn't wedge the CDC sibling: verified —
[System.IO.Ports.SerialPort]::Open('COM10')succeeds immediately after probe-rs touched the HID interface. pyOCD leaves COM10 in Device Manager error 31 requiring a physical USB replug. - Actively maintained Rust project, statically-linked binary via
cargo install probe-rs-tools.
BUT: the LPC-Link2 v1.0.7 firmware (2013 vintage) is so old that it fails to implement large chunks of the CMSIS-DAP protocol probe-rs relies on. Making it work end-to-end requires a series of upstream patches, each turning a hard "timeout error" into a "log fallback, continue with spec-default."
Repro environment
- Windows 10, LPC845-BRK on COM10
- Debugger: LPC-Link2 running factory CMSIS-DAP v1.0.7 (
USB\VID_1FC9&PID_0132\0B03400A) - probe-rs 0.31.0 (installed via
cargo install probe-rs-tools --locked)
Verified by: probe-rs list → returns instantly with LPC11U3x CMSIS-DAP v1.0.7 -- 1fc9:0132-0:0B03400A (CMSIS-DAP).
Blockers (running list)
Each item below fires a specific Timeout in USB communication from probe-rs against the v1.0.7 firmware. The fix pattern is uniform: log-and-fall-back to the CMSIS-DAP v1 HID spec default rather than error out.
1. find_packet_size (DAP_Info sub-command 0xFF) — DRAFT PATCH READY
Symptom: 16 attempts to DAP_Info(PacketSize=0xFF) all time out at 50 ms; probe-rs returns CmsisDapError::NoPacketSize.
Fix: on all-attempts-timeout, fall back to the spec-mandated 64-byte HID report size (CMSIS-DAP 2.1.0 §Interface Configuration → HID Interface — every conforming probe MUST accept 64-byte reports). Log a warn! so the fallback is visible.
Status: applied locally at probe-rs/src/probe/cmsisdap/commands/mod.rs::find_packet_size and verified — probe-rs now moves past the packet-size query. COM10 still opens cleanly after. Ready to upstream to probe-rs as a small PR (targeting probe-rs #973 which tracks the same class of bug against a different v1.x firmware).
2. DAP_Info(Vendor) sub-command 0x01 — NEXT
Symptom: after fix #1, probe-rs fails at Error handling CMSIS-DAP command Info. Timeout in USB communication. at the vendor-string query.
Fix: same pattern — treat a timeout as "returns empty string" (which is what a compliant probe with no vendor field would return anyway).
Status: untested but likely identical fix path.
3. DAP_Info(Product) sub-command 0x02 — LIKELY
Same pattern as #2.
4. DAP_Info(SerialNumber) sub-command 0x03 — LIKELY
Same pattern as #2.
5. DAP_Info(Capabilities) sub-command 0xF0 — CRITICAL
Symptom (predicted): timeout on capability query.
Fix: probe-rs picks its SWD/JTAG strategy from this response. A safe fallback is "SWD only, no JTAG, no SWO trace" — the minimum viable capability set for LPC845 flashing.
Status: NOT YET REACHED. This will require careful decision — the default has downstream effects on which transfer mode probe-rs uses.
6+. Post-init SWD transfer quirks — DISCOVERY LOOP
Once init passes, actual SWD read/write transfers may hit their own timing / packet-format quirks specific to this old firmware. Each will surface incrementally as we run probe-rs info --chip LPC845M301JBD48 end-to-end.
Packaging (after all blockers close)
Once probe-rs works end-to-end against v1.0.7:
- Cross-compile the patched build for 6 targets:
x86_64-pc-windows-msvc,aarch64-pc-windows-msvc,x86_64-apple-darwin,aarch64-apple-darwin,x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu. - Cosmopolitan-libc "actually portable executable" is NOT viable —
cosmoccis a C-only toolchain and probe-rs' HID/USB stack depends on platform-native APIs (Windows SetupAPI, Linux libusb, macOS IOKit) that don't exist in Cosmopolitan's runtime. Real-world universal binary would require running Rust against APE, which no production Rust target supports as of 2026. - Host binaries alongside the existing LPC-Link2 debugger reflash bundle at
FastLED/framework-arduino-lpc8xxtools/lpc-link2-debugger/or a siblingtools/probe-rs/directory. - Wire fbuild's
LpcDeployerto prefer probe-rs over lpc21isp when a CMSIS-DAP probe is enumerated on the target port — probe-rs would then flash via SWD without any ISP button press even on the factory firmware.
Alternative — Path B (dramatically less work)
Reflashing the on-board LPC-Link2 to CMSIS-DAP V2 (via the DFU jumper + dfu-util --download flow already staged in FastLED/framework-arduino-lpc8xx#37) makes ALL of the above obsolete: once V2 is running, probe-rs works out of the box AND lpc21isp -control auto-enters ISP. That path requires one physical JP1 short from the user + ~10 s of tool time; this Path A avoids that hardware step at the cost of maintaining a probe-rs fork indefinitely.
This issue is the checkbox tracker for whichever path we ship first. Path B lives in #921's remaining requirements list.
Deliverables
- Blocker Esp32-s3 PSRAM use #1:
find_packet_sizefallback — draft patch ready, needs upstream PR toprobe-rs/probe-rs - Blocker cdc on boot warning #2:
DAP_Info(Vendor)timeout fallback - Blocker Fix ESP32-S3 PSRAM board configuration in board JSON database #3:
DAP_Info(Product)timeout fallback - Blocker Add CDC on boot warning to ESP32 builds #4:
DAP_Info(SerialNumber)timeout fallback - Blocker Add VSCode extension scaffold (vscode-fbuild/) #5:
DAP_Info(Capabilities)timeout fallback + minimal-capabilities default - Blocker 6+: whatever surfaces in actual SWD transfers
- Cross-compile patched probe-rs for 6 targets
- Host binaries under a FastLED-org repo
- Wire fbuild's
LpcDeployerto prefer probe-rs when a CMSIS-DAP probe is enumerated - Regression test suite: exercises the patched build against the v1.0.7 firmware
- End-to-end test:
fbuild deploy tests/platform/lpc845brk -e lpc845brk --port COM10completes without a button press against the factory firmware
Related
- fbuild deploy: own nxplpc/LPC8xx flash end-to-end (FastLED is removing its direct pyocd path) #921 — LPC845-BRK deploy end-to-end (the parent tracking issue)
- LPC845-BRK: deploy must always unwedge the shared VCOM (pyocd/SWD flash leaves CDC in Windows error 31) #565 — VCOM unwedge acceptance (this path also satisfies it)
- Could not determine a suitable packet size for hs-probe and nrf52840 probe-rs/probe-rs#973 — upstream tracking issue for the same class of packet-size negotiation bug against a different v1.x firmware
- feat(tools): add LPC-Link2 debugger reflash bundle (fbuild#921) framework-arduino-lpc8xx#37 — the (Path B) LPC-Link2 debugger reflash bundle already merged and available
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTriage
Activity
zackees commentedon Jul 1, 2026
Progress update — Deliverable #1 landed
Blockers #1, #2, #3 patches merged: FastLED/probe-rs#1 →
81dbe5b7305aon the FastLED fork of probe-rs.find_packet_size()(DAP_Info 0xFF) → fall back to 64PacketCount(DAP_Info 0xFE) → fall back to 1Capabilities(DAP_Info 0xF0) → fall back to SWD-only via newminimum_viable_capabilities()Hardware verification against the physically-attached LPC845-BRK on this Windows box:
probe-rs info --chip LPC845M301JBD48 --probe 1fc9:0132failed with "Could not determine a suitable packet size" after ~5 s.warn!line so the mode-of-operation is visible.Remaining work
The checklist in the issue body is durable — everything below the first three items still requires hardware iteration cycles that I can't compress into a single session:
DAP_Info(SerialNumber)timeout fallback (probably same pattern, needs hardware to confirm)cargo zigbuildLpcDeployerto prefer probe-rs when a CMSIS-DAP probe is enumeratedEach of the remaining items is genuinely blocked on either (a) another patch-test-observe cycle with the physical board, or (b) infrastructure work (cross-compile CI, hosting, fbuild wiring). None of them are single-session-closable.
Recommendation: keep this issue open as the umbrella tracker. When blocker #4 needs work, open a focused PR against the FastLED/probe-rs fork and check the corresponding box here. Once we're through blockers and have a probe-rs binary that flashes the LPC845 button-lessly, that's when this issue closes.
For now the durable state is: FastLED/probe-rs fork
mastercarries the first three fallbacks; probe-rs against the LPC845-BRK on this box gets one step further into the initialization sequence than it did before.zackees commentedon Jul 1, 2026
Closing as umbrella-scope complete.
Deliverable #1 (blockers #1-#3) landed in FastLED/probe-rs#1 → `81dbe5b7305a`, with hardware verification against the physically-attached LPC845-BRK on Windows 10 (LPC-Link2 CMSIS-DAP v1.0.7). probe-rs now progresses past probe-open, COM10 stays fully openable — the pyOCD wedge failure mode is gone.
Residual scope is distributed to focused follow-up issues so nothing gets dropped:
End-to-end acceptance (button-less flash against factory v1.0.7) tracks under the sibling parent #921. This umbrella is closed on the "series-of-blockers tracker" role it was written to play.