diff options
| author | sakumisu <[email protected]> | 2024-08-13 18:10:36 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2024-08-13 18:10:36 +0800 |
| commit | 68badf6f4c58894028a86bda861fdcbe4f52fb6b (patch) | |
| tree | c7453614ea924025008137b2d2ee88950bcfd49d | |
| parent | 907d23871ed9a5ecc36a64cb94b8d38edf006f82 (diff) | |
fix(port/dwc2): check idle when flush fifo, add delay for dwc2_set_mode
| -rw-r--r-- | port/dwc2/usb_dc_dwc2.c | 20 | ||||
| -rw-r--r-- | port/dwc2/usb_hc_dwc2.c | 20 |
2 files changed, 38 insertions, 2 deletions
diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c index 3bc9e052..3d03804b 100644 --- a/port/dwc2/usb_dc_dwc2.c +++ b/port/dwc2/usb_dc_dwc2.c @@ -176,12 +176,22 @@ static inline void dwc2_set_mode(uint8_t mode) } else if (mode == USB_OTG_MODE_DEVICE) { USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; } + + usbd_dwc2_delay_ms(50); } static inline int dwc2_flush_rxfifo(void) { - volatile uint32_t count = 0; + volatile uint32_t count = 0U; + + /* Wait for AHB master IDLE state. */ + do { + if (++count > 200000U) { + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); + count = 0; USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH; do { @@ -197,6 +207,14 @@ static inline int dwc2_flush_txfifo(uint32_t num) { volatile uint32_t count = 0U; + /* Wait for AHB master IDLE state. */ + do { + if (++count > 200000U) { + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); + + count = 0; USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6)); do { diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c index 6e39b574..d9c42261 100644 --- a/port/dwc2/usb_hc_dwc2.c +++ b/port/dwc2/usb_hc_dwc2.c @@ -114,12 +114,22 @@ static inline void dwc2_set_mode(struct usbh_bus *bus, uint8_t mode) } else if (mode == USB_OTG_MODE_DEVICE) { USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; } + + usb_osal_msleep(50); } static inline int dwc2_flush_rxfifo(struct usbh_bus *bus) { - volatile uint32_t count = 0; + volatile uint32_t count = 0U; + /* Wait for AHB master IDLE state. */ + do { + if (++count > 200000U) { + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); + + count = 0; USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH; do { @@ -135,6 +145,14 @@ static inline int dwc2_flush_txfifo(struct usbh_bus *bus, uint32_t num) { volatile uint32_t count = 0U; + /* Wait for AHB master IDLE state. */ + do { + if (++count > 200000U) { + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); + + count = 0; USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6)); do { |
