Skip to content

LPC845-BRK: deploy must always unwedge the shared VCOM (pyocd/SWD flash leaves CDC in Windows error 31) #565

Description

@zackees

Summary

Flashing the LPC845-BRK via pyOCD/SWD wedges the board's shared USB VCOM on Windows: after a flash the CDC serial port goes to Device Manager error 31 ("This device cannot start") and only a physical USB replug brings it back. This breaks any flash-then-monitor flow (e.g. the FastLED AutoResearch RPC harness), which must reopen the serial port immediately after deploy.

Requirement: deploy must always unwedge — after every flash the VCOM must be usable again with no physical intervention.

Why this happens

The LPC845-BRK's on-board debug probe is a USB composite device exposing both a CMSIS-DAP HID interface and a CDC VCOM bridge (wired to P0_24/P0_25, per crates/fbuild-build/src/nxplpc/assets/arduino_stub/HardwareSerial.cpp). pyOCD opens the CMSIS-DAP HID to flash over SWD; its post-flash target reset leaves the composite device's CDC function wedged on Windows (error 31). Observed workaround so far is "don't issue a pyocd reset after flash" + physical replug.

Current state in fbuild

There is no LPC deployer wired yet. The daemon's platform dispatch falls through to:

crates/fbuild-daemon/src/handlers/operations/deploy.rs:707
    "deployer for {:?} not yet implemented",   // Platform::NxpLpc lands here

So today the board is flashed by pyOCD outside fbuild, with no recovery step — hence the manual replug. This is the deploy gap tracked by #551; this issue adds the "always unwedge" acceptance criterion to it.

Proposed fix

Implement an fbuild-deploy Deployer for Platform::NxpLpc that owns the unwedge:

  1. Prefer lpc21isp ISP-over-UART (the README's primary path, upload.protocol in lpc845brk.json). ISP flashing runs over the VCOM serial line itself and never opens the CMSIS-DAP HID, so the composite device cannot wedge. This is the cleanest "always unwedge."
  2. If SWD/pyOCD is used, own a deterministic post-flash recovery instead of leaving it to pyocd's default:
    • Skip pyocd's post-flash reset (the step correlated with the wedge); rely on the baked-in vector checksum + a clean DAP disconnect to start the image.
    • If the VCOM is still wedged, force a Windows USB re-enumeration of the composite devnode (restart the device / cycle the port) before returning success — modeled on the existing TeensyDeployer state machine, which already "takes a wedged Windows host and recovers it" (crates/fbuild-deploy/src/teensy/).
  3. Verify on hardware (LPC845-BRK): flash → reopen VCOM → AutoResearch RPC echo succeeds with no replug.

Acceptance

  • fbuild deploy <lpc845 project> -e lpc845brk flashes and the VCOM is immediately openable afterward, repeatably, with zero physical replugs.

Related: #551 (LPC8xx Stage 7 deploy support), #4 (use pyocd to flash).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions