Skip to content

feat(serial): consult PlatformIO-style upload.* hints for reset dispatch (#906) - #908

Merged
zackees merged 1 commit into
mainfrom
feat/906-upload-hint-dispatch
Jul 1, 2026
Merged

feat(serial): consult PlatformIO-style upload.* hints for reset dispatch (#906)#908
zackees merged 1 commit into
mainfrom
feat/906-upload-hint-dispatch

Conversation

@zackees

@zackeeszackees commented Jul 1, 2026

Copy link
Copy Markdown
Member

Ecosystem survey (documented in issue #906) shows PlatformIO's data-driven per-board upload.* schema is the frontrunner for encoding reset semantics; Arduino CLI ships the same 3-key subset; esptool.py does VID/PID-scoped strategy dispatch; avrdude bakes reset into the programmer name. Nobody does OS kernel-class fallback — fbuild's #895 is unique and we keep it.

fbuild already extracts these fields into board JSONs via crates/fbuild-config/src/bin/enrich_boards.rs::UPLOAD_FIELDS (protocol, speed, use_1200bps_touch, wait_for_upload_port, require_upload_port, etc.), but the runtime reset dispatch in crates/fbuild-serial/src/boards.rsnever consulted them — it fell back purely to VID/PID. This closes that gap.

What lands

Two new public items in fbuild_serial::boards:

pubstructUploadHint{pubprotocol:Option<String>,pubuse_1200bps_touch:Option<bool>,pubnative_usb:Option<bool>,}pubfnfamily_from_upload_hint(&UploadHint) -> Option<BoardFamily>;pubfnfamily_for_port_with_hint(&str,Option<&UploadHint>) -> Option<BoardFamily>;

The mapping table matches the ecosystem vocabulary verbatim:

upload.protocolBoardFamily
esptool / esptool_py + native_usb: trueEsp32NativeUsbCdc
esptool / esptool_py (default / false)Esp32ExternalUart
arduinoArduinoAutoReset
sam-ba / bossac / bossac18NativeUsbCdcReset1200Bps
picotoolNativeUsbCdcReset1200Bps
teensy-gui / teensy-cli / teensy_loader_cliTeensy
cmsis-dap / jlink / stlink / raspberrypi-swd / atmel-ice / openocdCdcAcmBridge
(missing protocol) + use_1200bps_touch: trueNativeUsbCdcReset1200Bps

Case- and whitespace-tolerant so " ESPTOOL " from a hand-authored board JSON still hits the right arm.

New detection chain

family_for_port_with_hint(port, Some(hint))
1. UploadHint.protocol / use_1200bps_touch <- NEW (#906)
2. family_for_vid_pid (existing)
3. family_for_port_via_kernel_class (added by #895)
4. None -> caller defaults via family_for_port_or_default

Deploy paths that have BoardConfig in scope should thread it through here to avoid guessing from VID/PID. Wiring the deploy path is a follow-up (needs BoardConfig to grow the extra upload fields first — see #906's "Follow-ups" section).

Tests

11 new tests in boards::tests:

  • Every documented upload.protocol string covered
  • esptool split on native_usb true / false / missing
  • Case + whitespace tolerance
  • use_1200bps_touch fallback when protocol missing
  • Unknown protocol returns None
  • family_for_port_with_hint precedence (hint wins) and fallback (no hint degrades to family_for_port)

Docs

Extended docs/usb-cdc-control-line-matrix.md with a new "Ecosystem upload.protocol mapping" section holding the full protocol → family table and cross-referencing #906.

Verification

  • soldr cargo check -p fbuild-serial --all-targets — clean
  • soldr cargo clippy -p fbuild-serial --all-targets -- -D warnings — clean
  • soldr cargo test -p fbuild-serial --lib boards:: — passes (existing tests unchanged, 11 new pass)

Follow-ups (not this PR)

  1. Extend BoardConfig with upload_use_1200bps_touch, upload_native_usb, upload_disable_flushing, upload_wait_for_upload_port.
  2. Wire the deploy path to build an UploadHint from BoardConfig and pass it to family_for_port_with_hint.
  3. PlatformIO-style protocols: [] array support for multi-protocol boards.
  4. Optional probe-based ESP_SYNC detection for truly unknown ports (behind a --probe-unknown flag).

Closes#906

Summary by CodeRabbit

  • New Features

    • Added support for using board upload metadata to better identify board families.
    • Improved detection for several common upload methods, with smarter fallback behavior when specific metadata is missing.
  • Documentation

    • Expanded USB CDC control-line guidance with a new mapping table and notes on when to update it.
  • Tests

    • Added coverage for upload-metadata-based detection, including protocol variants and fallback cases.

…tch (#906)
Ecosystem survey (documented on #906) shows PlatformIO's data-driven
per-board upload.* schema is the frontrunner for encoding reset
semantics. Arduino CLI ships the same 3-key subset. esptool.py does
VID/PID-scoped strategy dispatch. avrdude bakes reset into the
programmer name. Nobody does OS kernel-class fallback (fbuild's #895
is unique — keep it).
fbuild already extracts these fields into board JSONs via
crates/fbuild-config/src/bin/enrich_boards.rs::UPLOAD_FIELDS (protocol,
speed, use_1200bps_touch, wait_for_upload_port, require_upload_port,
etc.), but the runtime reset dispatch in crates/fbuild-serial/src/
boards.rs never consulted them — it fell back purely to VID/PID.
This closes that gap.
# What lands
Two new public items in fbuild-serial::boards:
pub struct UploadHint {
pub protocol: Option<String>,
pub use_1200bps_touch: Option<bool>,
pub native_usb: Option<bool>,
}
pub fn family_from_upload_hint(&UploadHint) -> Option<BoardFamily>
pub fn family_for_port_with_hint(&str, Option<&UploadHint>) -> Option<BoardFamily>
The mapping table matches the ecosystem vocabulary verbatim:
- esptool / esptool_py + native_usb=true -> Esp32NativeUsbCdc
- esptool / esptool_py (default) -> Esp32ExternalUart
- arduino -> ArduinoAutoReset (DTR-cap)
- sam-ba / bossac / bossac18 -> NativeUsbCdcReset1200Bps
- picotool -> NativeUsbCdcReset1200Bps
- teensy-gui / teensy-cli /
teensy_loader_cli -> Teensy
- cmsis-dap / jlink / stlink /
raspberrypi-swd / atmel-ice / openocd -> CdcAcmBridge
- (missing protocol) + use_1200bps_touch -> NativeUsbCdcReset1200Bps
Case- and whitespace-tolerant so ' ESPTOOL ' from a hand-authored
board JSON still hits the right arm.
# Detection chain (highest priority first)
family_for_port_with_hint(port, Some(hint))
1. UploadHint.protocol / use_1200bps_touch <- NEW (#906)
2. family_for_vid_pid (existing)
3. family_for_port_via_kernel_class (added by #895)
4. None -> caller defaults via family_for_port_or_default
Deploy paths that have BoardConfig in scope should thread it through
here to avoid guessing from VID/PID. Wiring the deploy path is a
follow-up (BoardConfig needs the extra fields exposed first).
# Tests
11 new tests in boards::tests covering:
- Every documented upload.protocol string
- esptool split on native_usb true/false/missing
- Case + whitespace tolerance
- use_1200bps_touch fallback when protocol missing
- Unknown protocol returns None
- family_for_port_with_hint precedence (hint wins) and fallback
(no hint degrades to family_for_port)
# Docs
Extended docs/usb-cdc-control-line-matrix.md with an
'Ecosystem upload.protocol mapping' section that captures the full
protocol -> family table and cites #906.
Closes#906
@zackees
zackees merged commit 4d8ce47 into mainJul 1, 2026
4 of 14 checks passed
@zackees
zackees deleted the feat/906-upload-hint-dispatch branch July 1, 2026 00:29
@coderabbitai

coderabbitaiBot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7111a1f3-c4f0-4785-8b9f-fbd229db3ee9

📥 Commits

Reviewing files that changed from the base of the PR and between 219ce58 and 88461b9.

📒 Files selected for processing (2)
  • crates/fbuild-serial/src/boards.rs
  • docs/usb-cdc-control-line-matrix.md

📝 Walkthrough

Walkthrough

Adds an UploadHint struct and family_from_upload_hint/family_for_port_with_hint functions to crates/fbuild-serial/src/boards.rs, mapping PlatformIO-style upload.protocol/use_1200bps_touch/native_usb metadata to BoardFamily, prioritized over existing VID/PID detection. Adds unit tests and updates documentation with the mapping table.

Changes

Upload Hint Detection

Layer / File(s)Summary
UploadHint struct and protocol mapping
crates/fbuild-serial/src/boards.rs
Adds UploadHint struct (protocol, use_1200bps_touch, native_usb) and family_from_upload_hint mapping normalized protocol strings and touch flag to BoardFamily variants.
Priority dispatch and fallback wiring
crates/fbuild-serial/src/boards.rs
Adds family_for_port_with_hint that prefers hint-derived family, falling back to existing family_for_port VID/PID/kernel-class detection; updates docs pointing callers to the new function.
Tests and mapping documentation
crates/fbuild-serial/src/boards.rs, docs/usb-cdc-control-line-matrix.md
Adds unit tests covering protocol aliases, case/whitespace tolerance, touch-only fallback, and hint precedence; documents the protocol-to-family mapping table and idle DTR/RTS levels.

Sequence Diagram(s)

sequenceDiagram
participant Caller
participant family_for_port_with_hint
participant family_from_upload_hint
participant family_for_port
Caller->>family_for_port_with_hint: name, Option<UploadHint>
alt hint resolves to a family
family_for_port_with_hint->>family_from_upload_hint: hint
family_from_upload_hint-->>family_for_port_with_hint: BoardFamily
else no usable hint
family_for_port_with_hint->>family_for_port: name
family_for_port-->>family_for_port_with_hint: BoardFamily or None
end
family_for_port_with_hint-->>Caller: Option<BoardFamily>
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Possibly related PRs

  • FastLED/fbuild#700: Both PRs modify crates/fbuild-serial/src/boards.rs board-family detection, with the main PR adding upload-hint mapping on top of that VID/PID logic.
  • FastLED/fbuild#703: The main PR maps upload-hint metadata into the same BoardFamily taxonomy introduced for reset/DTR/RTS dispatch in that PR.

Poem

A hint arrives before the wire,
"esptool" whispers, "no need to inquire!"
No more guessing VID and PID,
the board just tells us what it did. 🐇
Hop, reset, touch at twelve-oh-oh —
this bunny's board detection now just... knows. 🥕

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/906-upload-hint-dispatch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

zackees added a commit that referenced this pull request Jul 1, 2026
Pre-existing clippy field_reassign_with_default lint from PR #908 (the
upload-hint tests) — my local soldr silently didn't run clippy for
#908 so the lint slipped through. #910's CI now trips on the same
file. Rewrite as struct-literal syntax.
zackees added a commit that referenced this pull request Jul 1, 2026
Pre-existing clippy field_reassign_with_default lint from PR #908 (the
upload-hint tests) — my local soldr silently didn't run clippy for
#908 so the lint slipped through. #910's CI now trips on the same
file. Rewrite as struct-literal syntax.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

serial: consult PlatformIO-style upload.* hints from board JSON when dispatching reset

1 participant

@zackees