mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
rp2040/rp23xx: preserve SIE_CTRL.PULLUP_EN in usbdev_register
usbdev_register() calls CLASS_BIND, which ends with DEV_CONNECT (composite_bind/cdcacm_bind) and sets SIE_CTRL.PULLUP_EN, and then performs a wholesale putreg32 of SIE_CTRL to set EP0_INT_1BUF -- clobbering the pull-up microseconds after it was asserted. Enumeration only ever succeeded because the host happened to latch the microsecond pull-up blip and issued a bus reset, whose handler (CLASS_DISCONNECT -> DEV_CONNECT) re-arms the pull-up. A warm host port catches the blip; a cold-plugged port is still in attach debounce, misses it, and never resets -- PULLUP_EN stays 0 forever and the device is totally silent on the bus while NuttX runs normally underneath. This presented as an intermittent, image-dependent "cold boot brick" (boot timing shifts the blip in or out of the host's blind window). Fix: set EP0_INT_1BUF with setbits_reg32 so PULLUP_EN survives. Validated on RP2350 silicon (Raspberry Pi Pico 2 W): an image that failed 0/10 cold plugs enumerated 10/10 with the fix; a second board that had never enumerated at all was recovered by it. The rp2040 driver has the identical code and receives the identical fix (build-tested; the RP2350 validation exercised the shared logic). Fixes apache/nuttx#19434 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Ricard Rosson <ricard@groundbits.com>
This commit is contained in:
parent
ce645060fa
commit
53c27e155b
2 changed files with 22 additions and 4 deletions
|
|
@ -2184,8 +2184,17 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
|
|||
|
||||
/* Enable interrupt */
|
||||
|
||||
putreg32(RP2040_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
|
||||
RP2040_USBCTRL_REGS_SIE_CTRL);
|
||||
/* Use setbits, NOT putreg32: CLASS_BIND above ends with DEV_CONNECT
|
||||
* (composite_bind/cdcacm_bind), which sets SIE_CTRL.PULLUP_EN. A
|
||||
* wholesale write here clobbers that pull-up microseconds after it was
|
||||
* asserted; enumeration then only succeeds if the host happened to
|
||||
* latch the short pull-up blip and issues a bus reset (whose handler
|
||||
* re-arms the pull-up). A cold-plugged host port misses the blip and
|
||||
* the device stays disconnected forever.
|
||||
*/
|
||||
|
||||
setbits_reg32(RP2040_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
|
||||
RP2040_USBCTRL_REGS_SIE_CTRL);
|
||||
putreg32(RP2040_USBCTRL_REGS_INTR_BUFF_STATUS |
|
||||
RP2040_USBCTRL_REGS_INTR_BUS_RESET |
|
||||
RP2040_USBCTRL_REGS_INTR_SETUP_REQ,
|
||||
|
|
|
|||
|
|
@ -2176,8 +2176,17 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
|
|||
|
||||
/* Enable interrupt */
|
||||
|
||||
putreg32(RP23XX_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
|
||||
RP23XX_USBCTRL_REGS_SIE_CTRL);
|
||||
/* Use setbits, NOT putreg32: CLASS_BIND above ends with DEV_CONNECT
|
||||
* (composite_bind/cdcacm_bind), which sets SIE_CTRL.PULLUP_EN. A
|
||||
* wholesale write here clobbers that pull-up microseconds after it was
|
||||
* asserted; enumeration then only succeeds if the host happened to
|
||||
* latch the short pull-up blip and issues a bus reset (whose handler
|
||||
* re-arms the pull-up). A cold-plugged host port misses the blip and
|
||||
* the device stays disconnected forever.
|
||||
*/
|
||||
|
||||
setbits_reg32(RP23XX_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
|
||||
RP23XX_USBCTRL_REGS_SIE_CTRL);
|
||||
putreg32(RP23XX_USBCTRL_REGS_INTR_BUFF_STATUS |
|
||||
RP23XX_USBCTRL_REGS_INTR_BUS_RESET |
|
||||
RP23XX_USBCTRL_REGS_INTR_SETUP_REQ,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue