Problem
fbuild's RP2040 deployer treats the Windows mass-storage path (RPI-RP2 volume + NEW.UF2 filesystem write) as the primary and only automatic first transport. Picotool/PICOBOOT is reached only as a fallback — after all mass-storage copy attempts fail, or when the volume never mounts (crates/fbuild-deploy/src/rp2040.rs:1377-1448 at 16bb9ffa).
The mass-storage path is exactly the surface implicated in the #1161 reproduction (Disk 51/153 events, G:\NEW.UF2 write stalls). The ecosystem comparison in #1161 (comment) shows:
- PlatformIO (
platform-raspberrypi/builder/main.py): default upload_protocol is picotool, executed via Arduino's rp2040load — direct PICOBOOT transport, never touches the RPI-RP2 drive. (The 1200-baud touch is gated on the board's use_1200bps_touch config, not unconditional.)
- Arduino-pico (
platform.txt): ships a first-class picotool method running picotool load <uf2> -f -x.
- Arduino
rp2040tools (main.go): orchestrates picotool info → picotool load → picotool reboot.
Current fallback gaps (crates/fbuild-deploy/src/rp2040_picotool.rs)
- Runs
picotool load <uf2> -x — no -f, so it only works if the board is already in BOOTSEL; it cannot force-reboot a board sitting in application mode into BOOTSEL over the vendor interface.
- No
picotool info probe before loading, no verify step.
- Hard 30-second timeout, not configurable.
Proposal
Make PICOBOOT/picotool a first-class, explicitly selectable transport and the primary automatic path; keep the RPI-RP2 mass-storage copy as an explicit alternative/fallback.
- Add a transport selector (e.g.
--transport picotool|uf2, default picotool).
- Primary automatic flow (mirrors the PlatformIO/Arduino model):
- If application CDC is present, perform the 1200-baud reset/touch (or rely on
picotool -f vendor reset).
- Wait for the
2E8A:0003 BOOTSEL/PICOBOOT interface.
- Probe with
picotool info.
picotool load <uf2> -f -x (add -f; keep -x to execute).
- Verify application re-enumeration.
- Fall back to the mass-storage
NEW.UF2 copy on PICOBOOT failure, with error classification distinguishing driver-missing (see the Windows preflight sub-issue) from device/transport failure.
- Make the load timeout configurable; 30s is tight for large images plus a vendor reset round-trip.
The packaging already exists (fbuild_packages::toolchain::Rp2040Picotool), so this is mostly transport ordering, -f, the probe, and error classification — not a new PICOBOOT implementation.
Acceptance
- Default deploy on a healthy board goes through PICOBOOT without opening the
RPI-RP2 volume.
--transport uf2 restores the current behavior.
- Unit tests cover transport selection and fallback ordering.
Part of the meta issue tracking the #1161 transport strategy change. Defaults chosen by the drafting agent are listed inline — edit as needed.
Problem
fbuild's RP2040 deployer treats the Windows mass-storage path (
RPI-RP2volume +NEW.UF2filesystem write) as the primary and only automatic first transport. Picotool/PICOBOOT is reached only as a fallback — after all mass-storage copy attempts fail, or when the volume never mounts (crates/fbuild-deploy/src/rp2040.rs:1377-1448at16bb9ffa).The mass-storage path is exactly the surface implicated in the #1161 reproduction (Disk 51/153 events,
G:\NEW.UF2write stalls). The ecosystem comparison in #1161 (comment) shows:platform-raspberrypi/builder/main.py): defaultupload_protocolispicotool, executed via Arduino'srp2040load— direct PICOBOOT transport, never touches theRPI-RP2drive. (The 1200-baud touch is gated on the board'suse_1200bps_touchconfig, not unconditional.)platform.txt): ships a first-class picotool method runningpicotool load <uf2> -f -x.rp2040tools(main.go): orchestratespicotool info→picotool load→picotool reboot.Current fallback gaps (
crates/fbuild-deploy/src/rp2040_picotool.rs)picotool load <uf2> -x— no-f, so it only works if the board is already in BOOTSEL; it cannot force-reboot a board sitting in application mode into BOOTSEL over the vendor interface.picotool infoprobe before loading, no verify step.Proposal
Make PICOBOOT/picotool a first-class, explicitly selectable transport and the primary automatic path; keep the
RPI-RP2mass-storage copy as an explicit alternative/fallback.--transport picotool|uf2, defaultpicotool).picotool -fvendor reset).2E8A:0003BOOTSEL/PICOBOOT interface.picotool info.picotool load <uf2> -f -x(add-f; keep-xto execute).NEW.UF2copy on PICOBOOT failure, with error classification distinguishing driver-missing (see the Windows preflight sub-issue) from device/transport failure.The packaging already exists (
fbuild_packages::toolchain::Rp2040Picotool), so this is mostly transport ordering,-f, the probe, and error classification — not a new PICOBOOT implementation.Acceptance
RPI-RP2volume.--transport uf2restores the current behavior.Part of the meta issue tracking the #1161 transport strategy change. Defaults chosen by the drafting agent are listed inline — edit as needed.