Browse Source

fix(port/dwc2): check idle when flush fifo, add delay for dwc2_set_mode

sakumisu 1 year ago
parent
commit
68badf6f4c
2 changed files with 38 additions and 2 deletions
  1. 19 1
      port/dwc2/usb_dc_dwc2.c
  2. 19 1
      port/dwc2/usb_hc_dwc2.c

+ 19 - 1
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 {

+ 19 - 1
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 {