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,