You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
USB CDC ACM SET_CONTROL_LINE_STATE exposes DTR and RTS to host software. What these two bits actually do on the target chip is vendor-specific — and that fact has now burned multiple sessions on different boards. There's no canonical reference inside the FastLED + fbuild stack that maps (BoardFamily, DTR-state, RTS-state) → effect. Every future board port will rediscover the wrong default unless there's somewhere to look first.
This issue asks for a docs/usb-cdc-control-line-matrix.md (or wherever fbuild docs live) that pins down the rules in one place, with links to the datasheets / app notes that back them.
DTR=False is fine on ESP32 native USB CDC (post-reset idle).
DTR=False is fatal on the LPC11U35 USB-VCOM bridge (LPC845-BRK), CP2102 in CDC mode with some firmware revs, and FTDI FT232 in some modes — the bridge treats DTR as a "host ready" gate and silently drops every transmit byte from the target.
Nothing in either repo documents this matrix. The fact lives in scattered comments inside esp_reset.rs, three Python sites that just got fixed, and one short paragraph in the docstring of the new ci/util/serial_probe.py helper. None of these are a reference a future contributor would find.
Proposed shape
A single doc — docs/usb-cdc-control-line-matrix.md in this repo (or crates/fbuild-serial/docs/, maintainer preference) — structured as:
Concrete rules (the "what to set when you open a port" cheat sheet)
Default safe state: DTR=True, RTS=True. Works for every CDC bridge as
"host ready" and is the ESP post-reset idle state (no reset trigger
because the CDC peripheral consumes the bits at re-enumeration, not on
live toggle).
ESP32 reset sequence (esptool ClassicReset):
DTR=False, RTS=True → EN low (reset hold)
sleep(100ms)
DTR=True, RTS=False → EN high (release reset), BOOT low (run firmware)
Final state: DTR=False, RTS=False. [ESP-correct.]
LPC845-BRK reset:
Use pyocd / probe-rs CMSIS-DAP SWD reset.
Do NOT touch DTR/RTS — bridge is sensitive to DTR for data flow.
Post-reset: re-assert DTR=True, RTS=True before monitor open.
Teensy / SAMD51 / RP2040 reset:
Open port at 1200 baud, close. Bootloader engages on disconnect.
Re-enumerate at the bootloader's VID:PID.
Post-reset: DTR=True, RTS=True at app baud.
Empirical probe (the test that produces this table for a new board)
Use ci/util/serial_probe.py probe-dtr-rts <port> (FastLED side) — sweeps the 4 combinations, reports bytes seen, identifies which combo gates data and which triggers reset. Note: that subcommand was proposed during the audit; if not yet implemented in #686 or here, it's a worthy add.
Cross-links
crates/fbuild-serial/src/esp_reset.rs — references this doc from its module header.
TL;DR
USB CDC ACM
SET_CONTROL_LINE_STATEexposes DTR and RTS to host software. What these two bits actually do on the target chip is vendor-specific — and that fact has now burned multiple sessions on different boards. There's no canonical reference inside the FastLED + fbuild stack that maps(BoardFamily, DTR-state, RTS-state) → effect. Every future board port will rediscover the wrong default unless there's somewhere to look first.This issue asks for a
docs/usb-cdc-control-line-matrix.md(or wherever fbuild docs live) that pins down the rules in one place, with links to the datasheets / app notes that back them.Where this came from
The audit on FastLED/fbuild#684 and the LPC845-BRK bring-up incident (FastLED/FastLED#3300 / #3325) exposed that:
esp_reset.rs, three Python sites that just got fixed, and one short paragraph in the docstring of the newci/util/serial_probe.pyhelper. None of these are a reference a future contributor would find.Proposed shape
A single doc —
docs/usb-cdc-control-line-matrix.mdin this repo (orcrates/fbuild-serial/docs/, maintainer preference) — structured as:Per-chip matrix
Concrete rules (the "what to set when you open a port" cheat sheet)
Empirical probe (the test that produces this table for a new board)
Cross-links
crates/fbuild-serial/src/esp_reset.rs— references this doc from its module header.crates/fbuild-serial/src/manager.rs::open_port— references this doc from the DTR/RTS-assertion block (lines 120-134, the fix(esp32): prevent ESP32-S3 serial reset deadlock and boot-mode lockup #532 reference).crates/fbuild-build/src/<family>/configs/*.json— reference this doc when adding a new family.agents/docs/onboarding-a-new-board.md(if it exists; otherwise file separately) — links here too.Acceptance criteria
docs/usb-cdc-control-line-matrix.md(or equivalent path) exists with the per-chip table + concrete rules.FastLED#3339would have been a 15-minute investigation if this table existed."Out of scope
Refs
hard_reset_blockingDTR=low fix. Hints at the matrix but doesn't pin it.BOARD_FINGERPRINTStable. This doc is the why behind those entries.Filed during the audit fan-out on FastLED/FastLED#3339.