Răsfoiți Sursa

refactor usb host stack: hcd api, hub process and usb no cache ram process

sakumisu 3 ani în urmă
părinte
comite
62d0000926
46 a modificat fișierele cu 2359 adăugiri și 3184 ștergeri
  1. 0 1
      .gitignore
  2. 24 13
      cherryusb_config_template.h
  3. 31 50
      class/cdc/usbh_cdc_acm.c
  4. 4 4
      class/cdc/usbh_cdc_acm.h
  5. 32 23
      class/hid/usbh_hid.c
  6. 3 2
      class/hid/usbh_hid.h
  7. 320 215
      class/hub/usbh_hub.c
  8. 4 0
      class/hub/usbh_hub.h
  9. 50 59
      class/msc/usbh_msc.c
  10. 4 5
      class/msc/usbh_msc.h
  11. 6 12
      class/mtp/usbh_mtp.c
  12. 3 3
      class/mtp/usbh_mtp.h
  13. 8 14
      class/printer/usbh_printer.c
  14. 2 2
      class/printer/usbh_printer.h
  15. 4 10
      class/template/usbh_xxx.c
  16. 2 2
      class/template/usbh_xxx.h
  17. 3 3
      class/vendor/axusbnet.c
  18. 3 3
      class/vendor/axusbnet.h
  19. 4 4
      class/vendor/usbh_air724.c
  20. 10 16
      class/wireless/usbh_rndis.c
  21. 3 3
      class/wireless/usbh_rndis.h
  22. 43 130
      common/usb_hc.h
  23. 18 15
      common/usb_list.h
  24. 264 478
      core/usbh_core.c
  25. 144 45
      core/usbh_core.h
  26. 4 4
      demo/es32/usb_device/ES32F369x/MDK-ARM/example.uvoptx
  27. 4 4
      demo/es32/usb_device/ES32F369x/MDK-ARM/example.uvprojx
  28. 24 13
      demo/es32/usb_host/ES32F369x/Inc/usb_config.h
  29. 143 26
      demo/es32/usb_host/ES32F369x/MDK-ARM/example.uvoptx
  30. 0 5
      demo/es32/usb_host/ES32F369x/MDK-ARM/example.uvprojx
  31. 2 1
      demo/es32/usb_host/ES32F369x/Src/main.c
  32. 56 41
      demo/stm32/usb_host/stm32f429igt6/Core/Inc/usb_config.h
  33. 3 2
      demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c
  34. 39 47
      demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx
  35. 11 1
      demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx
  36. 56 41
      demo/stm32/usb_host/stm32h743xih6/Core/Inc/usb_config.h
  37. 7 15
      demo/stm32/usb_host/stm32h743xih6/Core/Src/main.c
  38. 26 2
      demo/stm32/usb_host/stm32h743xih6/MDK-ARM/stm32h743xih6.uvoptx
  39. 17 7
      demo/stm32/usb_host/stm32h743xih6/MDK-ARM/stm32h743xih6.uvprojx
  40. 19 0
      demo/stm32/usb_host/stm32h743xih6/MDK-ARM/stm32h743xih6/stm32h743xih6.sct
  41. 32 12
      demo/usb_host.c
  42. 5 0
      port/dwc2/usb_dc_dwc2.c
  43. 329 456
      port/dwc2/usb_hc_dwc2.c
  44. 190 793
      port/ehci/usb_hc_ehci.h
  45. 5 0
      port/musb/usb_dc_musb.c
  46. 398 602
      port/musb/usb_hc_musb.c

+ 0 - 1
.gitignore

@@ -15,7 +15,6 @@
 *.iex
 *.lst
 *.axf
-*.sct
 *.hex
 *.Bak
 *.uvguix.*

+ 24 - 13
cherryusb_config_template.h

@@ -16,17 +16,25 @@
 #define CONFIG_USB_PRINTF printf
 #endif
 
-/* attribute data into no cache ram */
-// #define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
 /* Enable print with color */
 #define CONFIG_USB_PRINTF_COLOR_ENABLE
 
+/* data align size when use dma */
+#ifndef CONFIG_USB_ALIGN_SIZE
+#define CONFIG_USB_ALIGN_SIZE 4
+#endif
+
+/* attribute data into no cache ram */
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
+
 /* ================ USB DEVICE Configuration ================*/
 
 /* core */
 
 /* Ep0 max transfer buffer, specially for receiving data from ep0 out */
+#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
 #define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
+#endif
 /* Setup packet log for debug */
 // #define CONFIG_USBDEV_SETUP_LOG_PRINT
 /* Check if the input descriptor is correct */
@@ -79,6 +87,11 @@
 #endif
 
 /* ================ USB HOST Configuration ================ */
+/* core */
+/* Ep0 max transfer buffer */
+#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
+#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
+#endif
 
 #ifndef CONFIG_USBHOST_RHPORTS
 #define CONFIG_USBHOST_RHPORTS 1
@@ -88,10 +101,6 @@
 #define CONFIG_USBHOST_EHPORTS 4
 #endif
 
-#ifndef CONFIG_USBHOST_PIPE_NUM
-#define CONFIG_USBHOST_PIPE_NUM 10
-#endif
-
 #ifndef CONFIG_USBHOST_INTF_NUM
 #define CONFIG_USBHOST_INTF_NUM 6
 #endif
@@ -101,7 +110,7 @@
 #endif
 
 #ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
-#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 5000
+#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
 #endif
 
 #ifndef CONFIG_USBHOST_MSC_TIMEOUT
@@ -112,22 +121,24 @@
 #define CONFIG_USBHOST_PSC_PRIO 4
 #endif
 #ifndef CONFIG_USBHOST_PSC_STACKSIZE
-#define CONFIG_USBHOST_PSC_STACKSIZE 4096
+#define CONFIG_USBHOST_PSC_STACKSIZE 2048
 #endif
 
 #ifndef CONFIG_USBHOST_DEV_NAMELEN
 #define CONFIG_USBHOST_DEV_NAMELEN 16
 #endif
 
-#define CONFIG_USBHOST_ASYNCH
 //#define CONFIG_USBHOST_GET_STRING_DESC
 
+#ifndef CONFIG_USBHOST_PIPE_NUM
+#define CONFIG_USBHOST_PIPE_NUM 10
+#endif
+
 /* ================ EHCI Configuration ================ */
 
-#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
-#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
-#define CONFIG_USB_EHCI_QH_NUM    (10)
-#define CONFIG_USB_EHCI_QTD_NUM   (10)
+#define CONFIG_USB_EHCI_HCCR_BASE   (0x20072000)
+#define CONFIG_USB_EHCI_HCOR_BASE   (0x20072000 + 0x10)
+#define CONFIG_EHCI_FRAME_LIST_SIZE 1024
 // #define CONFIG_USB_EHCI_INFO_ENABLE
 // #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
 // #define CONFIG_USB_EHCI_CONFIGFLAG

+ 31 - 50
class/cdc/usbh_cdc_acm.c

@@ -10,6 +10,8 @@
 
 static uint32_t g_devinuse = 0;
 
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct cdc_line_coding g_cdc_line_coding;
+
 /****************************************************************************
  * Name: usbh_cdc_acm_devno_alloc
  *
@@ -59,8 +61,7 @@ static void usbh_cdc_acm_devno_free(struct usbh_cdc_acm *cdc_acm_class)
 
 int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
 {
-    struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
-    int ret;
+    struct usb_setup_packet *setup = &cdc_acm_class->hport->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
     setup->bRequest = CDC_REQUEST_SET_LINE_CODING;
@@ -68,17 +69,14 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
     setup->wIndex = cdc_acm_class->ctrl_intf;
     setup->wLength = 7;
 
-    ret = usbh_control_transfer(cdc_acm_class->hport->ep0, setup, (uint8_t *)line_coding);
-    if (ret < 0) {
-        return ret;
-    }
-    memcpy(cdc_acm_class->linecoding, line_coding, sizeof(struct cdc_line_coding));
-    return 0;
+    memcpy((uint8_t *)&g_cdc_line_coding, line_coding, sizeof(struct cdc_line_coding));
+
+    return usbh_control_transfer(cdc_acm_class->hport->ep0, setup, (uint8_t *)&g_cdc_line_coding);
 }
 
 int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
 {
-    struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
+    struct usb_setup_packet *setup = &cdc_acm_class->hport->setup;
     int ret;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -87,18 +85,17 @@ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
     setup->wIndex = cdc_acm_class->ctrl_intf;
     setup->wLength = 7;
 
-    ret = usbh_control_transfer(cdc_acm_class->hport->ep0, setup, (uint8_t *)line_coding);
+    ret = usbh_control_transfer(cdc_acm_class->hport->ep0, setup, (uint8_t *)&g_cdc_line_coding);
     if (ret < 0) {
         return ret;
     }
-    memcpy(cdc_acm_class->linecoding, line_coding, sizeof(struct cdc_line_coding));
-    return 0;
+    memcpy(line_coding, (uint8_t *)&g_cdc_line_coding, sizeof(struct cdc_line_coding));
+    return ret;
 }
 
 int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts)
 {
-    struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
-    int ret;
+    struct usb_setup_packet *setup = &cdc_acm_class->hport->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
     setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE;
@@ -106,15 +103,10 @@ int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bo
     setup->wIndex = cdc_acm_class->ctrl_intf;
     setup->wLength = 0;
 
-    ret = usbh_control_transfer(cdc_acm_class->hport->ep0, setup, NULL);
-    if (ret < 0) {
-        return ret;
-    }
-
     cdc_acm_class->dtr = dtr;
     cdc_acm_class->rts = rts;
 
-    return 0;
+    return usbh_control_transfer(cdc_acm_class->hport->ep0, setup, NULL);
 }
 
 static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
@@ -138,17 +130,11 @@ static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
     hport->config.intf[intf].priv = cdc_acm_class;
     hport->config.intf[intf + 1].priv = NULL;
 
-    cdc_acm_class->linecoding = usb_iomalloc(sizeof(struct cdc_line_coding));
-    if (cdc_acm_class->linecoding == NULL) {
-        USB_LOG_ERR("Fail to alloc linecoding\r\n");
-        return -ENOMEM;
-    }
-
-    cdc_acm_class->linecoding->dwDTERate = 115200;
-    cdc_acm_class->linecoding->bDataBits = 8;
-    cdc_acm_class->linecoding->bParityType = 0;
-    cdc_acm_class->linecoding->bCharFormat = 0;
-    ret = usbh_cdc_acm_set_line_coding(cdc_acm_class, cdc_acm_class->linecoding);
+    cdc_acm_class->linecoding.dwDTERate = 115200;
+    cdc_acm_class->linecoding.bDataBits = 8;
+    cdc_acm_class->linecoding.bParityType = 0;
+    cdc_acm_class->linecoding.bCharFormat = 0;
+    ret = usbh_cdc_acm_set_line_coding(cdc_acm_class, &cdc_acm_class->linecoding);
     if (ret < 0) {
         USB_LOG_ERR("Fail to set linecoding\r\n");
         return ret;
@@ -167,7 +153,7 @@ static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
     ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
     ep_cfg.ep_interval = ep_desc->bInterval;
     ep_cfg.hport = hport;
-    usbh_ep_alloc(&cdc_acm_class->intin, &ep_cfg);
+    usbh_pipe_alloc(&cdc_acm_class->intin, &ep_cfg);
 
 #endif
     for (uint8_t i = 0; i < hport->config.intf[intf + 1].intf_desc.bNumEndpoints; i++) {
@@ -175,14 +161,20 @@ static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
 
         ep_cfg.ep_addr = ep_desc->bEndpointAddress;
         ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
-        ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
+        ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&cdc_acm_class->bulkin, &ep_cfg);
+            usbh_pipe_alloc(&cdc_acm_class->bulkin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&cdc_acm_class->bulkout, &ep_cfg);
+            usbh_pipe_alloc(&cdc_acm_class->bulkout, &ep_cfg);
         }
+
+        USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u\r\n",
+                     ep_desc->bEndpointAddress,
+                     ep_desc->bmAttributes,
+                     ep_desc->wMaxPacketSize,
+                     ep_desc->bInterval);
     }
 
     snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, cdc_acm_class->minor);
@@ -199,33 +191,22 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
     struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv;
 
     if (cdc_acm_class) {
+
         usbh_cdc_acm_devno_free(cdc_acm_class);
 
         if (cdc_acm_class->bulkin) {
-            ret = usb_ep_cancel(cdc_acm_class->bulkin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(cdc_acm_class->bulkin);
+            usbh_pipe_free(cdc_acm_class->bulkin);
         }
 
         if (cdc_acm_class->bulkout) {
-            ret = usb_ep_cancel(cdc_acm_class->bulkout);
-            if (ret < 0) {
-            }
-            usbh_ep_free(cdc_acm_class->bulkout);
+            usbh_pipe_free(cdc_acm_class->bulkout);
         }
 
-        if (cdc_acm_class->linecoding)
-            usb_iofree(cdc_acm_class->linecoding);
-
+        memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
         usb_free(cdc_acm_class);
 
         if (hport->config.intf[intf].devname[0] != '\0')
             USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname);
-
-        memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN);
-        hport->config.intf[intf].priv = NULL;
-        hport->config.intf[intf + 1].priv = NULL;
     }
 
     return ret;

+ 4 - 4
class/cdc/usbh_cdc_acm.h

@@ -11,16 +11,16 @@
 struct usbh_cdc_acm {
     struct usbh_hubport *hport;
 
-    struct cdc_line_coding *linecoding;
+    struct cdc_line_coding linecoding;
     uint8_t ctrl_intf; /* Control interface number */
     uint8_t data_intf; /* Data interface number */
     bool dtr;
     bool rts;
     uint8_t minor;
-    usbh_epinfo_t bulkin;  /* Bulk IN endpoint */
-    usbh_epinfo_t bulkout; /* Bulk OUT endpoint */
+    usbh_pipe_t bulkin;  /* Bulk IN endpoint */
+    usbh_pipe_t bulkout; /* Bulk OUT endpoint */
 #ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY
-    usbh_epinfo_t intin; /* Interrupt IN endpoint (optional) */
+    usbh_pipe_t intin; /* Interrupt IN endpoint (optional) */
 #endif
 };
 

+ 32 - 23
class/hid/usbh_hid.c

@@ -10,6 +10,8 @@
 
 static uint32_t g_devinuse = 0;
 
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[128];
+
 /****************************************************************************
  * Name: usbh_hid_devno_alloc
  *
@@ -59,7 +61,8 @@ static void usbh_hid_devno_free(struct usbh_hid *hid_class)
 
 static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer)
 {
-    struct usb_setup_packet *setup = hid_class->hport->setup;
+    struct usb_setup_packet *setup = &hid_class->hport->setup;
+    int ret;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
@@ -67,12 +70,17 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b
     setup->wIndex = hid_class->intf;
     setup->wLength = 128;
 
-    return usbh_control_transfer(hid_class->hport->ep0, setup, buffer);
+    ret = usbh_control_transfer(hid_class->hport->ep0, setup, g_hid_buf);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(buffer, g_hid_buf, ret - 8);
+    return ret;
 }
 
 int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration)
 {
-    struct usb_setup_packet *setup = hid_class->hport->setup;
+    struct usb_setup_packet *setup = &hid_class->hport->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
     setup->bRequest = HID_REQUEST_SET_IDLE;
@@ -85,7 +93,8 @@ int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t dur
 
 int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
 {
-    struct usb_setup_packet *setup = hid_class->hport->setup;
+    struct usb_setup_packet *setup = &hid_class->hport->setup;
+    int ret;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
     setup->bRequest = HID_REQUEST_GET_IDLE;
@@ -93,7 +102,12 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
     setup->wIndex = hid_class->intf;
     setup->wLength = 1;
 
-    return usbh_control_transfer(hid_class->hport->ep0, setup, buffer);
+    ret = usbh_control_transfer(hid_class->hport->ep0, setup, g_hid_buf);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(buffer, g_hid_buf, 1);
+    return ret;
 }
 
 int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
@@ -120,26 +134,29 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
         return ret;
     }
 
-    uint8_t *report_buffer = usb_iomalloc(128);
-    ret = usbh_hid_get_report_descriptor(hid_class, report_buffer);
+    ret = usbh_hid_get_report_descriptor(hid_class, hid_class->report_desc);
     if (ret < 0) {
-        usb_iofree(report_buffer);
         return ret;
     }
-    usb_iofree(report_buffer);
 
     for (uint8_t i = 0; i < hport->config.intf[intf].intf_desc.bNumEndpoints; i++) {
         ep_desc = &hport->config.intf[intf].ep[i].ep_desc;
         ep_cfg.ep_addr = ep_desc->bEndpointAddress;
         ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
-        ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
+        ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&hid_class->intin, &ep_cfg);
+            usbh_pipe_alloc(&hid_class->intin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&hid_class->intout, &ep_cfg);
+            usbh_pipe_alloc(&hid_class->intout, &ep_cfg);
         }
+
+        USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u\r\n",
+                     ep_desc->bEndpointAddress,
+                     ep_desc->bmAttributes,
+                     ep_desc->wMaxPacketSize,
+                     ep_desc->bInterval);
     }
 
     snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hid_class->minor);
@@ -159,26 +176,18 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
         usbh_hid_devno_free(hid_class);
 
         if (hid_class->intin) {
-            ret = usb_ep_cancel(hid_class->intin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(hid_class->intin);
+            usbh_pipe_free(hid_class->intin);
         }
 
         if (hid_class->intout) {
-            ret = usb_ep_cancel(hid_class->intout);
-            if (ret < 0) {
-            }
-            usbh_ep_free(hid_class->intout);
+            usbh_pipe_free(hid_class->intout);
         }
 
+        memset(hid_class, 0, sizeof(struct usbh_hid));
         usb_free(hid_class);
 
         if (hport->config.intf[intf].devname[0] != '\0')
             USB_LOG_INFO("Unregister HID Class:%s\r\n", hport->config.intf[intf].devname);
-
-        memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN);
-        hport->config.intf[intf].priv = NULL;
     }
 
     return ret;

+ 3 - 2
class/hid/usbh_hid.h

@@ -11,10 +11,11 @@
 struct usbh_hid {
     struct usbh_hubport *hport;
 
+    uint8_t report_desc[128];
     uint8_t intf; /* interface number */
     uint8_t minor;
-    usbh_epinfo_t intin;  /* INTR IN endpoint */
-    usbh_epinfo_t intout; /* INTR OUT endpoint */
+    usbh_pipe_t intin;  /* INTR IN endpoint */
+    usbh_pipe_t intout; /* INTR OUT endpoint */
 };
 
 #ifdef __cplusplus

+ 320 - 215
class/hub/usbh_hub.c

@@ -3,32 +3,32 @@
  *
  * SPDX-License-Identifier: Apache-2.0
  */
-#include "usbh_core.h"
 #include "usbh_hub.h"
 
 #define DEV_FORMAT "/dev/hub%d"
 
+#define DEBOUNCE_TIMEOUT       400
+#define DEBOUNCE_TIME_STEP     25
+#define DELAY_TIME_AFTER_RESET 200
+
 static uint32_t g_devinuse = 0;
 
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[32];
+
+usb_slist_t hub_event_head = USB_SLIST_OBJECT_INIT(hub_event_head);
 usb_slist_t hub_class_head = USB_SLIST_OBJECT_INIT(hub_class_head);
 
-USB_MEM_ALIGNX uint8_t int_buffer[6][USBH_HUB_INTIN_BUFSIZE];
-extern void usbh_external_hport_connect(struct usbh_hubport *hport);
-extern void usbh_external_hport_disconnect(struct usbh_hubport *hport);
-extern void usbh_hport_activate(struct usbh_hubport *hport);
-extern void usbh_hport_deactivate(struct usbh_hubport *hport);
+usb_osal_sem_t hub_event_wait;
+usb_osal_thread_t hub_thread;
 
-static void usbh_external_hub_callback(void *arg, int nbytes);
+USB_NOCACHE_RAM_SECTION struct usbh_hub roothub;
+struct usbh_hubport roothub_parent_port;
 
-static inline void usbh_hub_register(struct usbh_hub *hub_class)
-{
-    usb_slist_add_tail(&hub_class_head, &hub_class->list);
-}
+extern int usbh_hport_activate_ep0(struct usbh_hubport *hport);
+extern int usbh_hport_deactivate_ep0(struct usbh_hubport *hport);
+extern int usbh_enumerate(struct usbh_hubport *hport);
 
-static inline void usbh_hub_unregister(struct usbh_hub *hub_class)
-{
-    usb_slist_remove(&hub_class_head, &hub_class->list);
-}
+static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed" };
 
 /****************************************************************************
  * Name: usbh_hub_devno_alloc
@@ -38,7 +38,7 @@ static inline void usbh_hub_unregister(struct usbh_hub *hub_class)
  *
  ****************************************************************************/
 
-static int usbh_hub_devno_alloc(struct usbh_hub *hub_class)
+static int usbh_hub_devno_alloc(struct usbh_hub *hub)
 {
     size_t flags;
     int devno;
@@ -48,7 +48,7 @@ static int usbh_hub_devno_alloc(struct usbh_hub *hub_class)
         uint32_t bitno = 1 << devno;
         if ((g_devinuse & bitno) == 0) {
             g_devinuse |= bitno;
-            hub_class->index = devno;
+            hub->index = devno;
             usb_osal_leave_critical_section(flags);
             return 0;
         }
@@ -66,9 +66,9 @@ static int usbh_hub_devno_alloc(struct usbh_hub *hub_class)
  *
  ****************************************************************************/
 
-static void usbh_hub_devno_free(struct usbh_hub *hub_class)
+static void usbh_hub_devno_free(struct usbh_hub *hub)
 {
-    int devno = hub_class->index;
+    int devno = hub->index;
 
     if (devno >= 2 && devno < 32) {
         size_t flags = usb_osal_enter_critical_section();
@@ -77,11 +77,12 @@ static void usbh_hub_devno_free(struct usbh_hub *hub_class)
     }
 }
 
-static int usbh_hub_get_hub_descriptor(struct usbh_hub *hub_class, uint8_t *buffer)
+static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
 {
     struct usb_setup_packet *setup;
+    int ret;
 
-    setup = hub_class->parent->setup;
+    setup = &hub->parent->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
@@ -89,14 +90,20 @@ static int usbh_hub_get_hub_descriptor(struct usbh_hub *hub_class, uint8_t *buff
     setup->wIndex = 0;
     setup->wLength = USB_SIZEOF_HUB_DESC;
 
-    return usbh_control_transfer(hub_class->parent->ep0, setup, buffer);
+    ret = usbh_control_transfer(hub->parent->ep0, setup, g_hub_buf);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(buffer, g_hub_buf, USB_SIZEOF_HUB_DESC);
+    return ret;
 }
 
-static int usbh_hub_get_status(struct usbh_hub *hub_class, uint8_t *buffer)
+static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
 {
     struct usb_setup_packet *setup;
+    int ret;
 
-    setup = hub_class->parent->setup;
+    setup = &hub->parent->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
     setup->bRequest = HUB_REQUEST_GET_STATUS;
@@ -104,14 +111,20 @@ static int usbh_hub_get_status(struct usbh_hub *hub_class, uint8_t *buffer)
     setup->wIndex = 0;
     setup->wLength = 2;
 
-    return usbh_control_transfer(hub_class->parent->ep0, setup, buffer);
+    ret = usbh_control_transfer(hub->parent->ep0, setup, g_hub_buf);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(buffer, g_hub_buf, 2);
+    return ret;
 }
 
-static int usbh_hub_get_portstatus(struct usbh_hub *hub_class, uint8_t port, struct hub_port_status *port_status)
+static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
 {
     struct usb_setup_packet *setup;
+    int ret;
 
-    setup = hub_class->parent->setup;
+    setup = &hub->parent->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
     setup->bRequest = HUB_REQUEST_GET_STATUS;
@@ -119,14 +132,19 @@ static int usbh_hub_get_portstatus(struct usbh_hub *hub_class, uint8_t port, str
     setup->wIndex = port;
     setup->wLength = 4;
 
-    return usbh_control_transfer(hub_class->parent->ep0, setup, (uint8_t *)port_status);
+    ret = usbh_control_transfer(hub->parent->ep0, setup, g_hub_buf);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(port_status, g_hub_buf, 4);
+    return ret;
 }
 
-static int usbh_hub_set_feature(struct usbh_hub *hub_class, uint8_t port, uint8_t feature)
+static int _usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature)
 {
     struct usb_setup_packet *setup;
 
-    setup = hub_class->parent->setup;
+    setup = &hub->parent->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
     setup->bRequest = HUB_REQUEST_SET_FEATURE;
@@ -134,14 +152,14 @@ static int usbh_hub_set_feature(struct usbh_hub *hub_class, uint8_t port, uint8_
     setup->wIndex = port;
     setup->wLength = 0;
 
-    return usbh_control_transfer(hub_class->parent->ep0, setup, NULL);
+    return usbh_control_transfer(hub->parent->ep0, setup, NULL);
 }
 
-static int usbh_hub_clear_feature(struct usbh_hub *hub_class, uint8_t port, uint8_t feature)
+static int _usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature)
 {
     struct usb_setup_packet *setup;
 
-    setup = hub_class->parent->setup;
+    setup = &hub->parent->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
     setup->bRequest = HUB_REQUEST_CLEAR_FEATURE;
@@ -149,7 +167,7 @@ static int usbh_hub_clear_feature(struct usbh_hub *hub_class, uint8_t port, uint
     setup->wIndex = port;
     setup->wLength = 0;
 
-    return usbh_control_transfer(hub_class->parent->ep0, setup, NULL);
+    return usbh_control_transfer(hub->parent->ep0, setup, NULL);
 }
 
 static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length)
@@ -161,97 +179,147 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length
         USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
         return -2;
     } else {
-        USB_LOG_INFO("Device Descriptor:\r\n");
-        USB_LOG_INFO("bLength: 0x%02x             \r\n", desc->bLength);
-        USB_LOG_INFO("bDescriptorType: 0x%02x     \r\n", desc->bDescriptorType);
-        USB_LOG_INFO("bNbrPorts: 0x%02x           \r\n", desc->bNbrPorts);
-        USB_LOG_INFO("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
-        USB_LOG_INFO("bPwrOn2PwrGood: 0x%02x      \r\n", desc->bPwrOn2PwrGood);
-        USB_LOG_INFO("bHubContrCurrent: 0x%02x    \r\n", desc->bHubContrCurrent);
-        USB_LOG_INFO("DeviceRemovable: 0x%02x     \r\n", desc->DeviceRemovable);
-        USB_LOG_INFO("PortPwrCtrlMask: 0x%02x     \r\n", desc->PortPwrCtrlMask);
+        USB_LOG_RAW("Device Descriptor:\r\n");
+        USB_LOG_RAW("bLength: 0x%02x             \r\n", desc->bLength);
+        USB_LOG_RAW("bDescriptorType: 0x%02x     \r\n", desc->bDescriptorType);
+        USB_LOG_RAW("bNbrPorts: 0x%02x           \r\n", desc->bNbrPorts);
+        USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
+        USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x      \r\n", desc->bPwrOn2PwrGood);
+        USB_LOG_RAW("bHubContrCurrent: 0x%02x    \r\n", desc->bHubContrCurrent);
+        USB_LOG_RAW("DeviceRemovable: 0x%02x     \r\n", desc->DeviceRemovable);
+        USB_LOG_RAW("PortPwrCtrlMask: 0x%02x     \r\n", desc->PortPwrCtrlMask);
     }
     return 0;
 }
 
+static int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
+{
+    struct usb_setup_packet roothub_setup;
+    struct usb_setup_packet *setup;
+
+    if (hub->is_roothub) {
+        setup = &roothub_setup;
+        setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
+        setup->bRequest = HUB_REQUEST_GET_STATUS;
+        setup->wValue = 0;
+        setup->wIndex = port;
+        setup->wLength = 4;
+        return usbh_roothub_control(&roothub_setup, (uint8_t *)port_status);
+    } else {
+        return _usbh_hub_get_portstatus(hub, port, port_status);
+    }
+}
+
+static int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature)
+{
+    struct usb_setup_packet roothub_setup;
+    struct usb_setup_packet *setup;
+
+    if (hub->is_roothub) {
+        setup = &roothub_setup;
+        setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
+        setup->bRequest = HUB_REQUEST_SET_FEATURE;
+        setup->wValue = feature;
+        setup->wIndex = port;
+        setup->wLength = 0;
+        return usbh_roothub_control(setup, NULL);
+    } else {
+        return _usbh_hub_set_feature(hub, port, feature);
+    }
+}
+
+static int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature)
+{
+    struct usb_setup_packet roothub_setup;
+    struct usb_setup_packet *setup;
+
+    if (hub->is_roothub) {
+        setup = &roothub_setup;
+        setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
+        setup->bRequest = HUB_REQUEST_CLEAR_FEATURE;
+        setup->wValue = feature;
+        setup->wIndex = port;
+        setup->wLength = 0;
+        return usbh_roothub_control(setup, NULL);
+    } else {
+        return _usbh_hub_clear_feature(hub, port, feature);
+    }
+}
+
+static void usbh_hub_thread_wakeup(struct usbh_hub *hub)
+{
+    usb_slist_add_tail(&hub_event_head, &hub->hub_event_list);
+    usb_osal_sem_give(hub_event_wait);
+}
+
 static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
 {
     struct usbh_endpoint_cfg ep_cfg = { 0 };
     struct usb_endpoint_descriptor *ep_desc;
+    struct hub_port_status port_status;
     int ret;
 
-    struct usbh_hub *hub_class = usb_malloc(sizeof(struct usbh_hub));
-    if (hub_class == NULL) {
-        USB_LOG_ERR("Fail to alloc hub_class\r\n");
-        return -ENOMEM;
-    }
-
-    memset(hub_class, 0, sizeof(struct usbh_hub));
-    usbh_hub_devno_alloc(hub_class);
-    hub_class->dev_addr = hport->dev_addr;
-    hub_class->parent = hport;
-
-    hub_class->port_status = usb_iomalloc(sizeof(struct hub_port_status));
-    if (hub_class->port_status == NULL) {
-        USB_LOG_ERR("Fail to alloc port_status\r\n");
+    struct usbh_hub *hub = usb_malloc(sizeof(struct usbh_hub));
+    if (hub == NULL) {
+        USB_LOG_ERR("Fail to alloc hub\r\n");
         return -ENOMEM;
     }
 
-    hport->config.intf[intf].priv = hub_class;
+    memset(hub, 0, sizeof(struct usbh_hub));
+    usbh_hub_devno_alloc(hub);
+    hub->hub_addr = hport->dev_addr;
+    hub->parent = hport;
 
-    uint8_t *hub_desc_buffer = usb_iomalloc(32);
+    hport->config.intf[intf].priv = hub;
 
-    ret = usbh_hub_get_hub_descriptor(hub_class, hub_desc_buffer);
-    if (ret != 0) {
-        usb_iofree(hub_desc_buffer);
+    ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc);
+    if (ret < 0) {
         return ret;
     }
 
-    parse_hub_descriptor((struct usb_hub_descriptor *)hub_desc_buffer, USB_SIZEOF_HUB_DESC);
-    memcpy(&hub_class->hub_desc, hub_desc_buffer, USB_SIZEOF_HUB_DESC);
-    usb_iofree(hub_desc_buffer);
-
-    hub_class->nports = hub_class->hub_desc.bNbrPorts;
+    parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC);
 
-    for (uint8_t port = 1; port <= hub_class->nports; port++) {
-        hub_class->child[port - 1].port = port;
-        hub_class->child[port - 1].parent = hub_class;
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        hub->child[port].port = port + 1;
+        hub->child[port].parent = hub;
     }
 
-    hub_class->int_buffer = int_buffer[hub_class->index - 2];
-    usbh_hub_register(hub_class);
-
     ep_desc = &hport->config.intf[intf].ep[0].ep_desc;
     ep_cfg.ep_addr = ep_desc->bEndpointAddress;
     ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
-    ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
+    ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
     ep_cfg.ep_interval = ep_desc->bInterval;
     ep_cfg.hport = hport;
     if (ep_desc->bEndpointAddress & 0x80) {
-        usbh_ep_alloc(&hub_class->intin, &ep_cfg);
+        usbh_pipe_alloc(&hub->intin, &ep_cfg);
+        USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u\r\n",
+                     ep_desc->bEndpointAddress,
+                     ep_desc->bmAttributes,
+                     ep_desc->wMaxPacketSize,
+                     ep_desc->bInterval);
     } else {
         return -1;
     }
 
-    for (uint8_t port = 1; port <= hub_class->nports; port++) {
-        ret = usbh_hub_set_feature(hub_class, 1, HUB_PORT_FEATURE_POWER);
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        ret = usbh_hub_set_feature(hub, 1, HUB_PORT_FEATURE_POWER);
         if (ret < 0) {
             return ret;
         }
     }
 
-    for (uint8_t port = 1; port <= hub_class->nports; port++) {
-        ret = usbh_hub_get_portstatus(hub_class, port, hub_class->port_status);
-        USB_LOG_INFO("Port:%d, status:0x%02x, change:0x%02x\r\n", port, hub_class->port_status->wPortStatus, hub_class->port_status->wPortChange);
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
+        USB_LOG_INFO("port %u, status:0x%02x, change:0x%02x\r\n", port, port_status.wPortStatus, port_status.wPortChange);
         if (ret < 0) {
             return ret;
         }
     }
 
-    snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hub_class->index);
+    snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hub->index);
+    usbh_hub_register(hub);
     USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname);
 
-    ret = usbh_ep_intr_async_transfer(hub_class->intin, hub_class->int_buffer, USBH_HUB_INTIN_BUFSIZE, usbh_external_hub_callback, hub_class);
     return 0;
 }
 
@@ -260,24 +328,18 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
     struct usbh_hubport *child;
     int ret = 0;
 
-    struct usbh_hub *hub_class = (struct usbh_hub *)hport->config.intf[intf].priv;
+    struct usbh_hub *hub = (struct usbh_hub *)hport->config.intf[intf].priv;
 
-    if (hub_class) {
-        usbh_hub_devno_free(hub_class);
+    if (hub) {
+        usbh_hub_devno_free(hub);
 
-        if (hub_class->intin) {
-            ret = usb_ep_cancel(hub_class->intin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(hub_class->intin);
+        if (hub->intin) {
+            usbh_pipe_free(hub->intin);
         }
 
-        if (hub_class->port_status)
-            usb_iofree(hub_class->port_status);
-
-        for (uint8_t port = 1; port <= hub_class->nports; port++) {
-            child = &hub_class->child[port - 1];
-            usbh_hport_deactivate(child);
+        for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+            child = &hub->child[port];
+            usbh_hport_deactivate_ep0(child);
             for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
                 if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
                     ret = CLASS_DISCONNECT(child, i);
@@ -288,215 +350,258 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
             child->parent = NULL;
         }
 
-        usbh_hub_unregister(hub_class);
-        usb_free(hub_class);
+        usbh_hub_unregister(hub);
+        memset(hub, 0, sizeof(struct usbh_hub));
+        usb_free(hub);
 
         if (hport->config.intf[intf].devname[0] != '\0')
             USB_LOG_INFO("Unregister HUB Class:%s\r\n", hport->config.intf[intf].devname);
-
-        memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN);
-        hport->config.intf[intf].priv = NULL;
     }
     return ret;
 }
 
-static void usbh_extern_hub_psc_event(void *arg)
+static void usbh_roothub_register(void)
 {
-    struct usbh_hub *hub_class;
-    struct usbh_hubport *connport;
-    uint8_t port_change;
-    uint16_t status;
-    uint16_t change;
+    memset(&roothub, 0, sizeof(struct usbh_hub));
+    memset(&roothub_parent_port, 0, sizeof(struct usbh_hubport));
+    roothub_parent_port.port = 1;
+    roothub_parent_port.dev_addr = 1;
+    roothub.connected = true;
+    roothub.index = 1;
+    roothub.is_roothub = true;
+    roothub.parent = &roothub_parent_port;
+    roothub.hub_addr = roothub_parent_port.dev_addr;
+    roothub.hub_desc.bNbrPorts = CONFIG_USBHOST_RHPORTS;
+    usbh_hub_register(&roothub);
+}
+
+static void usbh_hub_events(struct usbh_hub *hub)
+{
+    struct usbh_hubport *child;
+    struct hub_port_status port_status;
+    uint8_t portchange_index;
+    uint16_t portstatus;
+    uint16_t portchange;
     uint16_t mask;
     uint16_t feat;
+    uint8_t speed;
     int ret;
 
-    hub_class = (struct usbh_hub *)arg;
-
-    /* Has the hub been disconnected? */
-    if (!hub_class->parent->connected) {
+    if (!hub->connected) {
         return;
     }
 
-    port_change = hub_class->int_buffer[0];
-    USB_LOG_DBG("port_change:0x%02x\r\n", port_change);
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        portchange_index = hub->int_buffer[0];
+
+        USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index);
 
-    /* Check for status change on any port */
-    for (uint8_t port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) {
-        /* Check if port status has changed */
-        if ((port_change & (1 << port)) == 0) {
+        if (!(portchange_index & (1 << (port + 1)))) {
             continue;
         }
-        USB_LOG_DBG("Port %d change\r\n", port);
-
-        /* Port status changed, check what happened */
-        port_change &= ~(1 << port);
+        portchange_index &= ~(1 << (port + 1));
+        USB_LOG_DBG("Port %d change\r\n", port + 1);
 
         /* Read hub port status */
-        ret = usbh_hub_get_portstatus(hub_class, port, hub_class->port_status);
+        ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
         if (ret < 0) {
-            USB_LOG_ERR("Failed to read port:%d status, errorcode: %d\r\n", port, ret);
+            USB_LOG_ERR("Failed to read port %u status, errorcode: %d\r\n", port + 1, ret);
             continue;
         }
-        status = hub_class->port_status->wPortStatus;
-        change = hub_class->port_status->wPortChange;
 
-        USB_LOG_DBG("Port:%d, status:0x%02x, change:0x%02x\r\n", port, status, change);
+        portstatus = port_status.wPortStatus;
+        portchange = port_status.wPortChange;
+
+        USB_LOG_DBG("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
 
         /* First, clear all change bits */
         mask = 1;
         feat = HUB_PORT_FEATURE_C_CONNECTION;
-        while (change) {
-            if (change & mask) {
-                ret = usbh_hub_clear_feature(hub_class, port, feat);
+        while (portchange) {
+            if (portchange & mask) {
+                ret = usbh_hub_clear_feature(hub, port + 1, feat);
                 if (ret < 0) {
-                    USB_LOG_ERR("Failed to clear port:%d, change mask:%04x, errorcode:%d\r\n", port, mask, ret);
+                    USB_LOG_ERR("Failed to clear port %u, change mask:%04x, errorcode:%d\r\n", port + 1, mask, ret);
+                    continue;
                 }
-                change &= (~mask);
+                portchange &= (~mask);
             }
             mask <<= 1;
             feat++;
         }
 
-        change = hub_class->port_status->wPortChange;
+        portchange = port_status.wPortChange;
 
-        /* Handle connect or disconnect, no power management */
-        if (change & HUB_PORT_STATUS_C_CONNECTION) {
-            uint16_t debouncetime = 0;
+        /* Second, if port changes, debounces first */
+        if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
+            uint16_t connection = 0;
             uint16_t debouncestable = 0;
-            uint16_t connection = 0xffff;
-
-            /* Debounce */
-            while (debouncetime < 1500) {
-                ret = usbh_hub_get_portstatus(hub_class, port, hub_class->port_status);
+            for (uint32_t debouncetime = 0; debouncetime < DEBOUNCE_TIMEOUT; debouncetime += DEBOUNCE_TIME_STEP) {
+                usb_osal_msleep(DEBOUNCE_TIME_STEP);
+                /* Read hub port status */
+                ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
                 if (ret < 0) {
-                    USB_LOG_ERR("Failed to read port:%d status, errorcode: %d\r\n", port, ret);
-                    break;
+                    USB_LOG_ERR("Failed to read port %u status, errorcode: %d\r\n", port + 1, ret);
+                    continue;
                 }
-                status = hub_class->port_status->wPortStatus;
-                change = hub_class->port_status->wPortChange;
-
-                if ((change & HUB_PORT_STATUS_C_CONNECTION) == 0 &&
-                    (status & HUB_PORT_STATUS_CONNECTION) == connection) {
-                    debouncestable += 25;
-                    if (debouncestable >= 100) {
-                        USB_LOG_DBG("Port %d debouncestable=%d\r\n",
-                                    port, debouncestable);
-                        break;
+
+                portstatus = port_status.wPortStatus;
+                portchange = port_status.wPortChange;
+
+                USB_LOG_DBG("Port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
+                if ((portstatus & HUB_PORT_STATUS_CONNECTION) == connection) {
+                    if (connection) {
+                        if (++debouncestable == 4) {
+                            break;
+                        }
                     }
                 } else {
                     debouncestable = 0;
-                    connection = status & HUB_PORT_STATUS_CONNECTION;
                 }
 
-                if ((change & HUB_PORT_STATUS_C_CONNECTION) != 0) {
-                    ret = usbh_hub_clear_feature(hub_class, port, HUB_PORT_FEATURE_C_CONNECTION);
-                    if (ret < 0) {
-                        USB_LOG_ERR("Failed to clear port:%d, change mask:%04x, errorcode:%d\r\n", port, mask, ret);
-                    }
-                }
-                debouncetime += 25;
-                usb_osal_msleep(25);
-            }
+                connection = portstatus & HUB_PORT_STATUS_CONNECTION;
 
-            if (ret < 0 || debouncetime >= 1500) {
-                USB_LOG_ERR("ERROR: Failed to debounce port %d: %d\r\n", port, ret);
-                continue;
+                if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
+                    usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_CONNECTION);
+                }
             }
 
-            if (status & HUB_PORT_STATUS_CONNECTION) {
-                /* Device connected to a port on the hub */
-                USB_LOG_DBG("Connection on port:%d\n", port);
-
-                ret = usbh_hub_set_feature(hub_class, port, HUB_PORT_FEATURE_RESET);
+            /* Last, check connect status */
+            if (portstatus & HUB_PORT_STATUS_CONNECTION) {
+                ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_RESET);
                 if (ret < 0) {
-                    USB_LOG_ERR("Failed to reset port:%d,errorcode:%d\r\n", port, ret);
+                    USB_LOG_ERR("Failed to reset port %u,errorcode:%d\r\n", port, ret);
                     continue;
                 }
 
-                usb_osal_msleep(100);
-
-                ret = usbh_hub_get_portstatus(hub_class, port, hub_class->port_status);
+                usb_osal_msleep(DELAY_TIME_AFTER_RESET);
+                /* Read hub port status */
+                ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
                 if (ret < 0) {
-                    USB_LOG_ERR("Failed to read port:%d status, errorcode: %d\r\n", port, ret);
+                    USB_LOG_ERR("Failed to read port %u status, errorcode: %d\r\n", port + 1, ret);
                     continue;
                 }
-                status = hub_class->port_status->wPortStatus;
-                change = hub_class->port_status->wPortChange;
-
-                USB_LOG_DBG("Port:%d, status:0x%02x, change:0x%02x after reset\r\n", port, status, change);
 
-                if ((status & HUB_PORT_STATUS_RESET) == 0 && (status & HUB_PORT_STATUS_ENABLE) != 0) {
-                    if (change & HUB_PORT_STATUS_C_RESET) {
-                        ret = usbh_hub_clear_feature(hub_class, port, HUB_PORT_FEATURE_C_RESET);
+                portstatus = port_status.wPortStatus;
+                portchange = port_status.wPortChange;
+                if (!(portstatus & HUB_PORT_STATUS_RESET) && (portstatus & HUB_PORT_STATUS_ENABLE)) {
+                    if (portchange & HUB_PORT_STATUS_C_RESET) {
+                        ret = usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_RESET);
                         if (ret < 0) {
-                            USB_LOG_ERR("Failed to clear port:%d reset change, errorcode: %d\r\n", port, ret);
+                            USB_LOG_ERR("Failed to clear port %u reset change, errorcode: %d\r\n", port, ret);
                         }
                     }
-                    connport = &hub_class->child[port - 1];
 
-                    if (status & HUB_PORT_STATUS_HIGH_SPEED) {
-                        connport->speed = USB_SPEED_HIGH;
-                    } else if (status & HUB_PORT_STATUS_LOW_SPEED) {
-                        connport->speed = USB_SPEED_LOW;
+                    if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) {
+                        speed = USB_SPEED_HIGH;
+                    } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
+                        speed = USB_SPEED_LOW;
                     } else {
-                        connport->speed = USB_SPEED_FULL;
+                        speed = USB_SPEED_FULL;
                     }
 
-                    /* Device connected from a port on the hub, wakeup psc thread. */
-                    usbh_external_hport_connect(connport);
+                    child = &hub->child[port];
+
+                    memset(child, 0, sizeof(struct usbh_hubport));
+                    child->parent = hub;
+                    child->connected = true;
+                    child->port = port + 1;
+                    child->speed = speed;
 
+                    USB_LOG_INFO("New %s device on Hub %u, Port %u connected\r\n", speed_table[speed], hub->index, port + 1);
+
+                    /* Allocate ep info for control endpoint */
+                    usbh_hport_activate_ep0(child);
+                    if (usbh_enumerate(child) < 0) {
+                        USB_LOG_ERR("Port %u enumerate fail\r\n", port + 1);
+                    }
                 } else {
-                    USB_LOG_ERR("Failed to enable port:%d\r\n", port);
+                    USB_LOG_ERR("Failed to enable port %u\r\n", port + 1);
                     continue;
                 }
             } else {
-                /* Device disconnected from a port on the hub, wakeup psc thread. */
-                connport = &hub_class->child[port - 1];
-                usbh_external_hport_disconnect(connport);
+                child = &hub->child[port];
+                child->connected = false;
+                usbh_hport_deactivate_ep0(child);
+                for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
+                    if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
+                        CLASS_DISCONNECT(child, i);
+                    }
+                }
+
+                USB_LOG_INFO("Device on on Hub %u, Port %u disconnected\r\n", hub->index, port + 1);
+                usbh_device_unmount_done_callback(child);
+                memset(child, 0, sizeof(struct usbh_hubport));
             }
-        } else {
-            USB_LOG_WRN("status %04x change %04x not handled\r\n", status, change);
         }
     }
+}
 
-    /* Check for hub status change */
+static void usbh_hub_thread(void *argument)
+{
+    size_t flags;
+    int ret = 0;
 
-    if ((port_change & 1) != 0) {
-        /* Hub status changed */
-        USB_LOG_WRN("Hub status changed, not handled\n");
-    }
+    usbh_roothub_register();
+    usb_hc_init();
+    while (1) {
+        ret = usb_osal_sem_take(hub_event_wait, 0xffffffff);
+        if (ret < 0) {
+            continue;
+        }
 
-    if (hub_class->parent->connected) {
-        ret = usbh_ep_intr_async_transfer(hub_class->intin, hub_class->int_buffer, USBH_HUB_INTIN_BUFSIZE, usbh_external_hub_callback, hub_class);
+        while (!usb_slist_isempty(&hub_event_head)) {
+            struct usbh_hub *hub = usb_slist_first_entry(&hub_event_head, struct usbh_hub, hub_event_list);
+            flags = usb_osal_enter_critical_section();
+            usb_slist_remove(&hub_event_head, &hub->hub_event_list);
+            usb_osal_leave_critical_section(flags);
+            usbh_hub_events(hub);
+        }
     }
 }
 
-static void usbh_external_hub_callback(void *arg, int nbytes)
+void usbh_roothub_thread_wakeup(uint8_t port)
 {
-    struct usbh_hub *hub_class = (struct usbh_hub *)arg;
-    uint32_t delay = 0;
-    if (nbytes < 0) {
-        hub_class->int_buffer[0] = 0;
-        delay = 100;
+    roothub.int_buffer[0] |= (1 << port);
+    usbh_hub_thread_wakeup(&roothub);
+}
+
+void usbh_hub_register(struct usbh_hub *hub)
+{
+    usb_slist_add_tail(&hub_class_head, &hub->list);
+}
+
+void usbh_hub_unregister(struct usbh_hub *hub)
+{
+    usb_slist_remove(&hub_class_head, &hub->list);
+}
+
+int usbh_hub_initialize(void)
+{
+    hub_event_wait = usb_osal_sem_create(0);
+    if (hub_event_wait == NULL) {
+        return -1;
     }
-    if (hub_class->parent->connected) {
-        usb_workqueue_submit(&g_lpworkq, &hub_class->work, usbh_extern_hub_psc_event, (void *)hub_class, delay);
+
+    hub_thread = usb_osal_thread_create("usbh_hub", CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbh_hub_thread, NULL);
+    if (hub_thread == NULL) {
+        return -1;
     }
+    return 0;
 }
 
-const struct usbh_class_driver hub_class_driver = {
+const struct usbh_class_driver hub_driver = {
     .driver_name = "hub",
     .connect = usbh_hub_connect,
     .disconnect = usbh_hub_disconnect
 };
 
-CLASS_INFO_DEFINE const struct usbh_class_info hub_class_info = {
+CLASS_INFO_DEFINE const struct usbh_class_info hub_info = {
     .match_flags = USB_CLASS_MATCH_INTF_CLASS,
     .class = USB_DEVICE_CLASS_HUB,
     .subclass = 0,
     .protocol = 0,
     .vid = 0x00,
     .pid = 0x00,
-    .class_driver = &hub_class_driver
+    .class_driver = &hub_driver
 };

+ 4 - 0
class/hub/usbh_hub.h

@@ -6,6 +6,7 @@
 #ifndef USBH_HUB_H
 #define USBH_HUB_H
 
+#include "usbh_core.h"
 #include "usb_hub.h"
 
 #define USBH_HUB_MAX_PORTS 4
@@ -17,6 +18,9 @@ extern usb_slist_t hub_class_head;
 #ifdef __cplusplus
 extern "C" {
 #endif
+void usbh_roothub_thread_wakeup(uint8_t port);
+void usbh_hub_register(struct usbh_hub *hub);
+void usbh_hub_unregister(struct usbh_hub *hub);
 int usbh_hub_initialize(void);
 #ifdef __cplusplus
 }

+ 50 - 59
class/msc/usbh_msc.c

@@ -11,6 +11,8 @@
 
 static uint32_t g_devinuse = 0;
 
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[32];
+
 /****************************************************************************
  * Name: usbh_msc_devno_alloc
  *
@@ -60,7 +62,7 @@ static void usbh_msc_devno_free(struct usbh_msc *msc_class)
 
 static int usbh_msc_get_maxlun(struct usbh_msc *msc_class, uint8_t *buffer)
 {
-    struct usb_setup_packet *setup = msc_class->hport->setup;
+    struct usb_setup_packet *setup = &msc_class->hport->setup;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
     setup->bRequest = MSC_REQUEST_GET_MAX_LUN;
@@ -111,7 +113,7 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
     struct CBW *cbw;
 
     /* Construct the CBW */
-    cbw = (struct CBW *)msc_class->tx_buffer;
+    cbw = (struct CBW *)g_msc_buf;
     memset(cbw, 0, USB_SIZEOF_MSC_CBW);
     cbw->dSignature = MSC_CBW_Signature;
 
@@ -120,12 +122,12 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
 
     usbh_msc_cbw_dump(cbw);
     /* Send the CBW */
-    nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
+    nbytes = usbh_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
     if (nbytes >= 0) {
         /* Receive the CSW */
-        nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
+        nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
         if (nbytes >= 0) {
-            usbh_msc_csw_dump((struct CSW *)msc_class->tx_buffer);
+            usbh_msc_csw_dump((struct CSW *)g_msc_buf);
         }
     }
     return nbytes < 0 ? (int)nbytes : 0;
@@ -137,7 +139,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
     struct CBW *cbw;
 
     /* Construct the CBW */
-    cbw = (struct CBW *)msc_class->tx_buffer;
+    cbw = (struct CBW *)g_msc_buf;
     memset(cbw, 0, USB_SIZEOF_MSC_CBW);
     cbw->dSignature = MSC_CBW_Signature;
 
@@ -149,15 +151,15 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
 
     usbh_msc_cbw_dump(cbw);
     /* Send the CBW */
-    nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
+    nbytes = usbh_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
     if (nbytes >= 0) {
         /* Receive the sense data response */
-        nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, SCSIRESP_FIXEDSENSEDATA_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
+        nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, SCSIRESP_FIXEDSENSEDATA_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
         if (nbytes >= 0) {
             /* Receive the CSW */
-            nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
+            nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
             if (nbytes >= 0) {
-                usbh_msc_csw_dump((struct CSW *)msc_class->tx_buffer);
+                usbh_msc_csw_dump((struct CSW *)g_msc_buf);
             }
         }
     }
@@ -170,7 +172,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
     struct CBW *cbw;
 
     /* Construct the CBW */
-    cbw = (struct CBW *)msc_class->tx_buffer;
+    cbw = (struct CBW *)g_msc_buf;
     memset(cbw, 0, USB_SIZEOF_MSC_CBW);
     cbw->dSignature = MSC_CBW_Signature;
 
@@ -182,15 +184,15 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
 
     usbh_msc_cbw_dump(cbw);
     /* Send the CBW */
-    nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
+    nbytes = usbh_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
     if (nbytes >= 0) {
         /* Receive the sense data response */
-        nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, SCSIRESP_INQUIRY_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
+        nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, SCSIRESP_INQUIRY_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
         if (nbytes >= 0) {
             /* Receive the CSW */
-            nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
+            nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
             if (nbytes >= 0) {
-                usbh_msc_csw_dump((struct CSW *)msc_class->tx_buffer);
+                usbh_msc_csw_dump((struct CSW *)g_msc_buf);
             }
         }
     }
@@ -203,7 +205,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
     struct CBW *cbw;
 
     /* Construct the CBW */
-    cbw = (struct CBW *)msc_class->tx_buffer;
+    cbw = (struct CBW *)g_msc_buf;
     memset(cbw, 0, USB_SIZEOF_MSC_CBW);
     cbw->dSignature = MSC_CBW_Signature;
 
@@ -214,18 +216,18 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
 
     usbh_msc_cbw_dump(cbw);
     /* Send the CBW */
-    nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
+    nbytes = usbh_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
     if (nbytes >= 0) {
         /* Receive the sense data response */
-        nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, SCSIRESP_READCAPACITY10_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
+        nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, SCSIRESP_READCAPACITY10_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
         if (nbytes >= 0) {
             /* Save the capacity information */
-            msc_class->blocknum = GET_BE32(&msc_class->tx_buffer[0]) + 1;
-            msc_class->blocksize = GET_BE32(&msc_class->tx_buffer[4]);
+            msc_class->blocknum = GET_BE32(&g_msc_buf[0]) + 1;
+            msc_class->blocksize = GET_BE32(&g_msc_buf[4]);
             /* Receive the CSW */
-            nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
+            nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
             if (nbytes >= 0) {
-                usbh_msc_csw_dump((struct CSW *)msc_class->tx_buffer);
+                usbh_msc_csw_dump((struct CSW *)g_msc_buf);
             }
         }
     }
@@ -238,7 +240,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
     struct CBW *cbw;
 
     /* Construct the CBW */
-    cbw = (struct CBW *)msc_class->tx_buffer;
+    cbw = (struct CBW *)g_msc_buf;
     memset(cbw, 0, USB_SIZEOF_MSC_CBW);
     cbw->dSignature = MSC_CBW_Signature;
 
@@ -251,15 +253,15 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
 
     usbh_msc_cbw_dump(cbw);
     /* Send the CBW */
-    nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
+    nbytes = usbh_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
     if (nbytes >= 0) {
         /* Send the user data */
-        nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)buffer, msc_class->blocksize * nsectors, CONFIG_USBHOST_MSC_TIMEOUT);
+        nbytes = usbh_bulk_transfer(msc_class->bulkout, (uint8_t *)buffer, msc_class->blocksize * nsectors, CONFIG_USBHOST_MSC_TIMEOUT);
         if (nbytes >= 0) {
             /* Receive the CSW */
-            nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
+            nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
             if (nbytes >= 0) {
-                usbh_msc_csw_dump((struct CSW *)msc_class->tx_buffer);
+                usbh_msc_csw_dump((struct CSW *)g_msc_buf);
             }
         }
     }
@@ -272,7 +274,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
     struct CBW *cbw;
 
     /* Construct the CBW */
-    cbw = (struct CBW *)msc_class->tx_buffer;
+    cbw = (struct CBW *)g_msc_buf;
     memset(cbw, 0, USB_SIZEOF_MSC_CBW);
     cbw->dSignature = MSC_CBW_Signature;
 
@@ -286,15 +288,15 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
 
     usbh_msc_cbw_dump(cbw);
     /* Send the CBW */
-    nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
+    nbytes = usbh_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
     if (nbytes >= 0) {
         /* Receive the user data */
-        nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, (uint8_t *)buffer, msc_class->blocksize * nsectors, CONFIG_USBHOST_MSC_TIMEOUT);
+        nbytes = usbh_bulk_transfer(msc_class->bulkin, (uint8_t *)buffer, msc_class->blocksize * nsectors, CONFIG_USBHOST_MSC_TIMEOUT);
         if (nbytes >= 0) {
             /* Receive the CSW */
-            nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
+            nbytes = usbh_bulk_transfer(msc_class->bulkin, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
             if (nbytes >= 0) {
-                usbh_msc_csw_dump((struct CSW *)msc_class->tx_buffer);
+                usbh_msc_csw_dump((struct CSW *)g_msc_buf);
             }
         }
     }
@@ -320,32 +322,32 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
 
     hport->config.intf[intf].priv = msc_class;
 
-    msc_class->tx_buffer = usb_iomalloc(64);
-    if (msc_class->tx_buffer == NULL) {
-        USB_LOG_ERR("Fail to alloc tx_buffer\r\n");
-        return -ENOMEM;
-    }
-
-    ret = usbh_msc_get_maxlun(msc_class, msc_class->tx_buffer);
+    ret = usbh_msc_get_maxlun(msc_class, g_msc_buf);
     if (ret < 0) {
         return ret;
     }
 
-    USB_LOG_INFO("Get max LUN:%u\r\n", msc_class->tx_buffer[0] + 1);
+    USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[0] + 1);
 
     for (uint8_t i = 0; i < hport->config.intf[intf].intf_desc.bNumEndpoints; i++) {
         ep_desc = &hport->config.intf[intf].ep[i].ep_desc;
 
         ep_cfg.ep_addr = ep_desc->bEndpointAddress;
         ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
-        ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
+        ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&msc_class->bulkin, &ep_cfg);
+            usbh_pipe_alloc(&msc_class->bulkin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&msc_class->bulkout, &ep_cfg);
+            usbh_pipe_alloc(&msc_class->bulkout, &ep_cfg);
         }
+
+        USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u\r\n",
+                     ep_desc->bEndpointAddress,
+                     ep_desc->bmAttributes,
+                     ep_desc->wMaxPacketSize,
+                     ep_desc->bInterval);
     }
 
     ret = usbh_msc_scsi_testunitready(msc_class);
@@ -364,11 +366,11 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
         return ret;
     }
 
-    if (msc_class->blocksize) {
+    if (msc_class->blocksize > 0) {
         USB_LOG_INFO("Capacity info:\r\n");
         USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize);
     } else {
-        USB_LOG_ERR("Fail to read capacity10\r\n");
+        USB_LOG_ERR("Invalid block size\r\n");
         return -ERANGE;
     }
 
@@ -389,29 +391,18 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
         usbh_msc_devno_free(msc_class);
 
         if (msc_class->bulkin) {
-            ret = usb_ep_cancel(msc_class->bulkin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(msc_class->bulkin);
+            usbh_pipe_free(msc_class->bulkin);
         }
 
         if (msc_class->bulkout) {
-            ret = usb_ep_cancel(msc_class->bulkout);
-            if (ret < 0) {
-            }
-            usbh_ep_free(msc_class->bulkout);
+            usbh_pipe_free(msc_class->bulkout);
         }
 
-        if (msc_class->tx_buffer)
-            usb_iofree(msc_class->tx_buffer);
-
+        memset(msc_class, 0, sizeof(struct usbh_msc));
         usb_free(msc_class);
 
         if (hport->config.intf[intf].devname[0] != '\0')
             USB_LOG_INFO("Unregister MSC Class:%s\r\n", hport->config.intf[intf].devname);
-
-        memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN);
-        hport->config.intf[intf].priv = NULL;
     }
 
     return ret;

+ 4 - 5
class/msc/usbh_msc.h

@@ -14,11 +14,10 @@ struct usbh_msc {
 
     uint8_t intf; /* Data interface number */
     uint8_t sdchar;
-    usbh_epinfo_t bulkin;  /* Bulk IN endpoint */
-    usbh_epinfo_t bulkout; /* Bulk OUT endpoint */
-    uint8_t *tx_buffer;
-    uint32_t blocknum;  /* Number of blocks on the USB mass storage device */
-    uint16_t blocksize; /* Block size of USB mass storage device */
+    usbh_pipe_t bulkin;  /* Bulk IN endpoint */
+    usbh_pipe_t bulkout; /* Bulk OUT endpoint */
+    uint32_t blocknum;   /* Number of blocks on the USB mass storage device */
+    uint16_t blocksize;  /* Block size of USB mass storage device */
 };
 
 int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);

+ 6 - 12
class/mtp/usbh_mtp.c

@@ -37,7 +37,7 @@ static int usbh_mtp_connect(struct usbh_hubport *hport, uint8_t intf)
     ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
     ep_cfg.ep_interval = ep_desc->bInterval;
     ep_cfg.hport = hport;
-    usbh_ep_alloc(&mtp_class->intin, &ep_cfg);
+    usbh_pipe_alloc(&mtp_class->intin, &ep_cfg);
 
 #endif
     for (uint8_t i = 0; i < hport->config.intf[intf + 1].intf_desc.bNumEndpoints; i++) {
@@ -45,13 +45,13 @@ static int usbh_mtp_connect(struct usbh_hubport *hport, uint8_t intf)
 
         ep_cfg.ep_addr = ep_desc->bEndpointAddress;
         ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
-        ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
+        ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;;
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&mtp_class->bulkin, &ep_cfg);
+            usbh_pipe_alloc(&mtp_class->bulkin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&mtp_class->bulkout, &ep_cfg);
+            usbh_pipe_alloc(&mtp_class->bulkout, &ep_cfg);
         }
     }
 
@@ -70,17 +70,11 @@ static int usbh_mtp_disconnect(struct usbh_hubport *hport, uint8_t intf)
 
     if (mtp_class) {
         if (mtp_class->bulkin) {
-            ret = usb_ep_cancel(mtp_class->bulkin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(mtp_class->bulkin);
+            usbh_pipe_free(mtp_class->bulkin);
         }
 
         if (mtp_class->bulkout) {
-            ret = usb_ep_cancel(mtp_class->bulkout);
-            if (ret < 0) {
-            }
-            usbh_ep_free(mtp_class->bulkout);
+            usbh_pipe_free(mtp_class->bulkout);
         }
 
         usb_free(mtp_class);

+ 3 - 3
class/mtp/usbh_mtp.h

@@ -12,10 +12,10 @@ struct usbh_mtp {
     struct usbh_hubport *hport;
 
     uint8_t intf;          /* interface number */
-    usbh_epinfo_t bulkin;  /* BULK IN endpoint */
-    usbh_epinfo_t bulkout; /* BULK OUT endpoint */
+    usbh_pipe_t bulkin;  /* BULK IN endpoint */
+    usbh_pipe_t bulkout; /* BULK OUT endpoint */
 #ifdef CONFIG_USBHOST_MTP_NOTIFY
-    usbh_epinfo_t intin; /* Interrupt IN endpoint (optional) */
+    usbh_pipe_t intin; /* Interrupt IN endpoint (optional) */
 #endif
 };
 

+ 8 - 14
class/printer/usbh_printer.c

@@ -10,7 +10,7 @@
 
 static int usbh_printer_get_device_id(struct usbh_printer *printer_class, uint8_t *buffer)
 {
-    struct usb_setup_packet *setup = printer_class->hport->setup;
+    struct usb_setup_packet *setup = &printer_class->hport->setup;
     int ret;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -24,7 +24,7 @@ static int usbh_printer_get_device_id(struct usbh_printer *printer_class, uint8_
 
 static int usbh_printer_get_port_status(struct usbh_printer *printer_class, uint8_t *buffer)
 {
-    struct usb_setup_packet *setup = printer_class->hport->setup;
+    struct usb_setup_packet *setup = &printer_class->hport->setup;
     int ret;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -38,7 +38,7 @@ static int usbh_printer_get_port_status(struct usbh_printer *printer_class, uint
 
 static int usbh_printer_soft_reset(struct usbh_printer *printer_class)
 {
-    struct usb_setup_packet *setup = printer_class->hport->setup;
+    struct usb_setup_packet *setup = &printer_class->hport->setup;
     int ret;
 
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -74,13 +74,13 @@ static int usbh_printer_connect(struct usbh_hubport *hport, uint8_t intf)
 
         ep_cfg.ep_addr = ep_desc->bEndpointAddress;
         ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
-        ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
+        ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&printer_class->bulkin, &ep_cfg);
+            usbh_pipe_alloc(&printer_class->bulkin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&printer_class->bulkout, &ep_cfg);
+            usbh_pipe_alloc(&printer_class->bulkout, &ep_cfg);
         }
     }
 
@@ -101,17 +101,11 @@ static int usbh_printer_disconnect(struct usbh_hubport *hport, uint8_t intf)
 
     if (printer_class) {
         if (printer_class->bulkin) {
-            ret = usb_ep_cancel(printer_class->bulkin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(printer_class->bulkin);
+            usbh_pipe_free(printer_class->bulkin);
         }
 
         if (printer_class->bulkout) {
-            ret = usb_ep_cancel(printer_class->bulkout);
-            if (ret < 0) {
-            }
-            usbh_ep_free(printer_class->bulkout);
+            usbh_pipe_free(printer_class->bulkout);
         }
 
         usb_free(printer_class);

+ 2 - 2
class/printer/usbh_printer.h

@@ -12,8 +12,8 @@ struct usbh_printer {
     struct usbh_hubport *hport;
 
     uint8_t intf;          /* interface number */
-    usbh_epinfo_t bulkin;  /* BULK IN endpoint */
-    usbh_epinfo_t bulkout; /* BULK OUT endpoint */
+    usbh_pipe_t bulkin;  /* BULK IN endpoint */
+    usbh_pipe_t bulkout; /* BULK OUT endpoint */
 };
 
 #ifdef __cplusplus

+ 4 - 10
class/template/usbh_xxx.c

@@ -32,9 +32,9 @@ static int usbh_xxx_connect(struct usbh_hubport *hport, uint8_t intf)
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&rndis_class->bulkin, &ep_cfg);
+            usbh_pipe_alloc(&rndis_class->bulkin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&rndis_class->bulkout, &ep_cfg);
+            usbh_pipe_alloc(&rndis_class->bulkout, &ep_cfg);
         }
     }
 
@@ -51,17 +51,11 @@ static int usbh_xxx_disconnect(struct usbh_hubport *hport, uint8_t intf)
 
     if (xxx_class) {
         if (xxx_class->bulkin) {
-            ret = usb_ep_cancel(xxx_class->bulkin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(xxx_class->bulkin);
+            usbh_pipe_free(xxx_class->bulkin);
         }
 
         if (xxx_class->bulkout) {
-            ret = usb_ep_cancel(xxx_class->bulkout);
-            if (ret < 0) {
-            }
-            usbh_ep_free(xxx_class->bulkout);
+            usbh_pipe_free(xxx_class->bulkout);
         }
 
         usb_free(xxx_class);

+ 2 - 2
class/template/usbh_xxx.h

@@ -7,8 +7,8 @@ struct usbh_xxx {
     struct usbh_hubport *hport;
 
     uint8_t intf; /* interface number */
-    usbh_epinfo_t intin;  /* INTR IN endpoint */
-    usbh_epinfo_t intout; /* INTR OUT endpoint */
+    usbh_pipe_t intin;  /* INTR IN endpoint */
+    usbh_pipe_t intout; /* INTR OUT endpoint */
 };
 
 #endif

+ 3 - 3
class/vendor/axusbnet.c

@@ -1166,14 +1166,14 @@ static int usbh_axusbnet_connect(struct usbh_hubport *hport, uint8_t intf)
         if(ep_cfg.ep_type == USB_ENDPOINT_TYPE_BULK)
         {
             if (ep_desc->bEndpointAddress & 0x80) {
-                usbh_ep_alloc(&class->bulkin, &ep_cfg);
+                usbh_pipe_alloc(&class->bulkin, &ep_cfg);
             } else {
-                usbh_ep_alloc(&class->bulkout, &ep_cfg);
+                usbh_pipe_alloc(&class->bulkout, &ep_cfg);
             }
         }
         else
         {
-            usbh_ep_alloc(&class->int_notify, &ep_cfg);
+            usbh_pipe_alloc(&class->int_notify, &ep_cfg);
         }
     }
 

+ 3 - 3
class/vendor/axusbnet.h

@@ -20,9 +20,9 @@ struct usbh_axusbnet {
 
     uint8_t intf; /* interface number */
 
-    usbh_epinfo_t int_notify; /* Notify endpoint */
-    usbh_epinfo_t bulkin;  /* Bulk IN endpoint */
-    usbh_epinfo_t bulkout; /* Bulk OUT endpoint */
+    usbh_pipe_t int_notify; /* Notify endpoint */
+    usbh_pipe_t bulkin;  /* Bulk IN endpoint */
+    usbh_pipe_t bulkout; /* Bulk OUT endpoint */
 
     uint32_t bulkin_buf[2048/sizeof(uint32_t)];
 };

+ 4 - 4
class/vendor/usbh_air724.c

@@ -12,8 +12,8 @@ static uint32_t g_devinuse = 0;
 struct usbh_cdc_custom_air724 {
     struct usbh_hubport *hport;
 
-    usbh_epinfo_t bulkin;  /* Bulk IN endpoint */
-    usbh_epinfo_t bulkout; /* Bulk OUT endpoint */
+    usbh_pipe_t bulkin;  /* Bulk IN endpoint */
+    usbh_pipe_t bulkout; /* Bulk OUT endpoint */
 };
 
 int usbh_air724_connect(struct usbh_hubport *hport, uint8_t intf)
@@ -48,9 +48,9 @@ int usbh_air724_connect(struct usbh_hubport *hport, uint8_t intf)
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&cdc_custom_class->bulkin, &ep_cfg);
+            usbh_pipe_alloc(&cdc_custom_class->bulkin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&cdc_custom_class->bulkout, &ep_cfg);
+            usbh_pipe_alloc(&cdc_custom_class->bulkout, &ep_cfg);
         }
     }
 

+ 10 - 16
class/wireless/usbh_rndis.c

@@ -11,7 +11,7 @@
 
 static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
 {
-    struct usb_setup_packet *setup = rndis_class->hport->setup;
+    struct usb_setup_packet *setup = &rndis_class->hport->setup;
     int ret = 0;
     rndis_initialize_msg_t cmd;
     rndis_initialize_cmplt_t resp;
@@ -54,7 +54,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
 
 int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, uint32_t query_len, uint8_t *info, uint32_t *info_len)
 {
-    struct usb_setup_packet *setup = rndis_class->hport->setup;
+    struct usb_setup_packet *setup = &rndis_class->hport->setup;
     int ret = 0;
     rndis_query_msg_t cmd;
     rndis_query_cmplt_t *resp;
@@ -110,7 +110,7 @@ error_out:
 
 static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, uint8_t *info, uint32_t info_len)
 {
-    struct usb_setup_packet *setup = rndis_class->hport->setup;
+    struct usb_setup_packet *setup = &rndis_class->hport->setup;
     int ret = 0;
     rndis_set_msg_t *cmd;
     rndis_set_cmplt_t resp;
@@ -164,7 +164,7 @@ error_out:
 
 int usbh_rndis_keepalive(struct usbh_rndis *rndis_class)
 {
-    struct usb_setup_packet *setup = rndis_class->hport->setup;
+    struct usb_setup_packet *setup = &rndis_class->hport->setup;
     int ret = 0;
     rndis_keepalive_msg_t cmd;
     rndis_keepalive_cmplt_t resp;
@@ -231,10 +231,10 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
     ep_desc = &hport->config.intf[intf].ep[0].ep_desc;
     ep_cfg.ep_addr = ep_desc->bEndpointAddress;
     ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
-    ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
+    ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;;
     ep_cfg.ep_interval = ep_desc->bInterval;
     ep_cfg.hport = hport;
-    usbh_ep_alloc(&rndis_class->intin, &ep_cfg);
+    usbh_pipe_alloc(&rndis_class->intin, &ep_cfg);
 
 #endif
     for (uint8_t i = 0; i < hport->config.intf[intf + 1].intf_desc.bNumEndpoints; i++) {
@@ -246,9 +246,9 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
         ep_cfg.ep_interval = ep_desc->bInterval;
         ep_cfg.hport = hport;
         if (ep_desc->bEndpointAddress & 0x80) {
-            usbh_ep_alloc(&rndis_class->bulkin, &ep_cfg);
+            usbh_pipe_alloc(&rndis_class->bulkin, &ep_cfg);
         } else {
-            usbh_ep_alloc(&rndis_class->bulkout, &ep_cfg);
+            usbh_pipe_alloc(&rndis_class->bulkout, &ep_cfg);
         }
     }
 
@@ -355,17 +355,11 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
 
     if (rndis_class) {
         if (rndis_class->bulkin) {
-            ret = usb_ep_cancel(rndis_class->bulkin);
-            if (ret < 0) {
-            }
-            usbh_ep_free(rndis_class->bulkin);
+            usbh_pipe_free(rndis_class->bulkin);
         }
 
         if (rndis_class->bulkout) {
-            ret = usb_ep_cancel(rndis_class->bulkout);
-            if (ret < 0) {
-            }
-            usbh_ep_free(rndis_class->bulkout);
+            usbh_pipe_free(rndis_class->bulkout);
         }
 
         usb_free(rndis_class);

+ 3 - 3
class/wireless/usbh_rndis.h

@@ -14,9 +14,9 @@ struct usbh_rndis {
     uint8_t ctrl_intf; /* Control interface number */
     uint8_t data_intf; /* Data interface number */
 
-    usbh_epinfo_t bulkin;  /* Bulk IN endpoint */
-    usbh_epinfo_t bulkout; /* Bulk OUT endpoint */
-    usbh_epinfo_t intin;   /* Notify endpoint */
+    usbh_pipe_t bulkin;  /* Bulk IN endpoint */
+    usbh_pipe_t bulkout; /* Bulk OUT endpoint */
+    usbh_pipe_t intin;   /* Notify endpoint */
 
     uint32_t request_id;
     uint8_t mac[6];

+ 43 - 130
common/usb_hc.h

@@ -12,8 +12,8 @@
 extern "C" {
 #endif
 
-typedef void (*usbh_asynch_callback_t)(void *arg, int nbytes);
-typedef void *usbh_epinfo_t;
+typedef void (*usbh_complete_callback_t)(void *arg, int nbytes);
+typedef void *usbh_pipe_t;
 
 /**
  * @brief USB Endpoint Configuration.
@@ -29,174 +29,87 @@ struct usbh_endpoint_cfg {
 };
 
 /**
- * @brief usb host software init, used for global reset.
- *
- * @return On success will return 0, and others indicate fail.
- */
-int usb_hc_sw_init(void);
+ * @brief USB Urb Configuration.
+ *
+ * Structure containing the USB Urb configuration.
+ */
+struct usbh_urb {
+    usbh_pipe_t pipe;
+    struct usb_setup_packet *setup;
+    uint8_t *transfer_buffer;
+    uint32_t transfer_buffer_length;
+    int transfer_flags;
+    uint32_t actual_length;
+    uint32_t timeout;
+    int errorcode;
+    usbh_complete_callback_t complete;
+    void *arg;
+};
 
 /**
  * @brief usb host controller hardware init.
  *
  * @return On success will return 0, and others indicate fail.
  */
-int usb_hc_hw_init(void);
+int usb_hc_init(void);
 
 /**
- * @brief get port connect status
+ * @brief control roothub.
  *
- * @param port
+ * @param setup setup request buffer.
+ * @param buf buf for reading response or write data.
  * @return On success will return 0, and others indicate fail.
  */
-bool usbh_get_port_connect_status(const uint8_t port);
-
-/**
- * @brief reset roothub port
- *
- * @param port port index
- * @return On success will return 0, and others indicate fail.
- */
-int usbh_reset_port(const uint8_t port);
-
-/**
- * @brief get roothub port speed
- *
- * @param port port index
- * @return return 1 means USB_SPEED_LOW, 2 means USB_SPEED_FULL and 3 means USB_SPEED_HIGH.
- */
-uint8_t usbh_get_port_speed(const uint8_t port);
+int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf);
 
 /**
- * @brief reconfig control endpoint.
+ * @brief reconfig control endpoint pipe.
  *
- * @param ep A memory location provided by the caller.
+ * @param pipe A memory allocated for pipe.
  * @param dev_addr device address.
  * @param ep_mps control endpoint max packet size.
  * @param speed port speed
  * @return On success will return 0, and others indicate fail.
  */
-int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed);
+int usbh_ep0_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed);
 
 /**
- * @brief Allocate and config endpoint
+ * @brief Allocate pipe for endpoint
  *
- * @param ep A memory location provided by the caller in which to save the allocated endpoint info.
+ * @param pipe A memory location provided by the caller in which to save the allocated pipe.
  * @param ep_cfg Describes the endpoint info to be allocated.
  * @return  On success will return 0, and others indicate fail.
  */
-int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg);
+int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg);
 
 /**
- * @brief Free a memory in which saves endpoint info.
+ * @brief Free a pipe in which saves endpoint info.
  *
- * @param ep A memory location provided by the caller in which to free the allocated endpoint info.
+ * @param pipe A memory location provided by the caller in which to free the allocated endpoint info.
  * @return On success will return 0, and others indicate fail.
  */
-int usbh_ep_free(usbh_epinfo_t ep);
+int usbh_pipe_free(usbh_pipe_t pipe);
 
 /**
- * @brief Perform a control transfer.
- * This is a blocking method; this method will not return until the transfer has completed.
+ * @brief Submit a usb transfer request to an endpoint.
  *
- * @param ep The control endpoint to send/receive the control request.
- * @param setup Setup packet to be sent.
- * @param buffer buffer used for sending the request and for returning any responses.  This buffer must be large enough to hold the length value
- *  in the request description.
- * @return On success will return 0, and others indicate fail.
- */
-int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint8_t *buffer);
-
-/**
- * @brief  Process a request to handle a transfer descriptor.  This method will
- * enqueue the transfer request and wait for it to complete.  Only one transfer may be queued;
- * This is a blocking method; this method will not return until the transfer has completed.
+ * If timeout is not zero, this function will be in poll transfer mode,
+ * otherwise will be in async transfer mode.
  *
- * @param ep The IN or OUT endpoint descriptor for the device endpoint on which to perform the transfer.
- * @param buffer A buffer containing the data to be sent (OUT endpoint) or received (IN endpoint).
- * @param buflen The length of the data to be sent or received.
- * @param timeout Timeout for transfer, unit is ms.
- * @return On success, a non-negative value is returned that indicates the number
- *   of bytes successfully transferred.  On a failure, a negated errno value
- *   is returned that indicates the nature of the failure:
- *
- *     -EAGAIN - If devices NAKs the transfer (or NYET or other error where
- *              it may be appropriate to restart the entire transaction).
- *     -EPERM  - If the endpoint stalls
- *     -EIO    - On a TX or data toggle error
- *     -EPIPE  - Overrun errors
- *     -ETIMEDOUT  - Sem wait timeout
- *
- */
-int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-
-/**
- * @brief  Process a request to handle a transfer descriptor.  This method will
- * enqueue the transfer request and wait for it to complete.  Only one transfer may be queued;
- * This is a blocking method; this method will not return until the transfer has completed.
- *
- * @param ep The IN or OUT endpoint descriptor for the device endpoint on which to perform the transfer.
- * @param buffer A buffer containing the data to be sent (OUT endpoint) or received (IN endpoint).
- * @param buflen The length of the data to be sent or received.
- * @param timeout Timeout for transfer, unit is ms.
- * @return On success, a non-negative value is returned that indicates the number
- *   of bytes successfully transferred.  On a failure, a negated errno value
- *   is returned that indicates the nature of the failure:
- *
- *     -EAGAIN - If devices NAKs the transfer (or NYET or other error where
- *              it may be appropriate to restart the entire transaction).
- *     -EPERM  - If the endpoint stalls
- *     -EIO    - On a TX or data toggle error
- *     -EPIPE  - Overrun errors
- *     -ETIMEDOUT  - Sem wait timeout
- *
- */
-int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-
-/**
- * @brief Process a request to handle a transfer asynchronously.  This method
- * will enqueue the transfer request and return immediately.  Only one transfer may be queued on a given endpoint
- * When the transfer completes, the callback will be invoked with the provided argument.
- *
- * This method is useful for receiving interrupt transfers which may come infrequently.
- *
- * @param ep The IN or OUT endpoint descriptor for the device endpoint on which to perform the transfer.
- * @param buffer A buffer containing the data to be sent (OUT endpoint) or received (IN endpoint).
- * @param buflen The length of the data to be sent or received.
- * @param callback This function will be called when the transfer completes.
- * @param arg The arbitrary parameter that will be passed to the callback function when the transfer completes.
- *
- * @return On success will return 0, and others indicate fail.
+ * @param urb Usb request block.
+ * @return  On success will return 0, and others indicate fail.
  */
-int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg);
+int usbh_submit_urb(struct usbh_urb *urb);
 
 /**
- * @brief Process a request to handle a transfer asynchronously.  This method
- * will enqueue the transfer request and return immediately.  Only one transfer may be queued on a given endpoint
- * When the transfer completes, the callback will be invoked with the provided argument.
+ * @brief Cancel a transfer request.
  *
- * This method is useful for receiving interrupt transfers which may come infrequently.
+ * This function will call When calls usbh_submit_urb and return -ETIMEOUT or -ESHUTDOWN.
  *
- * @param ep The IN or OUT endpoint descriptor for the device endpoint on which to perform the transfer.
- * @param buffer A buffer containing the data to be sent (OUT endpoint) or received (IN endpoint).
- * @param buflen The length of the data to be sent or received.
- * @param callback This function will be called when the transfer completes.
- * @param arg The arbitrary parameter that will be passed to the callback function when the transfer completes.
- *
- * @return On success will return 0, and others indicate fail.
- */
-int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg);
-
-/**
- * @brief Cancel any pending syncrhonous or asynchronous transfer on an endpoint.
- *
- * @param ep The IN or OUT endpoint descriptor for the device endpoint on which to cancel.
- * @return On success will return 0, and others indicate fail.
+ * @param urb Usb request block.
+ * @return  On success will return 0, and others indicate fail.
  */
-int usb_ep_cancel(usbh_epinfo_t ep);
-
-/* usb hcd irq callback */
-
-void usbh_event_notify_handler(uint8_t event, uint8_t rhport);
+int usbh_kill_urb(struct usbh_urb *urb);
 
 #ifdef __cplusplus
 }

+ 18 - 15
common/usb_list.h

@@ -46,12 +46,14 @@ static inline void usb_slist_add_head(usb_slist_t *l, usb_slist_t *n)
 
 static inline void usb_slist_add_tail(usb_slist_t *l, usb_slist_t *n)
 {
-    while (l->next) {
-        l = l->next;
+    usb_slist_t *tmp = l;
+
+    while (tmp->next) {
+        tmp = tmp->next;
     }
 
     /* append the node to the tail */
-    l->next = n;
+    tmp->next = n;
     n->next = NULL;
 }
 
@@ -74,14 +76,15 @@ static inline void usb_slist_insert(usb_slist_t *l, usb_slist_t *next, usb_slist
 
 static inline usb_slist_t *usb_slist_remove(usb_slist_t *l, usb_slist_t *n)
 {
+    usb_slist_t *tmp = l;
     /* remove slist head */
-    while (l->next && l->next != n) {
-        l = l->next;
+    while (tmp->next && tmp->next != n) {
+        tmp = tmp->next;
     }
 
     /* remove node */
-    if (l->next != (usb_slist_t *)0) {
-        l->next = l->next->next;
+    if (tmp->next != (usb_slist_t *)0) {
+        tmp->next = tmp->next->next;
     }
 
     return l;
@@ -333,8 +336,8 @@ static inline unsigned int usb_dlist_len(const usb_dlist_t *l)
  * @brief initialize a dlist object
  */
 #define USB_DLIST_OBJECT_INIT(object) \
-    {                             \
-        &(object), &(object)      \
+    {                                 \
+        &(object), &(object)          \
     }
 /**
  * @brief initialize a dlist object
@@ -394,11 +397,11 @@ static inline unsigned int usb_dlist_len(const usb_dlist_t *l)
  * @n:      another dlist_t * to use as temporary storage
  * @head:   the head for your list.
  */
-#define usb_dlist_for_each_safe(pos, n, head)                  \
+#define usb_dlist_for_each_safe(pos, n, head)              \
     for (pos = (head)->next, n = pos->next; pos != (head); \
          pos = n, n = pos->next)
 
-#define usb_dlist_for_each_prev_safe(pos, n, head)             \
+#define usb_dlist_for_each_prev_safe(pos, n, head)         \
     for (pos = (head)->prev, n = pos->prev; pos != (head); \
          pos = n, n = pos->prev)
 /**
@@ -409,7 +412,7 @@ static inline unsigned int usb_dlist_len(const usb_dlist_t *l)
  */
 #define usb_dlist_for_each_entry(pos, head, member)                 \
     for (pos = usb_dlist_entry((head)->next, typeof(*pos), member); \
-         &pos->member != (head);                                \
+         &pos->member != (head);                                    \
          pos = usb_dlist_entry(pos->member.next, typeof(*pos), member))
 
 /**
@@ -420,7 +423,7 @@ static inline unsigned int usb_dlist_len(const usb_dlist_t *l)
  */
 #define usb_dlist_for_each_entry_reverse(pos, head, member)         \
     for (pos = usb_dlist_entry((head)->prev, typeof(*pos), member); \
-         &pos->member != (head);                                \
+         &pos->member != (head);                                    \
          pos = usb_dlist_entry(pos->member.prev, typeof(*pos), member))
 
 /**
@@ -433,7 +436,7 @@ static inline unsigned int usb_dlist_len(const usb_dlist_t *l)
 #define usb_dlist_for_each_entry_safe(pos, n, head, member)          \
     for (pos = usb_dlist_entry((head)->next, typeof(*pos), member),  \
         n = usb_dlist_entry(pos->member.next, typeof(*pos), member); \
-         &pos->member != (head);                                 \
+         &pos->member != (head);                                     \
          pos = n, n = usb_dlist_entry(n->member.next, typeof(*n), member))
 
 /**
@@ -446,7 +449,7 @@ static inline unsigned int usb_dlist_len(const usb_dlist_t *l)
 #define usb_dlist_for_each_entry_safe_reverse(pos, n, head, member)  \
     for (pos = usb_dlist_entry((head)->prev, typeof(*pos), field),   \
         n = usb_dlist_entry(pos->member.prev, typeof(*pos), member); \
-         &pos->member != (head);                                 \
+         &pos->member != (head);                                     \
          pos = n, n = usb_dlist_entry(pos->member.prev, typeof(*pos), member))
 
 #ifdef __cplusplus

+ 264 - 478
core/usbh_core.c

@@ -4,13 +4,12 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 #include "usbh_core.h"
+#include "usbh_hub.h"
 
 struct usbh_class_info *usbh_class_info_table_begin = NULL;
 struct usbh_class_info *usbh_class_info_table_end = NULL;
 
-static const char *speed_table[] = { "error speed", "low speed", "full speed", "high speed" };
-
-static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subcalss, uint8_t protocol, uint16_t vid, uint16_t pid);
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_REQUEST_BUFFER_LEN];
 
 /* general descriptor field offsets */
 #define DESC_bLength         0 /** Length offset */
@@ -20,7 +19,7 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
 #define USB_DEV_ADDR_MARK_OFFSET 5
 #define USB_DEV_ADDR_MARK_MASK   0x1f
 
-struct usbh_devaddr_priv {
+struct usbh_devaddr_map {
     /**
      * alloctab[0]:addr from 0~31
      * alloctab[1]:addr from 32~63
@@ -32,26 +31,11 @@ struct usbh_devaddr_priv {
     uint32_t alloctab[4]; /* Bit allocation table */
 };
 
-struct usbh_roothubport_priv {
-    struct usbh_hubport hport;
-    struct usbh_devaddr_priv devgen;
-};
-
-struct usbh_core_priv {
-    struct usbh_roothubport_priv rhport[CONFIG_USBHOST_RHPORTS];
-    volatile struct usbh_hubport *active_hport; /* Used to pass external hub port events */
-    usb_osal_event_t pscevent;                  /* Semaphore to wait for a port event */
-} usbh_core_cfg;
+struct usbh_bus {
+    struct usbh_devaddr_map devgen;
+} g_usbh_bus;
 
-static inline struct usbh_roothubport_priv *usbh_find_roothub_port(struct usbh_hubport *hport)
-{
-    while (hport->parent != NULL) {
-        hport = hport->parent->parent;
-    }
-    return (struct usbh_roothubport_priv *)hport;
-}
-
-static int usbh_allocate_devaddr(struct usbh_devaddr_priv *devgen)
+static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
 {
     uint8_t startaddr = devgen->next;
     uint8_t devaddr;
@@ -61,7 +45,7 @@ static int usbh_allocate_devaddr(struct usbh_devaddr_priv *devgen)
     for (;;) {
         devaddr = devgen->next;
         if (devgen->next >= 0x7f) {
-            devgen->next = 1;
+            devgen->next = 2;
         } else {
             devgen->next++;
         }
@@ -79,7 +63,7 @@ static int usbh_allocate_devaddr(struct usbh_devaddr_priv *devgen)
     }
 }
 
-static int usbh_free_devaddr(struct usbh_devaddr_priv *devgen, uint8_t devaddr)
+static int usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
 {
     int index;
     int bitno;
@@ -103,58 +87,35 @@ static int usbh_free_devaddr(struct usbh_devaddr_priv *devgen, uint8_t devaddr)
     return 0;
 }
 
-static int usbh_devaddr_create(struct usbh_hubport *hport)
+static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol,
+                                                              uint16_t vid, uint16_t pid)
 {
-    struct usbh_roothubport_priv *rhport;
-    rhport = usbh_find_roothub_port(hport);
-
-    return usbh_allocate_devaddr(&rhport->devgen);
-}
-
-static int usbh_devaddr_destroy(struct usbh_hubport *hport, uint8_t dev_addr)
-{
-    struct usbh_roothubport_priv *rhport;
-    rhport = usbh_find_roothub_port(hport);
-
-    return usbh_free_devaddr(&rhport->devgen, dev_addr);
-}
-
-void usbh_hport_activate(struct usbh_hubport *hport)
-{
-    struct usbh_endpoint_cfg ep0_cfg;
-
-    memset(&ep0_cfg, 0, sizeof(struct usbh_endpoint_cfg));
-
-    ep0_cfg.ep_addr = 0x00;
-    ep0_cfg.ep_interval = 0x00;
-    ep0_cfg.ep_mps = 0x08;
-    ep0_cfg.ep_type = USB_ENDPOINT_TYPE_CONTROL;
-    ep0_cfg.hport = hport;
-    /* Allocate memory for roothub port control endpoint */
-    usbh_ep_alloc(&hport->ep0, &ep0_cfg);
-}
-
-void usbh_hport_deactivate(struct usbh_hubport *hport)
-{
-    size_t flags;
+    struct usbh_class_info *index = NULL;
 
-    /* Don't free the control pipe of root hub ports! */
-    if (hport->parent != NULL && hport->ep0 != NULL) {
-        usb_ep_cancel(hport->ep0);
-        usbh_ep_free(hport->ep0);
-        hport->ep0 = NULL;
+    for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) {
+        if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) ==
+            (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) {
+            if (index->vid == vid && index->pid == pid &&
+                index->class == class && index->subclass == subclass && index->protocol == protocol) {
+                return index->class_driver;
+            }
+        } else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) ==
+                   (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) {
+            if (index->class == class && index->subclass == subclass && index->protocol == protocol) {
+                return index->class_driver;
+            }
+        } else if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) ==
+                   (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) {
+            if (index->vid == vid && index->pid == pid && index->class == class) {
+                return index->class_driver;
+            }
+        } else if (index->match_flags & (USB_CLASS_MATCH_INTF_CLASS)) {
+            if (index->class == class) {
+                return index->class_driver;
+            }
+        }
     }
-
-    flags = usb_osal_enter_critical_section();
-    /* Free the device address if one has been assigned */
-    usbh_devaddr_destroy(hport, hport->dev_addr);
-    hport->dev_addr = 0;
-    usb_osal_leave_critical_section(flags);
-
-    if (hport->setup)
-        usb_iofree(hport->setup);
-
-    hport->setup = NULL;
+    return NULL;
 }
 
 static int parse_device_descriptor(struct usbh_hubport *hport, struct usb_device_descriptor *desc, uint16_t length)
@@ -206,10 +167,15 @@ static int parse_device_descriptor(struct usbh_hubport *hport, struct usb_device
 
 static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_configuration_descriptor *desc, uint16_t length)
 {
-    uint32_t total_len = 0;
-    uint8_t ep_num = 0;
-    uint8_t intf_num = 0;
-    uint8_t *p = (uint8_t *)desc;
+    struct usb_interface_descriptor *intf_desc;
+    struct usb_endpoint_descriptor *ep_desc;
+    uint8_t cur_alt_setting;
+    uint8_t cur_iface = 0xff;
+    uint8_t cur_ep = 0xff;
+    uint8_t cur_ep_num;
+    uint32_t desc_len = 0;
+    uint8_t *p;
+
     if (desc->bLength != USB_SIZEOF_CONFIG_DESC) {
         USB_LOG_ERR("invalid config bLength 0x%02x\r\n", desc->bLength);
         return -EINVAL;
@@ -241,12 +207,26 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
         hport->config.config_desc.bmAttributes = desc->bmAttributes;
         hport->config.config_desc.bMaxPower = desc->bMaxPower;
 
-        if (length > USB_SIZEOF_CONFIG_DESC) {
-            while (p[DESC_bLength] && (total_len < desc->wTotalLength) && (intf_num < desc->bNumInterfaces)) {
-                p += p[DESC_bLength];
-                total_len += p[DESC_bLength];
-                if (p[DESC_bDescriptorType] == USB_DESCRIPTOR_TYPE_INTERFACE) {
-                    struct usb_interface_descriptor *intf_desc = (struct usb_interface_descriptor *)p;
+        p = (uint8_t *)desc;
+        p += USB_SIZEOF_CONFIG_DESC;
+        desc_len = USB_SIZEOF_CONFIG_DESC;
+
+        while (p[DESC_bLength] && (desc_len <= length)) {
+            switch (p[DESC_bDescriptorType]) {
+                case USB_DESCRIPTOR_TYPE_INTERFACE:
+                    intf_desc = (struct usb_interface_descriptor *)p;
+                    cur_iface = intf_desc->bInterfaceNumber;
+                    cur_alt_setting = intf_desc->bAlternateSetting;
+                    cur_ep_num = intf_desc->bNumEndpoints;
+                    cur_ep = 0;
+                    if (cur_iface > CONFIG_USBHOST_INTF_NUM) {
+                        return -ENOMEM;
+                    }
+                    if (cur_ep_num > CONFIG_USBHOST_EP_NUM) {
+                        return -ENOMEM;
+                    }
+
+                    memset(&hport->config.intf[cur_iface], 0, sizeof(struct usbh_interface));
 #if 0
                     USB_LOG_DBG("Interface Descriptor:\r\n");
                     USB_LOG_DBG("bLength: 0x%02x            \r\n", intf_desc->bLength);
@@ -259,77 +239,43 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
                     USB_LOG_DBG("bInterfaceProtocol: 0x%02x \r\n", intf_desc->bInterfaceProtocol);
                     USB_LOG_DBG("iInterface: 0x%02x         \r\n", intf_desc->iInterface);
 #endif
-                    memset(&hport->config.intf[intf_num], 0, sizeof(struct usbh_interface));
-
-                    hport->config.intf[intf_num].intf_desc.bLength = intf_desc->bLength;
-                    hport->config.intf[intf_num].intf_desc.bDescriptorType = intf_desc->bDescriptorType;
-                    hport->config.intf[intf_num].intf_desc.bInterfaceNumber = intf_desc->bInterfaceNumber;
-                    hport->config.intf[intf_num].intf_desc.bAlternateSetting = intf_desc->bAlternateSetting;
-                    hport->config.intf[intf_num].intf_desc.bNumEndpoints = intf_desc->bNumEndpoints;
-                    hport->config.intf[intf_num].intf_desc.bInterfaceClass = intf_desc->bInterfaceClass;
-                    hport->config.intf[intf_num].intf_desc.bInterfaceSubClass = intf_desc->bInterfaceSubClass;
-                    hport->config.intf[intf_num].intf_desc.bInterfaceProtocol = intf_desc->bInterfaceProtocol;
-                    hport->config.intf[intf_num].intf_desc.iInterface = intf_desc->iInterface;
-                    ep_num = 0;
-                    while (p[DESC_bLength] && (total_len < desc->wTotalLength) && (ep_num < intf_desc->bNumEndpoints)) {
-                        p += p[DESC_bLength];
-                        total_len += p[DESC_bLength];
-                        if (p[DESC_bDescriptorType] == USB_DESCRIPTOR_TYPE_ENDPOINT) {
-                            struct usb_endpoint_descriptor *ep_desc = (struct usb_endpoint_descriptor *)p;
-#if 0
-                            USB_LOG_DBG("Endpoint Descriptor:\r\n");
-                            USB_LOG_DBG("bLength: 0x%02x          \r\n", ep_desc->bLength);
-                            USB_LOG_DBG("bDescriptorType: 0x%02x  \r\n", ep_desc->bDescriptorType);
-                            USB_LOG_DBG("bEndpointAddress: 0x%02x \r\n", ep_desc->bEndpointAddress);
-                            USB_LOG_DBG("bmAttributes: 0x%02x     \r\n", ep_desc->bmAttributes);
-                            USB_LOG_DBG("wMaxPacketSize: 0x%04x   \r\n", ep_desc->wMaxPacketSize);
-                            USB_LOG_DBG("bInterval: 0x%02x        \r\n", ep_desc->bInterval);
-#endif
-                            memset(&hport->config.intf[intf_num].ep[ep_num], 0, sizeof(struct usbh_endpoint));
-
-                            hport->config.intf[intf_num].ep[ep_num].ep_desc.bLength = ep_desc->bLength;
-                            hport->config.intf[intf_num].ep[ep_num].ep_desc.bDescriptorType = ep_desc->bDescriptorType;
-                            hport->config.intf[intf_num].ep[ep_num].ep_desc.bEndpointAddress = ep_desc->bEndpointAddress;
-                            hport->config.intf[intf_num].ep[ep_num].ep_desc.bmAttributes = ep_desc->bmAttributes;
-                            hport->config.intf[intf_num].ep[ep_num].ep_desc.wMaxPacketSize = ep_desc->wMaxPacketSize;
-                            hport->config.intf[intf_num].ep[ep_num].ep_desc.bInterval = ep_desc->bInterval;
-                            ep_num++;
-                        }
+                    memcpy(&hport->config.intf[cur_iface].intf_desc, intf_desc, 9);
+                    if (cur_alt_setting == 1) {
+                        USB_LOG_WRN("Altsetting enable, the previous intf info will be overwrited\r\n");
                     }
-                    intf_num++;
-                }
+                    break;
+                case USB_DESCRIPTOR_TYPE_ENDPOINT:
+                    ep_desc = (struct usb_endpoint_descriptor *)p;
+                    memset(&hport->config.intf[cur_iface].ep[cur_ep], 0, sizeof(struct usbh_endpoint));
+                    memcpy(&hport->config.intf[cur_iface].ep[cur_ep].ep_desc, ep_desc, 7);
+                    cur_ep++;
+                    break;
+
+                default:
+                    break;
             }
+            /* skip to next descriptor */
+            p += p[DESC_bLength];
+            desc_len += p[DESC_bLength];
         }
     }
     return 0;
 }
 
 #ifdef CONFIG_USBHOST_GET_STRING_DESC
-static int parse_string_descriptor(struct usbh_hubport *hport, struct usb_string_descriptor *desc, uint8_t str_idx)
+void usbh_print_string(char *lead, uint8_t *str)
 {
     uint8_t string[64 + 1] = { 0 };
-    uint8_t *p = (uint8_t *)desc;
 
-    if (desc->bDescriptorType != USB_DESCRIPTOR_TYPE_STRING) {
-        USB_LOG_ERR("unexpected string descriptor 0x%02x\r\n", desc->bDescriptorType);
-        return -2;
-    } else {
-        p += 2;
-        for (uint32_t i = 0; i < (desc->bLength - 2) / 2; i++) {
-            string[i] = *p;
-            p += 2;
-        }
-        if (str_idx == USB_STRING_MFC_INDEX) {
-            USB_LOG_INFO("Manufacturer :%s\r\n", string);
-        } else if (str_idx == USB_STRING_PRODUCT_INDEX) {
-            USB_LOG_INFO("Product :%s\r\n", string);
+    int len, i = 2, j = 0;
 
-        } else if (str_idx == USB_STRING_SERIAL_INDEX) {
-            USB_LOG_INFO("SerialNumber :%s\r\n", string);
-        } else {
-        }
+    len = str[0];
+    while (i < len) {
+        string[j] = str[i];
+        i += 2;
+        j++;
     }
-    return 0;
+    USB_LOG_RAW("%s%s\r\n", lead, string);
 }
 #endif
 
@@ -385,33 +331,45 @@ static void usbh_print_hubport_info(struct usbh_hubport *hport)
     }
 }
 
-static int usbh_enumerate(struct usbh_hubport *hport)
+int usbh_hport_activate_ep0(struct usbh_hubport *hport)
+{
+    struct usbh_endpoint_cfg ep0_cfg = { 0 };
+
+    ep0_cfg.ep_addr = 0x00;
+    ep0_cfg.ep_interval = 0x00;
+    ep0_cfg.ep_mps = 0x08;
+    ep0_cfg.ep_type = USB_ENDPOINT_TYPE_CONTROL;
+    ep0_cfg.hport = hport;
+
+    usbh_pipe_alloc(&hport->ep0, &ep0_cfg);
+    return 0;
+}
+
+int usbh_hport_deactivate_ep0(struct usbh_hubport *hport)
+{
+    if (hport->dev_addr > 0) {
+        usbh_free_devaddr(&g_usbh_bus.devgen, hport->dev_addr);
+    }
+    if (hport->ep0) {
+        usbh_pipe_free(hport->ep0);
+    }
+
+    hport->ep0 = NULL;
+    hport->dev_addr = 0;
+    return 0;
+}
+
+int usbh_enumerate(struct usbh_hubport *hport)
 {
     struct usb_interface_descriptor *intf_desc;
     struct usb_setup_packet *setup;
-    uint8_t *ep0_buffer;
     uint8_t descsize;
     int dev_addr;
     uint8_t ep_mps;
     int ret;
 
 #define USB_REQUEST_BUFFER_SIZE 256
-    /* Allocate buffer for setup and data buffer */
-    if (hport->setup == NULL) {
-        hport->setup = usb_iomalloc(sizeof(struct usb_setup_packet));
-        if (hport->setup == NULL) {
-            USB_LOG_ERR("Fail to alloc setup\r\n");
-            return -ENOMEM;
-        }
-    }
-
-    setup = hport->setup;
-
-    ep0_buffer = usb_iomalloc(USB_REQUEST_BUFFER_SIZE);
-    if (ep0_buffer == NULL) {
-        USB_LOG_ERR("Fail to alloc ep0_buffer\r\n");
-        return -ENOMEM;
-    }
+    setup = &hport->setup;
 
     /* Pick an appropriate packet size for this device
      *
@@ -431,13 +389,13 @@ static int usbh_enumerate(struct usbh_hubport *hport)
         ep_mps = 64;
         descsize = USB_SIZEOF_DEVICE_DESC;
     } else {
-        /* For low or full, we use 8 bytes, 64 bytes is also ok */
+        /* For low or full, we use 8 bytes */
         ep_mps = 8;
         descsize = 8;
     }
 
     /* Configure EP0 with the initial maximum packet size */
-    usbh_ep0_reconfigure(hport->ep0, 0, ep_mps, hport->speed);
+    usbh_ep0_pipe_reconfigure(hport->ep0, 0, ep_mps, hport->speed);
 
     /* Read the first 8 bytes of the device descriptor */
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -446,26 +404,22 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = descsize;
 
-    ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer);
+    ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_buffer, descsize);
-
-    if ((hport->parent == NULL) && (hport->speed != USB_SPEED_HIGH)) {
-        usbh_reset_port(hport->port);
-    }
+    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, descsize);
 
     /* Extract the correct max packetsize from the device descriptor */
-    ep_mps = ((struct usb_device_descriptor *)ep0_buffer)->bMaxPacketSize0;
+    ep_mps = ((struct usb_device_descriptor *)ep0_request_buffer)->bMaxPacketSize0;
 
     /* And reconfigure EP0 with the correct maximum packet size */
-    usbh_ep0_reconfigure(hport->ep0, 0, ep_mps, hport->speed);
+    usbh_ep0_pipe_reconfigure(hport->ep0, 0, ep_mps, hport->speed);
 
     /* Assign a function address to the device connected to this port */
-    dev_addr = usbh_devaddr_create(hport);
+    dev_addr = usbh_allocate_devaddr(&g_usbh_bus.devgen);
     if (dev_addr < 0) {
         USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
         goto errout;
@@ -491,7 +445,7 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     hport->dev_addr = dev_addr;
 
     /* And reconfigure EP0 with the correct address */
-    usbh_ep0_reconfigure(hport->ep0, dev_addr, ep_mps, hport->speed);
+    usbh_ep0_pipe_reconfigure(hport->ep0, dev_addr, ep_mps, hport->speed);
 
     /* Read the full device descriptor */
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -500,17 +454,17 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = USB_SIZEOF_DEVICE_DESC;
 
-    ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer);
+    ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_buffer, USB_SIZEOF_DEVICE_DESC);
+    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, USB_SIZEOF_DEVICE_DESC);
     USB_LOG_INFO("New device found,idVendor:%04x,idProduct:%04x,bcdDevice:%04x\r\n",
-                 ((struct usb_device_descriptor *)ep0_buffer)->idVendor,
-                 ((struct usb_device_descriptor *)ep0_buffer)->idProduct,
-                 ((struct usb_device_descriptor *)ep0_buffer)->bcdDevice);
+                 ((struct usb_device_descriptor *)ep0_request_buffer)->idVendor,
+                 ((struct usb_device_descriptor *)ep0_request_buffer)->idProduct,
+                 ((struct usb_device_descriptor *)ep0_request_buffer)->bcdDevice);
 
     /* Read the first 9 bytes of the config descriptor */
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -519,16 +473,16 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = USB_SIZEOF_CONFIG_DESC;
 
-    ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer);
+    ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_buffer, USB_SIZEOF_CONFIG_DESC);
+    parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer, USB_SIZEOF_CONFIG_DESC);
 
     /* Read the full size of the configuration data */
-    uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_buffer)->wTotalLength;
+    uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_request_buffer)->wTotalLength;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
@@ -536,14 +490,14 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = wTotalLength;
 
-    ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer);
+    ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_buffer, wTotalLength);
-    USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_buffer)->bNumInterfaces);
+    parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer, wTotalLength);
+    USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer)->bNumInterfaces);
 
 #ifdef CONFIG_USBHOST_GET_STRING_DESC
     /* Get Manufacturer string */
@@ -553,13 +507,13 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0x0409;
     setup->wLength = 255;
 
-    ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer);
+    ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_string_descriptor(hport, (struct usb_string_descriptor *)ep0_buffer, USB_STRING_MFC_INDEX);
+    usbh_print_string("Manufacturer: ", ep0_request_buffer);
 
     /* Get Product string */
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -568,13 +522,13 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0x0409;
     setup->wLength = 255;
 
-    ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer);
+    ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_string_descriptor(hport, (struct usb_string_descriptor *)ep0_buffer, USB_STRING_PRODUCT_INDEX);
+    usbh_print_string("Product: ", ep0_request_buffer);
 
     /* Get SerialNumber string */
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -583,13 +537,13 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0x0409;
     setup->wLength = 255;
 
-    ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer);
+    ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_string_descriptor(hport, (struct usb_string_descriptor *)ep0_buffer, USB_STRING_SERIAL_INDEX);
+    usbh_print_string("SerialNumber: ", ep0_request_buffer);
 #endif
     /* Select device configuration 1 */
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -631,204 +585,145 @@ static int usbh_enumerate(struct usbh_hubport *hport)
     usbh_device_mount_done_callback(hport);
 errout:
     if (ret < 0) {
-        usbh_hport_deactivate(hport);
-    }
-
-    if (ep0_buffer) {
-        usb_iofree(ep0_buffer);
+        usbh_hport_deactivate_ep0(hport);
     }
 
     return ret;
 }
 
-static int usbh_portchange_wait(struct usbh_hubport **hport)
+struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr)
 {
-    struct usbh_hubport *connport = NULL;
-    uint32_t recved_event;
-    size_t flags;
-    int ret;
-
-    /* Loop until a change in connection state is detected */
-    while (1) {
-        ret = usb_osal_event_recv(usbh_core_cfg.pscevent, USBH_EVENT_CONNECTED | USBH_EVENT_DISCONNECTED, &recved_event);
-        if (ret < 0) {
-            continue;
-        }
-
-        flags = usb_osal_enter_critical_section();
-        for (uint8_t port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) {
-            /* Check for a change in the connection state on any root hub port */
-            connport = &usbh_core_cfg.rhport[port - 1].hport;
-            if (connport->port_change) {
-                connport->port_change = false;
-                /* debounce for port,in order to keep port connect status stability*/
-                usb_osal_msleep(100);
-                if (recved_event & USBH_EVENT_CONNECTED) {
-                    if (usbh_get_port_connect_status(port)) {
-                        if (!connport->connected) {
-                            connport->connected = true;
-                            *hport = connport;
-                            usb_osal_leave_critical_section(flags);
-                            return 0;
-                        }
-                    }
-                }
-                if (recved_event & USBH_EVENT_DISCONNECTED) {
-                    if (!usbh_get_port_connect_status(port)) {
-                        if (connport->connected) {
-                            connport->connected = false;
-                            *hport = connport;
-                            usb_osal_leave_critical_section(flags);
-                            return 0;
-                        }
-                    }
+    struct usbh_hubport *hport;
+    usb_slist_t *hub_list;
+    usb_slist_for_each(hub_list, &hub_class_head)
+    {
+        struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
+        for (int port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+            hport = &hub->child[port - 1];
+            if (hport->connected) {
+                if (hport->dev_addr == dev_addr) {
+                    return &hub->child[port - 1];
                 }
             }
         }
-#ifdef CONFIG_USBHOST_HUB
-        /* Is a device connected to an external hub? */
-        if (usbh_core_cfg.active_hport) {
-            connport = (struct usbh_hubport *)usbh_core_cfg.active_hport;
-            usbh_core_cfg.active_hport = NULL;
-            *hport = connport;
-            usb_osal_leave_critical_section(flags);
-            return 0;
-        }
-#endif
-        usb_osal_leave_critical_section(flags);
     }
+    return NULL;
 }
 
-static void usbh_portchange_detect_thread(void *argument)
+void *usbh_find_class_instance(const char *devname)
 {
-    struct usbh_hubport *hport = NULL;
-
-    usb_hc_sw_init();
-
-    for (uint8_t port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) {
-        usbh_core_cfg.rhport[port - 1].hport.port = port;
-        usbh_core_cfg.rhport[port - 1].devgen.next = 1;
-        usbh_hport_activate(&usbh_core_cfg.rhport[port - 1].hport);
-    }
+    struct usbh_hubport *hport;
+    usb_slist_t *hub_list;
 
-    usb_hc_hw_init();
-
-    while (1) {
-        usbh_portchange_wait(&hport);
-        if (hport->connected) {
-            /*if roothub port,reset port first*/
-            if (ROOTHUB(hport)) {
-                /* Reset the host port */
-                usbh_reset_port(hport->port);
-                usb_osal_msleep(200);
-                /* Get the current device speed */
-                hport->speed = usbh_get_port_speed(hport->port);
-                USB_LOG_INFO("Hub %u, Port %u connected, %s\r\n", 1, hport->port, speed_table[hport->speed]);
-            } else {
-                USB_LOG_INFO("Hub %u, Port %u connected, %s\r\n", hport->parent->index, hport->port, speed_table[hport->speed]);
-            }
-            usbh_enumerate(hport);
-        } else {
-            usbh_device_unmount_done_callback(hport);
-            usbh_hport_deactivate(hport);
-            for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
-                if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->disconnect) {
-                    CLASS_DISCONNECT(hport, i);
+    usb_slist_for_each(hub_list, &hub_class_head)
+    {
+        struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
+        for (int port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+            hport = &hub->child[port];
+            if (hport->connected) {
+                for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
+                    if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
+                        return hport->config.intf[itf].priv;
                 }
             }
-
-            hport->config.config_desc.bNumInterfaces = 0;
-
-            if (ROOTHUB(hport)) {
-                USB_LOG_INFO("Hub %u,Port:%u disconnected\r\n", 1, hport->port);
-            } else {
-                USB_LOG_INFO("Hub %u,Port:%u disconnected\r\n", hport->parent->index, hport->port);
-            }
         }
     }
+    return NULL;
 }
 
-void usbh_external_hport_connect(struct usbh_hubport *hport)
+int usbh_initialize(void)
 {
-    size_t flags;
+    memset(&g_usbh_bus, 0, sizeof(struct usbh_bus));
 
-    usbh_hport_activate(hport);
-
-    flags = usb_osal_enter_critical_section();
+#ifdef __ARMCC_VERSION /* ARM C Compiler */
+    extern const int usbh_class_info$$Base;
+    extern const int usbh_class_info$$Limit;
+    usbh_class_info_table_begin = (struct usbh_class_info *)&usbh_class_info$$Base;
+    usbh_class_info_table_end = (struct usbh_class_info *)&usbh_class_info$$Limit;
+#elif defined(__GNUC__)
+    extern uint32_t __usbh_class_info_start__;
+    extern uint32_t __usbh_class_info_end__;
+    usbh_class_info_table_begin = (struct usbh_class_info *)&__usbh_class_info_start__;
+    usbh_class_info_table_end = (struct usbh_class_info *)&__usbh_class_info_end__;
+#endif
 
-    hport->connected = true;
-    usbh_core_cfg.active_hport = hport;
-    usb_osal_leave_critical_section(flags);
+    /* devaddr 1 is for roothub */
+    g_usbh_bus.devgen.next = 2;
 
-    usb_osal_event_send(usbh_core_cfg.pscevent, USBH_EVENT_CONNECTED);
+    usbh_hub_initialize();
+    return 0;
 }
 
-void usbh_external_hport_disconnect(struct usbh_hubport *hport)
+/* usb host transfer wrapper */
+
+int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer)
 {
-    size_t flags;
+    struct usbh_urb *urb;
+    int ret;
 
-    flags = usb_osal_enter_critical_section();
+    urb = usb_malloc(sizeof(struct usbh_urb));
+    memset(urb, 0, sizeof(struct usbh_urb));
 
-    hport->connected = false;
-    usbh_core_cfg.active_hport = hport;
+    usbh_control_urb_fill(urb, pipe, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
 
-    usb_osal_leave_critical_section(flags);
-    usb_osal_event_send(usbh_core_cfg.pscevent, USBH_EVENT_DISCONNECTED);
+    ret = usbh_submit_urb(urb);
+    if (ret == 0) {
+        ret = urb->actual_length;
+    }
+    usb_free(urb);
+    return ret;
 }
 
-void usbh_event_notify_handler(uint8_t event, uint8_t rhport)
+int usbh_bulk_transfer(usbh_pipe_t pipe, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
 {
-    usbh_core_cfg.rhport[rhport - 1].hport.port_change = true;
-    usb_osal_event_send(usbh_core_cfg.pscevent, event);
+    struct usbh_urb *urb;
+    int ret;
+
+    urb = usb_malloc(sizeof(struct usbh_urb));
+    memset(urb, 0, sizeof(struct usbh_urb));
+
+    usbh_bulk_urb_fill(urb, pipe, buffer, buflen, timeout, NULL, NULL);
+
+    ret = usbh_submit_urb(urb);
+    if (ret == 0) {
+        ret = urb->actual_length;
+    }
+    usb_free(urb);
+    return ret;
 }
 
-int usbh_initialize(void)
+int usbh_int_transfer(usbh_pipe_t pipe, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
 {
-    usb_osal_thread_t usb_thread;
-
-    memset(&usbh_core_cfg, 0, sizeof(struct usbh_core_priv));
+    struct usbh_urb *urb;
+    int ret;
 
-#ifdef __ARMCC_VERSION /* ARM C Compiler */
-    extern const int usbh_class_info$$Base;
-    extern const int usbh_class_info$$Limit;
-    usbh_class_info_table_begin = (struct usbh_class_info *)&usbh_class_info$$Base;
-    usbh_class_info_table_end = (struct usbh_class_info *)&usbh_class_info$$Limit;
-#elif defined(__GNUC__)
-    extern uint32_t __usbh_class_info_start__;
-    extern uint32_t __usbh_class_info_end__;
-    usbh_class_info_table_begin = (struct usbh_class_info *)&__usbh_class_info_start__;
-    usbh_class_info_table_end = (struct usbh_class_info *)&__usbh_class_info_end__;
-#endif
+    urb = usb_malloc(sizeof(struct usbh_urb));
+    memset(urb, 0, sizeof(struct usbh_urb));
 
-    usbh_core_cfg.pscevent = usb_osal_event_create();
-    if (usbh_core_cfg.pscevent == NULL) {
-        return -1;
-    }
+    usbh_int_urb_fill(urb, pipe, buffer, buflen, timeout, NULL, NULL);
 
-    usb_thread = usb_osal_thread_create("usbh_psc", CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbh_portchange_detect_thread, NULL);
-    if (usb_thread == NULL) {
-        return -1;
+    ret = usbh_submit_urb(urb);
+    if (ret == 0) {
+        ret = urb->actual_length;
     }
-
-    return 0;
+    usb_free(urb);
+    return ret;
 }
 
 int lsusb(int argc, char **argv)
 {
-#ifdef CONFIG_USBHOST_HUB
-    usb_slist_t *hub_list;
-#endif
-    uint8_t port;
+    usb_slist_t *i;
+    struct usbh_hubport *hport;
 
     if (argc < 2) {
         USB_LOG_RAW("Usage: lsusb [options]...\r\n");
         USB_LOG_RAW("List USB devices\r\n");
         USB_LOG_RAW("  -v, --verbose\r\n");
         USB_LOG_RAW("      Increase verbosity (show descriptors)\r\n");
-        USB_LOG_RAW("  -s [[bus]:[devnum]]\r\n");
-        USB_LOG_RAW("      Show only devices with specified device and/or bus numbers (in decimal)\r\n");
-        USB_LOG_RAW("  -d vendor:[product]\r\n");
-        USB_LOG_RAW("      Show only devices with the specified vendor and product ID numbers (in hexadecimal)\r\n");
+        // USB_LOG_RAW("  -s [[bus]:[devnum]]\r\n");
+        // USB_LOG_RAW("      Show only devices with specified device and/or bus numbers (in decimal)\r\n");
+        // USB_LOG_RAW("  -d vendor:[product]\r\n");
+        // USB_LOG_RAW("      Show only devices with the specified vendor and product ID numbers (in hexadecimal)\r\n");
         USB_LOG_RAW("  -t, --tree\r\n");
         USB_LOG_RAW("      Dump the physical USB device hierachy as a tree\r\n");
         USB_LOG_RAW("  -V, --version\r\n");
@@ -837,165 +732,56 @@ int lsusb(int argc, char **argv)
         USB_LOG_RAW("      Show usage and help\r\n");
         return 0;
     }
-
     if (argc > 3) {
         return 0;
     }
 
     if (strcmp(argv[1], "-t") == 0) {
-        for (port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) {
-            if (usbh_core_cfg.rhport[port - 1].hport.connected) {
-                USB_LOG_RAW("/: Hub %02u,VID:PID 0x%04x:0x%04x\r\n", USBH_ROOT_HUB_INDEX, usbh_core_cfg.rhport[port - 1].hport.device_desc.idVendor, usbh_core_cfg.rhport[port - 1].hport.device_desc.idProduct);
-
-                for (uint8_t i = 0; i < usbh_core_cfg.rhport[port - 1].hport.config.config_desc.bNumInterfaces; i++) {
-                    if (usbh_core_cfg.rhport[port - 1].hport.config.intf[i].class_driver->driver_name) {
-                        USB_LOG_RAW("    |__Port %u,Port addr:0x%02x,If %u,ClassDriver=%s\r\n", usbh_core_cfg.rhport[port - 1].hport.port, usbh_core_cfg.rhport[port - 1].hport.dev_addr,
-                                    i, usbh_core_cfg.rhport[port - 1].hport.config.intf[i].class_driver->driver_name);
-                    }
-                }
-            }
-        }
-#ifdef CONFIG_USBHOST_HUB
-        usb_slist_for_each(hub_list, &hub_class_head)
+        usb_slist_for_each(i, &hub_class_head)
         {
-            usbh_hub_t *hub_class = usb_slist_entry(hub_list, struct usbh_hub, list);
-
-            for (port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) {
-                if (hub_class->child[port - 1].connected) {
-                    USB_LOG_RAW("/: Hub %02u,VID:PID 0x%04x:0x%04x\r\n", hub_class->index, hub_class->child[port - 1].device_desc.idVendor, hub_class->child[port - 1].device_desc.idProduct);
-
-                    for (uint8_t i = 0; i < hub_class->child[port - 1].config.config_desc.bNumInterfaces; i++) {
-                        if (hub_class->child[port - 1].config.intf[i].class_driver->driver_name) {
-                            USB_LOG_RAW("    |__Port %u,Port addr:0x%02x,If %u,ClassDriver=%s\r\n", hub_class->child[port - 1].port, hub_class->child[port - 1].dev_addr,
-                                        i, hub_class->child[port - 1].config.intf[i].class_driver->driver_name);
+            struct usbh_hub *hub = usb_slist_entry(i, struct usbh_hub, list);
+            for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+                hport = &hub->child[port - 1];
+                if (hport->connected) {
+                    USB_LOG_RAW("/: Hub %02u,VID:PID 0x%04x:0x%04x\r\n",
+                                hub->index,
+                                hport->device_desc.idVendor,
+                                hport->device_desc.idProduct);
+
+                    for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
+                        if (hport->config.intf[i].class_driver->driver_name) {
+                            USB_LOG_RAW("    |__Port %u,Port addr:0x%02x,If %u,ClassDriver=%s\r\n",
+                                        hport->port,
+                                        hport->dev_addr,
+                                        i,
+                                        hport->config.intf[i].class_driver->driver_name);
                         }
                     }
                 }
             }
         }
-#endif
-    } else if (strcmp(argv[1], "-v") == 0) {
-        for (port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) {
-            if (usbh_core_cfg.rhport[port - 1].hport.connected) {
-                USB_LOG_RAW("Hub %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n", USBH_ROOT_HUB_INDEX, usbh_core_cfg.rhport[port - 1].hport.port, usbh_core_cfg.rhport[port - 1].hport.dev_addr,
-                            usbh_core_cfg.rhport[port - 1].hport.device_desc.idVendor, usbh_core_cfg.rhport[port - 1].hport.device_desc.idProduct);
-                usbh_print_hubport_info(&usbh_core_cfg.rhport[port - 1].hport);
-            }
-        }
-#ifdef CONFIG_USBHOST_HUB
-        usb_slist_for_each(hub_list, &hub_class_head)
-        {
-            usbh_hub_t *hub_class = usb_slist_entry(hub_list, struct usbh_hub, list);
-
-            for (port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) {
-                if (hub_class->child[port - 1].connected) {
-                    USB_LOG_RAW("Hub %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n", hub_class->index, hub_class->child[port - 1].port, hub_class->child[port - 1].dev_addr,
-                                hub_class->child[port - 1].device_desc.idVendor, hub_class->child[port - 1].device_desc.idProduct);
-                    usbh_print_hubport_info(&hub_class->child[port - 1]);
-                }
-            }
-        }
-#endif
     }
 
-    return 0;
-}
-
-struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr)
-{
-#ifdef CONFIG_USBHOST_HUB
-    usb_slist_t *hub_list;
-#endif
-    uint8_t port;
-
-    for (port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) {
-        if (usbh_core_cfg.rhport[port - 1].hport.connected) {
-            if (usbh_core_cfg.rhport[port - 1].hport.dev_addr == dev_addr) {
-                return &usbh_core_cfg.rhport[port - 1].hport;
-            }
-        }
-    }
-#ifdef CONFIG_USBHOST_HUB
-    usb_slist_for_each(hub_list, &hub_class_head)
-    {
-        usbh_hub_t *hub_class = usb_slist_entry(hub_list, struct usbh_hub, list);
-
-        for (port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) {
-            if (hub_class->child[port - 1].connected) {
-                if (hub_class->child[port - 1].dev_addr == dev_addr) {
-                    return &hub_class->child[port - 1];
-                }
-            }
-        }
-    }
-#endif
-    return NULL;
-}
-
-void *usbh_find_class_instance(const char *devname)
-{
-#ifdef CONFIG_USBHOST_HUB
-    usb_slist_t *hub_list;
-#endif
-    struct usbh_hubport *hport;
-    uint8_t port;
-
-    for (port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) {
-        hport = &usbh_core_cfg.rhport[port - 1].hport;
-        if (hport->connected) {
-            for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
-                if (strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0)
-                    return hport->config.intf[itf].priv;
-            }
-        }
-    }
-#ifdef CONFIG_USBHOST_HUB
-    usb_slist_for_each(hub_list, &hub_class_head)
-    {
-        usbh_hub_t *hub_class = usb_slist_entry(hub_list, struct usbh_hub, list);
-
-        for (port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) {
-            hport = &hub_class->child[port - 1];
-            if (hport->connected) {
-                for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
-                    if (strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0)
-                        return hport->config.intf[itf].priv;
+    if (strcmp(argv[1], "-v") == 0) {
+        usb_slist_for_each(i, &hub_class_head)
+        {
+            struct usbh_hub *hub = usb_slist_entry(i, struct usbh_hub, list);
+            for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+                hport = &hub->child[port - 1];
+                if (hport->connected) {
+                    USB_LOG_RAW("Hub %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n",
+                                hub->index,
+                                hport->port,
+                                hport->dev_addr,
+                                hport->device_desc.idVendor,
+                                hport->device_desc.idProduct);
+                    usbh_print_hubport_info(hport);
                 }
             }
         }
     }
-#endif
-    return NULL;
-}
 
-static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, uint16_t vid, uint16_t pid)
-{
-    struct usbh_class_info *index = NULL;
-
-    for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) {
-        if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) ==
-            (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) {
-            if (index->vid == vid && index->pid == pid &&
-                index->class == class && index->subclass == subclass && index->protocol == protocol) {
-                return index->class_driver;
-            }
-        } else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) ==
-                   (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) {
-            if (index->class == class && index->subclass == subclass && index->protocol == protocol) {
-                return index->class_driver;
-            }
-        } else if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) ==
-                   (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) {
-            if (index->vid == vid && index->pid == pid && index->class == class) {
-                return index->class_driver;
-            }
-        } else if (index->match_flags & (USB_CLASS_MATCH_INTF_CLASS)) {
-            if (index->class == class) {
-                return index->class_driver;
-            }
-        }
-    }
-    return NULL;
+    return 0;
 }
 
 __WEAK void usbh_device_mount_done_callback(struct usbh_hubport *hport)

+ 144 - 45
core/usbh_core.h

@@ -20,22 +20,12 @@
 #include "usb_log.h"
 #include "usb_hc.h"
 #include "usb_osal.h"
-#include "usbh_hub.h"
+#include "usb_hub.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define USBH_ROOT_HUB_INDEX       1 /* roothub index*/
-#define USBH_EX_HUB_INDEX         2 /* external hub index */
-#define USBH_HUB_PORT_START_INDEX 1 /* first hub port index */
-
-#ifdef CONFIG_USBHOST_HUB
-#define ROOTHUB(hport) ((hport)->parent == NULL)
-#else
-#define ROOTHUB(hport) true
-#endif
-
 #define USB_CLASS_MATCH_VENDOR        0x0001
 #define USB_CLASS_MATCH_PRODUCT       0x0002
 #define USB_CLASS_MATCH_INTF_CLASS    0x0004
@@ -46,15 +36,62 @@ extern "C" {
 #define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i))
 
 #ifdef __ARMCC_VERSION /* ARM C Compiler */
-#define CLASS_INFO_DEFINE          __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
+#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
 #elif defined(__GNUC__)
-#define CLASS_INFO_DEFINE          __attribute__((section(".usbh_class_info"))) __USED __ALIGNED(1)
+#define CLASS_INFO_DEFINE __attribute__((section(".usbh_class_info"))) __USED __ALIGNED(1)
 #endif
 
-enum usbh_event_type {
-    USBH_EVENT_CONNECTED = (1 << 0),
-    USBH_EVENT_DISCONNECTED = (1 << 1),
-};
+static inline void usbh_control_urb_fill(struct usbh_urb *urb,
+                                         usbh_pipe_t pipe,
+                                         struct usb_setup_packet *setup,
+                                         uint8_t *transfer_buffer,
+                                         uint32_t transfer_buffer_length,
+                                         uint32_t timeout,
+                                         usbh_complete_callback_t complete,
+                                         void *arg)
+{
+    urb->pipe = pipe;
+    urb->setup = setup;
+    urb->transfer_buffer = transfer_buffer;
+    urb->transfer_buffer_length = transfer_buffer_length;
+    urb->timeout = timeout;
+    urb->complete = complete;
+    urb->arg = arg;
+}
+
+static inline void usbh_bulk_urb_fill(struct usbh_urb *urb,
+                                      usbh_pipe_t pipe,
+                                      uint8_t *transfer_buffer,
+                                      uint32_t transfer_buffer_length,
+                                      uint32_t timeout,
+                                      usbh_complete_callback_t complete,
+                                      void *arg)
+{
+    urb->pipe = pipe;
+    urb->setup = NULL;
+    urb->transfer_buffer = transfer_buffer;
+    urb->transfer_buffer_length = transfer_buffer_length;
+    urb->timeout = timeout;
+    urb->complete = complete;
+    urb->arg = arg;
+}
+
+static inline void usbh_int_urb_fill(struct usbh_urb *urb,
+                                     usbh_pipe_t pipe,
+                                     uint8_t *transfer_buffer,
+                                     uint32_t transfer_buffer_length,
+                                     uint32_t timeout,
+                                     usbh_complete_callback_t complete,
+                                     void *arg)
+{
+    urb->pipe = pipe;
+    urb->setup = NULL;
+    urb->transfer_buffer = transfer_buffer;
+    urb->transfer_buffer_length = transfer_buffer_length;
+    urb->timeout = timeout;
+    urb->complete = complete;
+    urb->arg = arg;
+}
 
 struct usbh_class_info {
     uint8_t match_flags; /* Used for product specific matches; range is inclusive */
@@ -73,59 +110,121 @@ struct usbh_class_driver {
     int (*disconnect)(struct usbh_hubport *hport, uint8_t intf);
 };
 
-typedef struct usbh_endpoint {
+struct usbh_endpoint {
     struct usb_endpoint_descriptor ep_desc;
-} usbh_endpoint_t;
+};
 
-typedef struct usbh_interface {
+struct usbh_interface {
     struct usb_interface_descriptor intf_desc;
     struct usbh_endpoint ep[CONFIG_USBHOST_EP_NUM];
     char devname[CONFIG_USBHOST_DEV_NAMELEN];
     struct usbh_class_driver *class_driver;
     void *priv;
-} usbh_interface_t;
+};
 
-typedef struct usbh_configuration {
+struct usbh_configuration {
     struct usb_configuration_descriptor config_desc;
     struct usbh_interface intf[CONFIG_USBHOST_INTF_NUM];
-} usbh_configuration_t;
-
-typedef struct usbh_hubport {
-    bool connected;    /* True: device connected; false: disconnected */
-    bool port_change;  /* True: port changed; false: port do not change */
-    uint8_t port;      /* Hub port index */
-    uint8_t dev_addr;  /* device address */
-    uint8_t speed;     /* device speed */
-    usbh_epinfo_t ep0; /* control ep info */
+};
+
+struct usbh_hubport {
+    bool connected;   /* True: device connected; false: disconnected */
+    uint8_t port;     /* Hub port index */
+    uint8_t dev_addr; /* device address */
+    uint8_t speed;    /* device speed */
+    usbh_pipe_t ep0;  /* control ep pipe info */
     struct usb_device_descriptor device_desc;
     struct usbh_configuration config;
+    const char *iManufacturer;
+    const char *iProduct;
+    const char *iSerialNumber;
 #if 0
-    uint8_t* config_desc;
+    uint8_t* raw_config_desc;
 #endif
-    struct usb_setup_packet *setup;
-    struct usbh_hub *parent; /*if NULL, is roothub*/
-} usbh_hubport_t;
+    USB_MEM_ALIGNX struct usb_setup_packet setup;
+    struct usbh_hub *parent;
+};
 
-typedef struct usbh_hub {
+struct usbh_hub {
     usb_slist_t list;
-    uint8_t index;    /* Hub index */
-    uint8_t nports;   /* Hub port number */
-    uint8_t dev_addr; /* Hub device address */
-    usbh_epinfo_t intin;
-    uint8_t *int_buffer;
-    struct hub_port_status *port_status;
+    bool connected;
+    bool is_roothub;
+    uint8_t index;
+    uint8_t hub_addr;
+    usbh_pipe_t intin;
+    USB_MEM_ALIGNX uint8_t int_buffer[1];
     struct usb_hub_descriptor hub_desc;
     struct usbh_hubport child[CONFIG_USBHOST_EHPORTS];
-    struct usbh_hubport *parent; /* Parent hub port */
-} usbh_hub_t;
+    struct usbh_hubport *parent;
+    usb_slist_t hub_event_list;
+};
+
+/* usb host transfer wrapper */
+
+/**
+ * @brief Submit an bulk transfer to an endpoint.
+ * This is a blocking method; this method will not return until the transfer has completed.
+ * Default timeout is 500ms.
+ *
+ * @param pipe The control endpoint to send/receive the control request.
+ * @param setup Setup packet to be sent.
+ * @param buffer buffer used for sending the request and for returning any responses.
+ * @return On success will return 0, and others indicate fail.
+ */
+int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer);
+
+/**
+ * @brief  Submit an bulk transfer to an endpoint.
+ * This is a blocking method; this method will not return until the transfer has completed.
+ *
+ * @param pipe The IN or OUT endpoint pipe info.
+ * @param buffer A buffer containing the data to be sent (OUT endpoint) or received (IN endpoint).
+ * @param buflen The length of the data to be sent or received.
+ * @param timeout Timeout for transfer, unit is ms.
+ * @return On success, a non-negative value is returned that indicates the number
+ *   of bytes successfully transferred.  On a failure, a negated errno value
+ *   is returned that indicates the nature of the failure:
+ *
+ *     -EAGAIN - If devices NAKs the transfer (or NYET or other error where
+ *              it may be appropriate to restart the entire transaction).
+ *     -EPERM  - If the endpoint stalls
+ *     -EIO    - On a TX or data toggle error
+ *     -EPIPE  - Overrun errors
+ *     -ETIMEDOUT  - Sem wait timeout
+ *
+ */
+int usbh_bulk_transfer(usbh_pipe_t pipe, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
+
+/**
+ * @brief  Submit an interrupt transfer to an endpoint.
+ * This is a blocking method; this method will not return until the transfer has completed.
+ *
+ * @param pipe The IN or OUT endpoint pipe info.
+ * @param buffer A buffer containing the data to be sent (OUT endpoint) or received (IN endpoint).
+ * @param buflen The length of the data to be sent or received.
+ * @param timeout Timeout for transfer, unit is ms.
+ * @return On success, a non-negative value is returned that indicates the number
+ *   of bytes successfully transferred.  On a failure, a negated errno value
+ *   is returned that indicates the nature of the failure:
+ *
+ *     -EAGAIN - If devices NAKs the transfer (or NYET or other error where
+ *              it may be appropriate to restart the entire transaction).
+ *     -EPERM  - If the endpoint stalls
+ *     -EIO    - On a TX or data toggle error
+ *     -EPIPE  - Overrun errors
+ *     -ETIMEDOUT  - Sem wait timeout
+ *
+ */
+int usbh_int_transfer(usbh_pipe_t pipe, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
 
 int usbh_initialize(void);
-int lsusb(int argc, char **argv);
 struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr);
 void *usbh_find_class_instance(const char *devname);
+
 void usbh_device_mount_done_callback(struct usbh_hubport *hport);
 void usbh_device_unmount_done_callback(struct usbh_hubport *hport);
 
+int lsusb(int argc, char **argv);
 #ifdef __cplusplus
 }
 #endif

+ 4 - 4
demo/es32/usb_device/ES32F369x/MDK-ARM/example.uvoptx

@@ -470,8 +470,8 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\..\..\..\..\port\musb\usb_dc_musb.c</PathWithFileName>
-      <FilenameWithoutPath>usb_dc_musb.c</FilenameWithoutPath>
+      <PathWithFileName>..\..\..\..\..\class\hid\usbd_hid.c</PathWithFileName>
+      <FilenameWithoutPath>usbd_hid.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
@@ -482,8 +482,8 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\..\..\..\..\class\hid\usbd_hid.c</PathWithFileName>
-      <FilenameWithoutPath>usbd_hid.c</FilenameWithoutPath>
+      <PathWithFileName>..\..\..\..\..\port\musb\usb_dc_musb.c</PathWithFileName>
+      <FilenameWithoutPath>usb_dc_musb.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>

+ 4 - 4
demo/es32/usb_device/ES32F369x/MDK-ARM/example.uvprojx

@@ -480,14 +480,14 @@
               <FilePath>..\..\..\..\..\class\cdc\usbd_cdc.c</FilePath>
             </File>
             <File>
-              <FileName>usb_dc_musb.c</FileName>
+              <FileName>usbd_hid.c</FileName>
               <FileType>1</FileType>
-              <FilePath>..\..\..\..\..\port\musb\usb_dc_musb.c</FilePath>
+              <FilePath>..\..\..\..\..\class\hid\usbd_hid.c</FilePath>
             </File>
             <File>
-              <FileName>usbd_hid.c</FileName>
+              <FileName>usb_dc_musb.c</FileName>
               <FileType>1</FileType>
-              <FilePath>..\..\..\..\..\class\hid\usbd_hid.c</FilePath>
+              <FilePath>..\..\..\..\..\port\musb\usb_dc_musb.c</FilePath>
             </File>
           </Files>
         </Group>

+ 24 - 13
demo/es32/usb_host/ES32F369x/Inc/usb_config.h

@@ -16,17 +16,25 @@
 #define CONFIG_USB_PRINTF printf
 #endif
 
-/* attribute data into no cache ram */
-// #define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
 /* Enable print with color */
 #define CONFIG_USB_PRINTF_COLOR_ENABLE
 
+/* data align size when use dma */
+#ifndef CONFIG_USB_ALIGN_SIZE
+#define CONFIG_USB_ALIGN_SIZE 4
+#endif
+
+/* attribute data into no cache ram */
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
+
 /* ================ USB DEVICE Configuration ================*/
 
 /* core */
 
 /* Ep0 max transfer buffer, specially for receiving data from ep0 out */
+#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
 #define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
+#endif
 /* Setup packet log for debug */
 // #define CONFIG_USBDEV_SETUP_LOG_PRINT
 /* Check if the input descriptor is correct */
@@ -79,6 +87,11 @@
 #endif
 
 /* ================ USB HOST Configuration ================ */
+/* core */
+/* Ep0 max transfer buffer */
+#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
+#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
+#endif
 
 #ifndef CONFIG_USBHOST_RHPORTS
 #define CONFIG_USBHOST_RHPORTS 1
@@ -88,10 +101,6 @@
 #define CONFIG_USBHOST_EHPORTS 4
 #endif
 
-#ifndef CONFIG_USBHOST_PIPE_NUM
-#define CONFIG_USBHOST_PIPE_NUM 10
-#endif
-
 #ifndef CONFIG_USBHOST_INTF_NUM
 #define CONFIG_USBHOST_INTF_NUM 6
 #endif
@@ -101,7 +110,7 @@
 #endif
 
 #ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
-#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 5000
+#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
 #endif
 
 #ifndef CONFIG_USBHOST_MSC_TIMEOUT
@@ -112,22 +121,24 @@
 #define CONFIG_USBHOST_PSC_PRIO 4
 #endif
 #ifndef CONFIG_USBHOST_PSC_STACKSIZE
-#define CONFIG_USBHOST_PSC_STACKSIZE 4096
+#define CONFIG_USBHOST_PSC_STACKSIZE 2048
 #endif
 
 #ifndef CONFIG_USBHOST_DEV_NAMELEN
 #define CONFIG_USBHOST_DEV_NAMELEN 16
 #endif
 
-#define CONFIG_USBHOST_ASYNCH
 //#define CONFIG_USBHOST_GET_STRING_DESC
 
+#ifndef CONFIG_USBHOST_PIPE_NUM
+#define CONFIG_USBHOST_PIPE_NUM 4
+#endif
+
 /* ================ EHCI Configuration ================ */
 
-#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
-#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
-#define CONFIG_USB_EHCI_QH_NUM    (10)
-#define CONFIG_USB_EHCI_QTD_NUM   (10)
+#define CONFIG_USB_EHCI_HCCR_BASE   (0x20072000)
+#define CONFIG_USB_EHCI_HCOR_BASE   (0x20072000 + 0x10)
+#define CONFIG_EHCI_FRAME_LIST_SIZE 1024
 // #define CONFIG_USB_EHCI_INFO_ENABLE
 // #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
 // #define CONFIG_USB_EHCI_CONFIGFLAG

+ 143 - 26
demo/es32/usb_host/ES32F369x/MDK-ARM/example.uvoptx

@@ -125,7 +125,7 @@
         <SetRegEntry>
           <Number>0</Number>
           <Key>CMSIS_AGDI</Key>
-          <Name>-X"essemi CMSIS-DAP" -U0001A000000A -O367 -S0 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0es32f36xx.FLM -FS00 -FL080000 -FP0($$Device:ES32F3696LT$Flash\es32f36xx.FLM)</Name>
+          <Name>-X"essemi CMSIS-DAP" -U0001A000000A -O334 -S0 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0es32f36xx.FLM -FS00 -FL080000 -FP0($$Device:ES32F3696LT$Flash\es32f36xx.FLM)</Name>
         </SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
@@ -163,7 +163,136 @@
           <Name>-T0</Name>
         </SetRegEntry>
       </TargetDriverDllRegistry>
-      <Breakpoint/>
+      <Breakpoint>
+        <Bp>
+          <Number>0</Number>
+          <Type>0</Type>
+          <LineNumber>962</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>0</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>0</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression></Expression>
+        </Bp>
+        <Bp>
+          <Number>1</Number>
+          <Type>0</Type>
+          <LineNumber>959</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>0</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>0</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression></Expression>
+        </Bp>
+        <Bp>
+          <Number>2</Number>
+          <Type>0</Type>
+          <LineNumber>964</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>1500</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>1</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression>\\out\../../../../../port/musb/usb_hc_musb.c\964</Expression>
+        </Bp>
+        <Bp>
+          <Number>3</Number>
+          <Type>0</Type>
+          <LineNumber>964</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>1516</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>1</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression>\\out\../../../../../port/musb/usb_hc_musb.c\964</Expression>
+        </Bp>
+        <Bp>
+          <Number>4</Number>
+          <Type>0</Type>
+          <LineNumber>960</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>1524</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>1</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression>\\out\../../../../../port/musb/usb_hc_musb.c\960</Expression>
+        </Bp>
+        <Bp>
+          <Number>5</Number>
+          <Type>0</Type>
+          <LineNumber>440</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>0</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>0</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression></Expression>
+        </Bp>
+        <Bp>
+          <Number>6</Number>
+          <Type>0</Type>
+          <LineNumber>447</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>0</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>0</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression></Expression>
+        </Bp>
+        <Bp>
+          <Number>7</Number>
+          <Type>0</Type>
+          <LineNumber>963</LineNumber>
+          <EnabledFlag>1</EnabledFlag>
+          <Address>0</Address>
+          <ByteObject>0</ByteObject>
+          <HtxType>0</HtxType>
+          <ManyObjects>0</ManyObjects>
+          <SizeOfObject>0</SizeOfObject>
+          <BreakByAccess>0</BreakByAccess>
+          <BreakIfRCount>0</BreakIfRCount>
+          <Filename>..\..\..\..\..\port\musb\usb_hc_musb.c</Filename>
+          <ExecCommand></ExecCommand>
+          <Expression></Expression>
+        </Bp>
+      </Breakpoint>
       <WatchWindow1>
         <Ww>
           <count>0</count>
@@ -260,7 +389,7 @@
 
   <Group>
     <GroupName>startup</GroupName>
-    <tvExp>1</tvExp>
+    <tvExp>0</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
@@ -280,7 +409,7 @@
 
   <Group>
     <GroupName>ald</GroupName>
-    <tvExp>1</tvExp>
+    <tvExp>0</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
@@ -396,7 +525,7 @@
 
   <Group>
     <GroupName>app</GroupName>
-    <tvExp>0</tvExp>
+    <tvExp>1</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
@@ -535,18 +664,6 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\..\..\..\..\osal\usb_workq.c</PathWithFileName>
-      <FilenameWithoutPath>usb_workq.c</FilenameWithoutPath>
-      <RteFlg>0</RteFlg>
-      <bShared>0</bShared>
-    </File>
-    <File>
-      <GroupNumber>4</GroupNumber>
-      <FileNumber>22</FileNumber>
-      <FileType>1</FileType>
-      <tvExp>0</tvExp>
-      <tvExpOptDlg>0</tvExpOptDlg>
-      <bDave2>0</bDave2>
       <PathWithFileName>..\..\..\..\..\port\musb\usb_hc_musb.c</PathWithFileName>
       <FilenameWithoutPath>usb_hc_musb.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
@@ -556,13 +673,13 @@
 
   <Group>
     <GroupName>FreeRTOS</GroupName>
-    <tvExp>1</tvExp>
+    <tvExp>0</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>22</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -574,7 +691,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>23</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -586,7 +703,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -598,7 +715,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -610,7 +727,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>27</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -622,7 +739,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>28</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -634,7 +751,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>29</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -646,7 +763,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>30</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 0 - 5
demo/es32/usb_host/ES32F369x/MDK-ARM/example.uvprojx

@@ -499,11 +499,6 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\..\..\osal\usb_osal_freertos.c</FilePath>
             </File>
-            <File>
-              <FileName>usb_workq.c</FileName>
-              <FileType>1</FileType>
-              <FilePath>..\..\..\..\..\osal\usb_workq.c</FilePath>
-            </File>
             <File>
               <FileName>usb_hc_musb.c</FileName>
               <FileType>1</FileType>

+ 2 - 1
demo/es32/usb_host/ES32F369x/Src/main.c

@@ -140,8 +140,9 @@ int main()
 
     uart_pin_init();
     printf("\rSystem start...\r\n");
-
+    extern void usbh_class_test(void);
     usbh_initialize();
+    usbh_class_test();
     vTaskStartScheduler();
     while (1) {
     }

+ 56 - 41
demo/stm32/usb_host/stm32f429igt6/Core/Inc/usb_config.h

@@ -1,7 +1,13 @@
-#ifndef _USB_CONFIG_H
-#define _USB_CONFIG_H
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef CHERRYUSB_CONFIG_H
+#define CHERRYUSB_CONFIG_H
+
+/* ================ USB common Configuration ================ */
 
-/* USB common Configuration */
 #ifndef CONFIG_USB_DBG_LEVEL
 #define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
 #endif
@@ -10,26 +16,42 @@
 #define CONFIG_USB_PRINTF printf
 #endif
 
+/* Enable print with color */
 #define CONFIG_USB_PRINTF_COLOR_ENABLE
 
-/* USB DEVICE Configuration */
-/* core */
-#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
-#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
+/* data align size when use dma */
+#ifndef CONFIG_USB_ALIGN_SIZE
+#define CONFIG_USB_ALIGN_SIZE 4
 #endif
 
-#ifndef CONFIG_USBDEV_DESC_CHECK
-#define CONFIG_USBDEV_DESC_CHECK 0
-#endif
+/* attribute data into no cache ram */
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
+
+/* ================ USB DEVICE Configuration ================*/
+
+/* core */
 
-#ifndef CONFIG_USBDEV_TEST_MODE
-#define CONFIG_USBDEV_TEST_MODE 0
+/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
+#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
+#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
 #endif
+/* Setup packet log for debug */
+// #define CONFIG_USBDEV_SETUP_LOG_PRINT
+/* Check if the input descriptor is correct */
+// #define CONFIG_USBDEV_DESC_CHECK
+/* Enable test mode */
+// #define CONFIG_USBDEV_TEST_MODE
 
 /* cdc class */
+
 // #define CONFIG_USBDEV_CDC_ACM_UART
 
 /* msc class */
+
+#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
+#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
+#endif
+
 #ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
 #define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
 #endif
@@ -55,15 +77,22 @@
 #endif
 
 /* audio class */
+
 #ifndef CONFIG_USBDEV_AUDIO_VERSION
 #define CONFIG_USBDEV_AUDIO_VERSION 0x0100
 #endif
 
 #ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
-#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 2
+#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
+#endif
+
+/* ================ USB HOST Configuration ================ */
+/* core */
+/* Ep0 max transfer buffer */
+#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
+#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
 #endif
 
-/* USB HOST Configuration */
 #ifndef CONFIG_USBHOST_RHPORTS
 #define CONFIG_USBHOST_RHPORTS 1
 #endif
@@ -72,10 +101,6 @@
 #define CONFIG_USBHOST_EHPORTS 4
 #endif
 
-#ifndef CONFIG_USBHOST_PIPE_NUM
-#define CONFIG_USBHOST_PIPE_NUM 10
-#endif
-
 #ifndef CONFIG_USBHOST_INTF_NUM
 #define CONFIG_USBHOST_INTF_NUM 6
 #endif
@@ -85,48 +110,38 @@
 #endif
 
 #ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
-#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 5000
+#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
 #endif
 
 #ifndef CONFIG_USBHOST_MSC_TIMEOUT
 #define CONFIG_USBHOST_MSC_TIMEOUT 5000
 #endif
 
-#ifndef CONFIG_USBHOST_HPWORKQ_PRIO
-#define CONFIG_USBHOST_HPWORKQ_PRIO 5
-#endif
-#ifndef CONFIG_USBHOST_HPWORKQ_STACKSIZE
-#define CONFIG_USBHOST_HPWORKQ_STACKSIZE 2048
-#endif
-
-#ifndef CONFIG_USBHOST_LPWORKQ_PRIO
-#define CONFIG_USBHOST_LPWORKQ_PRIO 1
-#endif
-#ifndef CONFIG_USBHOST_LPWORKQ_STACKSIZE
-#define CONFIG_USBHOST_LPWORKQ_STACKSIZE 2048
-#endif
-
 #ifndef CONFIG_USBHOST_PSC_PRIO
 #define CONFIG_USBHOST_PSC_PRIO 4
 #endif
 #ifndef CONFIG_USBHOST_PSC_STACKSIZE
-#define CONFIG_USBHOST_PSC_STACKSIZE 4096
+#define CONFIG_USBHOST_PSC_STACKSIZE 2048
 #endif
 
 #ifndef CONFIG_USBHOST_DEV_NAMELEN
 #define CONFIG_USBHOST_DEV_NAMELEN 16
 #endif
 
-#define CONFIG_USBHOST_ASYNCH
 //#define CONFIG_USBHOST_GET_STRING_DESC
 
-/* EHCI Configuration */
-#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
-#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
-#define CONFIG_USB_EHCI_QH_NUM    (10)
-#define CONFIG_USB_EHCI_QTD_NUM   (10)
+#ifndef CONFIG_USBHOST_PIPE_NUM
+#define CONFIG_USBHOST_PIPE_NUM 12
+#endif
+
+/* ================ EHCI Configuration ================ */
+
+#define CONFIG_USB_EHCI_HCCR_BASE   (0x20072000)
+#define CONFIG_USB_EHCI_HCOR_BASE   (0x20072000 + 0x10)
+#define CONFIG_EHCI_FRAME_LIST_SIZE 1024
 // #define CONFIG_USB_EHCI_INFO_ENABLE
-#define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
+// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
 // #define CONFIG_USB_EHCI_CONFIGFLAG
+// #define CONFIG_USB_EHCI_PORT_POWER
 
 #endif

+ 3 - 2
demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c

@@ -122,9 +122,10 @@ int main(void)
   MX_USART1_UART_Init();
   //MX_USB_OTG_HS_HCD_Init();
   /* USER CODE BEGIN 2 */
-                   
-  usbh_initialize();
   printf("Start usb host task...\r\n");
+  extern void usbh_class_test(void);                   
+  usbh_initialize();
+  usbh_class_test();
   vTaskStartScheduler();
   /* USER CODE END 2 */
 

+ 39 - 47
demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx

@@ -159,22 +159,6 @@
           <Type>0</Type>
           <LineNumber>347</LineNumber>
           <EnabledFlag>1</EnabledFlag>
-          <Address>134246552</Address>
-          <ByteObject>0</ByteObject>
-          <HtxType>0</HtxType>
-          <ManyObjects>0</ManyObjects>
-          <SizeOfObject>0</SizeOfObject>
-          <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>1</BreakIfRCount>
-          <Filename>..\..\..\..\..\class\msc\usbh_msc.c</Filename>
-          <ExecCommand></ExecCommand>
-          <Expression>\\stm32f429igt6\../../../../../class/msc/usbh_msc.c\347</Expression>
-        </Bp>
-        <Bp>
-          <Number>1</Number>
-          <Type>0</Type>
-          <LineNumber>1027</LineNumber>
-          <EnabledFlag>1</EnabledFlag>
           <Address>0</Address>
           <ByteObject>0</ByteObject>
           <HtxType>0</HtxType>
@@ -182,28 +166,12 @@
           <SizeOfObject>0</SizeOfObject>
           <BreakByAccess>0</BreakByAccess>
           <BreakIfRCount>0</BreakIfRCount>
-          <Filename>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</Filename>
-          <ExecCommand></ExecCommand>
-          <Expression></Expression>
-        </Bp>
-        <Bp>
-          <Number>2</Number>
-          <Type>0</Type>
-          <LineNumber>1030</LineNumber>
-          <EnabledFlag>1</EnabledFlag>
-          <Address>0</Address>
-          <ByteObject>0</ByteObject>
-          <HtxType>0</HtxType>
-          <ManyObjects>0</ManyObjects>
-          <SizeOfObject>0</SizeOfObject>
-          <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>0</BreakIfRCount>
-          <Filename>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</Filename>
+          <Filename>..\..\..\..\..\class\msc\usbh_msc.c</Filename>
           <ExecCommand></ExecCommand>
           <Expression></Expression>
         </Bp>
         <Bp>
-          <Number>3</Number>
+          <Number>1</Number>
           <Type>0</Type>
           <LineNumber>1309</LineNumber>
           <EnabledFlag>1</EnabledFlag>
@@ -219,7 +187,7 @@
           <Expression></Expression>
         </Bp>
         <Bp>
-          <Number>4</Number>
+          <Number>2</Number>
           <Type>0</Type>
           <LineNumber>1314</LineNumber>
           <EnabledFlag>1</EnabledFlag>
@@ -311,7 +279,7 @@
 
   <Group>
     <GroupName>Application/MDK-ARM</GroupName>
-    <tvExp>0</tvExp>
+    <tvExp>1</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
@@ -399,7 +367,7 @@
 
   <Group>
     <GroupName>Drivers/STM32F4xx_HAL_Driver</GroupName>
-    <tvExp>1</tvExp>
+    <tvExp>0</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
@@ -747,7 +715,7 @@
 
   <Group>
     <GroupName>CherryUSB</GroupName>
-    <tvExp>1</tvExp>
+    <tvExp>0</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
@@ -770,6 +738,18 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\..\..\class\hub\usbh_hub.c</PathWithFileName>
+      <FilenameWithoutPath>usbh_hub.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>36</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
       <PathWithFileName>..\..\..\..\..\class\cdc\usbh_cdc_acm.c</PathWithFileName>
       <FilenameWithoutPath>usbh_cdc_acm.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
@@ -777,7 +757,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>36</FileNumber>
+      <FileNumber>37</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -789,7 +769,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>37</FileNumber>
+      <FileNumber>38</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -801,7 +781,19 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>38</FileNumber>
+      <FileNumber>39</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\..\..\class\wireless\usbh_rndis.c</PathWithFileName>
+      <FilenameWithoutPath>usbh_rndis.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>40</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -813,7 +805,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>39</FileNumber>
+      <FileNumber>41</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -833,7 +825,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>40</FileNumber>
+      <FileNumber>42</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -845,7 +837,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>41</FileNumber>
+      <FileNumber>43</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -857,7 +849,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>42</FileNumber>
+      <FileNumber>44</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -869,7 +861,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>43</FileNumber>
+      <FileNumber>45</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -881,7 +873,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>44</FileNumber>
+      <FileNumber>46</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 11 - 1
demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx

@@ -340,7 +340,7 @@
               <MiscControls></MiscControls>
               <Define>USE_HAL_DRIVER,STM32F429xx</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;..\..\..\..\..\common;..\..\..\..\..\core;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hub;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\osal;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F;..\..\..\..\..\third_party\fatfs-0.14\source</IncludePath>
+              <IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\common;..\..\..\..\..\core;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hub;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\wireless;..\..\..\..\..\osal;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F;..\..\..\..\..\third_party\fatfs-0.14\source</IncludePath>
             </VariousControls>
           </Cads>
           <Aads>
@@ -579,6 +579,11 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\..\..\core\usbh_core.c</FilePath>
             </File>
+            <File>
+              <FileName>usbh_hub.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\..\class\hub\usbh_hub.c</FilePath>
+            </File>
             <File>
               <FileName>usbh_cdc_acm.c</FileName>
               <FileType>1</FileType>
@@ -594,6 +599,11 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\..\..\class\hid\usbh_hid.c</FilePath>
             </File>
+            <File>
+              <FileName>usbh_rndis.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\..\class\wireless\usbh_rndis.c</FilePath>
+            </File>
             <File>
               <FileName>usb_osal_freertos.c</FileName>
               <FileType>1</FileType>

+ 56 - 41
demo/stm32/usb_host/stm32h743xih6/Core/Inc/usb_config.h

@@ -1,7 +1,13 @@
-#ifndef _USB_CONFIG_H
-#define _USB_CONFIG_H
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef CHERRYUSB_CONFIG_H
+#define CHERRYUSB_CONFIG_H
+
+/* ================ USB common Configuration ================ */
 
-/* USB common Configuration */
 #ifndef CONFIG_USB_DBG_LEVEL
 #define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
 #endif
@@ -10,26 +16,42 @@
 #define CONFIG_USB_PRINTF printf
 #endif
 
+/* Enable print with color */
 #define CONFIG_USB_PRINTF_COLOR_ENABLE
 
-/* USB DEVICE Configuration */
-/* core */
-#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
-#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
+/* data align size when use dma */
+#ifndef CONFIG_USB_ALIGN_SIZE
+#define CONFIG_USB_ALIGN_SIZE 4
 #endif
 
-#ifndef CONFIG_USBDEV_DESC_CHECK
-#define CONFIG_USBDEV_DESC_CHECK 0
-#endif
+/* attribute data into no cache ram */
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
+
+/* ================ USB DEVICE Configuration ================*/
+
+/* core */
 
-#ifndef CONFIG_USBDEV_TEST_MODE
-#define CONFIG_USBDEV_TEST_MODE 0
+/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
+#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
+#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
 #endif
+/* Setup packet log for debug */
+// #define CONFIG_USBDEV_SETUP_LOG_PRINT
+/* Check if the input descriptor is correct */
+// #define CONFIG_USBDEV_DESC_CHECK
+/* Enable test mode */
+// #define CONFIG_USBDEV_TEST_MODE
 
 /* cdc class */
+
 // #define CONFIG_USBDEV_CDC_ACM_UART
 
 /* msc class */
+
+#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
+#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
+#endif
+
 #ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
 #define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
 #endif
@@ -55,15 +77,22 @@
 #endif
 
 /* audio class */
+
 #ifndef CONFIG_USBDEV_AUDIO_VERSION
 #define CONFIG_USBDEV_AUDIO_VERSION 0x0100
 #endif
 
 #ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
-#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 2
+#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
+#endif
+
+/* ================ USB HOST Configuration ================ */
+/* core */
+/* Ep0 max transfer buffer */
+#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
+#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
 #endif
 
-/* USB HOST Configuration */
 #ifndef CONFIG_USBHOST_RHPORTS
 #define CONFIG_USBHOST_RHPORTS 1
 #endif
@@ -72,10 +101,6 @@
 #define CONFIG_USBHOST_EHPORTS 4
 #endif
 
-#ifndef CONFIG_USBHOST_PIPE_NUM
-#define CONFIG_USBHOST_PIPE_NUM 10
-#endif
-
 #ifndef CONFIG_USBHOST_INTF_NUM
 #define CONFIG_USBHOST_INTF_NUM 6
 #endif
@@ -85,48 +110,38 @@
 #endif
 
 #ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
-#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 5000
+#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
 #endif
 
 #ifndef CONFIG_USBHOST_MSC_TIMEOUT
 #define CONFIG_USBHOST_MSC_TIMEOUT 5000
 #endif
 
-#ifndef CONFIG_USBHOST_HPWORKQ_PRIO
-#define CONFIG_USBHOST_HPWORKQ_PRIO 5
-#endif
-#ifndef CONFIG_USBHOST_HPWORKQ_STACKSIZE
-#define CONFIG_USBHOST_HPWORKQ_STACKSIZE 2048
-#endif
-
-#ifndef CONFIG_USBHOST_LPWORKQ_PRIO
-#define CONFIG_USBHOST_LPWORKQ_PRIO 1
-#endif
-#ifndef CONFIG_USBHOST_LPWORKQ_STACKSIZE
-#define CONFIG_USBHOST_LPWORKQ_STACKSIZE 2048
-#endif
-
 #ifndef CONFIG_USBHOST_PSC_PRIO
 #define CONFIG_USBHOST_PSC_PRIO 4
 #endif
 #ifndef CONFIG_USBHOST_PSC_STACKSIZE
-#define CONFIG_USBHOST_PSC_STACKSIZE 4096
+#define CONFIG_USBHOST_PSC_STACKSIZE 2048
 #endif
 
 #ifndef CONFIG_USBHOST_DEV_NAMELEN
 #define CONFIG_USBHOST_DEV_NAMELEN 16
 #endif
 
-#define CONFIG_USBHOST_ASYNCH
 //#define CONFIG_USBHOST_GET_STRING_DESC
 
-/* EHCI Configuration */
-#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
-#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
-#define CONFIG_USB_EHCI_QH_NUM    (10)
-#define CONFIG_USB_EHCI_QTD_NUM   (10)
+#ifndef CONFIG_USBHOST_PIPE_NUM
+#define CONFIG_USBHOST_PIPE_NUM 12
+#endif
+
+/* ================ EHCI Configuration ================ */
+
+#define CONFIG_USB_EHCI_HCCR_BASE   (0x20072000)
+#define CONFIG_USB_EHCI_HCOR_BASE   (0x20072000 + 0x10)
+#define CONFIG_EHCI_FRAME_LIST_SIZE 1024
 // #define CONFIG_USB_EHCI_INFO_ENABLE
-#define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
+// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
 // #define CONFIG_USB_EHCI_CONFIGFLAG
+// #define CONFIG_USB_EHCI_PORT_POWER
 
 #endif

+ 7 - 15
demo/stm32/usb_host/stm32h743xih6/Core/Src/main.c

@@ -225,15 +225,6 @@ void cpu_mpu_config(uint8_t Region, uint8_t Mode, uint32_t Address, uint32_t Siz
 
 }
 
-void usb_dcache_clean(uintptr_t addr, uint32_t len)
-{
-    SCB_CleanDCache_by_Addr((uint32_t*)addr,len);
-}
-
-void usb_dcache_invalidate(uintptr_t addr, uint32_t len)
-{
-    SCB_InvalidateDCache_by_Addr((uint32_t*)addr,len);
-}
 /* USER CODE END 0 */
 
 /**
@@ -248,10 +239,9 @@ int main(void)
 
   /* Enable I-Cache---------------------------------------------------------*/
   SCB_EnableICache();
-#ifdef CONFIG_USB_DCACHE_ENABLE
   /* Enable D-Cache---------------------------------------------------------*/
   SCB_EnableDCache();
-#endif
+
   /* MCU Configuration--------------------------------------------------------*/
 
   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
@@ -273,11 +263,13 @@ int main(void)
   MX_USART1_UART_Init();
   //MX_USB_OTG_HS_HCD_Init();
   /* USER CODE BEGIN 2 */
-#ifdef CONFIG_USB_DCACHE_ENABLE
-  cpu_mpu_config(0, MPU_Normal_WB, 0x24000000, MPU_REGION_SIZE_512KB);
-#endif
-  usbh_initialize();
+
+  cpu_mpu_config(0, MPU_Normal_NonCache, 0x24070000, MPU_REGION_SIZE_64KB);
+
   printf("Start usb host task...\r\n");
+  extern void usbh_class_test(void);                   
+  usbh_initialize();
+  usbh_class_test();
   vTaskStartScheduler();
   /* USER CODE END 2 */
 

+ 26 - 2
demo/stm32/usb_host/stm32h743xih6/MDK-ARM/stm32h743xih6.uvoptx

@@ -800,8 +800,8 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\..\..\..\..\osal\usb_osal_freertos.c</PathWithFileName>
-      <FilenameWithoutPath>usb_osal_freertos.c</FilenameWithoutPath>
+      <PathWithFileName>..\..\..\..\..\class\hub\usbh_hub.c</PathWithFileName>
+      <FilenameWithoutPath>usbh_hub.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
@@ -848,6 +848,30 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\..\..\class\wireless\usbh_rndis.c</PathWithFileName>
+      <FilenameWithoutPath>usbh_rndis.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>43</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\..\..\osal\usb_osal_freertos.c</PathWithFileName>
+      <FilenameWithoutPath>usb_osal_freertos.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>44</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
       <PathWithFileName>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</PathWithFileName>
       <FilenameWithoutPath>usb_hc_dwc2.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>

+ 17 - 7
demo/stm32/usb_host/stm32h743xih6/MDK-ARM/stm32h743xih6.uvprojx

@@ -211,7 +211,7 @@
             <Ra1Chk>0</Ra1Chk>
             <Ra2Chk>0</Ra2Chk>
             <Ra3Chk>0</Ra3Chk>
-            <Im1Chk>0</Im1Chk>
+            <Im1Chk>1</Im1Chk>
             <Im2Chk>1</Im2Chk>
             <OnChipMemories>
               <Ocm1>
@@ -338,9 +338,9 @@
             <v6Rtti>0</v6Rtti>
             <VariousControls>
               <MiscControls></MiscControls>
-              <Define>USE_HAL_DRIVER,STM32H743xx,STM32H7,CONFIG_USB_DCACHE_ENABLE,CONFIG_USB_ALIGN_SIZE=32</Define>
+              <Define>USE_HAL_DRIVER,STM32H743xx,STM32H7</Define>
               <Undefine></Undefine>
-              <IncludePath>../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\core;..\..\..\..\..\common;..\..\..\..\..\osal;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\hub;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM7\r0p1</IncludePath>
+              <IncludePath>../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\core;..\..\..\..\..\common;..\..\..\..\..\osal;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\hub;..\..\..\..\..\class\wireless;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM7\r0p1</IncludePath>
             </VariousControls>
           </Cads>
           <Aads>
@@ -362,7 +362,7 @@
             </VariousControls>
           </Aads>
           <LDads>
-            <umfTarg>1</umfTarg>
+            <umfTarg>0</umfTarg>
             <Ropi>0</Ropi>
             <Rwpi>0</Rwpi>
             <noStLib>0</noStLib>
@@ -371,7 +371,7 @@
             <TextAddressRange></TextAddressRange>
             <DataAddressRange></DataAddressRange>
             <pXoBase></pXoBase>
-            <ScatterFile></ScatterFile>
+            <ScatterFile>stm32h743xih6\stm32h743xih6.sct</ScatterFile>
             <IncludeLibs></IncludeLibs>
             <IncludeLibsPath></IncludeLibsPath>
             <Misc></Misc>
@@ -595,9 +595,9 @@
               <FilePath>..\..\..\..\..\core\usbh_core.c</FilePath>
             </File>
             <File>
-              <FileName>usb_osal_freertos.c</FileName>
+              <FileName>usbh_hub.c</FileName>
               <FileType>1</FileType>
-              <FilePath>..\..\..\..\..\osal\usb_osal_freertos.c</FilePath>
+              <FilePath>..\..\..\..\..\class\hub\usbh_hub.c</FilePath>
             </File>
             <File>
               <FileName>usbh_cdc_acm.c</FileName>
@@ -614,6 +614,16 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\..\..\class\msc\usbh_msc.c</FilePath>
             </File>
+            <File>
+              <FileName>usbh_rndis.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\..\class\wireless\usbh_rndis.c</FilePath>
+            </File>
+            <File>
+              <FileName>usb_osal_freertos.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\..\osal\usb_osal_freertos.c</FilePath>
+            </File>
             <File>
               <FileName>usb_hc_dwc2.c</FileName>
               <FileType>1</FileType>

+ 19 - 0
demo/stm32/usb_host/stm32h743xih6/MDK-ARM/stm32h743xih6/stm32h743xih6.sct

@@ -0,0 +1,19 @@
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
+  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
+   *.o (RESET, +First)
+   *(InRoot$$Sections)
+   .ANY (+RO)
+   .ANY (+XO)
+  }
+  RW_IRAM2 0x24000000 0x00070000  {  ; RW data
+   .ANY (+RW +ZI)
+  }
+  USB_NOCACHERAM 0x24070000 0x00010000  {  ; RW data
+   *(.noncacheable)
+  }
+}
+

+ 32 - 12
demo/usb_host.c

@@ -21,6 +21,8 @@ void usbh_cdc_acm_callback(void *arg, int nbytes)
 int cdc_acm_test(void)
 {
     int ret;
+    usbh_pipe_t bulkin;
+    usbh_pipe_t bulkout;
 
     struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0");
 
@@ -29,8 +31,11 @@ int cdc_acm_test(void)
         return -1;
     }
 
+    bulkin = cdc_acm_class->bulkin;
+    bulkout = cdc_acm_class->bulkout;
+
     memset(cdc_buffer, 0, 512);
-    ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkin, cdc_buffer, 512, 3000);
+    ret = usbh_bulk_transfer(bulkin, cdc_buffer, 20, 3000);
     if (ret < 0) {
         USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
     } else {
@@ -44,7 +49,7 @@ int cdc_acm_test(void)
     const uint8_t data1[10] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x14 };
 
     memcpy(cdc_buffer, data1, 8);
-    ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkout, cdc_buffer, 8, 3000);
+    ret = usbh_bulk_transfer(bulkout, cdc_buffer, 8, 3000);
     if (ret < 0) {
         USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
     } else {
@@ -52,9 +57,9 @@ int cdc_acm_test(void)
     }
 
 #if 0
-    usbh_ep_bulk_async_transfer(cdc_acm_class->bulkin, cdc_buffer, 512, usbh_cdc_acm_callback, cdc_acm_class);
+    usbh_bulk_async_transfer(bulkin, cdc_buffer, 512, usbh_cdc_acm_callback, cdc_acm_class);
 #else
-    ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkin, cdc_buffer, 512, 3000);
+    ret = usbh_bulk_transfer(bulkin, cdc_buffer, 512, 3000);
     if (ret < 0) {
         USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
     } else {
@@ -63,9 +68,7 @@ int cdc_acm_test(void)
             USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
         }
     }
-
     USB_LOG_RAW("\r\n");
-
     return ret;
 #endif
 }
@@ -166,13 +169,13 @@ int hid_test(void)
         USB_LOG_RAW("do not find /dev/input0\r\n");
         return -1;
     }
-#if 1
-    ret = usbh_ep_intr_async_transfer(hid_class->intin, hid_buffer, 128, usbh_hid_callback, hid_class);
+#if 0
+    ret = usbh_intr_async_transfer(hid_class->intin, hid_buffer, 8, usbh_hid_callback, hid_class);
     if (ret < 0) {
         USB_LOG_RAW("intr asnyc in error,ret:%d\r\n", ret);
     }
 #else
-    ret = usbh_ep_intr_transfer(hid_class->intin, hid_buffer, 128, 1000);
+    ret = usbh_int_transfer(hid_class->intin, hid_buffer, 8, 1000);
     if (ret < 0) {
         USB_LOG_RAW("intr in error,ret:%d\r\n", ret);
         return ret;
@@ -184,7 +187,24 @@ int hid_test(void)
 
 void usbh_device_mount_done_callback(struct usbh_hubport *hport)
 {
-    cdc_acm_test();
-    msc_test();
-    hid_test();
+}
+
+void usbh_device_unmount_done_callback(struct usbh_hubport *hport)
+{
+}
+
+static void usbh_class_test_thread(void *argument)
+{
+    while (1) {
+        printf("hellworld\r\n");
+        usb_osal_msleep(1000);
+        cdc_acm_test();
+        msc_test();
+        hid_test();
+    }
+}
+
+void usbh_class_test(void)
+{
+    usb_osal_thread_create("usbh_test", 4096, CONFIG_USBHOST_PSC_PRIO + 1, usbh_class_test_thread, NULL);
 }

+ 5 - 0
port/dwc2/usb_dc_dwc2.c

@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 #include "usbd_core.h"
 #include "usb_dwc2_reg.h"
 #include "cmsis_compiler.h"

Fișier diff suprimat deoarece este prea mare
+ 329 - 456
port/dwc2/usb_hc_dwc2.c


Fișier diff suprimat deoarece este prea mare
+ 190 - 793
port/ehci/usb_hc_ehci.h


+ 5 - 0
port/musb/usb_dc_musb.c

@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 #include "usbd_core.h"
 #include "usb_musb_reg.h"
 

Fișier diff suprimat deoarece este prea mare
+ 398 - 602
port/musb/usb_hc_musb.c


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff