JianyuWang0623 opened a new pull request, #20083:
URL: https://github.com/apache/nuttx/pull/20083
## 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 third
composite slot for `CONFIG_USBADB` (the generic ADB driver, which
with `CONFIG_USBFASTBOOT` becomes the "fastboot" personality)
alongside the existing MSC/CDC-ACM slots.
- New `fastboot_usb` defconfig for `waveshare-rp2040-zero` and
`waveshare-rp2040-lcd-1.28`: boots directly into `fastbootd`
(`CONFIG_INIT_ENTRYPOINT="fastbootd_main"`, no nsh) and brings up a
CDC/ACM (console) + USB fastboot composite device via
`CONFIG_SYSTEM_FASTBOOTD_USB_BOARDCTL`, so the CDC/ACM sub-interface
still provides console/log visibility without a wired UART, while
the fastboot vendor interface is what `fastboot devices`/`getvar`
talk to.
- `arch/arm/src/rp2040/rp2040_usbdev.c`: fix a bug in
`rp2040_allocep()` that this new fastboot config exposed. It indexes
the endpoint's DPSRAM buffer/control registers via
`RP2040_DPINDEX(eplog)`/`RP2040_EPINDEX(eplog)`, both of which take
the transfer direction from the direction bit of `eplog` itself
instead of trusting the explicit `in` argument 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`), 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 direction only via `in` - matching this
function's own "direction bit ignored" contract for `eplog`. For
such a bare-number IN endpoint, `USB_ISEPOUT(eplog)` always
evaluates true, so `RP2040_DPINDEX(eplog)` silently pointed the
endpoint'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 `eplog` to agree with `in` once, up front, so both
macros keep their original single-argument form.
## Impact
- RP2040 only.
- The `rp2040_allocep()` fix affects every RP2040 board, but only
changes 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`/`composite` configs used in prior testing).
## Testing
Host: Ubuntu (x86_64), `arm-none-eabi-gcc`, built with
`make PICO_SDK_PATH=<pico-sdk>` (required for the boot2 stage to be
included in the generated `.uf2`).
Board: `waveshare-rp2040-lcd-1.28` (physically connected over USB via
`picotool`/BOOTSEL for flashing). `waveshare-rp2040-zero`'s
`fastboot_usb` defconfig was build-tested only (no second physical
board available in this environment).
Before the `rp2040_usbdev.c` fix, the fastboot USB interface enumerated
correctly but every response from device to host hard-STALLed.
Captured with `usbmon` on a `getvar:product` request:
```
S Bo:1:050:7 -115 14 = 67657476 61723a70 726f6475 6374 (OUT
"getvar:product", host->device, succeeds)
C Bo:1:050:7 0 14 >
S Bi:1:050:6 -115 64 < (IN, device->host,
host requests the reply)
C Bi:1:050:6 -32 0 (completes with
errno -32 = EPIPE, i.e. a real STALL)
```
After the fix, on the same board/defconfig:
```
$ lsusb -v -d 03eb:2023 | grep -E "bInterfaceNumber|bInterfaceClass"
bInterfaceNumber 0
bInterfaceClass 2 Communications
bInterfaceNumber 1
bInterfaceClass 10 CDC Data
bInterfaceNumber 2
bInterfaceClass 255 Vendor Specific Class
$ fastboot devices
0101 fastboot
$ fastboot getvar product
product: NuttX
Finished. Total time: 0.001s
$ fastboot reboot bootloader
Rebooting into bootloader OKAY [ 0.000s]
```
`dmesg` shows clean enumeration with no `can't set config` errors and
all three interfaces bound:
```
usb 1-5.4: New USB device found, idVendor=03eb, idProduct=2023,
bcdDevice=10.10
usb 1-5.4: Product: NuttX Fastboot Composite
usb 1-5.4: Manufacturer: NuttX
cdc_acm 1-5.4:1.0: ttyACM5: USB ACM device
```
`tools/nxstyle` and `tools/checkpatch.sh` are clean for both commits'
actual changed lines (spot-checked directly; `checkpatch.sh -g HEAD`
reports `All checks pass`; some pre-existing, unrelated nxstyle
violations in `rp2040_usbdev.c` predate this series - confirmed via
`git blame` to point at the original 2021 driver commit `b860e3c4ad35`
- and are not touched by either commit here).
Known limitation, not yet root-caused: individual `getvar` queries
occasionally return a stale/misaligned answer (the value for a
different variable than the one just queried) on the first 1-2
exchanges after a fresh USB connection, stabilizing afterward; retries
reliably converge to the correct value. This does not affect command
delivery (`reboot`/`reboot bootloader` are reliable) and is tracked as
a follow-up rather than blocking this series, since it long predates
and is independent of both changes here (reproduces with the STALL
fix applied and unmodified upstream ADB/fastboot driver code in a
standalone, non-composite config too). This NuttX fastbootd also has
no special handling for the `getvar all` pseudo-variable (confirmed via
`usbmon` that the `fastboot` client sends it as a literal
`getvar:all` command); individual variable queries are the supported
path today.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]