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]

Reply via email to