Repository navigation
Description
TL;DR
Companion to the closed #684 (hard_reset_blocking DTR=low fix) and the merged FastLED/FastLED#3339. That PR landed two new artifacts on the FastLED side that fbuild doesn't have a counterpart for, and that should be shared between the two repos so future board ports only add data in one place:
ci/util/serial_probe.py— agent-facing CLI for ad-hoc port probe with the correct DTR/RTS=True default for USB-VCOM bridges.BOARD_FINGERPRINTS: dict[(vid, pid), str]andENVIRONMENT_TO_VCOM_VID_PIDtables — VID:PID-keyed board identification and PlatformIO-env-to-VCOM-port lookup.
Neither has a parallel in fbuild-serial / fbuild-cli today, which means:
- Agents debugging fbuild-side flows reach for ad-hoc probes that ignore the correct DTR/RTS for the target board — the exact failure mode that FastLED/FastLED#3336 caught on the FastLED side.
- When a new board is ported, its VID:PID has to be added to two places (FastLED's
port_utils.pyplus whatever fbuild-side decision point names the port). They will drift.
This issue asks fbuild to adopt the same data + the same probing surface.
What's missing on fbuild
1. No port-probe CLI / Rust helper
FastLED's serial_probe.py is small (≈300 LOC) and exposes three subcommands:
$ uv run --no-project --with pyserial python ci/util/serial_probe.py list
COM25 303A:1001 ser=80:F1:B2:D1:DF:B1 USB Serial Device (COM25) [Espressif native USB CDC (ESP32-S3/C3/C6/H2/P4)]
COM20 16C0:0483 ser=15821020 USB Serial Device (COM20) [LPC11U35 VCOM bridge (LPC845-BRK USART0) OR PJRC Teensy USB-Serial]
COM10 1FC9:0132 ser=0B03400A USB Serial Device (COM10) [NXP CMSIS-DAP debug (LPC845-BRK / LPC11U35)]
$ uv run --no-project --with pyserial python ci/util/serial_probe.py find-lpc
COM20 ...
$ uv run --no-project --with pyserial python ci/util/serial_probe.py read COM20 --seconds 4 --send '{"jsonrpc":"2.0","id":1,"method":"echo","params":[4242]}'
src/fl/remote/remote.cpp.hpp(151): INFO: Stored request ID for echo (id=1)
src/fl/remote/rpc/rpc.cpp.hpp(102): WARN: RPC: Method not found: echo
REMOTE: {...}fbuild has fbuild-serial::manager (long-lived monitor) and the ESP-specific fbuild-deploy/esp32_native, but no general-purpose port-probe surface. Useful sites for one inside fbuild:
fbuild serial probe list— same as FastLED'slist. Belongs infbuild-cli.fbuild serial probe read <port> [--send X] [--seconds N]— open with correct DTR/RTS for the board family (using theBoardFamily::idle_dtr_rts()API fbuild-serial: hard_reset_blocking leaves DTR=low — fatal for CDC-ACM bridges (LPC11U35, FTDI CDC). Mirror the FastLED #3300/#3339 lessons. #684 hinted at), dump bytes.fbuild serial probe find --vid-pid VID:PID— return device path or non-zero exit.
Rust side gets a clean reusable building block; agents and humans get a built-in tool that already knows the DTR/RTS rules, so they stop reinventing wrong ones.
2. No shared board-fingerprint data
FastLED's two tables in ci/util/serial_probe.py and ci/util/port_utils.py:
BOARD_FINGERPRINTS: dict[tuple[int, int], str] = {
(0x1FC9, 0x0132): "NXP CMSIS-DAP debug (LPC845-BRK / LPC11U35)",
(0x16C0, 0x0483): "LPC11U35 VCOM bridge (LPC845-BRK USART0) OR PJRC Teensy USB-Serial",
(0x303A, 0x1001): "Espressif native USB CDC (ESP32-S3/C3/C6/H2/P4)",
(0x10C4, 0xEA60): "Silicon Labs CP2102 USB-UART (ESP32 dev kit)",
(0x1A86, 0x7523): "WCH CH340 USB-Serial",
(0x0403, 0x6001): "FTDI FT232R USB-UART",
# ... etc
}
ENVIRONMENT_TO_VCOM_VID_PID: dict[str, tuple[int, int]] = {
"lpc845brk": (0x16C0, 0x0483),
"lpc845": (0x16C0, 0x0483),
"lpc804": (0x16C0, 0x0483),
"lpcxpresso845max": (0x16C0, 0x0483),
"lpcxpresso804": (0x16C0, 0x0483),
}Two natural homes inside this repo:
crates/fbuild-serial/boards.toml(orboards.json) — a vendored data file shipped with the crate. BothBOARD_FINGERPRINTSandENVIRONMENT_TO_VCOM_VID_PIDlive here; the crate exposespub fn board_hint(vid: u16, pid: u16) -> Option<&'static str>andpub fn vcom_for_env(env: &str) -> Option<(u16, u16)>.- Cross-repo source-of-truth file — fbuild owns the canonical TOML, FastLED's Python helpers read it at runtime via a small loader. Removes the two-places-to-edit problem permanently. Slightly more design work; better long-term.
Either path closes the drift gap. (1) is the cheap version; (2) is the right one if the maintainer wants it.
Why this matters
These aren't speculative quality-of-life features — they're the structural lessons from #3300 / #3325 / #3336 / #3339 turned into shared infrastructure. The two sessions burnt on the LPC bring-up were entirely caused by host-side bugs that didn't have a canonical helper to consult; the fix on the FastLED side prevents that on FastLED's hot path, but fbuild's hot path is a separate code surface that can rediscover the same bug independently the moment a contributor writes one ad-hoc serialport::new(port).open()? without re-asserting DTR. A shared CLI + shared data table is the durable fix.
Acceptance criteria
-
fbuild-serialexposes aboard_hint(vid, pid)and avcom_for_env(env)API backed by a single data table. -
fbuild-cliships aserial probesubcommand with at leastlist,read, andfindmodes (parameter shape can differ from FastLED's; the capability is what matters). - One of: (a) FastLED's Python helpers read fbuild's data file at runtime, OR (b) the two tables are kept in sync via a CI check that diffs them. (a) preferred, (b) acceptable.
- The new probe API picks the right DTR/RTS for the target board family by consulting
BoardFamily::idle_dtr_rts()(the API hinted at in fbuild-serial: hard_reset_blocking leaves DTR=low — fatal for CDC-ACM bridges (LPC11U35, FTDI CDC). Mirror the FastLED #3300/#3339 lessons. #684) — no more silent ESP-defaults on non-ESP boards.
Out of scope
- The reset-sequence policy itself (closed fbuild-serial: hard_reset_blocking leaves DTR=low — fatal for CDC-ACM bridges (LPC11U35, FTDI CDC). Mirror the FastLED #3300/#3339 lessons. #684's scope).
- LPC VCOM unwedging on Windows (LPC845-BRK: deploy must always unwedge the shared VCOM (pyocd/SWD flash leaves CDC in Windows error 31) #565's scope; different symptom).
- The LPC8xx burn-down meta plumbing ([META] LPC845-BRK on-hand burn-down: cover the open LPC8xx work end-to-end #586).
Refs
- FastLED/fbuild#684 — parent (closed) — DTR/RTS hard_reset_blocking fix.
- FastLED/fbuild#565 — LPC VCOM Windows-error-31 unwedging.
- FastLED/fbuild#586 — LPC845-BRK burn-down meta.
- FastLED/FastLED#3339 (merged) — the implementation to mirror. The two artifacts named above (
ci/util/serial_probe.py,ci/util/port_utils.py::ENVIRONMENT_TO_VCOM_VID_PID) are the proximate cause for this issue. - FastLED/FastLED#3336 — agent hook + doc rule banning ad-hoc PowerShell SerialPort probes; the rule references the helper that doesn't exist on the fbuild side yet.
- FastLED/FastLED#3300, FastLED/FastLED#3325 — the LPC bring-up incident the helpers came out of.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTriage
Activity
feat(serial): board fingerprints + `fbuild serial probe` CLI (#686) (#…
docs(serial): USB CDC DTR/RTS control-line semantics matrix (#689) (#701
docs(agents): agents/docs/ MVP + root CLAUDE.md routing table (#695) (#…
feat(cli): fbuild bringup orchestrator scaffold (#697) (#711)