summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2024-08-13 18:10:36 +0800
committersakumisu <[email protected]>2024-08-13 18:10:36 +0800
commit68badf6f4c58894028a86bda861fdcbe4f52fb6b (patch)
treec7453614ea924025008137b2d2ee88950bcfd49d
parent907d23871ed9a5ecc36a64cb94b8d38edf006f82 (diff)
fix(port/dwc2): check idle when flush fifo, add delay for dwc2_set_mode
-rw-r--r--port/dwc2/usb_dc_dwc2.c20
-rw-r--r--port/dwc2/usb_hc_dwc2.c20
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 {