This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 53c27e155bb rp2040/rp23xx: preserve SIE_CTRL.PULLUP_EN in 
usbdev_register
53c27e155bb is described below

commit 53c27e155bb1dc5a7593e10667de62922751be46
Author: Ricard Rosson <[email protected]>
AuthorDate: Wed Jul 15 21:00:42 2026 +0100

    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 <[email protected]>
    Signed-off-by: Ricard Rosson <[email protected]>
---
 arch/arm/src/rp2040/rp2040_usbdev.c | 13 +++++++++++--
 arch/arm/src/rp23xx/rp23xx_usbdev.c | 13 +++++++++++--
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/arm/src/rp2040/rp2040_usbdev.c 
b/arch/arm/src/rp2040/rp2040_usbdev.c
index ceb7a9e965c..470f32567ed 100644
--- a/arch/arm/src/rp2040/rp2040_usbdev.c
+++ b/arch/arm/src/rp2040/rp2040_usbdev.c
@@ -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,
diff --git a/arch/arm/src/rp23xx/rp23xx_usbdev.c 
b/arch/arm/src/rp23xx/rp23xx_usbdev.c
index cfece8936bf..357b96eb8d8 100644
--- a/arch/arm/src/rp23xx/rp23xx_usbdev.c
+++ b/arch/arm/src/rp23xx/rp23xx_usbdev.c
@@ -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,

Reply via email to