boards/rp2040: add USB fastboot support for waveshare boards - #20083
Merged
Conversation
JianyuWang0623
force-pushed
the
rp2040/fastboot-usb
branch
from
September 7, 2026 12:28
9aeedd1 to
1a9fe3e
Compare
acassis
reviewed
Sep 7, 2026
JianyuWang0623
force-pushed
the
rp2040/fastboot-usb
branch
from
September 7, 2026 13:16
1a9fe3e to
1b4f2fa
Compare
acassis
requested changes
Sep 7, 2026
acassis
left a comment
Contributor
There was a problem hiding this comment.
@JianyuWang0623 please add fastboot_usb to the board Documentation to list it and explain how to use
Add a CDC/ACM (console) + USB fastboot (ADB "fastboot" personality) composite device to the shared rp2040_composite.c board glue, and a new "fastboot_usb" defconfig for waveshare-rp2040-zero and waveshare-rp2040-lcd-1.28. - boards/arm/rp2040/common/src/rp2040_composite.c: add a third composite slot for CONFIG_USBADB (covers both plain ADB and, with CONFIG_USBFASTBOOT, the "fastboot" personality of the same driver) alongside the existing MSC/CDC-ACM slots. While adding this, fixed a latent bug: the CDC/ACM block never advanced ifnobase/ strbase after filling in its own slot, because CDC/ACM used to always be the *last* device in the composite (nothing downstream ever needed the incremented values). Now that a device can follow CDC/ACM, the missing increment caused the fastboot interface to be assigned the same USB interface number as CDC/ACM's control interface (both 0), which the Linux kernel rejects with "Duplicate descriptor for config 1 interface 0 altsetting 0, skipping" and drops the fastboot interface entirely (confirmed via lsusb -v and disassembly of the generated board_composite_connect() code). - boards/arm/rp2040/waveshare-rp2040-zero/configs/fastboot_usb and boards/arm/rp2040/waveshare-rp2040-lcd-1.28/configs/fastboot_usb: new defconfig booting directly into fastbootd (CONFIG_INIT_ENTRYPOINT="fastbootd_main", no nsh) which brings up the CDC/ACM + fastboot composite via CONFIG_SYSTEM_FASTBOOTD_USB_BOARDCTL as soon as fastbootd starts, so the CDC/ACM sub-interface still provides a console for boot/ fastbootd log visibility without requiring a wired UART, while the fastboot vendor interface is what `fastboot devices`/`getvar` talk to. Assisted-by: OpenCode:claude-sonnet-5 Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
rp2040_allocep() indexes the endpoint's DPSRAM buffer/control registers via RP2040_DPINDEX(eplog) and RP2040_EPINDEX(eplog), both of which take the transfer direction from the direction bit of 'eplog' itself instead of trusting the explicit 'in' argument that is also passed to this function. This is harmless for callers that always encode the direction bit into 'eplog' (e.g. CDC/ACM's CDCACM_MKEPBULKIN()/MKEPINTIN(), which OR in USB_DIR_IN), since 'in' then always agrees with that bit. But drivers/usbdev/usbdev_fs.c (the generic ADB/fastboot class driver) calls DEV_ALLOCEP() with a bare endpoint number in 'eplog' (no direction bit) and passes the direction only via the separate 'in' parameter - matching this function's own "direction bit ignored" contract for 'eplog' (see its Input Parameters doc, and the pre-existing "Ignore any direction bits in the logical address" comment, both dating back to the original driver in b860e3c). For such a bare-number IN endpoint, USB_ISEPOUT(eplog) always evaluates true (the IN bit is never set on a plain number), so RP2040_DPINDEX(eplog) silently pointed the endpoint's buffer/control registers at its OUT slot instead of its IN slot. The real IN slot was left unconfigured, so the SIE responded to every IN token on that endpoint with a STALL - confirmed on real hardware via usbmon: 'C Bi:1:050:6 -32 0' (EPIPE) on every attempt, while the paired OUT endpoint (which "accidentally" resolved to the correct slot for the same reason) worked fine. Fix: normalize 'eplog' to agree with the explicit 'in' argument before it is used by RP2040_EPINDEX()/RP2040_DPINDEX(), so both macros keep their original, single-argument form and every use of eplog's direction bit below this point is consistent with 'in'. Existing 0x80-encoded callers (EP0, CDC/ACM) already agree with 'in' and are unaffected by the normalization. Also fix two pre-existing nxstyle violations in this same file (a misaligned comment block under USB_REQ_SYNCHFRAME, and a bare ';' body instead of empty braces on a while loop), both dating back to the original driver in b860e3c as well; CI runs nxstyle on the whole file whenever it is touched. Assisted-by: OpenCode:claude-sonnet-5 Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Add a "fastboot_usb" section to the waveshare-rp2040-zero and waveshare-rp2040-lcd-1.28 board doc pages, describing the USB fastboot composite configuration added by the previous commits: fastbootd runs on boot instead of NSH, composed together with CDC/ACM for the console, and reachable on the host via fastboot devices/getvar/reboot. Assisted-by: OpenCode:claude-sonnet-5 Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
JianyuWang0623
force-pushed
the
rp2040/fastboot-usb
branch
from
September 8, 2026 03:03
1b4f2fa to
d1c631c
Compare
Contributor
Author
@acassis done, "Documentation/rp2040: document fastboot_usb config for waveshare boards" |
xiaoxiang781216
approved these changes
Sep 8, 2026
JianyuWang0623
marked this pull request as ready for review
September 8, 2026 05:58
JianyuWang0623
requested review from
jerpelea,
linguini1 and
raiden00pl
as code owners
September 8, 2026 05:58
acassis
approved these changes
Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds USB fastboot support for the waveshare RP2040 boards and fixes a
real RP2040 usbdev driver bug found in the process (Stage 2 of the
"RP2040 waveshare series optimization" work, following the already
merged reboot-bootloader change in #20059).
boards/arm/rp2040/common/src/rp2040_composite.c: add a thirdcomposite slot for
CONFIG_USBADB(the generic ADB driver, whichwith
CONFIG_USBFASTBOOTbecomes the "fastboot" personality)alongside the existing MSC/CDC-ACM slots.
fastboot_usbdefconfig forwaveshare-rp2040-zeroandwaveshare-rp2040-lcd-1.28: boots directly intofastbootd(
CONFIG_INIT_ENTRYPOINT="fastbootd_main", no nsh) and brings up aCDC/ACM (console) + USB fastboot composite device via
CONFIG_SYSTEM_FASTBOOTD_USB_BOARDCTL, so the CDC/ACM sub-interfacestill provides console/log visibility without a wired UART, while
the fastboot vendor interface is what
fastboot devices/getvartalk to.
arch/arm/src/rp2040/rp2040_usbdev.c: fix a bug inrp2040_allocep()that this new fastboot config exposed. It indexesthe endpoint's DPSRAM buffer/control registers via
RP2040_DPINDEX(eplog)/RP2040_EPINDEX(eplog), both of which takethe transfer direction from the direction bit of
eplogitselfinstead of trusting the explicit
inargument also passed to thisfunction. This is harmless for callers that always encode the
direction bit into
eplog(e.g. CDC/ACM'sCDCACM_MKEPBULKIN()/MKEPINTIN(), which OR inUSB_DIR_IN), butdrivers/usbdev/usbdev_fs.c(the generic ADB/fastboot class driver)calls
DEV_ALLOCEP()with a bare endpoint number ineplog(nodirection bit) and passes direction only via
in- matching thisfunction's own "direction bit ignored" contract for
eplog. Forsuch a bare-number IN endpoint,
USB_ISEPOUT(eplog)alwaysevaluates true, so
RP2040_DPINDEX(eplog)silently pointed theendpoint's buffer/control registers at its OUT slot instead of its
IN slot, leaving the real IN slot unconfigured; the SIE then
responds to every IN token on that endpoint with a STALL. The fix
normalizes
eplogto agree withinonce, up front, so bothmacros keep their original single-argument form.
Impact
rp2040_allocep()fix affects every RP2040 board, but onlychanges behavior for callers that pass a bare (no direction bit)
eplog, which today is exactly the generic ADB/fastboot driver;existing CDC/ACM/MSC/composite configs already encode the direction
bit and are unaffected (verified: no behavior change observed on
the existing
usbnsh/compositeconfigs used in prior testing).Testing
Host: Ubuntu (x86_64),
arm-none-eabi-gcc, built withmake PICO_SDK_PATH=<pico-sdk>(required for the boot2 stage to beincluded in the generated
.uf2).Board:
waveshare-rp2040-lcd-1.28(physically connected over USB viapicotool/BOOTSEL for flashing).waveshare-rp2040-zero'sfastboot_usbdefconfig was build-tested only (no second physicalboard available in this environment).
Before the
rp2040_usbdev.cfix, the fastboot USB interface enumeratedcorrectly but every response from device to host hard-STALLed.
Captured with
usbmonon agetvar:productrequest:After the fix, on the same board/defconfig:
dmesgshows clean enumeration with nocan't set configerrors andall three interfaces bound:
tools/nxstyleandtools/checkpatch.share clean for both commits'actual changed lines (spot-checked directly;
checkpatch.sh -g HEADreports
All checks pass; some pre-existing, unrelated nxstyleviolations in
rp2040_usbdev.cpredate this series - confirmed viagit blameto point at the original 2021 driver commitb860e3c4ad35