Преглед на файлове

update hcd synopsys port, fix speed value when run HAL_HCD_HC_Init

sakumisu преди 3 години
родител
ревизия
eb08bcc5a0

+ 17 - 21
demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c

@@ -45,7 +45,7 @@
 /* Private variables ---------------------------------------------------------*/
 UART_HandleTypeDef huart1;
 
-HCD_HandleTypeDef hhcd_USB_OTG_HS;
+//HCD_HandleTypeDef hhcd_USB_OTG_HS;
 
 /* USER CODE BEGIN PV */
 
@@ -68,11 +68,6 @@ int fputc(int ch, FILE *f)
   return ch;
 }
 
-void usb_hc_low_level_init(void)
-{
-    MX_USB_OTG_HS_HCD_Init();
-}
-
 /* USER CODE END 0 */
 
 /**
@@ -107,8 +102,9 @@ int main(void)
   //MX_USB_OTG_HS_HCD_Init();
   /* USER CODE BEGIN 2 */
                    
-   usbh_initialize();
-   vTaskStartScheduler();
+  usbh_initialize();
+  printf("Start usb host task...\r\n");
+  vTaskStartScheduler();
   /* USER CODE END 2 */
 
   /* Infinite loop */
@@ -213,19 +209,19 @@ static void MX_USB_OTG_HS_HCD_Init(void)
   /* USER CODE BEGIN USB_OTG_HS_Init 1 */
 
   /* USER CODE END USB_OTG_HS_Init 1 */
-  hhcd_USB_OTG_HS.Instance = USB_OTG_HS;
-  hhcd_USB_OTG_HS.Init.Host_channels = 12;
-  hhcd_USB_OTG_HS.Init.speed = HCD_SPEED_FULL;
-  hhcd_USB_OTG_HS.Init.dma_enable = DISABLE;
-  hhcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY;
-  hhcd_USB_OTG_HS.Init.Sof_enable = DISABLE;
-  hhcd_USB_OTG_HS.Init.low_power_enable = DISABLE;
-  hhcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE;
-  hhcd_USB_OTG_HS.Init.use_external_vbus = DISABLE;
-  if (HAL_HCD_Init(&hhcd_USB_OTG_HS) != HAL_OK)
-  {
-    Error_Handler();
-  }
+//  hhcd_USB_OTG_HS.Instance = USB_OTG_HS;
+//  hhcd_USB_OTG_HS.Init.Host_channels = 12;
+//  hhcd_USB_OTG_HS.Init.speed = HCD_SPEED_FULL;
+//  hhcd_USB_OTG_HS.Init.dma_enable = DISABLE;
+//  hhcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY;
+//  hhcd_USB_OTG_HS.Init.Sof_enable = DISABLE;
+//  hhcd_USB_OTG_HS.Init.low_power_enable = DISABLE;
+//  hhcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE;
+//  hhcd_USB_OTG_HS.Init.use_external_vbus = DISABLE;
+//  if (HAL_HCD_Init(&hhcd_USB_OTG_HS) != HAL_OK)
+//  {
+//    Error_Handler();
+//  }
   /* USER CODE BEGIN USB_OTG_HS_Init 2 */
 
   /* USER CODE END USB_OTG_HS_Init 2 */

+ 9 - 9
demo/stm32/usb_host/stm32f429igt6/Core/Src/stm32f4xx_it.c

@@ -196,7 +196,7 @@ extern void xPortSysTickHandler(void);
       }
     #endif  /* INCLUDE_xTaskGetSchedulerState */
   /* USER CODE END SysTick_IRQn 0 */
-  //HAL_IncTick();
+  HAL_IncTick();
   /* USER CODE BEGIN SysTick_IRQn 1 */
 
   /* USER CODE END SysTick_IRQn 1 */
@@ -212,16 +212,16 @@ extern void xPortSysTickHandler(void);
 /**
   * @brief This function handles USB On The Go HS global interrupt.
   */
-void OTG_HS_IRQHandler(void)
-{
-  /* USER CODE BEGIN OTG_HS_IRQn 0 */
+//void OTG_HS_IRQHandler(void)
+//{
+//  /* USER CODE BEGIN OTG_HS_IRQn 0 */
 
-  /* USER CODE END OTG_HS_IRQn 0 */
-  HAL_HCD_IRQHandler(&hhcd_USB_OTG_HS);
-  /* USER CODE BEGIN OTG_HS_IRQn 1 */
+//  /* USER CODE END OTG_HS_IRQn 0 */
+//  HAL_HCD_IRQHandler(&hhcd_USB_OTG_HS);
+//  /* USER CODE BEGIN OTG_HS_IRQn 1 */
 
-  /* USER CODE END OTG_HS_IRQn 1 */
-}
+//  /* USER CODE END OTG_HS_IRQn 1 */
+//}
 
 /* USER CODE BEGIN 1 */
 

+ 16 - 16
demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx

@@ -157,18 +157,18 @@
         <Bp>
           <Number>0</Number>
           <Type>0</Type>
-          <LineNumber>89</LineNumber>
+          <LineNumber>360</LineNumber>
           <EnabledFlag>1</EnabledFlag>
-          <Address>0</Address>
+          <Address>134233946</Address>
           <ByteObject>0</ByteObject>
           <HtxType>0</HtxType>
           <ManyObjects>0</ManyObjects>
           <SizeOfObject>0</SizeOfObject>
           <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>0</BreakIfRCount>
-          <Filename>..\..\..\..\..\class\cdc\usbh_cdc_acm.c</Filename>
+          <BreakIfRCount>1</BreakIfRCount>
+          <Filename>..\..\..\..\..\class\msc\usbh_msc.c</Filename>
           <ExecCommand></ExecCommand>
-          <Expression></Expression>
+          <Expression>\\stm32f429igt6\../../../../../class/msc/usbh_msc.c\360</Expression>
         </Bp>
       </Breakpoint>
       <WatchWindow1>
@@ -269,12 +269,12 @@
     <File>
       <GroupNumber>2</GroupNumber>
       <FileNumber>2</FileNumber>
-      <FileType>1</FileType>
+      <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>../Core/Src/main.c</PathWithFileName>
-      <FilenameWithoutPath>main.c</FilenameWithoutPath>
+      <PathWithFileName>..\Core\Inc\FreeRTOSConfig.h</PathWithFileName>
+      <FilenameWithoutPath>FreeRTOSConfig.h</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
@@ -285,8 +285,8 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>../Core/Src/stm32f4xx_it.c</PathWithFileName>
-      <FilenameWithoutPath>stm32f4xx_it.c</FilenameWithoutPath>
+      <PathWithFileName>../Core/Src/main.c</PathWithFileName>
+      <FilenameWithoutPath>main.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
@@ -297,20 +297,20 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>../Core/Src/stm32f4xx_hal_msp.c</PathWithFileName>
-      <FilenameWithoutPath>stm32f4xx_hal_msp.c</FilenameWithoutPath>
+      <PathWithFileName>../Core/Src/stm32f4xx_it.c</PathWithFileName>
+      <FilenameWithoutPath>stm32f4xx_it.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
       <FileNumber>5</FileNumber>
-      <FileType>5</FileType>
+      <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\Core\Inc\FreeRTOSConfig.h</PathWithFileName>
-      <FilenameWithoutPath>FreeRTOSConfig.h</FilenameWithoutPath>
+      <PathWithFileName>../Core/Src/stm32f4xx_hal_msp.c</PathWithFileName>
+      <FilenameWithoutPath>stm32f4xx_hal_msp.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
@@ -562,7 +562,7 @@
 
   <Group>
     <GroupName>FreeRTOS</GroupName>
-    <tvExp>0</tvExp>
+    <tvExp>1</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>

+ 7 - 7
demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx

@@ -338,9 +338,9 @@
             <v6Rtti>0</v6Rtti>
             <VariousControls>
               <MiscControls></MiscControls>
-              <Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_HS</Define>
+              <Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_HS_IN_FULL</Define>
               <Undefine></Undefine>
-              <IncludePath>../Core/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy; ../Drivers/CMSIS/Device/ST/STM32F4xx/Include; ../Drivers/CMSIS/Include; ..\FreeRTOS\include; ..\FreeRTOS\portable\GCC\ARM_CM4F; ..\..\..\..\..\common; ..\..\..\..\..\core; ..\..\..\..\..\class\cdc; ..\..\..\..\..\class\hub; ..\..\..\..\..\class\hid; ..\..\..\..\..\class\msc; ..\..\..\..\..\osal</IncludePath>
+              <IncludePath>../Core/Inc;  ../Drivers/STM32F4xx_HAL_Driver/Inc;  ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;  ../Drivers/CMSIS/Device/ST/STM32F4xx/Include;  ../Drivers/CMSIS/Include;  ..\FreeRTOS\include;  ..\FreeRTOS\portable\GCC\ARM_CM4F;  ..\..\..\..\..\common;  ..\..\..\..\..\core;  ..\..\..\..\..\class\cdc;  ..\..\..\..\..\class\hub;  ..\..\..\..\..\class\hid;  ..\..\..\..\..\class\msc;  ..\..\..\..\..\osal</IncludePath>
             </VariousControls>
           </Cads>
           <Aads>
@@ -394,6 +394,11 @@
         <Group>
           <GroupName>Application/User/Core</GroupName>
           <Files>
+            <File>
+              <FileName>FreeRTOSConfig.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\Core\Inc\FreeRTOSConfig.h</FilePath>
+            </File>
             <File>
               <FileName>main.c</FileName>
               <FileType>1</FileType>
@@ -409,11 +414,6 @@
               <FileType>1</FileType>
               <FilePath>../Core/Src/stm32f4xx_hal_msp.c</FilePath>
             </File>
-            <File>
-              <FileName>FreeRTOSConfig.h</FileName>
-              <FileType>5</FileType>
-              <FilePath>..\Core\Inc\FreeRTOSConfig.h</FilePath>
-            </File>
           </Files>
         </Group>
         <Group>

+ 3 - 3
demo/stm32/usb_host/stm32f429igt6/stm32f429igt6.ioc

@@ -60,8 +60,8 @@ ProjectManager.BackupPrevious=false
 ProjectManager.CompilerOptimize=6
 ProjectManager.ComputerToolchain=false
 ProjectManager.CoupleFile=false
-ProjectManager.CustomerFirmwarePackage=E\:\\Library\\STM32\\STM32Cube_FW_F4_V1.25.2
-ProjectManager.DefaultFWLocation=false
+ProjectManager.CustomerFirmwarePackage=
+ProjectManager.DefaultFWLocation=true
 ProjectManager.DeletePrevious=true
 ProjectManager.DeviceId=STM32F429IGTx
 ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.26.0
@@ -69,7 +69,7 @@ ProjectManager.FreePins=false
 ProjectManager.HalAssertFull=false
 ProjectManager.HeapSize=0x200
 ProjectManager.KeepUserCode=true
-ProjectManager.LastFirmware=true
+ProjectManager.LastFirmware=false
 ProjectManager.LibraryCopy=0
 ProjectManager.MainLocation=Core/Src
 ProjectManager.NoMain=false

+ 447 - 329
port/synopsys/usb_hc_synopsys.c

@@ -1,11 +1,21 @@
 #include "usbh_core.h"
 #include "stm32f4xx_hal.h"
 
+#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL)
+HCD_HandleTypeDef hhcd_USB_OTG_HS;
+#ifndef USBH_IRQHandler
+#define USBH_IRQHandler OTG_HS_IRQHandler
+#endif
+#else
+HCD_HandleTypeDef hhcd_USB_OTG_FS;
+#ifndef USBH_IRQHandler
+#define USBH_IRQHandler OTG_FS_IRQHandler
+#endif
+#endif
+
 #define USBH_PID_SETUP 0U
 #define USBH_PID_DATA  1U
 
-#define USB_SNOPSYS_RETRY_COUNT 5
-
 #ifndef CONFIG_USBHOST_CHANNELS
 #define CONFIG_USBHOST_CHANNELS 12 /* Number of host channels */
 #endif
@@ -18,8 +28,11 @@
 
 struct usb_synopsys_chan {
     usb_osal_sem_t waitsem; /* Channel wait semaphore */
-    uint8_t chidx;          /* Channel index */
+    volatile int result;    /* The result of the transfer */
     bool inuse;             /* True: This channel is "in use" */
+    bool in;                /* True: IN endpoint */
+    volatile bool waiter;   /* True: Thread is waiting for a channel event */
+    volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */
 #ifdef CONFIG_USBHOST_ASYNCH
     usbh_asynch_callback_t callback; /* Transfer complete callback */
     void *arg;                       /* Argument that accompanies the callback */
@@ -90,6 +103,185 @@ static void usb_synopsys_chan_free(struct usb_synopsys_priv *priv, int chidx)
     priv->chan[chidx].inuse = false;
 }
 
+/****************************************************************************
+ * Name: usb_synopsys_chan_waitsetup
+ *
+ * Description:
+ *   Set the request for the transfer complete event well BEFORE enabling
+ *   the transfer (as soon as we are absolutely committed to the transfer).
+ *   We do this to minimize race conditions.  This logic would have to be
+ *   expanded if we want to have more than one packet in flight at a time!
+ *
+ * Assumptions:
+ *   Called from a normal thread context BEFORE the transfer has been
+ *   started.
+ *
+ ****************************************************************************/
+
+static int usb_synopsys_chan_waitsetup(struct usb_synopsys_priv *priv,
+                                       struct usb_synopsys_chan *chan)
+{
+    uint32_t flags;
+    int ret = -ENODEV;
+
+    flags = usb_osal_enter_critical_section();
+
+    /* Is the device still connected? */
+
+    if (priv->connected) {
+        /* Yes.. then set waiter to indicate that we expect to be informed
+       * when either (1) the device is disconnected, or (2) the transfer
+       * completed.
+       */
+
+        chan->waiter = true;
+#ifdef CONFIG_USBHOST_ASYNCH
+        chan->callback = NULL;
+        chan->arg = NULL;
+#endif
+        ret = 0;
+    }
+    usb_osal_leave_critical_section(flags);
+    return ret;
+}
+
+/****************************************************************************
+ * Name: usb_synopsys_chan_asynchsetup
+ *
+ * Description:
+ *   Set the request for the transfer complete event well BEFORE enabling
+ *   the transfer (as soon as we are absolutely committed to the to avoid
+ *   transfer).  We do this to minimize race conditions.  This logic would
+ *   have to be expanded if we want to have more than one packet in flight
+ *   at a time!
+ *
+ * Assumptions:
+ *   Might be called from the level of an interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static int usb_synopsys_chan_asynchsetup(struct usb_synopsys_priv *priv,
+                                         struct usb_synopsys_chan *chan,
+                                         usbh_asynch_callback_t callback, void *arg)
+{
+    uint32_t flags;
+    int ret = -ENODEV;
+
+    flags = usb_osal_enter_critical_section();
+    /* Is the device still connected? */
+
+    if (priv->connected) {
+        /* Yes.. then set waiter to indicate that we expect to be informed
+       * when either (1) the device is disconnected, or (2) the transfer
+       * completed.
+       */
+
+        chan->waiter = false;
+        chan->callback = callback;
+        chan->arg = arg;
+        ret = 0;
+    }
+
+    usb_osal_leave_critical_section(flags);
+    return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_chan_wait
+ *
+ * Description:
+ *   Wait for a transfer on a channel to complete.
+ *
+ * Assumptions:
+ *   Called from a normal thread context
+ *
+ ****************************************************************************/
+
+static int usb_synopsys_chan_wait(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan)
+{
+    int ret;
+
+    /* Loop, testing for an end of transfer condition.  The channel 'result'
+   * was set to EBUSY and 'waiter' was set to true before the transfer;
+   * 'waiter' will be set to false and 'result' will be set appropriately
+   * when the transfer is completed.
+   */
+
+    while (chan->waiter) {
+        usb_osal_sem_take(chan->waitsem);
+    }
+
+    /* The transfer is complete re-enable interrupts and return the result */
+    ret = chan->result;
+    return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_chan_wakeup
+ *
+ * Description:
+ *   A channel transfer has completed... wakeup any threads waiting for the
+ *   transfer to complete.
+ *
+ * Assumptions:
+ *   This function is called from the transfer complete interrupt handler for
+ *   the channel.  Interrupts are disabled.
+ *
+ ****************************************************************************/
+
+static void usb_synopsys_chan_wakeup(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan)
+{
+    usbh_asynch_callback_t callback;
+    void *arg;
+    int nbytes;
+
+    /* Is the transfer complete? */
+
+    if (chan->result != -EBUSY) {
+        /* Is there a thread waiting for this transfer to complete? */
+
+        if (chan->waiter) {
+            /* Wake'em up! */
+            chan->waiter = false;
+            usb_osal_sem_give(chan->waitsem);
+        }
+#ifdef CONFIG_USBHOST_ASYNCH
+        /* No.. is an asynchronous callback expected when the transfer
+       * completes?
+       */
+        else if (chan->callback) {
+            /* Handle continuation of IN/OUT pipes */
+            if (chan->in) {
+                callback = chan->callback;
+                arg = chan->arg;
+                nbytes = chan->xfrd;
+                chan->callback = NULL;
+                chan->arg = NULL;
+                if (chan->result < 0) {
+                    nbytes = chan->result;
+                }
+
+                callback(arg, nbytes);
+
+            } else {
+                callback = chan->callback;
+                arg = chan->arg;
+                nbytes = chan->xfrd;
+                chan->callback = NULL;
+                chan->arg = NULL;
+                if (chan->result < 0) {
+                    nbytes = chan->result;
+                }
+
+                callback(arg, nbytes);
+            }
+        }
+#endif
+    }
+}
+
 __WEAK void usb_hc_low_level_init(void)
 {
 }
@@ -97,12 +289,12 @@ __WEAK void usb_hc_low_level_init(void)
 int usb_hc_init(void)
 {
     memset(&g_usbhost, 0, sizeof(struct usb_synopsys_priv));
-#ifdef CONFIG_USB_HS
-    extern HCD_HandleTypeDef hhcd_USB_OTG_HS;
+#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL)
     g_usbhost.handle = &hhcd_USB_OTG_HS;
+    g_usbhost.handle->Instance = USB_OTG_HS;
 #else
-    extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
     g_usbhost.handle = &hhcd_USB_OTG_FS;
+    g_usbhost.handle->Instance = USB_OTG_FS;
 #endif
 
     g_usbhost.exclsem = usb_osal_mutex_create();
@@ -110,14 +302,23 @@ int usb_hc_init(void)
     for (uint8_t i = 0; i < CONFIG_USBHOST_CHANNELS; i++) {
         struct usb_synopsys_chan *chan = &g_usbhost.chan[i];
 
-        chan->chidx = i;
-
         /* The waitsem semaphore is used for signaling and, hence, should not
        * have priority inheritance enabled.
        */
         chan->waitsem = usb_osal_sem_create(0);
     }
-    usb_hc_low_level_init();
+
+    g_usbhost.handle->Init.Host_channels = CONFIG_USBHOST_CHANNELS;
+    g_usbhost.handle->Init.speed = HCD_SPEED_FULL;
+    g_usbhost.handle->Init.dma_enable = DISABLE;
+    g_usbhost.handle->Init.phy_itface = USB_OTG_EMBEDDED_PHY;
+    g_usbhost.handle->Init.Sof_enable = DISABLE;
+    g_usbhost.handle->Init.low_power_enable = DISABLE;
+    g_usbhost.handle->Init.vbus_sensing_enable = DISABLE;
+    g_usbhost.handle->Init.use_external_vbus = DISABLE;
+    if (HAL_HCD_Init(g_usbhost.handle) != HAL_OK) {
+        return -1;
+    }
     HAL_HCD_Start(g_usbhost.handle);
     return 0;
 }
@@ -168,6 +369,7 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
     struct usbh_hubport *hport;
     int chidx;
     int ret;
+    uint8_t speed;
 
     ret = usb_osal_mutex_take(g_usbhost.exclsem);
     if (ret < 0) {
@@ -176,27 +378,30 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
 
     hport = ep_cfg->hport;
 
-    if ((ep_cfg->ep_type & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_CONTROL) {
+    if (hport->speed == USB_SPEED_FULL) {
+        speed = HCD_SPEED_FULL;
+    } else if (hport->speed == USB_SPEED_LOW) {
+        speed = HCD_SPEED_LOW;
+    }
+
+    if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) {
         ep0 = usb_malloc(sizeof(struct usb_synopsys_ctrlinfo));
 
         ep0->outndx = usb_synopsys_chan_alloc(&g_usbhost);
         ep0->inndx = usb_synopsys_chan_alloc(&g_usbhost);
 
-        HAL_HCD_HC_Init(g_usbhost.handle, ep0->outndx, 0x00, hport->dev_addr, hport->speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
-        HAL_HCD_HC_Init(g_usbhost.handle, ep0->inndx, 0x80, hport->dev_addr, hport->speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
+        HAL_HCD_HC_Init(g_usbhost.handle, ep0->outndx, 0x00, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
+        HAL_HCD_HC_Init(g_usbhost.handle, ep0->inndx, 0x80, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
 
         *ep = (usbh_epinfo_t)ep0;
 
     } else {
         chidx = usb_synopsys_chan_alloc(&g_usbhost);
-        HAL_HCD_HC_Init(g_usbhost.handle, chidx, ep_cfg->ep_addr, hport->dev_addr, hport->speed, ep_cfg->ep_type, ep_cfg->ep_mps);
-        if ((ep_cfg->ep_type & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) {
-            if (g_usbhost.handle->hc[chidx].ep_is_in) {
-                g_usbhost.handle->hc[chidx].toggle_in = 0;
-            } else {
-                g_usbhost.handle->hc[chidx].toggle_out = 0;
-            }
-        }
+        HAL_HCD_HC_Init(g_usbhost.handle, chidx, ep_cfg->ep_addr, hport->dev_addr, speed, ep_cfg->ep_type, ep_cfg->ep_mps);
+
+        g_usbhost.handle->hc[chidx].toggle_in = 0;
+        g_usbhost.handle->hc[chidx].toggle_out = 0;
+
         *ep = (usbh_epinfo_t)chidx;
     }
     usb_osal_mutex_give(g_usbhost.exclsem);
@@ -204,185 +409,97 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
 }
 int usbh_ep_free(usbh_epinfo_t ep)
 {
+    uint8_t chidx = (uint8_t)ep;
+    usb_synopsys_chan_free(&g_usbhost, chidx);
     return 0;
 }
 
 int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint8_t *buffer)
 {
-    uint8_t retries;
     int ret;
+    uint32_t flags;
+    struct usb_synopsys_chan *chan;
+    struct usb_synopsys_priv *priv = &g_usbhost;
     struct usb_synopsys_ctrlinfo *ep0info = (struct usb_synopsys_ctrlinfo *)ep;
 
     ret = usb_osal_mutex_take(g_usbhost.exclsem);
     if (ret < 0) {
         return ret;
     }
-    for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-        ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                       ep0info->outndx,  /* Pipe index       */
-                                       0,                /* Direction : OUT  */
-                                       0,                /* EP type          */
-                                       USBH_PID_SETUP,   /* Type Data        */
-                                       (uint8_t *)setup, /* data buffer      */
-                                       8,                /* data length      */
-                                       0);               /* do ping (HS Only)*/
-
-        ret = usb_osal_sem_take(g_usbhost.chan[ep0info->outndx].waitsem);
-        if (ret < 0) {
-            goto errout_with_mutex;
-        }
-        usb_osal_msleep(5);
-        if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_NOTREADY) {
-            ret = -EAGAIN;
-            continue;
-        } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_STALL) {
-            ret = -EPERM;
-            goto errout_with_mutex;
-        } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_ERROR) {
-            ret = -EIO;
-            goto errout_with_mutex;
-        } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_DONE) {
-            break;
-        }
-    }
-    if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-        ret = -ETIMEDOUT;
+
+    flags = usb_osal_enter_critical_section();
+    chan = &priv->chan[ep0info->outndx];
+    usb_synopsys_chan_waitsetup(priv, chan);
+    ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                   ep0info->outndx,  /* Pipe index       */
+                                   0,                /* Direction : OUT  */
+                                   0,                /* EP type          */
+                                   USBH_PID_SETUP,   /* Type Data        */
+                                   (uint8_t *)setup, /* data buffer      */
+                                   8,                /* data length      */
+                                   0);               /* do ping (HS Only)*/
+    usb_osal_leave_critical_section(flags);
+
+    ret = usb_synopsys_chan_wait(priv, chan);
+    if (ret < 0) {
         goto errout_with_mutex;
     }
-
     if (setup->wLength && buffer) {
         if (setup->bmRequestType & 0x80) {
-            for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-                ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                               ep0info->inndx, /* Pipe index       */
-                                               1,              /* Direction : IN  */
-                                               0,              /* EP type          */
-                                               USBH_PID_DATA,  /* Type Data        */
-                                               buffer,         /* data buffer      */
-                                               setup->wLength, /* data length      */
-                                               0);             /* do ping (HS Only)*/
-                usb_osal_sem_take(g_usbhost.chan[ep0info->inndx].waitsem);
-                if (ret < 0) {
-                    goto errout_with_mutex;
-                }
-                usb_osal_msleep(5);
-                if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_NOTREADY) {
-                    ret = -EAGAIN;
-                    continue;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_STALL) {
-                    ret = -EPERM;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_ERROR) {
-                    ret = -EIO;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_DONE) {
-                    break;
-                }
-            }
-            if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-                ret = -ETIMEDOUT;
+            flags = usb_osal_enter_critical_section();
+            chan = &priv->chan[ep0info->inndx];
+            usb_synopsys_chan_waitsetup(priv, chan);
+            ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                           ep0info->inndx, /* Pipe index       */
+                                           1,              /* Direction : IN  */
+                                           0,              /* EP type          */
+                                           USBH_PID_DATA,  /* Type Data        */
+                                           buffer,         /* data buffer      */
+                                           setup->wLength, /* data length      */
+                                           0);             /* do ping (HS Only)*/
+            usb_osal_leave_critical_section(flags);
+            ret = usb_synopsys_chan_wait(priv, chan);
+            if (ret < 0) {
                 goto errout_with_mutex;
             }
-            for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-                ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                               ep0info->outndx, /* Pipe index       */
-                                               0,               /* Direction : OUT  */
-                                               0,               /* EP type          */
-                                               USBH_PID_DATA,   /* Type Data        */
-                                               NULL,            /* data buffer      */
-                                               0,               /* data length      */
-                                               0);              /* do ping (HS Only)*/
-                usb_osal_sem_take(g_usbhost.chan[ep0info->outndx].waitsem);
-                if (ret < 0) {
-                    goto errout_with_mutex;
-                }
-                usb_osal_msleep(5);
-                if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_NOTREADY) {
-                    ret = -EAGAIN;
-                    continue;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_STALL) {
-                    ret = -EPERM;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_ERROR) {
-                    ret = -EIO;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_DONE) {
-                    break;
-                }
-            }
-            if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-                ret = -ETIMEDOUT;
+
+            flags = usb_osal_enter_critical_section();
+            chan = &priv->chan[ep0info->outndx];
+            usb_synopsys_chan_waitsetup(priv, chan);
+            ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                           ep0info->outndx, /* Pipe index       */
+                                           0,               /* Direction : OUT  */
+                                           0,               /* EP type          */
+                                           USBH_PID_DATA,   /* Type Data        */
+                                           NULL,            /* data buffer      */
+                                           0,               /* data length      */
+                                           0);              /* do ping (HS Only)*/
+            usb_osal_leave_critical_section(flags);
+            ret = usb_synopsys_chan_wait(priv, chan);
+            if (ret < 0) {
                 goto errout_with_mutex;
             }
         } else {
-            for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-                ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                               ep0info->outndx, /* Pipe index       */
-                                               0,               /* Direction : OUT  */
-                                               0,               /* EP type          */
-                                               USBH_PID_DATA,   /* Type Data        */
-                                               buffer,          /* data buffer      */
-                                               setup->wLength,  /* data length      */
-                                               0);              /* do ping (HS Only)*/
-
-                usb_osal_sem_take(g_usbhost.chan[ep0info->outndx].waitsem);
-                if (ret < 0) {
-                    goto errout_with_mutex;
-                }
-                usb_osal_msleep(5);
-                if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_NOTREADY) {
-                    ret = -EAGAIN;
-                    continue;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_STALL) {
-                    ret = -EPERM;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_ERROR) {
-                    ret = -EIO;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_DONE) {
-                    break;
-                }
-            }
-
-            if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-                ret = -ETIMEDOUT;
+            flags = usb_osal_enter_critical_section();
+            chan = &priv->chan[ep0info->outndx];
+            usb_synopsys_chan_waitsetup(priv, chan);
+            ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                           ep0info->outndx, /* Pipe index       */
+                                           0,               /* Direction : OUT  */
+                                           0,               /* EP type          */
+                                           USBH_PID_DATA,   /* Type Data        */
+                                           buffer,          /* data buffer      */
+                                           setup->wLength,  /* data length      */
+                                           0);              /* do ping (HS Only)*/
+            usb_osal_leave_critical_section(flags);
+            ret = usb_synopsys_chan_wait(priv, chan);
+            if (ret < 0) {
                 goto errout_with_mutex;
             }
-            for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-                ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                               ep0info->inndx, /* Pipe index       */
-                                               1,              /* Direction : IN  */
-                                               0,              /* EP type          */
-                                               USBH_PID_DATA,  /* Type Data        */
-                                               NULL,           /* data buffer      */
-                                               0,              /* data length      */
-                                               0);             /* do ping (HS Only)*/
-                usb_osal_sem_take(g_usbhost.chan[ep0info->inndx].waitsem);
-                if (ret < 0) {
-                    goto errout_with_mutex;
-                }
-                usb_osal_msleep(5);
-                if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_NOTREADY) {
-                    ret = -EAGAIN;
-                    continue;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_STALL) {
-                    ret = -EPERM;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_ERROR) {
-                    ret = -EIO;
-                    goto errout_with_mutex;
-                } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_DONE) {
-                    break;
-                }
-            }
 
-            if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-                ret = -ETIMEDOUT;
-                goto errout_with_mutex;
-            }
-        }
-    } else {
-        for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
+            flags = usb_osal_enter_critical_section();
+            chan = &priv->chan[ep0info->inndx];
+            usb_synopsys_chan_waitsetup(priv, chan);
             ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
                                            ep0info->inndx, /* Pipe index       */
                                            1,              /* Direction : IN  */
@@ -391,26 +508,27 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
                                            NULL,           /* data buffer      */
                                            0,              /* data length      */
                                            0);             /* do ping (HS Only)*/
-            usb_osal_sem_take(g_usbhost.chan[ep0info->inndx].waitsem);
+            usb_osal_leave_critical_section(flags);
+            ret = usb_synopsys_chan_wait(priv, chan);
             if (ret < 0) {
                 goto errout_with_mutex;
             }
-            usb_osal_msleep(10);
-            if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_NOTREADY) {
-                ret = -EAGAIN;
-                continue;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_STALL) {
-                ret = -EPERM;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_ERROR) {
-                ret = -EIO;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_DONE) {
-                break;
-            }
         }
-        if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-            ret = -ETIMEDOUT;
+    } else {
+        flags = usb_osal_enter_critical_section();
+        chan = &priv->chan[ep0info->inndx];
+        usb_synopsys_chan_waitsetup(priv, chan);
+        ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                       ep0info->inndx, /* Pipe index       */
+                                       1,              /* Direction : IN  */
+                                       0,              /* EP type          */
+                                       USBH_PID_DATA,  /* Type Data        */
+                                       NULL,           /* data buffer      */
+                                       0,              /* data length      */
+                                       0);             /* do ping (HS Only)*/
+        usb_osal_leave_critical_section(flags);
+        ret = usb_synopsys_chan_wait(priv, chan);
+        if (ret < 0) {
             goto errout_with_mutex;
         }
     }
@@ -420,84 +538,39 @@ errout_with_mutex:
     usb_osal_mutex_give(g_usbhost.exclsem);
     return ret;
 }
+
 int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
 {
-    uint8_t retries;
     int ret;
+    uint32_t flags;
+    struct usb_synopsys_chan *chan;
+    struct usb_synopsys_priv *priv = &g_usbhost;
     uint8_t chidx = (uint8_t)ep;
 
     ret = usb_osal_mutex_take(g_usbhost.exclsem);
     if (ret < 0) {
         return ret;
     }
-    if (g_usbhost.handle->hc[chidx].ep_is_in) {
-        for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-            ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                           chidx,         /* Pipe index       */
-                                           1,             /* Direction : IN  */
-                                           2,             /* EP type          */
-                                           USBH_PID_DATA, /* Type Data        */
-                                           buffer,        /* data buffer      */
-                                           buflen,        /* data length      */
-                                           0);            /* do ping (HS Only)*/
-
-            usb_osal_sem_take(g_usbhost.chan[chidx].waitsem);
-            if (ret < 0) {
-                goto errout_with_mutex;
-            }
-            usb_osal_msleep(10);
-            if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) {
-                ret = -EAGAIN;
-                continue;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) {
-                ret = -EPERM;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) {
-                ret = -EIO;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) {
-                break;
-            }
-        }
-        if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-            ret = -ETIMEDOUT;
-            goto errout_with_mutex;
-        }
-    } else {
-        for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-            ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                           chidx,         /* Pipe index       */
-                                           0,             /* Direction : OUT  */
-                                           2,             /* EP type          */
-                                           USBH_PID_DATA, /* Type Data        */
-                                           buffer,        /* data buffer      */
-                                           buflen,        /* data length      */
-                                           1);            /* do ping (HS Only)*/
-            usb_osal_sem_take(g_usbhost.chan[chidx].waitsem);
-            if (ret < 0) {
-                goto errout_with_mutex;
-            }
-            usb_osal_msleep(10);
-            if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) {
-                ret = -EAGAIN;
-                continue;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) {
-                ret = -EPERM;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) {
-                ret = -EIO;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) {
-                break;
-            }
-        }
-        if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-            ret = -ETIMEDOUT;
-            goto errout_with_mutex;
-        }
+
+    flags = usb_osal_enter_critical_section();
+    chan = &priv->chan[chidx];
+    usb_synopsys_chan_waitsetup(priv, chan);
+    ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                   chidx,                                        /* Pipe index       */
+                                   g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN  */
+                                   2,                                            /* EP type          */
+                                   USBH_PID_DATA,                                /* Type Data        */
+                                   buffer,                                       /* data buffer      */
+                                   buflen,                                       /* data length      */
+                                   0);                                           /* do ping (HS Only)*/
+    usb_osal_leave_critical_section(flags);
+    ret = usb_synopsys_chan_wait(priv, chan);
+    if (ret < 0) {
+        goto errout_with_mutex;
     }
+
     usb_osal_mutex_give(g_usbhost.exclsem);
-    return HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx);
+    return g_usbhost.handle->hc[chidx].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx) : buflen;
 errout_with_mutex:
     usb_osal_mutex_give(g_usbhost.exclsem);
     return ret;
@@ -505,82 +578,35 @@ errout_with_mutex:
 
 int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
 {
-    uint8_t retries;
+    uint32_t flags;
     int ret;
+    struct usb_synopsys_chan *chan;
+    struct usb_synopsys_priv *priv = &g_usbhost;
     uint8_t chidx = (uint8_t)ep;
 
     ret = usb_osal_mutex_take(g_usbhost.exclsem);
     if (ret < 0) {
         return ret;
     }
-    if (g_usbhost.handle->hc[chidx].ep_is_in) {
-        for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-            ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                           chidx,         /* Pipe index       */
-                                           1,             /* Direction : IN  */
-                                           3,             /* EP type          */
-                                           USBH_PID_DATA, /* Type Data        */
-                                           buffer,        /* data buffer      */
-                                           buflen,        /* data length      */
-                                           0);            /* do ping (HS Only)*/
-
-            usb_osal_sem_take(g_usbhost.chan[chidx].waitsem);
-            if (ret < 0) {
-                goto errout_with_mutex;
-            }
-            usb_osal_msleep(10);
-            if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) {
-                ret = -EAGAIN;
-                continue;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) {
-                ret = -EPERM;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) {
-                ret = -EIO;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) {
-                break;
-            }
-        }
-        if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-            ret = -ETIMEDOUT;
-            goto errout_with_mutex;
-        }
-    } else {
-        for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) {
-            ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
-                                           chidx,         /* Pipe index       */
-                                           0,             /* Direction : OUT  */
-                                           3,             /* EP type          */
-                                           USBH_PID_DATA, /* Type Data        */
-                                           buffer,        /* data buffer      */
-                                           buflen,        /* data length      */
-                                           1);            /* do ping (HS Only)*/
-            usb_osal_sem_take(g_usbhost.chan[chidx].waitsem);
-            if (ret < 0) {
-                goto errout_with_mutex;
-            }
-            usb_osal_msleep(10);
-            if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) {
-                ret = -EAGAIN;
-                continue;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) {
-                ret = -EPERM;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) {
-                ret = -EIO;
-                goto errout_with_mutex;
-            } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) {
-                break;
-            }
-        }
-        if (retries >= USB_SNOPSYS_RETRY_COUNT) {
-            ret = -ETIMEDOUT;
-            goto errout_with_mutex;
-        }
+    flags = usb_osal_enter_critical_section();
+    chan = &priv->chan[chidx];
+    usb_synopsys_chan_waitsetup(priv, chan);
+    ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                   chidx,                                        /* Pipe index       */
+                                   g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN  */
+                                   3,                                            /* EP type          */
+                                   USBH_PID_DATA,                                /* Type Data        */
+                                   buffer,                                       /* data buffer      */
+                                   buflen,                                       /* data length      */
+                                   0);                                           /* do ping (HS Only)*/
+    usb_osal_leave_critical_section(flags);
+    ret = usb_synopsys_chan_wait(priv, chan);
+    if (ret < 0) {
+        goto errout_with_mutex;
     }
+
     usb_osal_mutex_give(g_usbhost.exclsem);
-    return HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx);
+    return g_usbhost.handle->hc[chidx].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx) : buflen;
 errout_with_mutex:
     usb_osal_mutex_give(g_usbhost.exclsem);
     return ret;
@@ -588,12 +614,64 @@ errout_with_mutex:
 
 int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
 {
-    return 0;
+    int ret;
+    uint32_t flags;
+    struct usb_synopsys_chan *chan;
+    struct usb_synopsys_priv *priv = &g_usbhost;
+    uint8_t chidx = (uint8_t)ep;
+
+    ret = usb_osal_mutex_take(g_usbhost.exclsem);
+    if (ret < 0) {
+        return ret;
+    }
+
+    flags = usb_osal_enter_critical_section();
+    chan = &priv->chan[chidx];
+    usb_synopsys_chan_asynchsetup(priv, chan, callback, arg);
+    ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                   chidx,                                        /* Pipe index       */
+                                   g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN  */
+                                   2,                                            /* EP type          */
+                                   USBH_PID_DATA,                                /* Type Data        */
+                                   buffer,                                       /* data buffer      */
+                                   buflen,                                       /* data length      */
+                                   0);                                           /* do ping (HS Only)*/
+    usb_osal_leave_critical_section(flags);
+
+    usb_osal_mutex_give(g_usbhost.exclsem);
+
+    return ret;
 }
 
 int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
 {
-    return 0;
+    int ret;
+    uint32_t flags;
+    struct usb_synopsys_chan *chan;
+    struct usb_synopsys_priv *priv = &g_usbhost;
+    uint8_t chidx = (uint8_t)ep;
+
+    ret = usb_osal_mutex_take(g_usbhost.exclsem);
+    if (ret < 0) {
+        return ret;
+    }
+
+    flags = usb_osal_enter_critical_section();
+    chan = &priv->chan[chidx];
+    usb_synopsys_chan_asynchsetup(priv, chan, callback, arg);
+    ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                   chidx,                                        /* Pipe index       */
+                                   g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN  */
+                                   3,                                            /* EP type          */
+                                   USBH_PID_DATA,                                /* Type Data        */
+                                   buffer,                                       /* data buffer      */
+                                   buflen,                                       /* data length      */
+                                   0);                                           /* do ping (HS Only)*/
+    usb_osal_leave_critical_section(flags);
+
+    usb_osal_mutex_give(g_usbhost.exclsem);
+
+    return ret;
 }
 
 int usb_ep_cancel(usbh_epinfo_t ep)
@@ -627,5 +705,45 @@ void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
 
 void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
 {
-    usb_osal_sem_give(g_usbhost.chan[chnum].waitsem);
-}
+    struct usb_synopsys_chan *chan;
+    struct usb_synopsys_priv *priv = &g_usbhost;
+
+    chan = &priv->chan[chnum];
+    if (urb_state == URB_DONE || urb_state == URB_STALL || urb_state == URB_ERROR || urb_state == URB_NOTREADY) {
+        if (urb_state != URB_NOTREADY) {
+            if (urb_state == URB_ERROR) {
+                chan->result = -EIO;
+                HAL_HCD_HC_Halt(hhcd, chnum);
+            } else if (urb_state == URB_STALL) {
+                chan->result = -EPERM;
+            } else if (urb_state == URB_DONE) {
+                chan->result = 0;
+            }
+            chan->in = g_usbhost.handle->hc[chnum].ep_is_in;
+            chan->xfrd = g_usbhost.handle->hc[chnum].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chnum) : g_usbhost.handle->hc[chnum].xfer_len;
+            usb_synopsys_chan_wakeup(priv, chan);
+        } else {
+            if (g_usbhost.handle->hc[chnum].ep_is_in == 0 && (g_usbhost.handle->hc[chnum].ep_type == USB_ENDPOINT_TYPE_CONTROL || g_usbhost.handle->hc[chnum].ep_type == USB_ENDPOINT_TYPE_BULK)) {
+                HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
+                                         chnum,                                 /* Pipe index       */
+                                         0,                                     /* Direction : OUT  */
+                                         g_usbhost.handle->hc[chnum].ep_type,   /* EP type          */
+                                         USBH_PID_DATA,                         /* Type Data        */
+                                         g_usbhost.handle->hc[chnum].xfer_buff, /* data buffer      */
+                                         g_usbhost.handle->hc[chnum].xfer_len,  /* data length      */
+                                         0);                                    /* do ping (HS Only)*/
+            }
+        }
+    }
+}
+
+void USBH_IRQHandler(void)
+{
+    /* USER CODE BEGIN OTG_HS_IRQn 0 */
+
+    /* USER CODE END OTG_HS_IRQn 0 */
+    HAL_HCD_IRQHandler(g_usbhost.handle);
+    /* USER CODE BEGIN OTG_HS_IRQn 1 */
+
+    /* USER CODE END OTG_HS_IRQn 1 */
+}