Просмотр исходного кода

update(cherryusb): update to v1.6.0

Signed-off-by: sakumisu <1203593632@qq.com>
sakumisu 2 дней назад
Родитель
Сommit
cdc50db570
100 измененных файлов с 7553 добавлено и 9585 удалено
  1. 1 1
      components/drivers/usb/Kconfig
  2. 1 0
      components/drivers/usb/cherryusb/.gitignore
  3. 225 163
      components/drivers/usb/cherryusb/Kconfig
  4. 0 462
      components/drivers/usb/cherryusb/Kconfig.rtt
  5. 0 500
      components/drivers/usb/cherryusb/Kconfig.rttpkg
  6. 28 25
      components/drivers/usb/cherryusb/README.md
  7. 6 5
      components/drivers/usb/cherryusb/README_zh.md
  8. 32 12
      components/drivers/usb/cherryusb/SConscript
  9. 2 2
      components/drivers/usb/cherryusb/VERSION
  10. 27 10
      components/drivers/usb/cherryusb/cherryusb.cmake
  11. 9 1
      components/drivers/usb/cherryusb/cherryusb_config_template.h
  12. 0 4
      components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c
  13. 46 58
      components/drivers/usb/cherryusb/class/audio/usb_audio.h
  14. 18 20
      components/drivers/usb/cherryusb/class/cdc/usb_cdc.h
  15. 0 285
      components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c
  16. 0 50
      components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.h
  17. 0 10
      components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c
  18. 0 10
      components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c
  19. 1 2
      components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c
  20. 224 0
      components/drivers/usb/cherryusb/class/gamepad/usb_gamepad.h
  21. 209 0
      components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c
  22. 22 0
      components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.h
  23. 106 123
      components/drivers/usb/cherryusb/class/hid/usb_hid.h
  24. 426 29
      components/drivers/usb/cherryusb/class/hid/usbh_hid.c
  25. 81 0
      components/drivers/usb/cherryusb/class/hid/usbh_hid.h
  26. 43 14
      components/drivers/usb/cherryusb/class/hub/usbh_hub.c
  27. 15 0
      components/drivers/usb/cherryusb/class/midi/usb_midi.h
  28. 266 0
      components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.c
  29. 19 0
      components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.h
  30. 409 0
      components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c
  31. 56 0
      components/drivers/usb/cherryusb/class/serial/usbh_ch34x.h
  32. 507 0
      components/drivers/usb/cherryusb/class/serial/usbh_cp210x.c
  33. 187 0
      components/drivers/usb/cherryusb/class/serial/usbh_cp210x.h
  34. 407 0
      components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c
  35. 341 0
      components/drivers/usb/cherryusb/class/serial/usbh_ftdi.h
  36. 131 0
      components/drivers/usb/cherryusb/class/serial/usbh_gsm.c
  37. 726 0
      components/drivers/usb/cherryusb/class/serial/usbh_pl2303.c
  38. 43 0
      components/drivers/usb/cherryusb/class/serial/usbh_pl2303.h
  39. 743 0
      components/drivers/usb/cherryusb/class/serial/usbh_serial.c
  40. 182 0
      components/drivers/usb/cherryusb/class/serial/usbh_serial.h
  41. 0 10
      components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c
  42. 5 15
      components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c
  43. 0 379
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c
  44. 0 76
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.h
  45. 0 328
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c
  46. 0 73
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.h
  47. 0 510
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c
  48. 0 96
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.h
  49. 0 449
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c
  50. 0 62
      components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.h
  51. 0 0
      components/drivers/usb/cherryusb/class/vendor/wifi/.gitkeep
  52. 0 6
      components/drivers/usb/cherryusb/class/vendor/wifi/README.md
  53. 0 513
      components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c
  54. 0 220
      components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h
  55. 74 64
      components/drivers/usb/cherryusb/class/video/usbh_video.c
  56. 3 2
      components/drivers/usb/cherryusb/class/video/usbh_video.h
  57. 9 10
      components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c
  58. 163 43
      components/drivers/usb/cherryusb/common/usb_def.h
  59. 39 0
      components/drivers/usb/cherryusb/common/usb_otg.h
  60. 19 2
      components/drivers/usb/cherryusb/common/usb_util.h
  61. 2 2
      components/drivers/usb/cherryusb/common/usb_version.h
  62. 18 220
      components/drivers/usb/cherryusb/core/usbd_core.c
  63. 2 9
      components/drivers/usb/cherryusb/core/usbd_core.h
  64. 394 200
      components/drivers/usb/cherryusb/core/usbh_core.c
  65. 39 3
      components/drivers/usb/cherryusb/core/usbh_core.h
  66. 155 0
      components/drivers/usb/cherryusb/core/usbotg_core.c
  67. 27 0
      components/drivers/usb/cherryusb/core/usbotg_core.h
  68. 4 84
      components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c
  69. 17 101
      components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c
  70. 103 147
      components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c
  71. 36 110
      components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c
  72. 63 148
      components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c
  73. 22 116
      components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c
  74. 2 84
      components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c
  75. 2 147
      components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c
  76. 2 85
      components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c
  77. 1 86
      components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c
  78. 1 88
      components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c
  79. 26 86
      components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c
  80. 1 85
      components/drivers/usb/cherryusb/demo/cdc_acm_template.c
  81. 5 114
      components/drivers/usb/cherryusb/demo/cdc_ecm_template.c
  82. 1 87
      components/drivers/usb/cherryusb/demo/cdc_rndis_template.c
  83. 1 133
      components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c
  84. 250 0
      components/drivers/usb/cherryusb/demo/gamepad_template.c
  85. 41 202
      components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c
  86. 4 151
      components/drivers/usb/cherryusb/demo/hid_keyboard_template.c
  87. 4 152
      components/drivers/usb/cherryusb/demo/hid_mouse_template.c
  88. 4 152
      components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c
  89. 11 178
      components/drivers/usb/cherryusb/demo/midi_template.c
  90. 1 84
      components/drivers/usb/cherryusb/demo/msc_ram_template.c
  91. 124 92
      components/drivers/usb/cherryusb/demo/usb_host.c
  92. 182 0
      components/drivers/usb/cherryusb/demo/usbh_bl616_wifi_cli.c
  93. 9 174
      components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c
  94. 1 93
      components/drivers/usb/cherryusb/demo/video_static_h264_template.c
  95. 1 93
      components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c
  96. 1 94
      components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c
  97. 34 275
      components/drivers/usb/cherryusb/demo/webusb_hid_template.c
  98. 84 291
      components/drivers/usb/cherryusb/demo/winusb1.0_template.c
  99. 27 225
      components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c
  100. 0 550
      components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c

+ 1 - 1
components/drivers/usb/Kconfig

@@ -1 +1 @@
-rsource "cherryusb/Kconfig.rtt"
+rsource "cherryusb/Kconfig"

+ 1 - 0
components/drivers/usb/cherryusb/.gitignore

@@ -1,4 +1,5 @@
 .vscode
+build
 **/Drivers/**
 **/MDK-ARM/DebugConfig/**
 **/MDK-ARM/RTE/**

+ 225 - 163
components/drivers/usb/cherryusb/Kconfig

@@ -1,146 +1,155 @@
-# Kconfig file for CherryUSB
-menuconfig CHERRYUSB
-    bool "CherryUSB Configuration"
+# Kconfig file for package CherryUSB
+menuconfig RT_USING_CHERRYUSB
+    bool "Using USB with CherryUSB"
     default n
 
-if CHERRYUSB
+if RT_USING_CHERRYUSB
 
-    menuconfig CHERRYUSB_DEVICE
+    menuconfig RT_CHERRYUSB_DEVICE
         bool "Enable usb device mode"
         default n
 
-    if CHERRYUSB_DEVICE
+    if RT_CHERRYUSB_DEVICE
         choice CHERRYUSB_DEVICE_SPEED
             prompt "Select usb device speed"
-            default CHERRYUSB_DEVICE_SPEED_FS
-            config CHERRYUSB_DEVICE_SPEED_FS
+            default RT_CHERRYUSB_DEVICE_SPEED_FS
+            config RT_CHERRYUSB_DEVICE_SPEED_FS
                 bool "FS"
-            config CHERRYUSB_DEVICE_SPEED_HS
+            config RT_CHERRYUSB_DEVICE_SPEED_HS
                 bool "HS"
-            config CHERRYUSB_DEVICE_SPEED_AUTO
+            config RT_CHERRYUSB_DEVICE_SPEED_AUTO
                 bool "AUTO"
         endchoice
 
         choice CHERRYUSB_DEVICE_IP
             prompt "Select usb device ip, and some ip need config in usb_config.h, please check"
-            default CHERRYUSB_DEVICE_CUSTOM
-            config CHERRYUSB_DEVICE_CUSTOM
+            default RT_CHERRYUSB_DEVICE_CUSTOM
+            config RT_CHERRYUSB_DEVICE_CUSTOM
                 bool "CUSTOM (Implement it yourself)"
-            config CHERRYUSB_DEVICE_FSDEV_ST
+            config RT_CHERRYUSB_DEVICE_FSDEV_ST
                 bool "fsdev_st"
-            config CHERRYUSB_DEVICE_FSDEV_CUSTOM
+            config RT_CHERRYUSB_DEVICE_FSDEV_CUSTOM
                 bool "fsdev_custom"
-            config CHERRYUSB_DEVICE_DWC2_ST
+            config RT_CHERRYUSB_DEVICE_DWC2_ST
                 bool "dwc2_st"
-            config CHERRYUSB_DEVICE_DWC2_ESP
+            config RT_CHERRYUSB_DEVICE_DWC2_ESP
                 bool "dwc2_esp"
-            config CHERRYUSB_DEVICE_DWC2_KENDRYTE
+            config RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE
                 bool "dwc2_kendryte"
-            config CHERRYUSB_DEVICE_DWC2_AT
+            config RT_CHERRYUSB_DEVICE_DWC2_INFINEON
+                bool "dwc2_infineon"
+            config RT_CHERRYUSB_DEVICE_DWC2_AT
                 bool "dwc2_at"
-            config CHERRYUSB_DEVICE_DWC2_HC
+            config RT_CHERRYUSB_DEVICE_DWC2_HC
                 bool "dwc2_hc"
-            config CHERRYUSB_DEVICE_DWC2_NATION
+            config RT_CHERRYUSB_DEVICE_DWC2_NATION
                 bool "dwc2_nation"
-            config CHERRYUSB_DEVICE_DWC2_GD
+            config RT_CHERRYUSB_DEVICE_DWC2_GD
                 bool "dwc2_gd"
-            config CHERRYUSB_DEVICE_DWC2_CUSTOM
+            config RT_CHERRYUSB_DEVICE_DWC2_CUSTOM
                 bool "dwc2_custom"
-            config CHERRYUSB_DEVICE_MUSB_ES
+            config RT_CHERRYUSB_DEVICE_MUSB_ES
                 bool "musb_es"
-            config CHERRYUSB_DEVICE_MUSB_SUNXI
+            config RT_CHERRYUSB_DEVICE_MUSB_SUNXI
                 bool "musb_sunxi"
-            config CHERRYUSB_DEVICE_MUSB_BK
+            config RT_CHERRYUSB_DEVICE_MUSB_BK
                 bool "musb_bk"
-            config CHERRYUSB_DEVICE_MUSB_SIFLI
+            config RT_CHERRYUSB_DEVICE_MUSB_SIFLI
                 bool "musb_sifli"
-            config CHERRYUSB_DEVICE_MUSB_CUSTOM
+            config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
                 bool "musb_custom"
-            config CHERRYUSB_DEVICE_CHIPIDEA_MCX
+            config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
                 bool "chipidea_mcx"
-            config CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM
+            config RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM
                 bool "chipidea_custom"
-            config CHERRYUSB_DEVICE_KINETIS_MCX
+            config RT_CHERRYUSB_DEVICE_KINETIS_MCX
                 bool "kinetis_mcx"
-            config CHERRYUSB_DEVICE_KINETIS_MM32
+            config RT_CHERRYUSB_DEVICE_KINETIS_MM32
                 bool "kinetis_mm32"
-            config CHERRYUSB_DEVICE_KINETIS_CUSTOM
+            config RT_CHERRYUSB_DEVICE_KINETIS_CUSTOM
                 bool "kinetis_custom"
-            config CHERRYUSB_DEVICE_BL
+            config RT_CHERRYUSB_DEVICE_BL
                 bool "bouffalo"
-            config CHERRYUSB_DEVICE_HPM
+            config RT_CHERRYUSB_DEVICE_HPM
                 bool "hpm"
-            config CHERRYUSB_DEVICE_AIC
+            config RT_CHERRYUSB_DEVICE_AIC
                 bool "aic"
-            config CHERRYUSB_DEVICE_RP2040
+            config RT_CHERRYUSB_DEVICE_RP2040
                 bool "rp2040"
-            config CHERRYUSB_DEVICE_CH32
+            config RT_CHERRYUSB_DEVICE_CH32
                 bool "ch32"
-            config CHERRYUSB_DEVICE_PUSB2
+            config RT_CHERRYUSB_DEVICE_PUSB2
                 bool "pusb2"
+            config RT_CHERRYUSB_DEVICE_NRF5X
+                bool "nrf5x"
         endchoice
 
-        config CHERRYUSB_DEVICE_CDC_ACM
+        config RT_CHERRYUSB_DEVICE_CDC_ACM
             bool
             prompt "Enable usb cdc acm device"
             default n
 
-        config CHERRYUSB_DEVICE_HID
+        config RT_CHERRYUSB_DEVICE_HID
             bool
             prompt "Enable usb hid device"
             default n
 
-        config CHERRYUSB_DEVICE_MSC
+        config RT_CHERRYUSB_DEVICE_MSC
             bool
             prompt "Enable usb msc device"
             default n
 
-        config CHERRYUSB_DEVICE_AUDIO
+        config RT_CHERRYUSB_DEVICE_AUDIO
             bool
             prompt "Enable usb audio device"
             default n
 
-        config CHERRYUSB_DEVICE_VIDEO
+        config RT_CHERRYUSB_DEVICE_VIDEO
             bool
             prompt "Enable usb video device"
             default n
 
-        config CHERRYUSB_DEVICE_CDC_RNDIS
+        config RT_CHERRYUSB_DEVICE_CDC_RNDIS
             bool
             prompt "Enable usb cdc rndis device"
             default n
 
-        config CHERRYUSB_DEVICE_CDC_ECM
+        config RT_CHERRYUSB_DEVICE_CDC_ECM
             bool
             prompt "Enable usb cdc ecm device"
             default n
 
-        config CHERRYUSB_DEVICE_CDC_NCM
+        config RT_CHERRYUSB_DEVICE_CDC_NCM
             bool
             prompt "Enable usb cdc ncm device"
             default n
 
-        config CHERRYUSB_DEVICE_MTP
+        config RT_CHERRYUSB_DEVICE_MTP
             bool
             prompt "Enable usb mtp device, it is commercial charge"
             default n
 
-        config CHERRYUSB_DEVICE_ADB
+        config RT_CHERRYUSB_DEVICE_ADB
             bool
             prompt "Enable usb adb device"
             default n
 
-        config CHERRYUSB_DEVICE_DFU
+        config RT_CHERRYUSB_DEVICE_DFU
             bool
             prompt "Enable usb dfu device"
             default n
 
-        config USBDEV_REQUEST_BUFFER_LEN
+        config RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
+            bool
+            prompt "Enable chardev for cdc acm device"
+            default n
+
+        config CONFIG_USBDEV_REQUEST_BUFFER_LEN
             int
             prompt "Set device control transfer max buffer size"
             default 512
 
-        config USBDEV_MSC_MAX_BUFSIZE
+        config CONFIG_USBDEV_MSC_MAX_BUFSIZE
             int
             prompt "Set usb msc device max buffer size"
             default 512
@@ -148,286 +157,339 @@ if CHERRYUSB
                 Set the maximum buffer size for usb msc device, it is used to transfer data.
                 you can change it to a larger value if you need larger speed but must be a power of blocksize.
 
-        config USBDEV_RNDIS_USING_LWIP
+        config CONFIG_USBDEV_RNDIS_USING_LWIP
             bool
             prompt "Enable usb rndis device with lwip for lan"
             default n
 
-        config USBDEV_CDC_ECM_USING_LWIP
+        config CONFIG_USBDEV_CDC_ECM_USING_LWIP
             bool
             prompt "Enable usb cdc ecm device with lwip for lan"
             default n
 
         choice CHERRYUSB_DEVICE_TEMPLATE
             prompt "Select usb device template, please select class driver first"
-            default CHERRYUSB_DEVICE_TEMPLATE_NONE
-            config CHERRYUSB_DEVICE_TEMPLATE_NONE
+            default RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
                 bool
                 prompt "none (Implement it yourself)"
-            config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
                 bool
                 prompt "cdc_acm"
-                depends on CHERRYUSB_DEVICE_CDC_ACM
-            config CHERRYUSB_DEVICE_TEMPLATE_MSC
+                depends on RT_CHERRYUSB_DEVICE_CDC_ACM
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
                 bool
                 prompt "msc_ram"
-                depends on CHERRYUSB_DEVICE_MSC
-            config CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
+                depends on RT_CHERRYUSB_DEVICE_MSC
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
+                bool
+                prompt "msc_blkdev"
+                depends on RT_CHERRYUSB_DEVICE_MSC
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
                 bool
                 prompt "hid_keyboard"
-                depends on CHERRYUSB_DEVICE_HID
-            config CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
+                depends on RT_CHERRYUSB_DEVICE_HID
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
                 bool
                 prompt "hid_mouse"
-                depends on CHERRYUSB_DEVICE_HID
-            config CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
+                depends on RT_CHERRYUSB_DEVICE_HID
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
                 bool
                 prompt "hid_custom"
-                depends on CHERRYUSB_DEVICE_HID
-            config CHERRYUSB_DEVICE_TEMPLATE_VIDEO
+                depends on RT_CHERRYUSB_DEVICE_HID
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_VIDEO
                 bool
                 prompt "video"
-                depends on CHERRYUSB_DEVICE_VIDEO
-            config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
+                depends on RT_CHERRYUSB_DEVICE_VIDEO
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
                 bool
                 prompt "audio_v1_mic_speaker_multichan"
-                depends on CHERRYUSB_DEVICE_AUDIO
-            config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
+                depends on RT_CHERRYUSB_DEVICE_AUDIO
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
                 bool
                 prompt "audio_v2_mic_speaker_multichan"
-                depends on CHERRYUSB_DEVICE_AUDIO
-            config CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
+                depends on RT_CHERRYUSB_DEVICE_AUDIO
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
                 bool
                 prompt "cdc_rndis"
-                depends on CHERRYUSB_DEVICE_CDC_RNDIS
-            config CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
+                depends on RT_CHERRYUSB_DEVICE_CDC_RNDIS
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
                 bool
                 prompt "cdc_ecm"
-                depends on CHERRYUSB_DEVICE_CDC_ECM
-            config CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
+                depends on RT_CHERRYUSB_DEVICE_CDC_ECM
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
                 bool
                 prompt "cdc_ncm"
-                depends on CHERRYUSB_DEVICE_CDC_NCM
-            config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
+                depends on RT_CHERRYUSB_DEVICE_CDC_NCM
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
                 bool
                 prompt "cdc_acm_msc"
-                depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC
-            config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
+                depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
                 bool
                 prompt "cdc_acm_msc_hid"
-                depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC && CHERRYUSB_DEVICE_HID
-            config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
+                depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC && RT_CHERRYUSB_DEVICE_HID
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
                 bool
                 prompt "winusbv1"
-            config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2
+                bool
+                prompt "winusbv2"
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
                 bool
                 prompt "winusbv2_cdc"
-                depends on CHERRYUSB_DEVICE_CDC_ACM
-            config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
+                depends on RT_CHERRYUSB_DEVICE_CDC_ACM
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID
+                bool
+                prompt "webusb_hid"
+                depends on RT_CHERRYUSB_DEVICE_HID
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB
+                bool
+                prompt "adb"
+                depends on RT_CHERRYUSB_DEVICE_ADB
+            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
                 bool
-                prompt "winusbv2_hid"
-                depends on CHERRYUSB_DEVICE_HID
+                prompt "cdc_acm_chardev"
+                depends on RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
         endchoice
+
+        config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
+            string "usb device msc block device name"
+            depends on RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
+            default "sd0"
+
     endif
 
-    menuconfig CHERRYUSB_HOST
+    menuconfig RT_CHERRYUSB_HOST
         bool "Enable usb host mode"
         default n
 
-    if CHERRYUSB_HOST
+    if RT_CHERRYUSB_HOST
         choice CHERRYUSB_HOST_IP
             prompt "Select usb host ip, and some ip need config in usb_config.h, please check"
-            default CHERRYUSB_HOST_CUSTOM
-            config CHERRYUSB_HOST_CUSTOM
+            default RT_CHERRYUSB_HOST_CUSTOM
+            config RT_CHERRYUSB_HOST_CUSTOM
                 bool "CUSTOM (Implement it yourself)"
-            config CHERRYUSB_HOST_EHCI_BL
+            config RT_CHERRYUSB_HOST_EHCI_BL
                 bool "ehci_bouffalo"
-            config CHERRYUSB_HOST_EHCI_HPM
+            config RT_CHERRYUSB_HOST_EHCI_HPM
                 bool "ehci_hpm"
-            config CHERRYUSB_HOST_EHCI_AIC
+            config RT_CHERRYUSB_HOST_EHCI_AIC
                 bool "ehci_aic"
-            config CHERRYUSB_HOST_EHCI_MCX
+            config RT_CHERRYUSB_HOST_EHCI_MCX
                 bool "ehci_mcx"
-            config CHERRYUSB_HOST_EHCI_NUC980
+            config RT_CHERRYUSB_HOST_EHCI_NUC980
                 bool "ehci_nuc980"
-            config CHERRYUSB_HOST_EHCI_MA35D0
+            config RT_CHERRYUSB_HOST_EHCI_MA35D0
                 bool "ehci_ma35d0"
-            config CHERRYUSB_HOST_EHCI_CUSTOM
+            config RT_CHERRYUSB_HOST_EHCI_CUSTOM
                 bool "ehci_custom"
-            config CHERRYUSB_HOST_DWC2_ST
+            config RT_CHERRYUSB_HOST_DWC2_ST
                 bool "dwc2_st"
-            config CHERRYUSB_HOST_DWC2_ESP
+            config RT_CHERRYUSB_HOST_DWC2_ESP
                 bool "dwc2_esp"
-            config CHERRYUSB_HOST_DWC2_KENDRYTE
+            config RT_CHERRYUSB_HOST_DWC2_KENDRYTE
                 bool "dwc2_kendryte"
-            config CHERRYUSB_HOST_DWC2_HC
+            config RT_CHERRYUSB_HOST_DWC2_INFINEON
+                bool "dwc2_infineon"
+            config RT_CHERRYUSB_HOST_DWC2_AT
+                bool "dwc2_at, f405 only"
+            config RT_CHERRYUSB_HOST_DWC2_HC
                 bool "dwc2_hc"
-            config CHERRYUSB_HOST_DWC2_NATION
+            config RT_CHERRYUSB_HOST_DWC2_NATION
                 bool "dwc2_nation"
-            config CHERRYUSB_HOST_DWC2_CUSTOM
+            config RT_CHERRYUSB_HOST_DWC2_CUSTOM
                 bool "dwc2_custom"
-            config CHERRYUSB_HOST_MUSB_ES
+            config RT_CHERRYUSB_HOST_MUSB_ES
                 bool "musb_es"
-            config CHERRYUSB_HOST_MUSB_SUNXI
+            config RT_CHERRYUSB_HOST_MUSB_SUNXI
                 bool "musb_sunxi"
-            config CHERRYUSB_HOST_MUSB_BK
+            config RT_CHERRYUSB_HOST_MUSB_BK
                 bool "musb_bk"
-            config CHERRYUSB_HOST_MUSB_SIFLI
+            config RT_CHERRYUSB_HOST_MUSB_SIFLI
                 bool "musb_sifli"
-            config CHERRYUSB_HOST_MUSB_CUSTOM
+            config RT_CHERRYUSB_HOST_MUSB_CUSTOM
                 bool "musb_custom"
-            config CHERRYUSB_HOST_PUSB2
+            config RT_CHERRYUSB_HOST_PUSB2
                 bool "pusb2"
-            config CHERRYUSB_HOST_XHCI_PHYTIUM
-                bool "xhci_phytium"
-            config CHERRYUSB_HOST_XHCI_CUSTOM
+            config RT_CHERRYUSB_HOST_XHCI
                 bool "xhci"
-            config CHERRYUSB_HOST_KINETIS_MCX
-                bool "kinetis_mcx"
-            config CHERRYUSB_HOST_KINETIS_MM32
-                bool "kinetis_mm32"
-            config CHERRYUSB_HOST_KINETIS_CUSTOM
-                bool "kinetis_custom"
-            config CHERRYUSB_HOST_RP2040
+            config RT_CHERRYUSB_HOST_RP2040
                 bool "rp2040"
         endchoice
 
-        config CHERRYUSB_HOST_CDC_ACM
+        config RT_CHERRYUSB_HOST_CDC_ACM
             bool
             prompt "Enable usb cdc acm driver"
+            select CONFIG_USBHOST_SERIAL
             default n
 
-        config CHERRYUSB_HOST_HID
+        config RT_CHERRYUSB_HOST_HID
             bool
             prompt "Enable usb hid driver"
             default n
 
-        config CHERRYUSB_HOST_MSC
+        config RT_CHERRYUSB_HOST_MSC
             bool
             prompt "Enable usb msc driver"
             default n
+            select RT_USING_DFS
+            select RT_USING_DFS_ELMFAT
 
-        config CHERRYUSB_HOST_CDC_ECM
+        config RT_CHERRYUSB_HOST_CDC_ECM
             bool
             prompt "Enable usb cdc ecm driver"
-            select USBHOST_PLATFORM_CDC_ECM
+            select RT_USING_LWIP
+            select CONFIG_USBHOST_PLATFORM_CDC_ECM
             default n
 
-        config CHERRYUSB_HOST_CDC_RNDIS
+        config RT_CHERRYUSB_HOST_CDC_RNDIS
             bool
             prompt "Enable usb rndis driver"
-            select USBHOST_PLATFORM_CDC_RNDIS
+            select RT_USING_LWIP
+            select CONFIG_USBHOST_PLATFORM_CDC_RNDIS
             default n
 
-        config CHERRYUSB_HOST_CDC_NCM
+        config RT_CHERRYUSB_HOST_CDC_NCM
             bool
             prompt "Enable usb cdc ncm driver"
-            select USBHOST_PLATFORM_CDC_NCM
+            select RT_USING_LWIP
+            select CONFIG_USBHOST_PLATFORM_CDC_NCM
             default n
 
-        config CHERRYUSB_HOST_VIDEO
+        config RT_CHERRYUSB_HOST_VIDEO
             bool
             prompt "Enable usb video driver, it is commercial charge"
             default n
 
-        config CHERRYUSB_HOST_AUDIO
+        config RT_CHERRYUSB_HOST_AUDIO
             bool
             prompt "Enable usb audio driver, it is commercial charge"
             default n
 
-        config CHERRYUSB_HOST_BLUETOOTH
+        config RT_CHERRYUSB_HOST_BLUETOOTH
             bool
             prompt "Enable usb bluetooth driver"
             default n
 
-        config CHERRYUSB_HOST_ASIX
+        config RT_CHERRYUSB_HOST_ASIX
             bool
             prompt "Enable usb asix driver"
-            select USBHOST_PLATFORM_ASIX
+            select RT_USING_LWIP
+            select CONFIG_USBHOST_PLATFORM_ASIX
             default n
 
-        config CHERRYUSB_HOST_RTL8152
+        config RT_CHERRYUSB_HOST_RTL8152
             bool
             prompt "Enable usb rtl8152 driver"
-            select USBHOST_PLATFORM_RTL8152
+            select RT_USING_LWIP
+            select CONFIG_USBHOST_PLATFORM_RTL8152
             default n
 
-        config CHERRYUSB_HOST_FTDI
+        config RT_CHERRYUSB_HOST_FTDI
             bool
             prompt "Enable usb ftdi driver"
+            select CONFIG_USBHOST_SERIAL
             default n
 
-        config CHERRYUSB_HOST_CH34X
+        config RT_CHERRYUSB_HOST_CH34X
             bool
             prompt "Enable usb ch34x driver"
+            select CONFIG_USBHOST_SERIAL
             default n
 
-        config CHERRYUSB_HOST_CP210X
+        config RT_CHERRYUSB_HOST_CP210X
             bool
             prompt "Enable usb cp210x driver"
+            select CONFIG_USBHOST_SERIAL
             default n
 
-        config CHERRYUSB_HOST_PL2303
+        config RT_CHERRYUSB_HOST_PL2303
             bool
             prompt "Enable usb pl2303 driver"
+            select CONFIG_USBHOST_SERIAL
             default n
 
-        config CHERRYUSB_HOST_AOA
+        config RT_CHERRYUSB_HOST_GSM
             bool
-            prompt "Enable usb aoa driver"
+            prompt "Enable usb gsm driver for 4g module"
+            select CONFIG_USBHOST_SERIAL
             default n
 
-        config USBHOST_PLATFORM_CDC_ECM
+        config CONFIG_USBHOST_SERIAL
             bool
 
-        config USBHOST_PLATFORM_CDC_RNDIS
+        config CONFIG_USBHOST_PLATFORM_CDC_ECM
             bool
 
-        config USBHOST_PLATFORM_CDC_NCM
+        config CONFIG_USBHOST_PLATFORM_CDC_RNDIS
             bool
 
-        config USBHOST_PLATFORM_ASIX
+        config CONFIG_USBHOST_PLATFORM_CDC_NCM
             bool
 
-        config USBHOST_PLATFORM_RTL8152
+        config CONFIG_USBHOST_PLATFORM_ASIX
             bool
 
-        config USBHOST_PSC_PRIO
+        config CONFIG_USBHOST_PLATFORM_RTL8152
+            bool
+
+        config CONFIG_USBHOST_PSC_PRIO
             int
             prompt "Set hubport change thread priority, 0 is the max priority"
             default 0
 
-        config USBHOST_PSC_STACKSIZE
+        config CONFIG_USBHOST_PSC_STACKSIZE
             int
             prompt "Set hubport change thread stacksize"
             default 4096
 
-        config USBHOST_REQUEST_BUFFER_LEN
+        config CONFIG_USBHOST_REQUEST_BUFFER_LEN
             int
             prompt "Set host control transfer max buffer size"
             default 512
 
-        config USBHOST_CONTROL_TRANSFER_TIMEOUT
+        config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
             int
             prompt "Set host control transfer timeout, unit is ms"
             default 500
 
+        config CONFIG_USBHOST_SERIAL_RX_SIZE
+            int
+            prompt "Set host serial rx max buffer size"
+            default 2048
+
+        config RT_LWIP_PBUF_POOL_BUFSIZE
+            int "The size of each pbuf in the pbuf pool"
+            range 1500 2000
+            default 1600
+
+        config CONFIG_USB_DFS_MOUNT_POINT
+            string "usb host dfs mount point"
+            depends on RT_CHERRYUSB_HOST_MSC
+            default "/"
+
         menu "Select USB host template, please select class driver first"
-            config TEST_USBH_CDC_ACM
-                int
-                prompt "demo for test cdc acm"
-                default 0
-                depends on CHERRYUSB_HOST_CDC_ACM
-            config TEST_USBH_HID
+            config CONFIG_TEST_USBH_SERIAL
+                bool
+                prompt "demo for test seial, cannot enable this demo, you can use rt-thread device api to test"
+                default n
+                depends on CONFIG_USBHOST_SERIAL
+            config CONFIG_TEST_USBH_HID
                 int
                 prompt "demo for test hid"
                 default 0
-                depends on CHERRYUSB_HOST_HID
-            config TEST_USBH_MSC
-                int
-                prompt "demo for test msc"
-                default 0
-                depends on CHERRYUSB_HOST_MSC
+                depends on RT_CHERRYUSB_HOST_HID
+            config CONFIG_TEST_USBH_MSC
+                bool
+                prompt "demo for test msc, cannot enable this demo, you can use rt-thread dfs api to test"
+                default n
+                depends on RT_CHERRYUSB_HOST_MSC
+            config CONFIG_TEST_USBH_NET
+                bool
+                prompt "demo for test net, cannot enable this demo, you can use lwip api to test"
+                default n
+                depends on RT_CHERRYUSB_HOST_CDC_ECM || RT_CHERRYUSB_HOST_CDC_RNDIS || RT_CHERRYUSB_HOST_CDC_NCM || RT_CHERRYUSB_HOST_ASIX || RT_CHERRYUSB_HOST_RTL8152
         endmenu
     endif
 endif

+ 0 - 462
components/drivers/usb/cherryusb/Kconfig.rtt

@@ -1,462 +0,0 @@
-# Kconfig file for package CherryUSB
-menuconfig RT_USING_CHERRYUSB
-    bool "Using USB with CherryUSB"
-    default n
-
-if RT_USING_CHERRYUSB
-
-    menuconfig RT_CHERRYUSB_DEVICE
-        bool "Enable usb device mode"
-        default n
-
-    if RT_CHERRYUSB_DEVICE
-        choice
-            prompt "Select usb device speed"
-            default RT_CHERRYUSB_DEVICE_SPEED_FS
-            config RT_CHERRYUSB_DEVICE_SPEED_FS
-                bool "FS"
-            config RT_CHERRYUSB_DEVICE_SPEED_HS
-                bool "HS"
-            config RT_CHERRYUSB_DEVICE_SPEED_AUTO
-                bool "AUTO"
-        endchoice
-
-        choice
-            prompt "Select usb device ip, and some ip need config in usb_config.h, please check"
-            default RT_CHERRYUSB_DEVICE_CUSTOM
-            config RT_CHERRYUSB_DEVICE_CUSTOM
-                bool "CUSTOM (Implement it yourself)"
-            config RT_CHERRYUSB_DEVICE_FSDEV_ST
-                bool "fsdev_st"
-            config RT_CHERRYUSB_DEVICE_FSDEV_CUSTOM
-                bool "fsdev_custom"
-            config RT_CHERRYUSB_DEVICE_DWC2_ST
-                bool "dwc2_st"
-            config RT_CHERRYUSB_DEVICE_DWC2_ESP
-                bool "dwc2_esp"
-            config RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE
-                bool "dwc2_kendryte"
-            config RT_CHERRYUSB_DEVICE_DWC2_AT
-                bool "dwc2_at"
-            config RT_CHERRYUSB_DEVICE_DWC2_HC
-                bool "dwc2_hc"
-            config RT_CHERRYUSB_DEVICE_DWC2_NATION
-                bool "dwc2_nation"
-            config RT_CHERRYUSB_DEVICE_DWC2_GD
-                bool "dwc2_gd"
-            config RT_CHERRYUSB_DEVICE_DWC2_CUSTOM
-                bool "dwc2_custom"
-            config RT_CHERRYUSB_DEVICE_MUSB_ES
-                bool "musb_es"
-            config RT_CHERRYUSB_DEVICE_MUSB_SUNXI
-                bool "musb_sunxi"
-            config RT_CHERRYUSB_DEVICE_MUSB_BK
-                bool "musb_bk"
-            config RT_CHERRYUSB_DEVICE_MUSB_SIFLI
-                bool "musb_sifli"
-            config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
-                bool "musb_custom"
-            config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
-                bool "chipidea_mcx"
-            config RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM
-                bool "chipidea_custom"
-            config RT_CHERRYUSB_DEVICE_KINETIS_MCX
-                bool "kinetis_mcx"
-            config RT_CHERRYUSB_DEVICE_KINETIS_MM32
-                bool "kinetis_mm32"
-            config RT_CHERRYUSB_DEVICE_KINETIS_CUSTOM
-                bool "kinetis_custom"
-            config RT_CHERRYUSB_DEVICE_BL
-                bool "bouffalo"
-            config RT_CHERRYUSB_DEVICE_HPM
-                bool "hpm"
-            config RT_CHERRYUSB_DEVICE_AIC
-                bool "aic"
-            config RT_CHERRYUSB_DEVICE_RP2040
-                bool "rp2040"
-            config RT_CHERRYUSB_DEVICE_CH32
-                bool "ch32"
-            config RT_CHERRYUSB_DEVICE_PUSB2
-                bool "pusb2"
-            config RT_CHERRYUSB_DEVICE_NRF5X
-                bool "nrf5x"
-        endchoice
-
-        config RT_CHERRYUSB_DEVICE_CDC_ACM
-            bool
-            prompt "Enable usb cdc acm device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_HID
-            bool
-            prompt "Enable usb hid device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_MSC
-            bool
-            prompt "Enable usb msc device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_AUDIO
-            bool
-            prompt "Enable usb audio device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_VIDEO
-            bool
-            prompt "Enable usb video device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_CDC_RNDIS
-            bool
-            prompt "Enable usb cdc rndis device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_CDC_ECM
-            bool
-            prompt "Enable usb cdc ecm device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_CDC_NCM
-            bool
-            prompt "Enable usb cdc ncm device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_MTP
-            bool
-            prompt "Enable usb mtp device, it is commercial charge"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_ADB
-            bool
-            prompt "Enable usb adb device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_DFU
-            bool
-            prompt "Enable usb dfu device"
-            default n
-
-        config RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
-            bool
-            prompt "Enable chardev for cdc acm device"
-            default n
-
-        config CONFIG_USBDEV_REQUEST_BUFFER_LEN
-            int
-            prompt "Set device control transfer max buffer size"
-            default 512
-
-        config CONFIG_USBDEV_MSC_MAX_BUFSIZE
-            int
-            prompt "Set usb msc device max buffer size"
-            default 512
-            help
-                Set the maximum buffer size for usb msc device, it is used to transfer data.
-                you can change it to a larger value if you need larger speed but must be a power of blocksize.
-
-        config CONFIG_USBDEV_RNDIS_USING_LWIP
-            bool
-            prompt "Enable usb rndis device with lwip for lan"
-            default n
-
-        config CONFIG_USBDEV_CDC_ECM_USING_LWIP
-            bool
-            prompt "Enable usb cdc ecm device with lwip for lan"
-            default n
-
-        choice
-            prompt "Select usb device template, please select class driver first"
-            default RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
-                bool
-                prompt "none (Implement it yourself)"
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
-                bool
-                prompt "cdc_acm"
-                depends on RT_CHERRYUSB_DEVICE_CDC_ACM
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
-                bool
-                prompt "msc_ram"
-                depends on RT_CHERRYUSB_DEVICE_MSC
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
-                bool
-                prompt "msc_blkdev"
-                depends on RT_CHERRYUSB_DEVICE_MSC
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
-                bool
-                prompt "hid_keyboard"
-                depends on RT_CHERRYUSB_DEVICE_HID
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
-                bool
-                prompt "hid_mouse"
-                depends on RT_CHERRYUSB_DEVICE_HID
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
-                bool
-                prompt "hid_custom"
-                depends on RT_CHERRYUSB_DEVICE_HID
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_VIDEO
-                bool
-                prompt "video"
-                depends on RT_CHERRYUSB_DEVICE_VIDEO
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
-                bool
-                prompt "audio_v1_mic_speaker_multichan"
-                depends on RT_CHERRYUSB_DEVICE_AUDIO
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
-                bool
-                prompt "audio_v2_mic_speaker_multichan"
-                depends on RT_CHERRYUSB_DEVICE_AUDIO
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
-                bool
-                prompt "cdc_rndis"
-                depends on RT_CHERRYUSB_DEVICE_CDC_RNDIS
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
-                bool
-                prompt "cdc_ecm"
-                depends on RT_CHERRYUSB_DEVICE_CDC_ECM
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
-                bool
-                prompt "cdc_ncm"
-                depends on RT_CHERRYUSB_DEVICE_CDC_NCM
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
-                bool
-                prompt "cdc_acm_msc"
-                depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
-                bool
-                prompt "cdc_acm_msc_hid"
-                depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC && RT_CHERRYUSB_DEVICE_HID
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
-                bool
-                prompt "winusbv1"
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
-                bool
-                prompt "winusbv2_cdc"
-                depends on RT_CHERRYUSB_DEVICE_CDC_ACM
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
-                bool
-                prompt "winusbv2_hid"
-                depends on RT_CHERRYUSB_DEVICE_HID
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB
-                bool
-                prompt "adb"
-                depends on RT_CHERRYUSB_DEVICE_ADB
-            config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
-                bool
-                prompt "cdc_acm_chardev"
-                depends on RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
-        endchoice
-
-        config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
-            string "usb device msc block device name"
-            depends on RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
-            default "sd0"
-
-    endif
-
-    menuconfig RT_CHERRYUSB_HOST
-        bool "Enable usb host mode"
-        default n
-
-    if RT_CHERRYUSB_HOST
-        choice
-            prompt "Select usb host ip, and some ip need config in usb_config.h, please check"
-            default RT_CHERRYUSB_HOST_CUSTOM
-            config RT_CHERRYUSB_HOST_CUSTOM
-                bool "CUSTOM (Implement it yourself)"
-            config RT_CHERRYUSB_HOST_EHCI_BL
-                bool "ehci_bouffalo"
-            config RT_CHERRYUSB_HOST_EHCI_HPM
-                bool "ehci_hpm"
-            config RT_CHERRYUSB_HOST_EHCI_AIC
-                bool "ehci_aic"
-            config RT_CHERRYUSB_HOST_EHCI_MCX
-                bool "ehci_mcx"
-            config RT_CHERRYUSB_HOST_EHCI_NUC980
-                bool "ehci_nuc980"
-            config RT_CHERRYUSB_HOST_EHCI_MA35D0
-                bool "ehci_ma35d0"
-            config RT_CHERRYUSB_HOST_EHCI_CUSTOM
-                bool "ehci_custom"
-            config RT_CHERRYUSB_HOST_DWC2_ST
-                bool "dwc2_st"
-            config RT_CHERRYUSB_HOST_DWC2_ESP
-                bool "dwc2_esp"
-            config RT_CHERRYUSB_HOST_DWC2_KENDRYTE
-                bool "dwc2_kendryte"
-            config RT_CHERRYUSB_HOST_DWC2_HC
-                bool "dwc2_hc"
-            config RT_CHERRYUSB_HOST_DWC2_NATION
-                bool "dwc2_nation"
-            config RT_CHERRYUSB_HOST_DWC2_CUSTOM
-                bool "dwc2_custom"
-            config RT_CHERRYUSB_HOST_MUSB_ES
-                bool "musb_es"
-            config RT_CHERRYUSB_HOST_MUSB_SUNXI
-                bool "musb_sunxi"
-            config RT_CHERRYUSB_HOST_MUSB_BK
-                bool "musb_bk"
-            config RT_CHERRYUSB_HOST_MUSB_SIFLI
-                bool "musb_sifli"
-            config RT_CHERRYUSB_HOST_MUSB_CUSTOM
-                bool "musb_custom"
-            config RT_CHERRYUSB_HOST_PUSB2
-                bool "pusb2"
-            config RT_CHERRYUSB_HOST_XHCI
-                bool "xhci"
-            config RT_CHERRYUSB_HOST_RP2040
-                bool "rp2040"
-        endchoice
-
-        config RT_CHERRYUSB_HOST_CDC_ACM
-            bool
-            prompt "Enable usb cdc acm driver"
-            default n
-
-        config RT_CHERRYUSB_HOST_HID
-            bool
-            prompt "Enable usb hid driver"
-            default n
-
-        config RT_CHERRYUSB_HOST_MSC
-            bool
-            prompt "Enable usb msc driver"
-            default n
-            select RT_USING_DFS
-            select RT_USING_DFS_ELMFAT
-
-        config RT_CHERRYUSB_HOST_CDC_ECM
-            bool
-            prompt "Enable usb cdc ecm driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_CDC_ECM
-            default n
-
-        config RT_CHERRYUSB_HOST_CDC_RNDIS
-            bool
-            prompt "Enable usb rndis driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_CDC_RNDIS
-            default n
-
-        config RT_CHERRYUSB_HOST_CDC_NCM
-            bool
-            prompt "Enable usb cdc ncm driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_CDC_NCM
-            default n
-
-        config RT_CHERRYUSB_HOST_VIDEO
-            bool
-            prompt "Enable usb video driver, it is commercial charge"
-            default n
-
-        config RT_CHERRYUSB_HOST_AUDIO
-            bool
-            prompt "Enable usb audio driver, it is commercial charge"
-            default n
-
-        config RT_CHERRYUSB_HOST_BLUETOOTH
-            bool
-            prompt "Enable usb bluetooth driver"
-            default n
-
-        config RT_CHERRYUSB_HOST_ASIX
-            bool
-            prompt "Enable usb asix driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_ASIX
-            default n
-
-        config RT_CHERRYUSB_HOST_RTL8152
-            bool
-            prompt "Enable usb rtl8152 driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_RTL8152
-            default n
-
-        config RT_CHERRYUSB_HOST_FTDI
-            bool
-            prompt "Enable usb ftdi driver"
-            default n
-
-        config RT_CHERRYUSB_HOST_CH34X
-            bool
-            prompt "Enable usb ch34x driver"
-            default n
-
-        config RT_CHERRYUSB_HOST_CP210X
-            bool
-            prompt "Enable usb cp210x driver"
-            default n
-
-        config RT_CHERRYUSB_HOST_PL2303
-            bool
-            prompt "Enable usb pl2303 driver"
-            default n
-
-        config CONFIG_USBHOST_PLATFORM_CDC_ECM
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_CDC_RNDIS
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_CDC_NCM
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_ASIX
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_RTL8152
-            bool
-
-        config CONFIG_USBHOST_PSC_PRIO
-            int
-            prompt "Set hubport change thread priority, 0 is the max priority"
-            default 0
-
-        config CONFIG_USBHOST_PSC_STACKSIZE
-            int
-            prompt "Set hubport change thread stacksize"
-            default 4096
-
-        config CONFIG_USBHOST_REQUEST_BUFFER_LEN
-            int
-            prompt "Set host control transfer max buffer size"
-            default 512
-
-        config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
-            int
-            prompt "Set host control transfer timeout, unit is ms"
-            default 500
-
-        config RT_LWIP_PBUF_POOL_BUFSIZE
-            int "The size of each pbuf in the pbuf pool"
-            range 1500 2000
-            default 1600
-
-        config CONFIG_USB_DFS_MOUNT_POINT
-            string "usb host dfs mount point"
-            depends on RT_CHERRYUSB_HOST_MSC
-            default "/"
-
-        menu "Select USB host template, please select class driver first"
-            config CONFIG_TEST_USBH_CDC_ACM
-                int
-                prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead"
-                default 0
-                depends on RT_CHERRYUSB_HOST_CDC_ACM
-            config CONFIG_TEST_USBH_HID
-                int
-                prompt "demo for test hid"
-                default 0
-                depends on RT_CHERRYUSB_HOST_HID
-            config CONFIG_TEST_USBH_MSC
-                int
-                prompt "demo for test msc, cannot enable this demo, we have used dfs instead"
-                default 0
-                depends on RT_CHERRYUSB_HOST_MSC
-        endmenu
-    endif
-endif

+ 0 - 500
components/drivers/usb/cherryusb/Kconfig.rttpkg

@@ -1,500 +0,0 @@
-# Kconfig file for package CherryUSB
-menuconfig PKG_USING_CHERRYUSB
-    depends on  RT_VER_NUM < 0x50200
-    bool "CherryUSB: tiny and portable USB host/device stack for embedded system with USB IP"
-    default n
-
-if PKG_USING_CHERRYUSB
-
-    menuconfig PKG_CHERRYUSB_DEVICE
-        bool "Enable usb device mode"
-        default n
-
-    if PKG_CHERRYUSB_DEVICE
-        choice
-            prompt "Select usb device speed"
-            default PKG_CHERRYUSB_DEVICE_SPEED_FS
-            config PKG_CHERRYUSB_DEVICE_SPEED_FS
-                bool "FS"
-            config PKG_CHERRYUSB_DEVICE_SPEED_HS
-                bool "HS"
-            config PKG_CHERRYUSB_DEVICE_SPEED_AUTO
-                bool "AUTO"
-        endchoice
-
-        choice
-            prompt "Select usb device ip, and some ip need config in usb_config.h, please check"
-            default PKG_CHERRYUSB_DEVICE_CUSTOM
-            config PKG_CHERRYUSB_DEVICE_CUSTOM
-                bool "CUSTOM (Implement it yourself)"
-            config PKG_CHERRYUSB_DEVICE_FSDEV_ST
-                bool "fsdev_st"
-            config PKG_CHERRYUSB_DEVICE_FSDEV_CUSTOM
-                bool "fsdev_custom"
-            config PKG_CHERRYUSB_DEVICE_DWC2_ST
-                bool "dwc2_st"
-            config PKG_CHERRYUSB_DEVICE_DWC2_ESP
-                bool "dwc2_esp"
-            config PKG_CHERRYUSB_DEVICE_DWC2_KENDRYTE
-                bool "dwc2_kendryte"
-            config PKG_CHERRYUSB_DEVICE_DWC2_AT
-                bool "dwc2_at"
-            config PKG_CHERRYUSB_DEVICE_DWC2_HC
-                bool "dwc2_hc"
-            config PKG_CHERRYUSB_DEVICE_DWC2_NATION
-                bool "dwc2_nation"
-            config PKG_CHERRYUSB_DEVICE_DWC2_GD
-                bool "dwc2_gd"
-            config PKG_CHERRYUSB_DEVICE_DWC2_CUSTOM
-                bool "dwc2_custom"
-            config PKG_CHERRYUSB_DEVICE_MUSB_ES
-                bool "musb_es"
-            config PKG_CHERRYUSB_DEVICE_MUSB_SUNXI
-                bool "musb_sunxi"
-            config PKG_CHERRYUSB_DEVICE_MUSB_BK
-                bool "musb_bk"
-            config PKG_CHERRYUSB_DEVICE_MUSB_SIFLI
-                bool "musb_sifli"
-            config PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM
-                bool "musb_custom"
-            config PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX
-                bool "chipidea_mcx"
-            config PKG_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM
-                bool "chipidea_custom"
-            config PKG_CHERRYUSB_DEVICE_KINETIS_MCX
-                bool "kinetis_mcx"
-            config PKG_CHERRYUSB_DEVICE_KINETIS_MM32
-                bool "kinetis_mm32"
-            config PKG_CHERRYUSB_DEVICE_KINETIS_CUSTOM
-                bool "kinetis_custom"
-            config PKG_CHERRYUSB_DEVICE_BL
-                bool "bouffalo"
-            config PKG_CHERRYUSB_DEVICE_HPM
-                bool "hpm"
-            config PKG_CHERRYUSB_DEVICE_AIC
-                bool "aic"
-            config PKG_CHERRYUSB_DEVICE_RP2040
-                bool "rp2040"
-            config PKG_CHERRYUSB_DEVICE_CH32
-                bool "ch32"
-            config PKG_CHERRYUSB_DEVICE_PUSB2
-                bool "pusb2"
-        endchoice
-
-        config PKG_CHERRYUSB_DEVICE_CDC_ACM
-            bool
-            prompt "Enable usb cdc acm device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_HID
-            bool
-            prompt "Enable usb hid device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_MSC
-            bool
-            prompt "Enable usb msc device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_AUDIO
-            bool
-            prompt "Enable usb audio device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_VIDEO
-            bool
-            prompt "Enable usb video device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_CDC_RNDIS
-            bool
-            prompt "Enable usb cdc rndis device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_CDC_ECM
-            bool
-            prompt "Enable usb cdc ecm device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_CDC_NCM
-            bool
-            prompt "Enable usb cdc ncm device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_MTP
-            bool
-            prompt "Enable usb mtp device, it is commercial charge"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_ADB
-            bool
-            prompt "Enable usb adb device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_DFU
-            bool
-            prompt "Enable usb dfu device"
-            default n
-
-        config PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
-            bool
-            prompt "Enable chardev for cdc acm device"
-            default n
-
-        config CONFIG_USBDEV_REQUEST_BUFFER_LEN
-            int
-            prompt "Set device control transfer max buffer size"
-            default 512
-
-        config CONFIG_USBDEV_MSC_MAX_BUFSIZE
-            int
-            prompt "Set usb msc device max buffer size"
-            default 512
-            help
-                Set the maximum buffer size for usb msc device, it is used to transfer data.
-                you can change it to a larger value if you need larger speed but must be a power of blocksize.
-
-        config CONFIG_USBDEV_RNDIS_USING_LWIP
-            bool
-            prompt "Enable usb rndis device with lwip for lan"
-            default n
-
-        config CONFIG_USBDEV_CDC_ECM_USING_LWIP
-            bool
-            prompt "Enable usb cdc ecm device with lwip for lan"
-            default n
-
-        choice
-            prompt "Select usb device template, please select class driver first"
-            default PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE
-                bool
-                prompt "none (Implement it yourself)"
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
-                bool
-                prompt "cdc_acm"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_ACM
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC
-                bool
-                prompt "msc_ram"
-                depends on PKG_CHERRYUSB_DEVICE_MSC
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
-                bool
-                prompt "msc_blkdev"
-                depends on PKG_CHERRYUSB_DEVICE_MSC
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
-                bool
-                prompt "hid_keyboard"
-                depends on PKG_CHERRYUSB_DEVICE_HID
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
-                bool
-                prompt "hid_mouse"
-                depends on PKG_CHERRYUSB_DEVICE_HID
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
-                bool
-                prompt "hid_custom"
-                depends on PKG_CHERRYUSB_DEVICE_HID
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_VIDEO
-                bool
-                prompt "video"
-                depends on PKG_CHERRYUSB_DEVICE_VIDEO
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
-                bool
-                prompt "audio_v1_mic_speaker_multichan"
-                depends on PKG_CHERRYUSB_DEVICE_AUDIO
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
-                bool
-                prompt "audio_v2_mic_speaker_multichan"
-                depends on PKG_CHERRYUSB_DEVICE_AUDIO
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
-                bool
-                prompt "cdc_rndis"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_RNDIS
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
-                bool
-                prompt "cdc_ecm"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_ECM
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
-                bool
-                prompt "cdc_ncm"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_NCM
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
-                bool
-                prompt "cdc_acm_msc"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
-                bool
-                prompt "cdc_acm_msc_hid"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC && PKG_CHERRYUSB_DEVICE_HID
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
-                bool
-                prompt "winusbv1"
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
-                bool
-                prompt "winusbv2_cdc"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_ACM
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
-                bool
-                prompt "winusbv2_hid"
-                depends on PKG_CHERRYUSB_DEVICE_HID
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB
-                bool
-                prompt "adb"
-                depends on PKG_CHERRYUSB_DEVICE_ADB
-            config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
-                bool
-                prompt "cdc_acm_chardev"
-                depends on PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
-        endchoice
-
-        config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
-            string "usb device msc block device name"
-            depends on PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
-            default "sd0"
-
-    endif
-
-    menuconfig PKG_CHERRYUSB_HOST
-        bool "Enable usb host mode"
-        default n
-
-    if PKG_CHERRYUSB_HOST
-        choice
-            prompt "Select usb host ip, and some ip need config in usb_config.h, please check"
-            default PKG_CHERRYUSB_HOST_CUSTOM
-            config PKG_CHERRYUSB_HOST_CUSTOM
-                bool "CUSTOM (Implement it yourself)"
-            config PKG_CHERRYUSB_HOST_EHCI_BL
-                bool "ehci_bouffalo"
-            config PKG_CHERRYUSB_HOST_EHCI_HPM
-                bool "ehci_hpm"
-            config PKG_CHERRYUSB_HOST_EHCI_AIC
-                bool "ehci_aic"
-            config PKG_CHERRYUSB_HOST_EHCI_MCX
-                bool "ehci_mcx"
-            config PKG_CHERRYUSB_HOST_EHCI_NUC980
-                bool "ehci_nuc980"
-            config PKG_CHERRYUSB_HOST_EHCI_MA35D0
-                bool "ehci_ma35d0"
-            config PKG_CHERRYUSB_HOST_EHCI_CUSTOM
-                bool "ehci_custom"
-            config PKG_CHERRYUSB_HOST_DWC2_ST
-                bool "dwc2_st"
-            config PKG_CHERRYUSB_HOST_DWC2_ESP
-                bool "dwc2_esp"
-            config PKG_CHERRYUSB_HOST_DWC2_KENDRYTE
-                bool "dwc2_kendryte"
-            config PKG_CHERRYUSB_HOST_DWC2_HC
-                bool "dwc2_hc"
-            config PKG_CHERRYUSB_HOST_DWC2_NATION
-                bool "dwc2_nation"
-            config PKG_CHERRYUSB_HOST_DWC2_CUSTOM
-                bool "dwc2_custom"
-            config PKG_CHERRYUSB_HOST_MUSB_ES
-                bool "musb_es"
-            config PKG_CHERRYUSB_HOST_MUSB_SUNXI
-                bool "musb_sunxi"
-            config PKG_CHERRYUSB_HOST_MUSB_BK
-                bool "musb_bk"
-            config PKG_CHERRYUSB_HOST_MUSB_SIFLI
-                bool "musb_sifli"
-            config PKG_CHERRYUSB_HOST_MUSB_CUSTOM
-                bool "musb_custom"
-            config PKG_CHERRYUSB_HOST_PUSB2
-                bool "pusb2"
-            config PKG_CHERRYUSB_HOST_XHCI
-                bool "xhci"
-            config PKG_CHERRYUSB_HOST_RP2040
-                bool "rp2040"
-        endchoice
-
-        config PKG_CHERRYUSB_HOST_CDC_ACM
-            bool
-            prompt "Enable usb cdc acm driver"
-            default n
-
-        config PKG_CHERRYUSB_HOST_HID
-            bool
-            prompt "Enable usb hid driver"
-            default n
-
-        config PKG_CHERRYUSB_HOST_MSC
-            bool
-            prompt "Enable usb msc driver"
-            default n
-            select RT_USING_DFS
-            select RT_USING_DFS_ELMFAT
-
-        config PKG_CHERRYUSB_HOST_CDC_ECM
-            bool
-            prompt "Enable usb cdc ecm driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_CDC_ECM
-            default n
-
-        config PKG_CHERRYUSB_HOST_CDC_RNDIS
-            bool
-            prompt "Enable usb rndis driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_CDC_RNDIS
-            default n
-
-        config PKG_CHERRYUSB_HOST_CDC_NCM
-            bool
-            prompt "Enable usb cdc ncm driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_CDC_NCM
-            default n
-
-        config PKG_CHERRYUSB_HOST_VIDEO
-            bool
-            prompt "Enable usb video driver, it is commercial charge"
-            default n
-
-        config PKG_CHERRYUSB_HOST_AUDIO
-            bool
-            prompt "Enable usb audio driver, it is commercial charge"
-            default n
-
-        config PKG_CHERRYUSB_HOST_BLUETOOTH
-            bool
-            prompt "Enable usb bluetooth driver"
-            default n
-
-        config PKG_CHERRYUSB_HOST_ASIX
-            bool
-            prompt "Enable usb asix driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_ASIX
-            default n
-
-        config PKG_CHERRYUSB_HOST_RTL8152
-            bool
-            prompt "Enable usb rtl8152 driver"
-            select RT_USING_LWIP
-            select CONFIG_USBHOST_PLATFORM_RTL8152
-            default n
-
-        config PKG_CHERRYUSB_HOST_FTDI
-            bool
-            prompt "Enable usb ftdi driver"
-            default n
-
-        config PKG_CHERRYUSB_HOST_CH34X
-            bool
-            prompt "Enable usb ch34x driver"
-            default n
-
-        config PKG_CHERRYUSB_HOST_CP210X
-            bool
-            prompt "Enable usb cp210x driver"
-            default n
-
-        config PKG_CHERRYUSB_HOST_PL2303
-            bool
-            prompt "Enable usb pl2303 driver"
-            default n
-
-        config CONFIG_USBHOST_PLATFORM_CDC_ECM
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_CDC_RNDIS
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_CDC_NCM
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_ASIX
-            bool
-
-        config CONFIG_USBHOST_PLATFORM_RTL8152
-            bool
-
-        config CONFIG_USBHOST_PSC_PRIO
-            int
-            prompt "Set hubport change thread priority, 0 is the max priority"
-            default 0
-
-        config CONFIG_USBHOST_PSC_STACKSIZE
-            int
-            prompt "Set hubport change thread stacksize"
-            default 4096
-
-        config CONFIG_USBHOST_REQUEST_BUFFER_LEN
-            int
-            prompt "Set host control transfer max buffer size"
-            default 512
-
-        config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
-            int
-            prompt "Set host control transfer timeout, unit is ms"
-            default 500
-
-        config RT_LWIP_PBUF_POOL_BUFSIZE
-            int "The size of each pbuf in the pbuf pool"
-            range 1500 2000
-            default 1600
-
-        config CONFIG_USB_DFS_MOUNT_POINT
-            string "usb host dfs mount point"
-            depends on RT_CHERRYUSB_HOST_MSC
-            default "/"
-
-        menu "Select USB host template, please select class driver first"
-            config CONFIG_TEST_USBH_CDC_ACM
-                int
-                prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead"
-                default 0
-                depends on PKG_CHERRYUSB_HOST_CDC_ACM
-            config CONFIG_TEST_USBH_HID
-                int
-                prompt "demo for test hid"
-                default 0
-                depends on PKG_CHERRYUSB_HOST_HID
-            config CONFIG_TEST_USBH_MSC
-                int
-                prompt "demo for test msc, cannot enable this demo, we have used dfs instead"
-                default 0
-                depends on PKG_CHERRYUSB_HOST_MSC
-        endmenu
-    endif
-
-    config PKG_CHERRYUSB_PATH
-        string
-        default "/packages/system/CherryUSB"
-
-    choice
-        prompt "Version"
-        default PKG_USING_CHERRYUSB_V010502
-        help
-            Select the package version
-
-        config PKG_USING_CHERRYUSB_LATEST_VERSION
-            bool "latest"
-        config PKG_USING_CHERRYUSB_V010502
-            bool "v1.5.2"
-        config PKG_USING_CHERRYUSB_V010501
-            bool "v1.5.1"
-        config PKG_USING_CHERRYUSB_V010500
-            bool "v1.5.0"
-        config PKG_USING_CHERRYUSB_V010403
-            bool "v1.4.3"
-        config PKG_USING_CHERRYUSB_V010301
-            bool "v1.3.1"
-        config PKG_USING_CHERRYUSB_V010200
-            bool "v1.2.0"
-        config PKG_USING_CHERRYUSB_V001002
-            bool "v0.10.2"
-    endchoice
-
-    config PKG_CHERRYUSB_VER
-       string
-       default "latest"    if PKG_USING_CHERRYUSB_LATEST_VERSION
-       default "v1.5.2"   if PKG_USING_CHERRYUSB_V010502
-       default "v1.5.1"   if PKG_USING_CHERRYUSB_V010501
-       default "v1.5.0"   if PKG_USING_CHERRYUSB_V010500
-       default "v1.4.3"   if PKG_USING_CHERRYUSB_V010403
-       default "v1.3.1"   if PKG_USING_CHERRYUSB_V010301
-       default "v1.2.0"   if PKG_USING_CHERRYUSB_V010200
-       default "v0.10.2"   if PKG_USING_CHERRYUSB_V001002
-endif

+ 28 - 25
components/drivers/usb/cherryusb/README.md

@@ -40,6 +40,8 @@ Taking into account USB performance issues and trying to achieve the theoretical
 - Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
 - Packetization is handled in interrupt
 
+Performance show:https://cherryusb.cherry-embedded.org/show/
+
 ## Directory Structure
 
 |   Directory       |  Description            |
@@ -103,14 +105,15 @@ CherryUSB Host Stack has the following functions:
 - Support blocking transfers and asynchronous transfers
 - Support Composite Device
 - Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2/ehci/xhci/rp2040)
-- Support Communication Device Class (CDC_ACM, CDC_ECM)
+- Support Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM)
 - Support Human Interface Device (HID)
 - Support Mass Storage Class (MSC)
 - Support USB Video CLASS (UVC1.0, UVC1.5)
 - Support USB Audio CLASS (UAC1.0)
 - Support Remote NDIS (RNDIS)
 - Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm)
-- Support Vendor class (serial, net, wifi)
+- Support Vendor Serial Class(CH34X、CP210X、PL2303、FTDI、GSM)
+- Support Vendor network Class(RTL8152、AX88772)
 - Support USB modeswitch
 - Support Android Open Accessory
 - Support multi host with the same USB IP
@@ -141,14 +144,14 @@ Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affe
 #define CONFIG_USBHOST_MAX_EXTHUBS          1
 #define CONFIG_USBHOST_MAX_EHPORTS          4
 #define CONFIG_USBHOST_MAX_INTERFACES       8
-#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
+#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
 #define CONFIG_USBHOST_MAX_ENDPOINTS        4
 ```
 
 x is affected by the following macros:
 
 ```
-#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
+#define CONFIG_USBHOST_MAX_SERIAL_CLASS  4
 #define CONFIG_USBHOST_MAX_HID_CLASS     4
 #define CONFIG_USBHOST_MAX_MSC_CLASS     2
 #define CONFIG_USBHOST_MAX_AUDIO_CLASS   1
@@ -179,32 +182,33 @@ Quickly start, USB basic concepts, API manual, Class basic concepts and examples
 
 ## Video Tutorial
 
-CherryUSB Cheese (based V1.4.3): https://www.bilibili.com/cheese/play/ss707687201 .
+CherryUSB Cheese (>= V1.4.3): https://www.bilibili.com/cheese/play/ss707687201 .
 
 ## Descriptor Generator Tool
 
-TODO
+Cherry Descriptor: https://desc.cherry-embedded.org/en
 
 ## Demo Repo
 
-|   Manufacturer       |  CHIP or Series    | USB IP| Repo Url | Support version     | Support status |
+|   Manufacturer       |  CHIP or Series    | USB IP| Repo Url | Support version     | Note |
 |:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
-|Bouffalolab    |  BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
-|ST             |  STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
-|HPMicro        |  HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
-|Essemi         |  ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
-|Phytium        |  e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0  | Long-term |
-|Artinchip      |  d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest  | Long-term |
-|Espressif      |  esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
-|NXP            |  mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
-|Kendryte       |  k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
-|Actionstech    |  ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term |
-|Nationstech    |  n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term |
-|Raspberry pi   |  rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
-|AllwinnerTech  |  F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
-|Bekencorp      |  bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
-|Sophgo         |  cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
-|WCH            |  CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD |
+|Bouffalolab    |  BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official |
+|ST             |  STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community |
+|HPMicro        |  HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official |
+|Essemi         |  ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
+|Phytium        |  e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0  | Official |
+|Artinchip      |  d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest  | Official |
+|Espressif      |  esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
+|Kendryte       |  k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
+|Actionstech    |  ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
+|SiFli          |  SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |
+|NXP            |  mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community |
+|Nationstech    |  n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing |
+|Raspberry pi   |  rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing |
+|AllwinnerTech  |  F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update |
+|Bekencorp      |  bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official |
+|Sophgo         |  cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official |
+|WCH            |  CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update |
 
 ## Package Support
 
@@ -226,5 +230,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
 
 Thanks to the following companies for their support (in no particular order):
 
-<img src="docs/assets/bouffalolab.jpg"  width="100" height="80"/> <img src="docs/assets/hpmicro.jpg"  width="100" height="80" /> <img src="docs/assets/eastsoft.jpg"  width="100" height="80" /> <img src="docs/assets/rtthread.jpg"  width="100" height="80" /> <img src="docs/assets/sophgo.jpg"  width="100" height="80" /> <img src="docs/assets/phytium.jpg"  width="100" height="80" /> <img src="docs/assets/thead.jpg"  width="100" height="80" /> <img src="docs/assets/nuvoton.jpg"  width="100" height="80" /> <img src="docs/assets/artinchip.jpg"  width="100" height="80" /> <img src="docs/assets/bekencorp.jpg"  width="100" height="80" /> <img src="docs/assets/nxp.png"  width="100" height="80" /> <img src="docs/assets/espressif.png"  width="100" height="80" /> <img src="docs/assets/canaan.jpg"  width="100" height="80" />
-<img src="docs/assets/actions.jpg"  width="100" height="80" /> <img src="docs/assets/nationstech.jpg"  width="100" height="80" />
+<img src="docs/assets/bouffalolab.jpg"  width="100" height="80"/> <img src="docs/assets/hpmicro.jpg"  width="100" height="80" /> <img src="docs/assets/eastsoft.jpg"  width="100" height="80" /> <img src="docs/assets/rtthread.jpg"  width="100" height="80" /> <img src="docs/assets/sophgo.jpg"  width="100" height="80" /> <img src="docs/assets/phytium.jpg"  width="100" height="80" /> <img src="docs/assets/thead.jpg"  width="100" height="80" /> <img src="docs/assets/nuvoton.jpg"  width="100" height="80" /> <img src="docs/assets/artinchip.jpg"  width="100" height="80" /> <img src="docs/assets/bekencorp.jpg"  width="100" height="80" /> <img src="docs/assets/nxp.png"  width="100" height="80" /> <img src="docs/assets/espressif.png"  width="100" height="80" /> <img src="docs/assets/canaan.jpg"  width="100" height="80" /> <img src="docs/assets/actions.jpg"  width="100" height="80" /> <img src="docs/assets/sifli.jpg"  width="100" height="80" /> <img src="docs/assets/nationstech.jpg"  width="100" height="80" />

+ 6 - 5
components/drivers/usb/cherryusb/README_zh.md

@@ -112,7 +112,8 @@ CherryUSB Host 协议栈当前实现以下功能:
 - Support USB Audio CLASS (UAC1.0)
 - 支持 Remote NDIS (RNDIS)
 - 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能)
-- 支持 Vendor 类 class (serial, net, wifi)
+- 支持 Vendor Serial 类(CH34X、CP210X、PL2303、FTDI、GSM)
+- 支持 Vendor network 类(RTL8152、AX88772)
 - 支持 USB modeswitch
 - 支持 Android Open Accessory
 - 支持相同 USB IP 的多主机
@@ -150,7 +151,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2,关闭 log)
 x 受以下宏影响:
 
 ```
-#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
+#define CONFIG_USBHOST_MAX_SERIAL_CLASS  4
 #define CONFIG_USBHOST_MAX_HID_CLASS     4
 #define CONFIG_USBHOST_MAX_MSC_CLASS     2
 #define CONFIG_USBHOST_MAX_AUDIO_CLASS   1
@@ -181,11 +182,11 @@ CherryUSB 快速入门、USB 基本概念、API 手册、Class 基本概念和
 
 ## 视频教程
 
-CherryUSB 课程(基于 V1.4.3):https://www.bilibili.com/cheese/play/ss707687201 。
+CherryUSB 课程(>= V1.4.3):https://www.bilibili.com/cheese/play/ss707687201 。
 
 ## 描述符生成工具
 
-TODO
+Cherry Descriptor: https://desc.cherry-embedded.org/zh
 
 ## 示例仓库
 
@@ -197,7 +198,7 @@ TODO
 |Essemi         |  ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
 |Phytium        |  e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0  | Official |
 |Artinchip      |  d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest  | Official |
-|Espressif      |  esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing |
+|Espressif      |  esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
 |Kendryte       |  k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
 |Actionstech    |  ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
 |SiFli          |  SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |

+ 32 - 12
components/drivers/usb/cherryusb/SConscript

@@ -14,9 +14,8 @@ path += [cwd + '/class/wireless']
 path += [cwd + '/class/midi']
 path += [cwd + '/class/adb']
 path += [cwd + '/class/dfu']
-path += [cwd + '/class/midi']
+path += [cwd + '/class/serial']
 path += [cwd + '/class/vendor/net']
-path += [cwd + '/class/vendor/serial']
 path += [cwd + '/class/vendor/wifi']
 src = []
 
@@ -47,6 +46,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
     if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE']):
         src += Glob('port/dwc2/usb_dc_dwc2.c')
         src += Glob('port/dwc2/usb_glue_kendryte.c')
+    if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_INFINEON']):
+        src += Glob('port/dwc2/usb_dc_dwc2.c')
+        src += Glob('port/dwc2/usb_glue_infineon.c')
     if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_AT']):
         src += Glob('port/dwc2/usb_dc_dwc2.c')
         src += Glob('port/dwc2/usb_glue_at.c')
@@ -112,6 +114,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
             LIBS = ['libpusb2_dc_a32_softfp_neon.a']
     if GetDepend(['RT_CHERRYUSB_DEVICE_NRF5X']):
         src += Glob('port/nrf5x/usb_dc_nrf5x.c')
+    if GetDepend(['RT_CHERRYUSB_DEVICE_RP2040']):
+        path += [cwd + '/port/rp2040']
+        src += Glob('port/rp2040/usb_dc_rp2040.c')
 
     if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_ACM']):
         src += Glob('class/cdc/usbd_cdc_acm.c')
@@ -166,10 +171,12 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
         src += Glob('demo/cdc_acm_hid_msc_template.c')
     if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1']):
         src += Glob('demo/winusb1.0_template.c')
+    if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2']):
+        src += Glob('demo/winusb2.0_template.c')
     if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC']):
         src += Glob('demo/winusb2.0_cdc_template.c')
-    if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID']):
-        src += Glob('demo/winusb2.0_hid_template.c')
+    if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID']):
+        src += Glob('demo/webusb_hid_template.c')
     if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_ADB']):
         src += Glob('demo/adb/usbd_adb_template.c')
     if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV']):
@@ -216,6 +223,12 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
     if GetDepend(['RT_CHERRYUSB_HOST_DWC2_KENDRYTE']):
         src += Glob('port/dwc2/usb_hc_dwc2.c')
         src += Glob('port/dwc2/usb_glue_kendryte.c')
+    if GetDepend(['RT_CHERRYUSB_HOST_DWC2_INFINEON']):
+        src += Glob('port/dwc2/usb_hc_dwc2.c')
+        src += Glob('port/dwc2/usb_glue_infineon.c')
+    if GetDepend(['RT_CHERRYUSB_HOST_DWC2_AT']):
+        src += Glob('port/dwc2/usb_hc_dwc2.c')
+        src += Glob('port/dwc2/usb_glue_at.c')
     if GetDepend(['RT_CHERRYUSB_HOST_DWC2_HC']):
         src += Glob('port/dwc2/usb_hc_dwc2.c')
         src += Glob('port/dwc2/usb_glue_hc.c')
@@ -266,8 +279,12 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
             LIBPATH = [cwd + '/port/xhci/phytium']
             LIBS = ['libxhci_a32_softfp_neon.a']
 
+    if GetDepend(['RT_CHERRYUSB_HOST_RP2040']):
+        path += [cwd + '/port/rp2040']
+        src += Glob('port/rp2040/usb_hc_rp2040.c')
+
     if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM']):
-        src += Glob('class/cdc/usbh_cdc_acm.c')
+        src += Glob('class/serial/usbh_cdc_acm.c')
     if GetDepend(['RT_CHERRYUSB_HOST_HID']):
         src += Glob('class/hid/usbh_hid.c')
     if GetDepend(['RT_CHERRYUSB_HOST_MSC']):
@@ -289,23 +306,26 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
     if GetDepend(['RT_CHERRYUSB_HOST_RTL8152']):
         src += Glob('class/vendor/net/usbh_rtl8152.c')
     if GetDepend(['RT_CHERRYUSB_HOST_FTDI']):
-        src += Glob('class/vendor/serial/usbh_ftdi.c')
+        src += Glob('class/serial/usbh_ftdi.c')
     if GetDepend(['RT_CHERRYUSB_HOST_CH34X']):
-        src += Glob('class/vendor/serial/usbh_ch34x.c')
+        src += Glob('class/serial/usbh_ch34x.c')
     if GetDepend(['RT_CHERRYUSB_HOST_CP210X']):
-        src += Glob('class/vendor/serial/usbh_cp210x.c')
+        src += Glob('class/serial/usbh_cp210x.c')
     if GetDepend(['RT_CHERRYUSB_HOST_PL2303']):
-        src += Glob('class/vendor/serial/usbh_pl2303.c')
+        src += Glob('class/serial/usbh_pl2303.c')
 
-    if GetDepend(['CONFIG_TEST_USBH_HID']):
+    if GetDepend(['RT_TEST_USBH_HID']):
+        CPPDEFINES+=['CONFIG_TEST_USBH_HID']
         src += Glob('demo/usb_host.c')
 
     if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM'])    \
         or GetDepend(['RT_CHERRYUSB_HOST_FTDI'])   \
         or GetDepend(['RT_CHERRYUSB_HOST_CH34X'])  \
         or GetDepend(['RT_CHERRYUSB_HOST_CP210X']) \
-        or GetDepend(['RT_CHERRYUSB_HOST_PL2303']):
-        src += Glob('platform/rtthread/usbh_serial.c')
+        or GetDepend(['RT_CHERRYUSB_HOST_PL2303']) \
+        or GetDepend(['RT_CHERRYUSB_HOST_GSM']):
+        src += Glob('class/serial/usbh_serial.c')
+        src += Glob('platform/rtthread/usbh_rtserial.c')
 
     if GetDepend('RT_USING_DFS') and GetDepend(['RT_CHERRYUSB_HOST_MSC']):
        src += Glob('platform/rtthread/usbh_dfs.c')

+ 2 - 2
components/drivers/usb/cherryusb/VERSION

@@ -1,5 +1,5 @@
 VERSION_MAJOR = 1
-VERSION_MINOR = 5
-PATCHLEVEL = 2
+VERSION_MINOR = 6
+PATCHLEVEL = 0
 VERSION_TWEAK = 0
 EXTRAVERSION = 0

+ 27 - 10
components/drivers/usb/cherryusb/cherryusb.cmake

@@ -47,10 +47,11 @@ list(
     ${CMAKE_CURRENT_LIST_DIR}/class/midi
     ${CMAKE_CURRENT_LIST_DIR}/class/adb
     ${CMAKE_CURRENT_LIST_DIR}/class/dfu
+    ${CMAKE_CURRENT_LIST_DIR}/class/serial
     ${CMAKE_CURRENT_LIST_DIR}/class/vendor/net
-    ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial
     ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi
     ${CMAKE_CURRENT_LIST_DIR}/class/aoa
+    ${CMAKE_CURRENT_LIST_DIR}/class/gamepad
 )
 
 if(CONFIG_CHERRYUSB_DEVICE)
@@ -85,6 +86,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
     if(CONFIG_CHERRYUSB_DEVICE_ADB)
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/adb/usbd_adb.c)
     endif()
+    if(CONFIG_CHERRYUSB_DEVICE_GAMEPAD)
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/gamepad/usbd_gamepad.c)
+    endif()
 
     if(CONFIG_CHERRYUSB_DEVICE_FSDEV_ST)
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/fsdev/usb_dc_fsdev.c)
@@ -156,7 +160,7 @@ if(CONFIG_CHERRYUSB_HOST)
     )
 
     if(CONFIG_CHERRYUSB_HOST_CDC_ACM)
-        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_acm.c)
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_cdc_acm.c)
     endif()
     if(CONFIG_CHERRYUSB_HOST_CDC_ECM)
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ecm.c)
@@ -235,30 +239,39 @@ if(CONFIG_CHERRYUSB_HOST)
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/net/usbh_rtl8152.c)
     endif()
     if(CONFIG_CHERRYUSB_HOST_CH34X)
-        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_ch34x.c)
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_ch34x.c)
     endif()
     if(CONFIG_CHERRYUSB_HOST_CP210X)
-        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_cp210x.c)
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_cp210x.c)
     endif()
     if(CONFIG_CHERRYUSB_HOST_FTDI)
-        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_ftdi.c)
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_ftdi.c)
     endif()
     if(CONFIG_CHERRYUSB_HOST_PL2303)
-        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_pl2303.c)
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_pl2303.c)
     endif()
-    if(CONFIG_CHERRYUSB_HOST_BL616)
-        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi/usbh_bl616.c)
+    if(CONFIG_CHERRYUSB_HOST_GSM)
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_gsm.c)
     endif()
     if(CONFIG_CHERRYUSB_HOST_AOA)
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/aoa/usbh_aoa.c)
     endif()
 
+    if(CONFIG_CHERRYUSB_HOST_CDC_ACM
+    OR CONFIG_CHERRYUSB_HOST_CH34X
+    OR CONFIG_CHERRYUSB_HOST_CP210X
+    OR CONFIG_CHERRYUSB_HOST_FTDI
+    OR CONFIG_CHERRYUSB_HOST_PL2303
+    OR CONFIG_CHERRYUSB_HOST_GSM
+    )
+        list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_serial.c)
+    endif()
+
     if(CONFIG_CHERRYUSB_HOST_CDC_ECM
     OR CONFIG_CHERRYUSB_HOST_CDC_RNDIS
     OR CONFIG_CHERRYUSB_HOST_CDC_NCM
     OR CONFIG_CHERRYUSB_HOST_ASIX
     OR CONFIG_CHERRYUSB_HOST_RTL8152
-    OR CONFIG_CHERRYUSB_HOST_BL616
     )
         if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf")
             list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_net.c)
@@ -335,11 +348,15 @@ if(CONFIG_CHERRYUSB_HOST)
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c)
     endif()
 
-    if(CONFIG_TEST_USBH_CDC_ACM OR CONFIG_TEST_USBH_HID OR CONFIG_TEST_USBH_MSC)
+    if(CONFIG_TEST_USBH_SERIAL OR CONFIG_TEST_USBH_HID OR CONFIG_TEST_USBH_MSC)
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/demo/usb_host.c)
     endif()
 endif()
 
+if(CONFIG_CHERRYUSB_DEVICE AND CONFIG_CHERRYUSB_HOST)
+list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/core/usbotg_core.c)
+endif()
+
 if(DEFINED CONFIG_CHERRYUSB_OSAL)
     if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos")
         list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_freertos.c)

+ 9 - 1
components/drivers/usb/cherryusb/cherryusb_config_template.h

@@ -157,7 +157,7 @@
 #define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
 #define CONFIG_USBHOST_MAX_ENDPOINTS        4
 
-#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
+#define CONFIG_USBHOST_MAX_SERIAL_CLASS  4
 #define CONFIG_USBHOST_MAX_HID_CLASS     4
 #define CONFIG_USBHOST_MAX_MSC_CLASS     2
 #define CONFIG_USBHOST_MAX_AUDIO_CLASS   1
@@ -188,6 +188,10 @@
 #define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
 #endif
 
+#ifndef CONFIG_USBHOST_SERIAL_RX_SIZE
+#define CONFIG_USBHOST_SERIAL_RX_SIZE 2048
+#endif
+
 #ifndef CONFIG_USBHOST_MSC_TIMEOUT
 #define CONFIG_USBHOST_MSC_TIMEOUT 5000
 #endif
@@ -301,6 +305,7 @@
 /* ---------------- MUSB Configuration ---------------- */
 #define CONFIG_USB_MUSB_PIPE_NUM 8
 // #define CONFIG_USB_MUSB_SUNXI
+// #define CONFIG_USB_MUSB_WITHOUT_MULTIPOINT
 
 /* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
  * the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
@@ -317,4 +322,7 @@
 #define usb_ramaddr2phyaddr(addr) (addr)
 #endif
 
+/* Enable OTG support, only support hpmicro now */
+// #define CONFIG_USB_OTG_ENABLE
+
 #endif

+ 0 - 4
components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c

@@ -176,9 +176,6 @@ int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *repo
 int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len)
 {
     struct usb_setup_packet *setup;
-    int ret;
-    uint8_t len;
-    uint32_t offset;
 
     if (!aoa_class || !aoa_class->hport) {
         return -USB_ERR_INVAL;
@@ -198,7 +195,6 @@ int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *ev
 static int usbh_aoa_connect(struct usbh_hubport *hport, uint8_t intf)
 {
     struct usb_endpoint_descriptor *ep_desc;
-    int ret = 0;
 
     struct usbh_aoa *aoa_class = &g_aoa_class;
 

+ 46 - 58
components/drivers/usb/cherryusb/class/audio/usb_audio.h

@@ -88,18 +88,6 @@
 #define AUDIO_ENDPOINT_UNDEFINED 0x00U
 #define AUDIO_ENDPOINT_GENERAL   0x01U
 
-/* Feature Unit Control Bits */
-#define AUDIO_CONTROL_MUTE              0x0001
-#define AUDIO_CONTROL_VOLUME            0x0002
-#define AUDIO_CONTROL_BASS              0x0004
-#define AUDIO_CONTROL_MID               0x0008
-#define AUDIO_CONTROL_TREBLE            0x0010
-#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
-#define AUDIO_CONTROL_AUTOMATIC_GAIN    0x0040
-#define AUDIO_CONTROL_DEALY             0x0080
-#define AUDIO_CONTROL_BASS_BOOST        0x0100
-#define AUDIO_CONTROL_LOUDNESS          0x0200
-
 /* Encoder Type Codes */
 #define AUDIO_ENCODER_UNDEF 0x00
 #define AUDIO_ENCODER_OTHER 0x01
@@ -245,22 +233,34 @@
 #define AUDIO_FU_CONTROL_OVERFLOW     0x0f
 #define AUDIO_FU_CONTROL_LATENCY      0x10
 
-#define AUDIO_V2_FU_CONTROL_UNDEF        0x00
-#define AUDIO_V2_FU_CONTROL_MUTE         (0x03 << 0)
-#define AUDIO_V2_FU_CONTROL_VOLUME       (0x03 << 2)
-#define AUDIO_V2_FU_CONTROL_BASS         (0x03 << 4)
-#define AUDIO_V2_FU_CONTROL_MID          (0x03 << 6)
-#define AUDIO_V2_FU_CONTROL_TREBLE       (0x03 << 8)
-#define AUDIO_V2_FU_CONTROL_EQUALIZER    (0x03 << 10)
-#define AUDIO_V2_FU_CONTROL_AGC          (0x03 << 12)
-#define AUDIO_V2_FU_CONTROL_DELAY        (0x03 << 14)
-#define AUDIO_V2_FU_CONTROL_BASS_BOOST   (0x03 << 16)
-#define AUDIO_V2_FU_CONTROL_LOUDNESS     (0x03 << 18)
-#define AUDIO_V2_FU_CONTROL_INP_GAIN     (0x03 << 20)
-#define AUDIO_V2_FU_CONTROL_INP_GAIN_PAD (0x03 << 22)
-#define AUDIO_V2_FU_CONTROL_PHASE_INVERT (0x03 << 24)
-#define AUDIO_V2_FU_CONTROL_UNDERFLOW    (0x03 << 26)
-#define AUDIO_V2_FU_CONTROL_OVERFLOW     (0x03 << 28)
+/* Feature Unit Control Bits */
+#define AUDIO_CONTROL_MUTE              0x0001
+#define AUDIO_CONTROL_VOLUME            0x0002
+#define AUDIO_CONTROL_BASS              0x0004
+#define AUDIO_CONTROL_MID               0x0008
+#define AUDIO_CONTROL_TREBLE            0x0010
+#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
+#define AUDIO_CONTROL_AUTOMATIC_GAIN    0x0040
+#define AUDIO_CONTROL_DEALY             0x0080
+#define AUDIO_CONTROL_BASS_BOOST        0x0100
+#define AUDIO_CONTROL_LOUDNESS          0x0200
+
+#define AUDIO_V2_CONTROL_UNDEF        0x00
+#define AUDIO_V2_CONTROL_MUTE         (0x03 << 0)
+#define AUDIO_V2_CONTROL_VOLUME       (0x03 << 2)
+#define AUDIO_V2_CONTROL_BASS         (0x03 << 4)
+#define AUDIO_V2_CONTROL_MID          (0x03 << 6)
+#define AUDIO_V2_CONTROL_TREBLE       (0x03 << 8)
+#define AUDIO_V2_CONTROL_EQUALIZER    (0x03 << 10)
+#define AUDIO_V2_CONTROL_AGC          (0x03 << 12)
+#define AUDIO_V2_CONTROL_DELAY        (0x03 << 14)
+#define AUDIO_V2_CONTROL_BASS_BOOST   (0x03 << 16)
+#define AUDIO_V2_CONTROL_LOUDNESS     (0x03 << 18)
+#define AUDIO_V2_CONTROL_INP_GAIN     (0x03 << 20)
+#define AUDIO_V2_CONTROL_INP_GAIN_PAD (0x03 << 22)
+#define AUDIO_V2_CONTROL_PHASE_INVERT (0x03 << 24)
+#define AUDIO_V2_CONTROL_UNDERFLOW    (0x03 << 26)
+#define AUDIO_V2_CONTROL_OVERFLOW     (0x03 << 28)
 
 /* Parametric Equalizer Section Effect Unit Control Selectors */
 #define AUDIO_PE_CONTROL_UNDEF      0x00
@@ -605,7 +605,7 @@ struct audio_cs_if_ac_header_descriptor {
     uint8_t baInterfaceNr[];
 } __PACKED;
 
-#define AUDIO_SIZEOF_AC_HEADER_DESC(n) (8 + n)
+#define AUDIO_SIZEOF_AC_HEADER_DESC(bInCollection) (8 + (bInCollection))
 
 struct audio_cs_if_ac_input_terminal_descriptor {
     uint8_t bLength;
@@ -646,7 +646,7 @@ struct audio_cs_if_ac_feature_unit_descriptor {
     uint8_t iFeature;
 } __PACKED;
 
-#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + (ch + 1) * n)
+#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(bNrChannels, bControlSize) (7 + ((bNrChannels) + 1) * (bControlSize))
 
 struct audio_cs_if_ac_selector_unit_descriptor {
     uint8_t bLength;
@@ -658,7 +658,7 @@ struct audio_cs_if_ac_selector_unit_descriptor {
     uint8_t iSelector;
 } __PACKED;
 
-#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(n) (6 + n)
+#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(bNrInPins) (6 + (bNrInPins))
 
 struct audio_cs_if_as_general_descriptor {
     uint8_t bLength;
@@ -683,7 +683,7 @@ struct audio_cs_if_as_format_type_descriptor {
     uint8_t tSamFreq[3];
 } __PACKED;
 
-#define AUDIO_SIZEOF_FORMAT_TYPE_DESC(n) (8 + 3 * n)
+#define AUDIO_SIZEOF_FORMAT_TYPE_DESC(bSamFreqType) (8 + 3 * (bSamFreqType))
 
 struct audio_ep_descriptor {
     uint8_t bLength;
@@ -738,7 +738,7 @@ struct audio_cs_ep_ep_general_descriptor {
     PP_NARG(__VA_ARGS__),            /* bInCollection */                                                                         \
     __VA_ARGS__                      /* baInterfaceNr */
 
-#define AUDIO_AC_DESCRIPTOR_INIT_LEN(n) (0x08 + 0x09 + 0x08 + n)
+#define AUDIO_AC_DESCRIPTOR_LEN(bInCollection) (0x08 + 0x09 + 0x08 + bInCollection)
 
 #define AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(bTerminalID, wTerminalType, bNrChannels, wChannelConfig) \
     0x0C,                            /* bLength */                                                   \
@@ -880,8 +880,8 @@ struct audio_cs_ep_ep_general_descriptor {
     0x03,                            /* bRefresh, 8ms */                                                                 \
     0x00                             /* bSynchAddress */
 
-#define AUDIO_AS_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07)
-#define AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07 + 0x09)
+#define AUDIO_AS_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07)
+#define AUDIO_AS_FEEDBACK_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07 + 0x09)
 
 #define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \
     0x09,                            /* bLength */                                                                       \
@@ -924,9 +924,9 @@ struct audio_cs_ep_ep_general_descriptor {
     0x00,                            /* wLockDelay */                                                                    \
     0x00
 
-#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07)
+#define AUDIO_AS_ALTSETTING_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07)
 
-#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber)                                               \
+#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber)                                                           \
     0x09,                            /* bLength */                                                                       \
     USB_DESCRIPTOR_TYPE_INTERFACE,   /* bDescriptorType */                                                               \
     bInterfaceNumber,                /* bInterfaceNumber */                                                              \
@@ -937,19 +937,6 @@ struct audio_cs_ep_ep_general_descriptor {
     AUDIO_PROTOCOL_UNDEFINED,        /* bInterfaceProtocol */                                                            \
     0x00                             /* iInterface */
 
-#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints)                                               \
-    0x09,                            /* bLength */                                                                       \
-    USB_DESCRIPTOR_TYPE_INTERFACE,   /* bDescriptorType */                                                               \
-    bInterfaceNumber,                /* bInterfaceNumber */                                                              \
-    0x00,                            /* bAlternateSetting */                                                             \
-    bNumEndpoints,                   /* bNumEndpoints */                                                                 \
-    USB_DEVICE_CLASS_AUDIO,          /* bInterfaceClass */                                                               \
-    AUDIO_SUBCLASS_MIDISTREAMING,    /* bInterfaceSubClass */                                                            \
-    AUDIO_PROTOCOL_UNDEFINED,        /* bInterfaceProtocol */                                                            \
-    0x00                             /* iInterface */
-
-#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT_LEN 0x09
-
 struct audio_v2_channel_cluster_descriptor {
     uint8_t bNrChannels;
     uint32_t bmChannelConfig;
@@ -993,7 +980,7 @@ struct audio_v2_cs_if_ac_clock_selector_descriptor {
     uint8_t iClockSelector;
 } __PACKED;
 
-#define AUDIO_SIZEOF_AC_CLOCK_SELECTOR_DESC(n) (7 + n)
+#define AUDIO_SIZEOF_AC_CLOCK_SELECTOR_DESC(bNrInPins) (7 + (bNrInPins))
 
 struct audio_v2_cs_if_ac_clock_multiplier_descriptor {
     uint8_t bLength;
@@ -1005,7 +992,7 @@ struct audio_v2_cs_if_ac_clock_multiplier_descriptor {
     uint8_t iClockMultiplier;
 } __PACKED;
 
-#define AUDIO_SIZEOF_AC_CLOCK_MULTIPLIER_DESC() (7)
+#define AUDIO_SIZEOF_AC_CLOCK_MULTIPLIER_DESC (7)
 
 struct audio_v2_cs_if_ac_input_terminal_descriptor {
     uint8_t bLength;
@@ -1049,7 +1036,7 @@ struct audio_v2_cs_if_ac_feature_unit_descriptor {
     uint8_t iFeature;
 } __PACKED;
 
-#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(ch) (6 + (ch + 1) * 4)
+#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(bNrChannels) (6 + ((bNrChannels) + 1) * 4)
 
 struct audio_v2_cs_if_as_general_descriptor {
     uint8_t bLength;
@@ -1124,7 +1111,7 @@ struct audio_v2_control_range3_param_block {
     WBVAL(wTotalLength),             /* wTotalLength */                                                                          \
     bmControls                       /* bmControls */                                                                            \
 
-#define AUDIO_V2_AC_DESCRIPTOR_INIT_LEN (0x08 + 0x09 + 0x09)
+#define AUDIO_V2_AC_DESCRIPTOR_LEN (0x08 + 0x09 + 0x09)
 
 #define AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(bClockID, bmAttributes, bmControls) \
     0x08,                            /* bLength */                               \
@@ -1262,7 +1249,7 @@ struct audio_v2_control_range3_param_block {
     0x00,                            /* wLockDelay */                                                                                                                     \
     0x00
 
-#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber)                                               \
+#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber)                                                        \
     0x09,                            /* bLength */                                                                       \
     USB_DESCRIPTOR_TYPE_INTERFACE,   /* bDescriptorType */                                                               \
     bInterfaceNumber,                /* bInterfaceNumber */                                                              \
@@ -1331,9 +1318,10 @@ struct audio_v2_control_range3_param_block {
 
 // clang-format on
 
-#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN            (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08)
-#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08)
-#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN   (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07)
+#define AUDIO_V2_AS_DESCRIPTOR_LEN            (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08)
+#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_LEN (0x09)
+#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08)
+#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN   (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07)
 
 #define AUDIO_SAMPLE_FREQ_NUM(num) (uint8_t)(num), (uint8_t)((num >> 8))
 #define AUDIO_SAMPLE_FREQ_3B(frq)  (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))

+ 18 - 20
components/drivers/usb/cherryusb/class/cdc/usb_cdc.h

@@ -217,12 +217,12 @@
 #define CDC_SERIAL_STATE_BREAK          (1 << 2) /* state of break detection */
 #define CDC_SERIAL_STATE_BREAK_Pos      (2)
 #define CDC_SERIAL_STATE_BREAK_Msk      (1 << CDC_SERIAL_STATE_BREAK_Pos)
-#define CDC_SERIAL_STATE_TX_CARRIER     (1 << 1) /* state of transmission carrier */
-#define CDC_SERIAL_STATE_TX_CARRIER_Pos (1)
-#define CDC_SERIAL_STATE_TX_CARRIER_Msk (1 << CDC_SERIAL_STATE_TX_CARRIER_Pos)
-#define CDC_SERIAL_STATE_RX_CARRIER     (1 << 0) /* state of receiver carrier */
-#define CDC_SERIAL_STATE_RX_CARRIER_Pos (0)
-#define CDC_SERIAL_STATE_RX_CARRIER_Msk (1 << CDC_SERIAL_STATE_RX_CARRIER_Pos)
+#define CDC_SERIAL_STATE_DSR            (1 << 1) /* state of transmission carrier */
+#define CDC_SERIAL_STATE_DSR_Pos        (1)
+#define CDC_SERIAL_STATE_DSR_Msk        (1 << CDC_SERIAL_STATE_DSR_Pos)
+#define CDC_SERIAL_STATE_DCD            (1 << 0) /* state of receiver carrier */
+#define CDC_SERIAL_STATE_DCD_Pos        (0)
+#define CDC_SERIAL_STATE_DCD_Msk        (1 << CDC_SERIAL_STATE_DCD_Pos)
 
 #define CDC_ECM_XMIT_OK                                     (1 << 0)
 #define CDC_ECM_RVC_OK                                      (1 << 1)
@@ -551,10 +551,9 @@ struct cdc_ncm_ndp16 {
 #define DBVAL_BE(x) ((x >> 24) & 0xFF), ((x >> 16) & 0xFF), ((x >> 8) & 0xFF), (x & 0xFF)
 
 /*Length of template descriptor: 71 bytes*/
-#define CDC_ECM_DESCRIPTOR_LEN   (8 + 9 + 5 + 5 + 13 + 7 + 9 + 7 + 7)
+#define CDC_ECM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 7 + 9 + 7 + 7)
 // clang-format off
-#define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, \
-eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) \
+#define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \
     /* Interface Associate */                                                                  \
     0x08,                                                  /* bLength */                       \
     USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,             /* bDescriptorType */               \
@@ -587,10 +586,10 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
     CDC_CS_INTERFACE,                                       /* bDescriptorType: CS_INTERFACE */\
     CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype  */\
     str_idx,                                                    /* Device's MAC string index */\
-    DBVAL_BE(eth_statistics),                                /* Ethernet statistics (bitmap) */\
-    WBVAL(wMaxSegmentSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
-    WBVAL(wNumberMCFilters),            /* wNumberMCFilters: the number of multicast filters */\
-    bNumberPowerFilters,          /* bNumberPowerFilters: the number of wakeup power filters */\
+    DBVAL_BE(0x00000000),                                    /* Ethernet statistics (bitmap) */\
+    WBVAL(1514),     /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
+    WBVAL(0),        /* wNumberMCFilters: the number of multicast filters */                   \
+    0,               /* bNumberPowerFilters: the number of wakeup power filters */             \
     0x07,                                                  /* bLength */                       \
     USB_DESCRIPTOR_TYPE_ENDPOINT,                          /* bDescriptorType */               \
     int_ep,                                                /* bEndpointAddress */              \
@@ -621,10 +620,9 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
 // clang-format on
 
 /*Length of template descriptor: 77 bytes*/
-#define CDC_NCM_DESCRIPTOR_LEN   (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 7 + 7)
+#define CDC_NCM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 7 + 7)
 // clang-format off
-#define CDC_NCM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, \
-eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) \
+#define CDC_NCM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \
     /* Interface Associate */                                                                  \
     0x08,                                                  /* bLength */                       \
     USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,             /* bDescriptorType */               \
@@ -657,10 +655,10 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
     CDC_CS_INTERFACE,                                       /* bDescriptorType: CS_INTERFACE */\
     CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype  */\
     str_idx,                                                    /* Device's MAC string index */\
-    DBVAL_BE(eth_statistics),                                /* Ethernet statistics (bitmap) */\
-    WBVAL(wMaxPacketSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
-    WBVAL(wNumberMCFilters),            /* wNumberMCFilters: the number of multicast filters */\
-    bNumberPowerFilters,          /* bNumberPowerFilters: the number of wakeup power filters */\
+    DBVAL_BE(0x00000000),                                    /* Ethernet statistics (bitmap) */\
+    WBVAL(1514),     /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
+    WBVAL(0),        /* wNumberMCFilters: the number of multicast filters */                   \
+    0,               /* bNumberPowerFilters: the number of wakeup power filters */             \
     0x06,                                                                                      \
     CDC_CS_INTERFACE,                                                                          \
     CDC_FUNC_DESC_NCM,                                                                         \

+ 0 - 285
components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c

@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2022, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbh_core.h"
-#include "usbh_cdc_acm.h"
-
-#undef USB_DBG_TAG
-#define USB_DBG_TAG "usbh_cdc_acm"
-#include "usb_log.h"
-
-#define DEV_FORMAT "/dev/ttyACM%d"
-
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
-
-static struct usbh_cdc_acm g_cdc_acm_class[CONFIG_USBHOST_MAX_CDC_ACM_CLASS];
-static uint32_t g_devinuse = 0;
-
-static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void)
-{
-    uint8_t devno;
-
-    for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) {
-        if ((g_devinuse & (1U << devno)) == 0) {
-            g_devinuse |= (1U << devno);
-            memset(&g_cdc_acm_class[devno], 0, sizeof(struct usbh_cdc_acm));
-            g_cdc_acm_class[devno].minor = devno;
-            return &g_cdc_acm_class[devno];
-        }
-    }
-    return NULL;
-}
-
-static void usbh_cdc_acm_class_free(struct usbh_cdc_acm *cdc_acm_class)
-{
-    uint8_t devno = cdc_acm_class->minor;
-
-    if (devno < 32) {
-        g_devinuse &= ~(1U << devno);
-    }
-    memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
-}
-
-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;
-
-    if (!cdc_acm_class || !cdc_acm_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    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;
-    setup->wValue = 0;
-    setup->wIndex = cdc_acm_class->intf;
-    setup->wLength = 7;
-
-    memcpy(g_cdc_acm_buf[cdc_acm_class->minor], line_coding, sizeof(struct cdc_line_coding));
-
-    return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]);
-}
-
-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;
-    int ret;
-
-    if (!cdc_acm_class || !cdc_acm_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = cdc_acm_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CDC_REQUEST_GET_LINE_CODING;
-    setup->wValue = 0;
-    setup->wIndex = cdc_acm_class->intf;
-    setup->wLength = 7;
-
-    ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]);
-    if (ret < 0) {
-        return ret;
-    }
-    memcpy(line_coding, g_cdc_acm_buf[cdc_acm_class->minor], 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;
-
-    if (!cdc_acm_class || !cdc_acm_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    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;
-    setup->wValue = (dtr << 0) | (rts << 1);
-    setup->wIndex = cdc_acm_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(cdc_acm_class->hport, setup, NULL);
-}
-
-static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
-{
-    struct usb_endpoint_descriptor *ep_desc;
-    int ret = 0;
-
-    struct usbh_cdc_acm *cdc_acm_class = usbh_cdc_acm_class_alloc();
-    if (cdc_acm_class == NULL) {
-        USB_LOG_ERR("Fail to alloc cdc_acm_class\r\n");
-        return -USB_ERR_NOMEM;
-    }
-
-    cdc_acm_class->hport = hport;
-    cdc_acm_class->intf = intf;
-
-    hport->config.intf[intf].priv = cdc_acm_class;
-    hport->config.intf[intf + 1].priv = NULL;
-
-#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY
-    ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
-    USBH_EP_INIT(cdc_acm_class->intin, ep_desc);
-#endif
-    for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) {
-        ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc;
-
-        if (ep_desc->bEndpointAddress & 0x80) {
-            USBH_EP_INIT(cdc_acm_class->bulkin, ep_desc);
-        } else {
-            USBH_EP_INIT(cdc_acm_class->bulkout, ep_desc);
-        }
-    }
-
-    snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, cdc_acm_class->minor);
-
-    USB_LOG_INFO("Register CDC ACM Class:%s\r\n", hport->config.intf[intf].devname);
-
-#if 0
-    USB_LOG_INFO("Test cdc acm rx and tx and rx for 5 times, baudrate is 115200\r\n");
-
-    struct cdc_line_coding linecoding;
-    uint8_t count = 5;
-
-    linecoding.dwDTERate = 115200;
-    linecoding.bDataBits = 8;
-    linecoding.bParityType = 0;
-    linecoding.bCharFormat = 0;
-    usbh_cdc_acm_set_line_coding(cdc_acm_class, &linecoding);
-    usbh_cdc_acm_set_line_state(cdc_acm_class, true, false);
-
-    memset(g_cdc_acm_buf, 'a', sizeof(g_cdc_acm_buf));
-    ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, g_cdc_acm_buf, sizeof(g_cdc_acm_buf), 0xfffffff);
-    USB_LOG_RAW("out ret:%d\r\n", ret);
-    while (count--) {
-        ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, g_cdc_acm_buf, sizeof(g_cdc_acm_buf), 0xfffffff);
-        USB_LOG_RAW("in ret:%d\r\n", ret);
-        if (ret > 0) {
-            for (uint32_t i = 0; i < ret; i++) {
-                USB_LOG_RAW("%02x ", g_cdc_acm_buf[i]);
-            }
-        }
-        USB_LOG_RAW("\r\n");
-    }
-#endif
-
-    usbh_cdc_acm_run(cdc_acm_class);
-    return ret;
-}
-
-static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
-{
-    int ret = 0;
-
-    struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv;
-
-    if (cdc_acm_class) {
-        if (cdc_acm_class->bulkin) {
-            usbh_kill_urb(&cdc_acm_class->bulkin_urb);
-        }
-
-        if (cdc_acm_class->bulkout) {
-            usbh_kill_urb(&cdc_acm_class->bulkout_urb);
-        }
-
-#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY
-        if (cdc_acm_class->intin) {
-            usbh_kill_urb(&cdc_acm_class->intin_urb);
-        }
-#endif
-
-        if (hport->config.intf[intf].devname[0] != '\0') {
-            usb_osal_thread_schedule_other();
-            USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname);
-            usbh_cdc_acm_stop(cdc_acm_class);
-        }
-
-        usbh_cdc_acm_class_free(cdc_acm_class);
-    }
-
-    return ret;
-}
-
-int usbh_cdc_acm_bulk_in_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &cdc_acm_class->bulkin_urb;
-
-    usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &cdc_acm_class->bulkout_urb;
-
-    usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkout, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf)
-{
-    (void)hport;
-    (void)intf;
-    return 0;
-}
-
-static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
-{
-    (void)hport;
-    (void)intf;
-    return 0;
-}
-
-__WEAK void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
-{
-    (void)cdc_acm_class;
-}
-
-__WEAK void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
-{
-    (void)cdc_acm_class;
-}
-
-const struct usbh_class_driver cdc_acm_class_driver = {
-    .driver_name = "cdc_acm",
-    .connect = usbh_cdc_acm_connect,
-    .disconnect = usbh_cdc_acm_disconnect
-};
-
-const struct usbh_class_driver cdc_data_class_driver = {
-    .driver_name = "cdc_data",
-    .connect = usbh_cdc_data_connect,
-    .disconnect = usbh_cdc_data_disconnect
-};
-
-CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = {
-    .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
-    .bInterfaceClass = USB_DEVICE_CLASS_CDC,
-    .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
-    .bInterfaceProtocol = 0x00,
-    .id_table = NULL,
-    .class_driver = &cdc_acm_class_driver
-};
-
-CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = {
-    .match_flags = USB_CLASS_MATCH_INTF_CLASS,
-    .bInterfaceClass = USB_DEVICE_CLASS_CDC_DATA,
-    .bInterfaceSubClass = 0x00,
-    .bInterfaceProtocol = 0x00,
-    .id_table = NULL,
-    .class_driver = &cdc_data_class_driver
-};

+ 0 - 50
components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.h

@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2022, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef USBH_CDC_ACM_H
-#define USBH_CDC_ACM_H
-
-#include "usb_cdc.h"
-
-struct usbh_cdc_acm {
-    struct usbh_hubport *hport;
-    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
-    struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
-#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY
-    struct usb_endpoint_descriptor *intin;   /* INTR IN endpoint (optional) */
-#endif
-    struct usbh_urb bulkout_urb;
-    struct usbh_urb bulkin_urb;
-#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY
-    struct usbh_urb intin_urb;
-#endif
-
-    struct cdc_line_coding linecoding;
-
-    uint8_t intf;
-    uint8_t minor;
-
-    void *user_data;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding);
-int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding);
-int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts);
-
-int usbh_cdc_acm_bulk_in_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-
-void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class);
-void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* USBH_CDC_ACM_H */

+ 0 - 10
components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c

@@ -306,16 +306,6 @@ int usbh_cdc_ecm_eth_output(uint32_t buflen)
     return usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb);
 }
 
-__WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
-{
-    (void)cdc_ecm_class;
-}
-
-__WEAK void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
-{
-    (void)cdc_ecm_class;
-}
-
 const struct usbh_class_driver cdc_ecm_class_driver = {
     .driver_name = "cdc_ecm",
     .connect = usbh_cdc_ecm_connect,

+ 0 - 10
components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c

@@ -386,16 +386,6 @@ int usbh_cdc_ncm_eth_output(uint32_t buflen)
     return usbh_submit_urb(&g_cdc_ncm_class.bulkout_urb);
 }
 
-__WEAK void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
-{
-    (void)cdc_ncm_class;
-}
-
-__WEAK void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
-{
-    (void)cdc_ncm_class;
-}
-
 const struct usbh_class_driver cdc_ncm_class_driver = {
     .driver_name = "cdc_ncm",
     .connect = usbh_cdc_ncm_connect,

+ 1 - 2
components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c

@@ -106,7 +106,6 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
 {
     struct usb_setup_packet *req = setup;
     uint32_t addr;
-    uint8_t *phaddr;
     /* Data setup request */
     if (req->wLength > 0U) {
         if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
@@ -143,7 +142,7 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
                 addr = ((g_usbd_dfu.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + g_usbd_dfu.data_ptr;
 
                 /* Return the physical address where data are stored */
-                phaddr = dfu_read_flash((uint8_t *)addr, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);
+                dfu_read_flash((uint8_t *)addr, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);
 
                 /* Send the status data over EP0 */
                 memcpy(*data, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);

+ 224 - 0
components/drivers/usb/cherryusb/class/gamepad/usb_gamepad.h

@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2026, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USB_GAMEPAD_H
+#define USB_GAMEPAD_H
+
+#include "usb_hid.h"
+
+/*
+ *  GAMEPAD BUTTON LAYOUT
+ *
+ *            ____________________________              __
+ *           / [__L2__]          [__R2__] \               |
+ *          / [__ L1 __]        [__ R1 __] \              | Triggers
+ *       __/________________________________\__         __|
+ *      /                                  _   \          |
+ *     /      /\           __             (B4)  \         |
+ *    /       ||      __  |A1|  __     _       _ \        | Main Pad
+ *   |    <===DP===> |S1|      |S2|  (B3) -|- (B2)|       |
+ *    \       ||      ¯¯        ¯¯       _       /        |
+ *    /\      \/   /   \        /   \   (B1)   /\       __|
+ *   /  \________ | LS  | ____ | RS  | _______/  \        |
+ *  |         /  \ \___/ /    \ \___/ /  \         |      | Sticks
+ *  |        /    \_____/      \_____/    \        |    __|
+ *  |       /       L3            R3       \       |
+ *   \_____/                                \_____/
+ *
+ *     |________|______|    |______|___________|
+ *       D-Pad    Left       Right    Face
+ *               Stick      Stick    Buttons
+ *
+ *  Extended: A2=Touchpad/Capture  A3=Mute  L4/R4=Paddles
+ */
+
+// W3C Gamepad API standard button order
+// Bit position = W3C button index (trivial conversion: 1 << index)
+//
+//             Gamepad                   XInput    Switch    PS3/4/5    DInput
+//              ------                   ------    ------    -------    ------
+
+// Face buttons (right cluster)
+#define USB_GAMEPAD_BUTTON_B1 (1 << 0) // A         B         Cross      2
+#define USB_GAMEPAD_BUTTON_B2 (1 << 1) // B         A         Circle     3
+#define USB_GAMEPAD_BUTTON_B3 (1 << 2) // X         Y         Square     1
+#define USB_GAMEPAD_BUTTON_B4 (1 << 3) // Y         X         Triangle   4
+
+// Shoulder buttons
+#define USB_GAMEPAD_BUTTON_L1 (1 << 4) // LB        L         L1         5
+#define USB_GAMEPAD_BUTTON_R1 (1 << 5) // RB        R         R1         6
+#define USB_GAMEPAD_BUTTON_L2 (1 << 6) // LT        ZL        L2         7
+#define USB_GAMEPAD_BUTTON_R2 (1 << 7) // RT        ZR        R2         8
+
+// Center cluster
+#define USB_GAMEPAD_BUTTON_S1 (1 << 8) // Back      -         Select     9
+#define USB_GAMEPAD_BUTTON_S2 (1 << 9) // Start     +         Start      10
+
+// Stick clicks
+#define USB_GAMEPAD_BUTTON_L3 (1 << 10) // LS        LS        L3         11
+#define USB_GAMEPAD_BUTTON_R3 (1 << 11) // RS        RS        R3         12
+
+// D-pad
+#define USB_GAMEPAD_BUTTON_DU (1 << 12) // D-Up      D-Up      D-Up       Hat
+#define USB_GAMEPAD_BUTTON_DD (1 << 13) // D-Down    D-Down    D-Down     Hat
+#define USB_GAMEPAD_BUTTON_DL (1 << 14) // D-Left    D-Left    D-Left     Hat
+#define USB_GAMEPAD_BUTTON_DR (1 << 15) // D-Right   D-Right   D-Right    Hat
+
+// Auxiliary
+#define USB_GAMEPAD_BUTTON_A1 (1 << 16) // Guide     Home      PS         13
+#define USB_GAMEPAD_BUTTON_A2 (1 << 17) // -         Capture   Touchpad   14
+#define USB_GAMEPAD_BUTTON_A3 (1 << 18) // -         -         Mute       -
+#define USB_GAMEPAD_BUTTON_A4 (1 << 19) // -         -         -          -
+
+// Paddles (extended)
+#define USB_GAMEPAD_BUTTON_L4 (1 << 20) // P1        -         -          -
+#define USB_GAMEPAD_BUTTON_R4 (1 << 21) // P2        -         -          -
+
+#define XINPUT_VID        0x045E // Microsoft
+#define XINPUT_PID        0x028E // Xbox 360 Controller
+#define XINPUT_BCD_DEVICE 0x0114 // v1.14
+
+/* XInput (Xbox 360) USB */
+
+// XInput Interface Class/Subclass/Protocol
+#define XINPUT_INTERFACE_CLASS    0xFF
+#define XINPUT_INTERFACE_SUBCLASS 0x5D
+#define XINPUT_INTERFACE_PROTOCOL 0x01
+
+#define XINPUT_BUTTON_MASK_UP    (1U << 0)
+#define XINPUT_BUTTON_MASK_DOWN  (1U << 1)
+#define XINPUT_BUTTON_MASK_LEFT  (1U << 2)
+#define XINPUT_BUTTON_MASK_RIGHT (1U << 3)
+#define XINPUT_BUTTON_MASK_START (1U << 4)
+#define XINPUT_BUTTON_MASK_BACK  (1U << 5)
+#define XINPUT_BUTTON_MASK_L3    (1U << 6)
+#define XINPUT_BUTTON_MASK_R3    (1U << 7)
+#define XINPUT_BUTTON_MASK_LB    (1U << 8)
+#define XINPUT_BUTTON_MASK_RB    (1U << 9)
+#define XINPUT_BUTTON_MASK_GUIDE (1U << 10)
+//#define XINPUT_BUTTON_MASK_UNUSED        (1U << 11)
+#define XINPUT_BUTTON_MASK_A (1U << 12)
+#define XINPUT_BUTTON_MASK_B (1U << 13)
+#define XINPUT_BUTTON_MASK_X (1U << 14)
+#define XINPUT_BUTTON_MASK_Y (1U << 15)
+
+// LED patterns for report_id 0x01
+#define XINPUT_LED_OFF          0x00
+#define XINPUT_LED_BLINK        0x01
+#define XINPUT_LED_FLASH_1      0x02
+#define XINPUT_LED_FLASH_2      0x03
+#define XINPUT_LED_FLASH_3      0x04
+#define XINPUT_LED_FLASH_4      0x05
+#define XINPUT_LED_ON_1         0x06
+#define XINPUT_LED_ON_2         0x07
+#define XINPUT_LED_ON_3         0x08
+#define XINPUT_LED_ON_4         0x09
+#define XINPUT_LED_ROTATE       0x0A
+#define XINPUT_LED_BLINK_SLOW   0x0B
+#define XINPUT_LED_BLINK_SLOW_1 0x0C
+#define XINPUT_LED_BLINK_SLOW_2 0x0D
+
+struct xinput_in_report {
+    uint8_t report_id;   /* Always 0x00 */
+    uint8_t report_size; /* Always 0x14 (20) */
+    uint16_t buttons;    /* DPAD, Start, Back, L3, R3, LB, RB, Guide, A, B, X, Y */
+    uint8_t lt;          /* Left trigger (0-255) */
+    uint8_t rt;          /* Right trigger (0-255) */
+    int16_t lx;          /* Left stick X (-32768 to 32767) */
+    int16_t ly;          /* Left stick Y (-32768 to 32767) */
+    int16_t rx;          /* Right stick X (-32768 to 32767) */
+    int16_t ry;          /* Right stick Y (-32768 to 32767) */
+    uint8_t reserved[6]; /* Reserved/padding */
+} __PACKED;
+
+struct xinput_out_report {
+    uint8_t report_id;   // 0x00 = rumble, 0x01 = LED
+    uint8_t report_size; // 0x08
+    uint8_t led;         // LED pattern (0x00 for rumble)
+    uint8_t rumble_l;    // Left motor (large, 0-255)
+    uint8_t rumble_r;    // Right motor (small, 0-255)
+    uint8_t reserved[3]; // Padding
+} __PACKED;
+
+// clang-format off
+#define XINPUT_DESCRIPTOR_LEN (9 + 16 + 7 + 7)
+
+#define XINPUT_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep)                                                                     \
+    USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, 0x02, 0xff, 0x5d, 0x01, 0x00), /* XInput proprietary descriptor (0x21) */ \
+    16, 0x21, 0x00, 0x01, 0x01, 0x24, in_ep, 0x14, 0x03, 0x00, 0x03, 0x13, out_ep, 0x00, 0x03, 0x00,                               \
+    USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x03, 32, 0x01),                                                                        \
+    USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x03, 32, 0x08)
+// clang-format on
+
+#define SWITCH_VID        0x0F0D // 0x057E Nintendo Pro Controller
+#define SWITCH_PID        0x0092 // 0x2009
+#define SWITCH_BCD_DEVICE 0x0100 // v1.00
+
+// Button masks (16-bit)
+#define SWITCH_MASK_Y       (1U << 0)
+#define SWITCH_MASK_B       (1U << 1)
+#define SWITCH_MASK_A       (1U << 2)
+#define SWITCH_MASK_X       (1U << 3)
+#define SWITCH_MASK_L       (1U << 4)
+#define SWITCH_MASK_R       (1U << 5)
+#define SWITCH_MASK_ZL      (1U << 6)
+#define SWITCH_MASK_ZR      (1U << 7)
+#define SWITCH_MASK_MINUS   (1U << 8)
+#define SWITCH_MASK_PLUS    (1U << 9)
+#define SWITCH_MASK_L3      (1U << 10)
+#define SWITCH_MASK_R3      (1U << 11)
+#define SWITCH_MASK_HOME    (1U << 12)
+#define SWITCH_MASK_CAPTURE (1U << 13)
+
+// D-pad / Hat switch values
+#define SWITCH_HAT_UP         0x00
+#define SWITCH_HAT_UP_RIGHT   0x01
+#define SWITCH_HAT_RIGHT      0x02
+#define SWITCH_HAT_DOWN_RIGHT 0x03
+#define SWITCH_HAT_DOWN       0x04
+#define SWITCH_HAT_DOWN_LEFT  0x05
+#define SWITCH_HAT_LEFT       0x06
+#define SWITCH_HAT_UP_LEFT    0x07
+#define SWITCH_HAT_CENTER     0x08
+
+// Analog stick range
+#define SWITCH_JOYSTICK_MIN 0x00
+#define SWITCH_JOYSTICK_MID 0x80
+#define SWITCH_JOYSTICK_MAX 0xFF
+
+struct switch_in_report {
+    uint16_t buttons; // 16 button bits
+    uint8_t hat;      // D-pad (hat switch, 0-8)
+    uint8_t lx;       // Left stick X (0-255, 128 = center)
+    uint8_t ly;       // Left stick Y (0-255, 128 = center)
+    uint8_t rx;       // Right stick X (0-255, 128 = center)
+    uint8_t ry;       // Right stick Y (0-255, 128 = center)
+    uint8_t vendor;   // Vendor-specific byte
+} __PACKED;
+
+struct switch_out_report {
+    uint8_t data[8]; // Vendor-specific rumble data
+} __PACKED;
+
+#define HID_SWITCH_REPORT_DESC_SIZE 86
+
+// clang-format off
+#define SWITCH_DESCRIPTOR_LEN HID_CUSTOM_INOUT_DESCRIPTOR_LEN
+
+#define SWITCH_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep) \
+    HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, HID_SWITCH_REPORT_DESC_SIZE, out_ep, in_ep, 64, 0x01)
+// clang-format on
+
+struct usb_gamepad_report {
+    uint32_t buttons;
+    uint8_t lt;
+    uint8_t rt;
+    uint8_t lx;
+    uint8_t ly;
+    uint8_t rx;
+    uint8_t ry;
+};
+
+#endif /* USB_GAMEPAD_H */

+ 209 - 0
components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c

@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2026, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usbd_hid.h"
+#include "usbd_gamepad.h"
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t gamepad_report_buffer[64];
+
+static int xinput_vendor_class_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
+{
+    struct xinput_in_report xinput_report;
+
+    memset(&xinput_report, 0, sizeof(xinput_report));
+    xinput_report.report_size = 20;
+
+    memcpy(*data, &xinput_report, sizeof(xinput_report));
+    *len = sizeof(xinput_report);
+    return 0;
+}
+
+int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *report)
+{
+    struct xinput_in_report *xinput_report;
+
+    xinput_report = (struct xinput_in_report *)gamepad_report_buffer;
+    memset(xinput_report, 0, sizeof(xinput_report));
+    xinput_report->report_size = 20;
+
+    if (report->buttons & USB_GAMEPAD_BUTTON_DU)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_UP;
+    if (report->buttons & USB_GAMEPAD_BUTTON_DD)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_DOWN;
+    if (report->buttons & USB_GAMEPAD_BUTTON_DL)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_LEFT;
+    if (report->buttons & USB_GAMEPAD_BUTTON_DR)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_RIGHT;
+    if (report->buttons & USB_GAMEPAD_BUTTON_S2)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_START;
+    if (report->buttons & USB_GAMEPAD_BUTTON_S1)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_BACK;
+    if (report->buttons & USB_GAMEPAD_BUTTON_L3)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_L3;
+    if (report->buttons & USB_GAMEPAD_BUTTON_R3)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_R3;
+    if (report->buttons & USB_GAMEPAD_BUTTON_L1)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_LB;
+    if (report->buttons & USB_GAMEPAD_BUTTON_R1)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_RB;
+    if (report->buttons & USB_GAMEPAD_BUTTON_A1)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_GUIDE;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B1)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_A;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B2)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_B;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B3)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_X;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B4)
+        xinput_report->buttons |= XINPUT_BUTTON_MASK_Y;
+
+    // Analog triggers (0-255), fall back to digital if analog is 0 but button pressed
+    xinput_report->lt = report->lt;
+    xinput_report->rt = report->rt;
+    if (xinput_report->lt == 0 && (report->buttons & USB_GAMEPAD_BUTTON_L2))
+        xinput_report->lt = 0xFF;
+    if (xinput_report->rt == 0 && (report->buttons & USB_GAMEPAD_BUTTON_R2))
+        xinput_report->rt = 0xFF;
+
+    return usbd_ep_start_write(0, ep, gamepad_report_buffer, sizeof(struct xinput_in_report));
+}
+
+// Convert gamepad dpad mask to switch hat value
+static uint8_t convert_dpad_to_switch_hat(uint32_t buttons)
+{
+    // Joypad uses active-high (1 = pressed)
+    uint8_t up = (buttons & USB_GAMEPAD_BUTTON_DU) ? 1 : 0;
+    uint8_t down = (buttons & USB_GAMEPAD_BUTTON_DD) ? 1 : 0;
+    uint8_t left = (buttons & USB_GAMEPAD_BUTTON_DL) ? 1 : 0;
+    uint8_t right = (buttons & USB_GAMEPAD_BUTTON_DR) ? 1 : 0;
+
+    if (up && right)
+        return SWITCH_HAT_UP_RIGHT;
+    if (up && left)
+        return SWITCH_HAT_UP_LEFT;
+    if (down && right)
+        return SWITCH_HAT_DOWN_RIGHT;
+    if (down && left)
+        return SWITCH_HAT_DOWN_LEFT;
+    if (up)
+        return SWITCH_HAT_UP;
+    if (down)
+        return SWITCH_HAT_DOWN;
+    if (left)
+        return SWITCH_HAT_LEFT;
+    if (right)
+        return SWITCH_HAT_RIGHT;
+
+    return SWITCH_HAT_CENTER;
+}
+
+int usbd_gamepad_switch_send_report(uint8_t ep, struct usb_gamepad_report *report)
+{
+    struct switch_in_report *switch_report;
+
+    switch_report = (struct switch_in_report *)gamepad_report_buffer;
+    memset(switch_report, 0, sizeof(switch_report));
+
+    if (report->buttons & USB_GAMEPAD_BUTTON_S1)
+        switch_report->buttons |= SWITCH_MASK_MINUS;
+    if (report->buttons & USB_GAMEPAD_BUTTON_S2)
+        switch_report->buttons |= SWITCH_MASK_PLUS;
+    if (report->buttons & USB_GAMEPAD_BUTTON_L1)
+        switch_report->buttons |= SWITCH_MASK_L;
+    if (report->buttons & USB_GAMEPAD_BUTTON_R1)
+        switch_report->buttons |= SWITCH_MASK_R;
+    if (report->buttons & USB_GAMEPAD_BUTTON_L2)
+        switch_report->buttons |= SWITCH_MASK_ZL;
+    if (report->buttons & USB_GAMEPAD_BUTTON_R2)
+        switch_report->buttons |= SWITCH_MASK_ZR;
+    if (report->buttons & USB_GAMEPAD_BUTTON_L3)
+        switch_report->buttons |= SWITCH_MASK_L3;
+    if (report->buttons & USB_GAMEPAD_BUTTON_R3)
+        switch_report->buttons |= SWITCH_MASK_R3;
+    if (report->buttons & USB_GAMEPAD_BUTTON_A1)
+        switch_report->buttons |= SWITCH_MASK_HOME;
+    if (report->buttons & USB_GAMEPAD_BUTTON_A2)
+        switch_report->buttons |= SWITCH_MASK_CAPTURE;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B1)
+        switch_report->buttons |= SWITCH_MASK_B;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B2)
+        switch_report->buttons |= SWITCH_MASK_A;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B3)
+        switch_report->buttons |= SWITCH_MASK_Y;
+    if (report->buttons & USB_GAMEPAD_BUTTON_B4)
+        switch_report->buttons |= SWITCH_MASK_X;
+
+    switch_report->hat = convert_dpad_to_switch_hat(report->buttons);
+
+    // Analog sticks (HID convention: 0=up, 255=down - no inversion needed)
+    switch_report->lx = report->lx;
+    switch_report->ly = report->ly;
+    switch_report->rx = report->rx;
+    switch_report->ry = report->ry;
+
+    switch_report->vendor = 0;
+
+    return usbd_ep_start_write(0, ep, gamepad_report_buffer, sizeof(struct switch_in_report));
+}
+
+struct usbd_interface *usbd_gamepad_xinput_init_intf(struct usbd_interface *intf)
+{
+    intf->class_interface_handler = NULL;
+    intf->class_endpoint_handler = NULL;
+    intf->vendor_handler = xinput_vendor_class_request_handler;
+    intf->notify_handler = NULL;
+
+    return intf;
+}
+
+static const uint8_t hid_switch_report_desc[HID_SWITCH_REPORT_DESC_SIZE] = {
+    0x05, 0x01,       // Usage Page (Generic Desktop Ctrls)
+    0x09, 0x05,       // Usage (Game Pad)
+    0xA1, 0x01,       // Collection (Application)
+    0x15, 0x00,       //   Logical Minimum (0)
+    0x25, 0x01,       //   Logical Maximum (1)
+    0x35, 0x00,       //   Physical Minimum (0)
+    0x45, 0x01,       //   Physical Maximum (1)
+    0x75, 0x01,       //   Report Size (1)
+    0x95, 0x10,       //   Report Count (16)
+    0x05, 0x09,       //   Usage Page (Button)
+    0x19, 0x01,       //   Usage Minimum (Button 1)
+    0x29, 0x10,       //   Usage Maximum (Button 16)
+    0x81, 0x02,       //   Input (Data,Var,Abs)
+    0x05, 0x01,       //   Usage Page (Generic Desktop Ctrls)
+    0x25, 0x07,       //   Logical Maximum (7)
+    0x46, 0x3B, 0x01, //   Physical Maximum (315)
+    0x75, 0x04,       //   Report Size (4)
+    0x95, 0x01,       //   Report Count (1)
+    0x65, 0x14,       //   Unit (Eng Rot:Angular Pos)
+    0x09, 0x39,       //   Usage (Hat switch)
+    0x81, 0x42,       //   Input (Data,Var,Abs,Null)
+    0x65, 0x00,       //   Unit (None)
+    0x95, 0x01,       //   Report Count (1)
+    0x81, 0x01,       //   Input (Const) - 4-bit padding
+    0x26, 0xFF, 0x00, //   Logical Maximum (255)
+    0x46, 0xFF, 0x00, //   Physical Maximum (255)
+    0x09, 0x30,       //   Usage (X) - Left Stick X
+    0x09, 0x31,       //   Usage (Y) - Left Stick Y
+    0x09, 0x32,       //   Usage (Z) - Right Stick X
+    0x09, 0x35,       //   Usage (Rz) - Right Stick Y
+    0x75, 0x08,       //   Report Size (8)
+    0x95, 0x04,       //   Report Count (4)
+    0x81, 0x02,       //   Input (Data,Var,Abs)
+    0x06, 0x00, 0xFF, //   Usage Page (Vendor Defined)
+    0x09, 0x20,       //   Usage (0x20)
+    0x95, 0x01,       //   Report Count (1)
+    0x81, 0x02,       //   Input (Data,Var,Abs) - Vendor byte
+    0x0A, 0x21, 0x26, //   Usage (0x2621)
+    0x95, 0x08,       //   Report Count (8)
+    0x91, 0x02,       //   Output (Data,Var,Abs) - Rumble
+    0xC0,             // End Collection
+};
+
+struct usbd_interface *usbd_gamepad_switch_init_intf(struct usbd_interface *intf)
+{
+    return usbd_hid_init_intf(0, intf, hid_switch_report_desc, HID_SWITCH_REPORT_DESC_SIZE);
+}

+ 22 - 0
components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2026, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBD_GAMEPAD_H
+#define USBD_GAMEPAD_H
+
+#include "usb_gamepad.h"
+
+#define USBD_GAMEPAD_MODE_XINPUT  0
+#define USBD_GAMEPAD_MODE_SWITCH  1
+#define USBD_GAMEPAD_MODE_XBOXONE 2
+#define USBD_GAMEPAD_MODE_PS4     3
+
+struct usbd_interface *usbd_gamepad_xinput_init_intf(struct usbd_interface *intf);
+struct usbd_interface *usbd_gamepad_switch_init_intf(struct usbd_interface *intf);
+
+int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *report);
+int usbd_gamepad_switch_send_report(uint8_t ep, struct usb_gamepad_report *report);
+
+#endif /* USBD_GAMEPAD_H */

+ 106 - 123
components/drivers/usb/cherryusb/class/hid/usb_hid.h

@@ -35,7 +35,7 @@
 #define HID_REPORT_OUTPUT  0x02
 #define HID_REPORT_FEATURE 0x03
 
-/* HID Descriptor ***********************************************************/
+/* HID Descriptor */
 
 #define HID_COUNTRY_NONE        0x00 /* Not Supported */
 #define HID_COUNTRY_ARABIC      0x01 /* Arabic */
@@ -74,99 +74,114 @@
 #define HID_COUNTRY_YUGOSLAVIA  0x34 /* Yugoslavia */
 #define HID_COUNTRY_TURKISHF    0x35 /* Turkish-F */
 
-/* HID report items */
-#define HID_REPORT_ITEM_SIZE_MASK   0x03
-#define HID_REPORT_ITEM_SIZE_0      0x00 /* No data follows */
-#define HID_REPORT_ITEM_SIZE_1      0x01 /* 1 byte of data follows */
-#define HID_REPORT_ITEM_SIZE_2      0x02 /* 2 bytes of data follow */
-#define HID_REPORT_ITEM_SIZE_4      0x03 /* 4 bytes of data follow */
-#define HID_REPORT_ITEM_TYPE_MASK   0x0c
-#define HID_REPORT_ITEM_TYPE_MAIN   0x00
-#define HID_REPORT_ITEM_TYPE_GLOBAL 0x04
-#define HID_REPORT_ITEM_TYPE_LOCAL  0x08
-#define HID_REPORT_ITEM_TAG_MASK    0xf0
+/* HID report See specification at
+ * https://www.usb.org/sites/default/files/hid1_11.pdf
+ * https://www.usb.org/sites/default/files/hut1_22.pdf
+ */
+
+#define HID_SIZE_MASK (0x3 << 0)
+#define HID_TYPE_MASK (0x3 << 2)
+#define HID_TAG_MASK  (0xF << 4)
+
+#define HID_ITEMTYPE_MAIN   (0x0 << 2)
+#define HID_ITEMTYPE_GLOBAL (0x1 << 2)
+#define HID_ITEMTYPE_LOCAL  (0x2 << 2)
+#define HID_ITEMTYPE_LONG   (0x3 << 2)
 
 /* Main Items (HID 6.2.2.4) */
-#define HID_MAIN_ITEM_CONSTANT      (1 << 0) /* Constant(1) vs Data(0) */
-#define HID_MAIN_ITEM_VARIABLE      (1 << 1) /* Variable(1) vs Array(0) */
-#define HID_MAIN_ITEM_RELATIVE      (1 << 2) /* Relative(1) vs Absolute(0) */
-#define HID_MAIN_ITEM_WRAP          (1 << 3) /* Wrap(1) vs No Wrap(0) */
-#define HID_MAIN_ITEM_NONLINEAR     (1 << 4) /* Non Linear(1) vs Linear(0) */
-#define HID_MAIN_ITEM_NOPREFERRED   (1 << 5) /* No Preferred (1) vs Preferred State(0) */
-#define HID_MAIN_ITEM_NULLSTATE     (1 << 6) /* Null state(1) vs No Null position(0) */
-#define HID_MAIN_ITEM_VOLATILE      (1 << 7) /* Volatile(1) vs Non volatile(0) */
-#define HID_MAIN_ITEM_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */
-
-#define HID_MAIN_ITEM_SIZE(pfx)           ((pfx)&HID_REPORT_ITEM_SIZE_MASK)
-#define HID_MAIN_ITEM_INPUT_PREFIX        0x80
-#define HID_MAIN_ITEM_INPUT_CONSTANT      HID_MAIN_ITEM_CONSTANT
-#define HID_MAIN_ITEM_INPUT_VARIABLE      HID_MAIN_ITEM_VARIABLE
-#define HID_MAIN_ITEM_INPUT_RELATIVE      HID_MAIN_ITEM_RELATIVE
-#define HID_MAIN_ITEM_INPUT_WRAP          HID_MAIN_ITEM_WRAP
-#define HID_MAIN_ITEM_INPUT_NONLINEAR     HID_MAIN_ITEM_NONLINEAR
-#define HID_MAIN_ITEM_INPUT_NOPREFERRED   HID_MAIN_ITEM_NOPREFERRED
-#define HID_MAIN_ITEM_INPUT_NULLSTATE     HID_MAIN_ITEM_NULLSTATE
-#define HID_MAIN_ITEM_INPUT_BUFFEREDBYTES HID_MAIN_ITEM_BUFFEREDBYTES
-
-#define HID_MAIN_ITEM_OUTPUT_PREFIX        0x90
-#define HID_MAIN_ITEM_OUTPUT_CONSTANT      HID_MAIN_ITEM_CONSTANT
-#define HID_MAIN_ITEM_OUTPUT_VARIABLE      HID_MAIN_ITEM_VARIABLE
-#define HID_MAIN_ITEM_OUTPUT_RELATIVE      HID_MAIN_ITEM_RELATIVE
-#define HID_MAIN_ITEM_OUTPUT_WRAP          HID_MAIN_ITEM_WRAP
-#define HID_MAIN_ITEM_OUTPUT_NONLINEAR     HID_MAIN_ITEM_NONLINEAR
-#define HID_MAIN_ITEM_OUTPUT_NOPREFERRED   HID_MAIN_ITEM_NOPREFERRED
-#define HID_MAIN_ITEM_OUTPUT_NULLSTATE     HID_MAIN_ITEM_NULLSTATE
-#define HID_MAIN_ITEM_OUTPUT_VOLATILE      HID_MAIN_ITEM_VOLATILE
-#define HID_MAIN_ITEM_OUTPUT_BUFFEREDBYTES HID_MAIN_ITEM_BUFFEREDBYTES
-
-#define HID_MAIN_ITEM_FEATURE_PREFIX        0xb0
-#define HID_MAIN_ITEM_FEATURE_CONSTANT      HID_MAIN_ITEM_CONSTANT
-#define HID_MAIN_ITEM_FEATURE_VARIABLE      HID_MAIN_ITEM_VARIABLE
-#define HID_MAIN_ITEM_FEATURE_RELATIVE      HID_MAIN_ITEM_RELATIVE
-#define HID_MAIN_ITEM_FEATURE_WRAP          HID_MAIN_ITEM_WRAP
-#define HID_MAIN_ITEM_FEATURE_NONLINEAR     HID_MAIN_ITEM_NONLINEAR
-#define HID_MAIN_ITEM_FEATURE_NOPREFERRED   HID_MAIN_ITEM_NOPREFERRED
-#define HID_MAIN_ITEM_FEATURE_NULLSTATE     HID_MAIN_ITEM_NULLSTATE
-#define HID_MAIN_ITEM_FEATURE_VOLATILE      HID_MAIN_ITEM_VOLATILE
-#define HID_MAIN_ITEM_FEATURE_BUFFEREDBYTES HID_MAIN_ITEM_BUFFEREDBYTES
-
-#define HID_MAIN_ITEM_COLLECTION_PREFIX    0xa0
-#define HID_MAIN_ITEM_COLLECTION_PHYSICAL  0x00 /* Physical (group of axes) */
-#define HID_MAIN_ITEM_COLLECTION_APPL      0x01 /* Application (mouse, keyboard) */
-#define HID_MAIN_ITEM_COLLECTION_LOGICAL   0x02 /* Logical (interrelated data) */
-#define HID_MAIN_ITEM_COLLECTION_REPORT    0x03 /* Report */
-#define HID_MAIN_ITEM_COLLECTION_ARRAY     0x04 /* Named Array */
-#define HID_MAIN_ITEM_COLLECTION_SWITCH    0x05 /* Usage Switch */
-#define HID_MAIN_ITEM_COLLECTION_MODIFIER  0x06 /* Usage Modifier */
-#define HID_MAIN_ITEM_ENDCOLLECTION_PREFIX 0xc0
+#define HID_MAINITEM_TAG_INPUT         (0x08 << 4)
+#define HID_MAINITEM_TAG_OUTPUT        (0x09 << 4)
+#define HID_MAINITEM_TAG_COLLECTION    (0x0a << 4)
+#define HID_MAINITEM_TAG_FEATURE       (0x0b << 4)
+#define HID_MAINITEM_TAG_ENDCOLLECTION (0x0c << 4)
+
+#define HID_MAINITEM_CONSTANT      (1 << 0) /* Constant(1) vs Data(0) */
+#define HID_MAINITEM_VARIABLE      (1 << 1) /* Variable(1) vs Array(0) */
+#define HID_MAINITEM_RELATIVE      (1 << 2) /* Relative(1) vs Absolute(0) */
+#define HID_MAINITEM_WRAP          (1 << 3) /* Wrap(1) vs No Wrap(0) */
+#define HID_MAINITEM_NONLINEAR     (1 << 4) /* Non Linear(1) vs Linear(0) */
+#define HID_MAINITEM_NOPREFERRED   (1 << 5) /* No Preferred (1) vs Preferred State(0) */
+#define HID_MAINITEM_NULLSTATE     (1 << 6) /* Null state(1) vs No Null position(0) */
+#define HID_MAINITEM_VOLATILE      (1 << 7) /* Volatile(1) vs Non volatile(0) */
+#define HID_MAINITEM_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */
+
+#define HID_MAINITEM_COLLECTION_PHYSICAL 0x00 /* Physical (group of axes) */
+#define HID_MAINITEM_COLLECTION_APPL     0x01 /* Application (mouse, keyboard) */
+#define HID_MAINITEM_COLLECTION_LOGICAL  0x02 /* Logical (interrelated data) */
+#define HID_MAINITEM_COLLECTION_REPORT   0x03 /* Report */
+#define HID_MAINITEM_COLLECTION_ARRAY    0x04 /* Named Array */
+#define HID_MAINITEM_COLLECTION_SWITCH   0x05 /* Usage Switch */
+#define HID_MAINITEM_COLLECTION_MODIFIER 0x06 /* Usage Modifier */
 
 /* Global Items (HID 6.2.2.7) */
-#define HID_GLOBAL_ITEM_SIZE(pfx)          ((pfx)&HID_REPORT_ITEM_SIZE_MASK)
-#define HID_GLOBAL_ITEM_USAGEPAGE_PREFIX   0x04 /* Usage Page */
-#define HID_GLOBAL_ITEM_LOGICALMIN_PREFIX  0x14 /* Logical Minimum */
-#define HID_GLOBAL_ITEM_LOGICALMAX_PREFIX  0x24 /* Logical Maximum */
-#define HID_GLOBAL_ITEM_PHYSICALMIN_PREFIX 0x34 /* Physical Minimum */
-#define HID_GLOBAL_ITEM_PHYSMICALAX_PREFIX 0x44 /* Physical Maximum */
-#define HID_GLOBAL_ITEM_UNITEXP_PREFIX     0x54 /* Unit Exponent */
-#define HID_GLOBAL_ITEM_UNIT_PREFIX        0x64 /* Unit */
-#define HID_GLOBAL_ITEM_REPORTSIZE_PREFIX  0x74 /* Report Size */
-#define HID_GLOBAL_ITEM_REPORTID_PREFIX    0x84 /* Report ID */
-#define HID_GLOBAL_ITEM_REPORTCOUNT_PREFIX 0x94 /* Report Count */
-#define HID_GLOBAL_ITEM_PUSH_PREFIX        0xa4 /* Push */
-#define HID_GLOBAL_ITEM_POP_PREFIX         0xb4 /* Pop */
+#define HID_GLOBALITEM_TAG_USAGE_PAGE   (0x00 << 4)
+#define HID_GLOBALITEM_TAG_LOGICAL_MIN  (0x01 << 4)
+#define HID_GLOBALITEM_TAG_LOGICAL_MAX  (0x02 << 4)
+#define HID_GLOBALITEM_TAG_PHYSICAL_MIN (0x03 << 4)
+#define HID_GLOBALITEM_TAG_PHYSICAL_MAX (0x04 << 4)
+#define HID_GLOBALITEM_TAG_UNIT_EXP     (0x05 << 4)
+#define HID_GLOBALITEM_TAG_UNIT         (0x06 << 4)
+#define HID_GLOBALITEM_TAG_REPORT_SIZE  (0x07 << 4)
+#define HID_GLOBALITEM_TAG_REPORT_ID    (0x08 << 4)
+#define HID_GLOBALITEM_TAG_REPORT_COUNT (0x09 << 4)
+#define HID_GLOBALITEM_TAG_PUSH         (0x0a << 4)
+#define HID_GLOBALITEM_TAG_POP          (0x0b << 4)
 
 /* Local Items (HID 6.2.2.8) */
-#define HID_LOCAL_ITEM_SIZE(pfx)            ((pfx)&HID_REPORT_ITEM_SIZE_MASK)
-#define HID_LOCAL_ITEM_USAGE_PREFIX         0x08 /* Usage */
-#define HID_LOCAL_ITEM_USAGEMIN_PREFIX      0x18 /* Usage Minimum */
-#define HID_LOCAL_ITEM_USAGEMAX_PREFIX      0x28 /* Usage Maximum */
-#define HID_LOCAL_ITEM_DESIGNATORIDX_PREFIX 0x38 /* Designator Index  */
-#define HID_LOCAL_ITEM_DESIGNATORMIN_PREFIX 0x48 /* Designator Minimum */
-#define HID_LOCAL_ITEM_DESIGNATORMAX_PREFIX 0x58 /* Designator Maximum */
-#define HID_LOCAL_ITEM_STRINGIDX_PREFIX     0x78 /* String Index */
-#define HID_LOCAL_ITEM_STRINGMIN_PREFIX     0x88 /* String Minimum */
-#define HID_LOCAL_ITEM_STRINGMAX_PREFIX     0x98 /* xx */
-#define HID_LOCAL_ITEM_DELIMITER_PREFIX     0xa8 /* Delimiter */
+#define HID_LOCALITEM_TAG_USAGE       (0x00 << 4)
+#define HID_LOCALITEM_TAG_USAGE_MIN   (0x01 << 4)
+#define HID_LOCALITEM_TAG_USAGE_MAX   (0x02 << 4)
+#define HID_LOCALITEM_TAG_DESIG_INDEX (0x03 << 4)
+#define HID_LOCALITEM_TAG_DESIG_MIN   (0x04 << 4)
+#define HID_LOCALITEM_TAG_DESIG_MAX   (0x05 << 4)
+/* No 6 in spec */
+#define HID_LOCALITEM_TAG_STRING_INDEX (0x07 << 4)
+#define HID_LOCALITEM_TAG_STRING_MIN   (0x08 << 4)
+#define HID_LOCALITEM_TAG_STRING_MAX   (0x09 << 4)
+#define HID_LOCALITEM_TAG_DELIMITER    (0x0a << 4) /* Also listed as reserved in spec! */
+
+/* Usage pages (HuT 3) */
+#define HID_USAGE_PAGE_UNDEFINED                0x00  /* Undefined */
+#define HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS 0x01  /* Generic Desktop Controls */
+#define HID_USAGE_PAGE_SIMULATION_CONTROLS      0x02  /* Simulation Controls */
+#define HID_USAGE_PAGE_VR_CONTROLS              0x03  /* VR Controls */
+#define HID_USAGE_PAGE_SPORT_CONTROLS           0x04  /* Sport Controls */
+#define HID_USAGE_PAGE_GAME_CONTROLS            0x05  /* Game Controls */
+#define HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS  0x06  /* Generic Device Controls */
+#define HID_USAGE_PAGE_KEYBOARD_KEYPAD          0x07  /* Keyboard/Keypad */
+#define HID_USAGE_PAGE_LED                      0x08  /* LEDs */
+#define HID_USAGE_PAGE_BUTTON                   0x09  /* Button */
+#define HID_USAGE_PAGE_ORDINAL                  0x0a  /* Ordinal */
+#define HID_USAGE_PAGE_TELEPHONY                0x0b  /* Telephony */
+#define HID_USAGE_PAGE_CONSUMER                 0x0c  /* Consumer */
+#define HID_USAGE_PAGE_DIGITIZER                0x0d  /* Digitizer */
+#define HID_USAGE_PAGE_HAPTICS                        /* 0x0e Reserved */
+#define HID_USAGE_PAGE_PID                      0x0f  /* PID Page  Physical Interface Device */
+#define HID_USAGE_PAGE_UNICODE                  0x10  /* Unicode */
+#define HID_USAGE_PAGE_SOC                      0x11  /* Sensor Orientation Category */
+#define HID_USAGE_PAGE_EYE_AND_HEAD_TRACKER     0x12  /* Eye and Head Tracker */
+                                                      /* 0x13 Reserved */
+#define HID_USAGE_PAGE_ALPHA_DISPLAY 0x14             /* Alphanumeric Display */
+                                                      /* 0x15-3f Reserved */
+#define HID_USAGE_PAGE_MEDICAL         0x40           /* Medical Instruments */
+#define HID_USAGE_PAGE_BRAILLE_DISPLAY 0x41           /* Braille Display */
+                                                      /* 0x42-0x58 Reserved */
+#define HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION 0x59 /* Lighting and Illumination */
+                                                      /* 0x5a-0x7f Reserved */
+#define HID_USAGE_PAGE_USB_MONITOR           0x80     /* USB Monitor */
+#define HID_USAGE_PAGE_USB_ENUMERATED_VALUES 0x81     /* USB Enumerated Values */
+#define HID_USAGE_PAGE_VESA_VIRTUAL_CONTROLS 0x82     /* VESA Virtual Controls */
+#define HID_USAGE_PAGE_POWER_DEVICE          0x84     /* Power Device */
+#define HID_USAGE_PAGE_BATTERY_SYSTEM        0x85     /* Battery System */
+#define HID_USAGE_PAGE_BARCODE_SCANNER       0x8c     /* Bar Code Scanner page */
+#define HID_USAGE_PAGE_SCALE                 0x8d     /* Scale page */
+#define HID_USAGE_PAGE_MSR                   0x8e     /* Magnetic Stripe Reading (MSR) Devices */
+#define HID_USAGE_PAGE_POS                   0x8f     /* Point of Sale devices */
+#define HID_USAGE_PAGE_CAMERA_CONTROL        0x90     /* Camera Control Page */
+#define HID_USAGE_PAGE_ARCADE                0x91
+#define HID_USAGE_PAGE_GAMING_DEVICE         0x92
+#define HID_USAGE_PAGE_FIDO_ALLIANCE         0xF1D0
+#define HID_USAGE_PAGE_VENDOR_PAGE_HBYTE     0xFF00
 
 /* Modifier Keys (HID 8.3) */
 #define HID_MODIFIER_LCTRL  (1 << 0) /* Left Ctrl */
@@ -205,38 +220,6 @@
 #define HID_JS_INPUT_REPORT_BUTTON3         (1 << 6)
 #define HID_JS_INPUT_REPORT_BUTTON4         (1 << 7)
 
-/* Usage pages (HuT 3) */
-#define HID_USAGE_PAGE_UNDEFINED       0x00 /* Undefined */
-#define HID_USAGE_PAGE_GENERIC_DCTRL   0x01 /* Generic Desktop Controls */
-#define HID_USAGE_PAGE_SIMCTRL         0x02 /* Simulation Controls */
-#define HID_USAGE_PAGE_VRCTRL          0x03 /* VR Controls */
-#define HID_USAGE_PAGE_SPORTCTRL       0x04 /* Sport Controls */
-#define HID_USAGE_PAGE_GAMECTRL        0x05 /* Game Controls */
-#define HID_USAGE_PAGE_GENERIC_DEVCTRL 0x06 /* Generic Device Controls */
-#define HID_USAGE_PAGE_KBD             0x07 /* Keyboard/Keypad */
-#define HID_USAGE_PAGE_LEDS            0x08 /* LEDs */
-#define HID_USAGE_PAGE_BUTTON          0x09 /* Button */
-#define HID_USAGE_PAGE_ORDINAL         0x0a /* Ordinal */
-#define HID_USAGE_PAGE_TELEPHONY       0x0b /* Telephony */
-#define HID_USAGE_PAGE_CONSUMER        0x0c /* Consumer */
-#define HID_USAGE_PAGE_DIGITIZER       0x0d /* Digitizer */
-                                            /* 0x0e Reserved */
-#define HID_USAGE_PAGE_PIDPAGE 0x0f         /* PID Page  Physical Interface Device */
-#define HID_USAGE_PAGE_UNICODE 0x10         /* Unicode */
-                                            /* 0x11-13 Reserved */
-#define HID_USAGE_PAGE_ALPHA_DISPLAY 0x14   /* Alphanumeric Display */
-                                            /* 0x15-3f Reserved */
-#define HID_USAGE_PAGE_MEDICAL 0x40         /* Medical Instruments */
-                                            /* 0x41-7f Reserved */
-                                            /* 0x80-83 Monitor Devices */
-                                            /* 0x84-87 Power Devices */
-                                            /* 0x88-8b Reserved */
-#define HID_USAGE_PAGE_BARCODE_SCANNER 0x8c /* Bar Code Scanner page */
-#define HID_USAGE_PAGE_SCALE           0x8d /* Scale page */
-#define HID_USAGE_PAGE_MSR             0x8e /* Magnetic Stripe Reading (MSR) Devices */
-#define HID_USAGE_PAGE_POS             0x8f /* Point of Sale devices */
-#define HID_USAGE_PAGE_CAMERA_CTRL     0x90 /* Camera Control Page */
-
 /* Generic Desktop Page Usage IDs (HuT 4) */
 #define HID_DESKTOP_USAGE_UNDEFINED 0x00        /* Undefined */
 #define HID_DESKTOP_USAGE_POINTER   0x01        /* Pointer */
@@ -634,7 +617,7 @@ struct usb_hid_js_report {
 
 #define HID_CUSTOM_INOUT_DESCRIPTOR_LEN (9 + 9 + 7 + 7)
 
-#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, in_ep, out_ep,wMaxPacketSize, bInterval) \
+#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, out_ep, in_ep, wMaxPacketSize, bInterval) \
     0x09,                          /* bLength: Interface Descriptor size */                                         \
     USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */                                 \
     bInterfaceNumber,              /* bInterfaceNumber: Number of Interface */                                      \
@@ -654,13 +637,13 @@ struct usb_hid_js_report {
     WBVAL(wItemLength),           /* wItemLength: Total length of Report descriptor */                              \
     0x07,                         /* bLength: Endpoint Descriptor size */                                           \
     USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */                                                            \
-    in_ep,                        /* bEndpointAddress: Endpoint Address (IN) */                                     \
+    out_ep,                       /* bEndpointAddress: Endpoint Address (OUT) */                                    \
     0x03,                         /* bmAttributes: Interrupt endpoint */                                            \
     WBVAL(wMaxPacketSize),        /* wMaxPacketSize: x Byte max */                                                  \
     bInterval,                    /* bInterval: Polling Interval */                                                 \
     0x07,                         /* bLength: Endpoint Descriptor size */                                           \
     USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */                                                            \
-    out_ep,                       /* bEndpointAddress: Endpoint Address (IN) */                                     \
+    in_ep,                        /* bEndpointAddress: Endpoint Address (IN) */                                     \
     0x03,                         /* bmAttributes: Interrupt endpoint */                                            \
     WBVAL(wMaxPacketSize),        /* wMaxPacketSize: x Byte max */                                                  \
     bInterval                     /* bInterval: Polling Interval */

+ 426 - 29
components/drivers/usb/cherryusb/class/hid/usbh_hid.c

@@ -20,7 +20,7 @@
 #define INTF_DESC_bInterfaceNumber  2 /** Interface number offset */
 #define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
 
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(32, CONFIG_USB_ALIGN_SIZE)];
 
 static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS];
 static uint32_t g_devinuse = 0;
@@ -106,7 +106,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
     if (ret < 8) {
         return ret;
     }
-    memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
+    memcpy(buffer, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1));
     return ret;
 }
 
@@ -148,7 +148,7 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol)
     if (ret < 8) {
         return ret;
     }
-    memcpy(protocol, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
+    memcpy(protocol, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1));
     return ret;
 }
 
@@ -173,7 +173,6 @@ int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
 int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen)
 {
     struct usb_setup_packet *setup;
-    int ret;
 
     if (!hid_class || !hid_class->hport) {
         return -USB_ERR_INVAL;
@@ -186,18 +185,12 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
     setup->wIndex = 0;
     setup->wLength = buflen;
 
-    ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
-    if (ret < 8) {
-        return ret;
-    }
-    memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, buflen));
-    return ret;
+    return usbh_control_transfer(hid_class->hport, setup, buffer);
 }
 
 int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
 {
     struct usb_endpoint_descriptor *ep_desc;
-    int ret;
     uint8_t cur_iface = 0xff;
     uint8_t *p;
     bool found = false;
@@ -249,23 +242,6 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
         return -USB_ERR_INVAL;
     }
 found:
-    // /* 0x0 = boot protocol, 0x1 = report protocol */
-    // ret = usbh_hid_set_protocol(hid_class, 0x1);
-    // if (ret < 0) {
-    //     return ret;
-    // }
-
-    ret = usbh_hid_set_idle(hid_class, 0, 0);
-    if (ret < 0) {
-        USB_LOG_WRN("Do not support set idle\r\n");
-    }
-
-    /* We read report desc but do nothing (because of too much memory usage for parsing report desc, parsed by users) */
-    ret = usbh_hid_get_report_descriptor(hid_class, g_hid_buf[hid_class->minor], MIN(sizeof(g_hid_buf[hid_class->minor]), hid_class->report_size));
-    if (ret < 0) {
-        return ret;
-    }
-
     for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
         ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
         if (ep_desc->bEndpointAddress & 0x80) {
@@ -280,7 +256,7 @@ found:
     USB_LOG_INFO("Register HID Class:%s\r\n", hport->config.intf[intf].devname);
 
     usbh_hid_run(hid_class);
-    return ret;
+    return 0;
 }
 
 int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
@@ -310,6 +286,427 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
     return ret;
 }
 
+static uint32_t hid_get_itemval(const uint8_t *data, unsigned int idx, unsigned int size)
+{
+    uint32_t value = 0;
+
+    for (unsigned int i = 1; i <= size; i++)
+        value |= data[idx + i] << (8 * (i - 1));
+
+    return value;
+}
+
+struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_len, uint32_t max_usages)
+{
+    uint32_t i = 0;
+    uint32_t itemtag, itemtype, itemsize;
+    uint32_t itemval;
+    struct hid_report_field field;
+    uint32_t usage_page = 0, usage = 0, usage_min = 0, usage_max = 0, flags = 0;
+    uint32_t *usages;
+    struct hid_report *hid_report;
+
+    hid_report = usb_osal_malloc(sizeof(struct hid_report));
+    if (!hid_report) {
+        USB_LOG_ERR("hid report malloc failed\r\n");
+        return NULL;
+    }
+
+    usages = usb_osal_malloc(sizeof(uint32_t) * max_usages);
+    if (!usages) {
+        USB_LOG_ERR("hid usages malloc failed\r\n");
+        goto err;
+    }
+
+    memset(hid_report, 0, sizeof(struct hid_report));
+    memset(&field, 0, sizeof(struct hid_report_field));
+
+    while (i < report_len) {
+        itemtag = data[i] & HID_TAG_MASK;
+        itemtype = data[i] & HID_TYPE_MASK;
+        itemsize = data[i] & HID_SIZE_MASK;
+
+        if (itemsize == 3) /* HID spec: 6.2.2.2 - Short Items */
+            itemsize = 4;
+
+        itemval = hid_get_itemval(data, i, itemsize);
+
+        USB_LOG_DBG("itemtype 0x%02x, itemtag 0x%02x, itemsize %d, itemval 0x%08x\r\n",
+                    itemtype, itemtag, itemsize, itemval);
+
+        switch (itemtype) {
+            case HID_ITEMTYPE_MAIN:
+                switch (itemtag) {
+                    case HID_MAINITEM_TAG_INPUT:
+                        if ((flags & HID_REPORT_FLAG_REQUIRED_MASK) != HID_REPORT_FLAG_REQUIRED_MASK)
+                            goto err;
+
+                        if (hid_report->input_count >= CONFIG_USBHOST_HID_MAX_INPUT) {
+                            USB_LOG_ERR("hid input fields exceed max limit\r\n");
+                            goto err;
+                        }
+
+                        field.flags = flags;
+                        field.properties = itemval;
+                        field.usage_page = usage_page;
+                        memcpy(&hid_report->input_fields[hid_report->input_count], &field, sizeof(struct hid_report_field));
+                        if (field.usage_count > 0) {
+                            hid_report->input_fields[hid_report->input_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count);
+                            if (!hid_report->input_fields[hid_report->input_count].usages) {
+                                USB_LOG_ERR("hid input usages malloc failed\r\n");
+                                goto err;
+                            }
+                            memcpy(hid_report->input_fields[hid_report->input_count].usages, usages, sizeof(uint32_t) * field.usage_count);
+                        }
+
+                        hid_report->input_count++;
+
+                        /* only keep the global items */
+                        flags &= HID_REPORT_FLAG_GLOBAL_MASK;
+                        memset(&field, 0, sizeof(struct hid_report_field));
+                        break;
+                    case HID_MAINITEM_TAG_OUTPUT:
+                        if ((flags & HID_REPORT_FLAG_REQUIRED_MASK) != HID_REPORT_FLAG_REQUIRED_MASK)
+                            goto err;
+
+                        if (hid_report->output_count >= CONFIG_USBHOST_HID_MAX_OUTPUT) {
+                            USB_LOG_ERR("hid output fields exceed max limit\r\n");
+                            goto err;
+                        }
+
+                        field.flags = flags;
+                        field.properties = itemval;
+                        field.usage_page = usage_page;
+                        memcpy(&hid_report->output_fields[hid_report->output_count], &field, sizeof(struct hid_report_field));
+                        if (field.usage_count > 0) {
+                            hid_report->output_fields[hid_report->output_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count);
+                            if (!hid_report->output_fields[hid_report->output_count].usages) {
+                                USB_LOG_ERR("hid output usages malloc failed\r\n");
+                                goto err;
+                            }
+                            memcpy(hid_report->output_fields[hid_report->output_count].usages, usages, sizeof(uint32_t) * field.usage_count);
+                        }
+
+                        hid_report->output_count++;
+
+                        /* only keep the global items */
+                        flags &= HID_REPORT_FLAG_GLOBAL_MASK;
+                        memset(&field, 0, sizeof(struct hid_report_field));
+                        break;
+                    case HID_MAINITEM_TAG_COLLECTION:
+                        memset(&field, 0, sizeof(struct hid_report_field));
+                        break;
+                    case HID_MAINITEM_TAG_FEATURE:
+
+                        if (hid_report->feature_count >= CONFIG_USBHOST_HID_MAX_FEATURE) {
+                            USB_LOG_ERR("hid feature fields exceed max limit\r\n");
+                            goto err;
+                        }
+
+                        field.flags = flags;
+                        field.properties = itemval;
+                        field.usage_page = usage_page;
+                        memcpy(&hid_report->feature_fields[hid_report->feature_count], &field, sizeof(struct hid_report_field));
+                        if (field.usage_count > 0) {
+                            hid_report->feature_fields[hid_report->feature_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count);
+                            if (!hid_report->feature_fields[hid_report->feature_count].usages) {
+                                USB_LOG_ERR("hid feature usages malloc failed\r\n");
+                                goto err;
+                            }
+                            memcpy(hid_report->feature_fields[hid_report->feature_count].usages, usages, sizeof(uint32_t) * field.usage_count);
+                        }
+
+                        hid_report->feature_count++;
+
+                        memset(&field, 0, sizeof(struct hid_report_field));
+
+                        break;
+                    case HID_MAINITEM_TAG_ENDCOLLECTION:
+                        break;
+                    default:
+                        goto err;
+                }
+                break;
+            case HID_ITEMTYPE_GLOBAL:
+                switch (itemtag) {
+                    case HID_GLOBALITEM_TAG_USAGE_PAGE:
+                        usage_page = itemval;
+
+                        if (usage_page > UINT16_MAX)
+                            goto err;
+
+                        flags |= HID_REPORT_FLAG_USAGE_PAGE;
+                        break;
+                    case HID_GLOBALITEM_TAG_LOGICAL_MIN:
+                        field.logical_min = (int32_t)itemval;
+                        flags |= HID_REPORT_FLAG_LOGICAL_MIN;
+                        break;
+                    case HID_GLOBALITEM_TAG_LOGICAL_MAX:
+                        field.logical_max = (int32_t)itemval;
+                        flags |= HID_REPORT_FLAG_LOGICAL_MAX;
+                        break;
+                    case HID_GLOBALITEM_TAG_REPORT_SIZE:
+                        field.report_size = itemval;
+                        flags |= HID_REPORT_FLAG_REPORT_SIZE;
+                        break;
+                    case HID_GLOBALITEM_TAG_REPORT_COUNT:
+                        field.report_count = itemval;
+                        flags |= HID_REPORT_FLAG_REPORT_COUNT;
+                        break;
+                    case HID_GLOBALITEM_TAG_REPORT_ID:
+                        hid_report->uses_report_id = true;
+                        field.report_id = itemval;
+                        flags |= HID_REPORT_FLAG_REPORT_ID;
+                        break;
+                    default:
+                        goto err;
+                }
+                break;
+            case HID_ITEMTYPE_LOCAL:
+                switch (itemtag) {
+                    case HID_LOCALITEM_TAG_USAGE:
+                        usage = itemval;
+                        /* Extended usage (size 4) combines both usage page and id */
+                        if (itemsize != 4) {
+                            if (!(flags & HID_REPORT_FLAG_USAGE_PAGE))
+                                goto err;
+                            usage |= usage_page << 16;
+                        }
+
+                        usages[field.usage_count++] = usage;
+
+                        break;
+                    case HID_LOCALITEM_TAG_USAGE_MIN:
+                        usage_min = itemval;
+                        if (itemsize == 4) {
+                            /* Usage max must be extended as well */
+                            flags |= HID_REPORT_FLAG_EXTENDED_USAGE;
+                        } else {
+                            if (!(flags & HID_REPORT_FLAG_USAGE_PAGE))
+                                goto err;
+                            usage_min |= usage_page << 16;
+                        }
+                        field.usage_min = usage_min;
+                        flags |= HID_REPORT_FLAG_USAGE_MIN;
+                        break;
+                    case HID_LOCALITEM_TAG_USAGE_MAX:
+                        if (!(flags & HID_REPORT_FLAG_USAGE_MIN))
+                            goto err;
+
+                        usage_max = itemval;
+                        if (flags & HID_REPORT_FLAG_EXTENDED_USAGE) {
+                            /* Fail if max is not extended usage (HID spec 6.2.2.8) */
+                            if (itemsize != 4)
+                                goto err;
+                        } else if (itemsize == 4) {
+                            /* Fail because min wasn't extended, but max is */
+                            goto err;
+                        } else {
+                            if (!(flags & HID_REPORT_FLAG_USAGE_PAGE))
+                                goto err;
+                            usage_max |= usage_page << 16;
+                        }
+
+                        /* Usage min and max must be on the same page */
+                        if (USAGE_PAGE(usage_min) != USAGE_PAGE(usage_max)) {
+                            goto err;
+                        }
+
+                        if (usage_min > usage_max) {
+                            goto err;
+                        }
+
+                        for (uint32_t j = usage_min; j <= usage_max; j++) {
+                            usages[field.usage_count++] = j;
+                        }
+
+                        field.usage_max = usage_max;
+                        flags |= HID_REPORT_FLAG_USAGE_MAX;
+                        flags &= ~(HID_REPORT_FLAG_USAGE_MIN | HID_REPORT_FLAG_EXTENDED_USAGE);
+                        break;
+                    default:
+                        goto err;
+                }
+                break;
+            default:
+                goto err;
+        }
+
+        i += (1 + itemsize);
+    }
+    usb_osal_free(usages);
+    return hid_report;
+err:
+    if (hid_report) {
+        usb_osal_free(hid_report);
+
+        for (uint32_t j = 0; j < hid_report->input_count; j++)
+            usb_osal_free(hid_report->input_fields[j].usages);
+
+        for (uint32_t j = 0; j < hid_report->output_count; j++)
+            usb_osal_free(hid_report->output_fields[j].usages);
+
+        for (uint32_t j = 0; j < hid_report->feature_count; j++)
+            usb_osal_free(hid_report->feature_fields[j].usages);
+    }
+
+    if (usages)
+        usb_osal_free(usages);
+    return NULL;
+}
+
+void usbh_hid_report_free(struct hid_report *hid_report)
+{
+    if (hid_report) {
+        for (uint32_t j = 0; j < hid_report->input_count; j++)
+            usb_osal_free(hid_report->input_fields[j].usages);
+
+        for (uint32_t j = 0; j < hid_report->output_count; j++)
+            usb_osal_free(hid_report->output_fields[j].usages);
+
+        for (uint32_t j = 0; j < hid_report->feature_count; j++)
+            usb_osal_free(hid_report->feature_fields[j].usages);
+
+        usb_osal_free(hid_report);
+    }
+}
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_report_buf[2048];
+
+static const char *hid_property_string(uint32_t value)
+{
+    uint32_t off = 0;
+    static char buffer[160];
+
+    memset(buffer, 0, sizeof(buffer));
+
+    if (value & HID_MAINITEM_CONSTANT)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Constant, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Data, ");
+
+    if (value & HID_MAINITEM_VARIABLE)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Variable, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Array, ");
+
+    if (value & HID_MAINITEM_RELATIVE)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Relative, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Absolute, ");
+
+    if (value & HID_MAINITEM_WRAP)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Wrap, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "NoWrap, ");
+
+    if (value & HID_MAINITEM_NONLINEAR)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "NonLinear, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Linear, ");
+
+    if (value & HID_MAINITEM_NOPREFERRED)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "NoPreferred, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Preferred, ");
+
+    if (value & HID_MAINITEM_NULLSTATE)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "NullState, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "NoNullState, ");
+
+    if (value & HID_MAINITEM_VOLATILE)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "Volatile, ");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "NonVolatile, ");
+
+    if (value & HID_MAINITEM_BUFFEREDBYTES)
+        off += snprintf(buffer + off, sizeof(buffer) - off, "BufferedBytes");
+    else
+        off += snprintf(buffer + off, sizeof(buffer) - off, "BitField");
+
+    return buffer;
+
+}
+
+static void usbh_hid_field_info_print(uint32_t idx, struct hid_report_field *field)
+{
+    USB_LOG_RAW("  Field %u:\r\n", idx);
+    USB_LOG_RAW("    Usage Page: 0x%04x\r\n", (unsigned int)field->usage_page);
+    USB_LOG_RAW("    Report ID: %u\r\n", (unsigned int)field->report_id);
+    USB_LOG_RAW("    Report Size: %ubit\r\n", (unsigned int)field->report_size);
+    USB_LOG_RAW("    Report Count: %u\r\n", (unsigned int)field->report_count);
+    USB_LOG_RAW("    Logical Min: %d\r\n", field->logical_min);
+    USB_LOG_RAW("    Logical Max: %d\r\n", field->logical_max);
+    USB_LOG_RAW("    Usage Count: %u\r\n", (unsigned int)field->usage_count);
+    if (field->usage_count > 0) {
+        if (field->usage_count == 1) {
+            USB_LOG_RAW("    Usage: 0x%04x\r\n", USAGE_ID(field->usages[0]));
+        } else {
+            USB_LOG_RAW("    Usages(0x%04x ~ 0x%04x)\r\n", USAGE_ID(field->usage_min), USAGE_ID(field->usage_max));
+        }
+    }
+    USB_LOG_RAW("    Flags: 0x%04x\r\n", (unsigned int)field->flags);
+    USB_LOG_RAW("    Properties: 0x%04x(%s)\r\n", (unsigned int)field->properties, hid_property_string(field->properties));
+}
+
+int lshid(int argc, char **argv)
+{
+    struct usbh_hid *hid_class;
+    struct hid_report *hid_report;
+    int ret;
+
+    if (argc < 2) {
+        USB_LOG_ERR("please input correct command: lshid path\r\n");
+        return -1;
+    }
+
+    hid_class = usbh_find_class_instance(argv[1]);
+    if (!hid_class) {
+        USB_LOG_ERR("cannot find hid device\r\n");
+        return -1;
+    }
+
+    if (hid_class->report_size > sizeof(g_hid_report_buf)) {
+        USB_LOG_ERR("hid report buffer is too small\r\n");
+        return -1;
+    }
+
+    ret = usbh_hid_get_report_descriptor(hid_class, g_hid_report_buf, hid_class->report_size);
+    if (ret < 0) {
+        USB_LOG_ERR("get hid report descriptor failed, errcode: %d\r\n", ret);
+        return -1;
+    }
+
+    hid_report = usbh_hid_report_parse(g_hid_report_buf, hid_class->report_size, 1024);
+    if (hid_report) {
+        USB_LOG_RAW("HID report parsed successfully\r\n");
+
+        USB_LOG_RAW("Input fields: %u\r\n", (unsigned int)hid_report->input_count);
+        for (uint32_t i = 0; i < hid_report->input_count; i++) {
+            struct hid_report_field *field = &hid_report->input_fields[i];
+            usbh_hid_field_info_print(i, field);
+        }
+
+        USB_LOG_RAW("Output fields: %u\r\n", (unsigned int)hid_report->output_count);
+        for (uint32_t i = 0; i < hid_report->output_count; i++) {
+            struct hid_report_field *field = &hid_report->output_fields[i];
+            usbh_hid_field_info_print(i, field);
+        }
+
+        USB_LOG_RAW("Feature fields: %u\r\n", (unsigned int)hid_report->feature_count);
+        for (uint32_t i = 0; i < hid_report->feature_count; i++) {
+            struct hid_report_field *field = &hid_report->feature_fields[i];
+            usbh_hid_field_info_print(i, field);
+        }
+
+        usbh_hid_report_free(hid_report);
+    } else {
+        USB_LOG_ERR("HID report parsed failed\r\n");
+    }
+    return 0;
+}
+
 __WEAK void usbh_hid_run(struct usbh_hid *hid_class)
 {
     (void)hid_class;

+ 81 - 0
components/drivers/usb/cherryusb/class/hid/usbh_hid.h

@@ -8,6 +8,82 @@
 
 #include "usb_hid.h"
 
+/* local items */
+#define HID_REPORT_FLAG_USAGE_MIN (1 << 0)
+#define HID_REPORT_FLAG_USAGE_MAX (1 << 1)
+
+/* global items */
+#define HID_REPORT_FLAG_REPORT_ID    (1 << 2)
+#define HID_REPORT_FLAG_REPORT_COUNT (1 << 3)
+#define HID_REPORT_FLAG_REPORT_SIZE  (1 << 4)
+#define HID_REPORT_FLAG_LOGICAL_MIN  (1 << 5)
+#define HID_REPORT_FLAG_LOGICAL_MAX  (1 << 6)
+#define HID_REPORT_FLAG_USAGE_PAGE   (1 << 7)
+
+/* main items */
+#define HID_REPORT_FLAG_INPUT   (1 << 8)
+#define HID_REPORT_FLAG_OUTPUT  (1 << 9)
+#define HID_REPORT_FLAG_FEATURE (1 << 10)
+
+#define HID_REPORT_FLAG_EXTENDED_USAGE (1 << 11)
+
+/* masks */
+
+#define HID_REPORT_FLAG_GLOBAL_MASK (HID_REPORT_FLAG_REPORT_ID |    \
+                                     HID_REPORT_FLAG_REPORT_COUNT | \
+                                     HID_REPORT_FLAG_REPORT_SIZE |  \
+                                     HID_REPORT_FLAG_LOGICAL_MIN |  \
+                                     HID_REPORT_FLAG_LOGICAL_MAX |  \
+                                     HID_REPORT_FLAG_USAGE_PAGE)
+
+#define HID_REPORT_FLAG_REQUIRED_MASK (HID_REPORT_FLAG_REPORT_COUNT | \
+                                       HID_REPORT_FLAG_REPORT_SIZE |  \
+                                       HID_REPORT_FLAG_LOGICAL_MIN |  \
+                                       HID_REPORT_FLAG_LOGICAL_MAX)
+
+#define USAGE_ID(usage)   (usage & 0x0000FFFF)
+#define USAGE_PAGE(usage) ((usage & 0xFFFF0000) >> 16)
+
+#ifndef CONFIG_USBHOST_HID_MAX_INPUT
+#define CONFIG_USBHOST_HID_MAX_INPUT 16
+#endif
+
+#ifndef CONFIG_USBHOST_HID_MAX_OUTPUT
+#define CONFIG_USBHOST_HID_MAX_OUTPUT 16
+#endif
+
+#ifndef CONFIG_USBHOST_HID_MAX_FEATURE
+#define CONFIG_USBHOST_HID_MAX_FEATURE 16
+#endif
+
+struct hid_report_field {
+    uint32_t *usages; /* usage page + usage */
+    uint32_t usage_count;
+    uint32_t usage_page;
+
+    uint32_t report_id; /* optional */
+    uint32_t report_count;
+    uint32_t report_size;
+    int32_t logical_min;
+    int32_t logical_max;
+    uint32_t properties;
+
+    uint32_t usage_min;
+    uint32_t usage_max;
+
+    uint32_t flags;
+};
+
+struct hid_report {
+    bool uses_report_id;
+    uint32_t input_count;
+    struct hid_report_field input_fields[CONFIG_USBHOST_HID_MAX_INPUT];
+    uint32_t output_count;
+    struct hid_report_field output_fields[CONFIG_USBHOST_HID_MAX_OUTPUT];
+    uint32_t feature_count;
+    struct hid_report_field feature_fields[CONFIG_USBHOST_HID_MAX_FEATURE];
+};
+
 struct usbh_hid {
     struct usbh_hubport *hport;
     struct usb_endpoint_descriptor *intin;  /* INTR IN endpoint */
@@ -36,9 +112,14 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol);
 int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen);
 int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen);
 
+struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_len, uint32_t max_usages);
+void usbh_hid_report_free(struct hid_report *hid_report);
+
 void usbh_hid_run(struct usbh_hid *hid_class);
 void usbh_hid_stop(struct usbh_hid *hid_class);
 
+int lshid(int argc, char **argv);
+
 #ifdef __cplusplus
 }
 #endif

+ 43 - 14
components/drivers/usb/cherryusb/class/hub/usbh_hub.c

@@ -238,6 +238,7 @@ 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;
+    int ret;
 
     if (hub->is_roothub) {
         setup = &roothub_setup;
@@ -246,9 +247,22 @@ int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature)
         setup->wValue = feature;
         setup->wIndex = port;
         setup->wLength = 0;
-        return usbh_roothub_control(hub->bus, setup, NULL);
+
+        ret = usbh_roothub_control(hub->bus, setup, NULL);
+
+        if ((feature == HUB_PORT_FEATURE_RESET) && (ret >= 0)) {
+            hub->bus->event_handler(hub->bus->busid, hub->index, port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_RESET);
+        }
+
+        return ret;
     } else {
-        return _usbh_hub_set_feature(hub, port, feature);
+        ret = _usbh_hub_set_feature(hub, port, feature);
+
+        if ((feature == HUB_PORT_FEATURE_RESET) && (ret >= 0)) {
+            hub->bus->event_handler(hub->bus->busid, hub->index, port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_RESET);
+        }
+
+        return ret;
     }
 }
 
@@ -337,11 +351,11 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
     }
 
     /*
-	 * Super-Speed hubs need to know their depth to be able to
-	 * parse the bits of the route-string that correspond to
-	 * their downstream port number.
-	 *
-	 */
+     * Super-Speed hubs need to know their depth to be able to
+     * parse the bits of the route-string that correspond to
+     * their downstream port number.
+     *
+     */
     if ((hport->depth != 0) && (hport->speed == USB_SPEED_SUPER)) {
         ret = usbh_hub_set_depth(hub, hport->depth - 1);
         if (ret < 0) {
@@ -373,6 +387,11 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
         hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5);
     }
 
+    if (hub->nports > CONFIG_USBHOST_MAX_EHPORTS) {
+        USB_LOG_ERR("Hub nports %u overflow\r\n", hub->nports);
+        return -USB_ERR_NOMEM;
+    }
+
     for (uint8_t port = 0; port < hub->nports; port++) {
         hub->child[port].port = port + 1;
         hub->child[port].parent = hub;
@@ -470,6 +489,8 @@ static void usbh_hub_events(struct usbh_hub *hub)
     int ret;
     size_t flags;
 
+    (void)speed_table;
+
     if (!hub->connected) {
         return;
     }
@@ -560,6 +581,8 @@ static void usbh_hub_events(struct usbh_hub *hub)
 
             /* Last, check connect status */
             if (portstatus & HUB_PORT_STATUS_CONNECTION) {
+                hub->bus->event_handler(hub->bus->busid, hub->index, port + 1, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_CONNECTED);
+
                 ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_RESET);
                 if (ret < 0) {
                     USB_LOG_ERR("Failed to reset port %u, errorcode: %d\r\n", port + 1, ret);
@@ -641,7 +664,6 @@ static void usbh_hub_events(struct usbh_hub *hub)
                 child = &hub->child[port];
                 /** release child sources */
                 usbh_hubport_release(child);
-                USB_LOG_INFO("Device on Bus %u, Hub %u, Port %u disconnected\r\n", hub->bus->busid, hub->index, port + 1);
             }
         }
     }
@@ -660,12 +682,15 @@ static void usbh_hub_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
     struct usbh_bus *bus = (struct usbh_bus *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
 
     usb_hc_init(bus);
+    bus->event_handler(bus->busid, USB_HUB_INDEX_ANY, USB_HUB_PORT_ANY, USB_INTERFACE_ANY, USBH_EVENT_INIT);
     while (1) {
         ret = usb_osal_mq_recv(bus->hub_mq, (uintptr_t *)&hub, USB_OSAL_WAITING_FOREVER);
         if (ret < 0) {
             continue;
         }
+        usb_osal_mutex_take(bus->mutex);
         usbh_hub_events(hub);
+        usb_osal_mutex_give(bus->mutex);
     }
 }
 
@@ -695,6 +720,12 @@ int usbh_hub_initialize(struct usbh_bus *bus)
         return -1;
     }
 
+    bus->mutex = usb_osal_mutex_create();
+    if (bus->mutex == NULL) {
+        USB_LOG_ERR("Failed to create bus mutex\r\n");
+        return -1;
+    }
+
     snprintf(thread_name, 32, "usbh_hub%u", bus->busid);
     bus->hub_thread = usb_osal_thread_create(thread_name, CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbh_hub_thread, bus);
     if (bus->hub_thread == NULL) {
@@ -708,8 +739,8 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
 {
     struct usbh_hubport *hport;
     struct usbh_hub *hub;
-    size_t flags;
 
+    usb_osal_mutex_take(bus->mutex);
     hub = &bus->hcd.roothub;
     for (uint8_t port = 0; port < hub->nports; port++) {
         hport = &hub->child[port];
@@ -717,15 +748,13 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
         usbh_hubport_release(hport);
     }
 
-    flags = usb_osal_enter_critical_section();
-
     usb_hc_deinit(bus);
 
-    usb_osal_leave_critical_section(flags);
-
-    usb_osal_mq_delete(bus->hub_mq);
     usb_osal_thread_delete(bus->hub_thread);
+    usb_osal_mq_delete(bus->hub_mq);
 
+    usb_osal_mutex_give(bus->mutex);
+    usb_osal_mutex_delete(bus->mutex);
     return 0;
 }
 

+ 15 - 0
components/drivers/usb/cherryusb/class/midi/usb_midi.h

@@ -6,6 +6,8 @@
 #ifndef USB_MIDI_H
 #define USB_MIDI_H
 
+#include "usb_audio.h"
+
 /* bDescriptorSubType */
 #define MIDI_VC_HEADER_DESCRIPTOR_SUBTYPE     0x01U
 #define MIDI_MS_HEADER_DESCRIPTOR_SUBTYPE     0x01U
@@ -201,6 +203,19 @@ struct midi_cs_ep_ms_general_descriptor {
 #define MIDI_SIZEOF_MS_GENERAL_DESC(n) (4 + n)
 
 // clang-format off
+#define MIDI_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints)                                               \
+    0x09,                            /* bLength */                                                                   \
+    USB_DESCRIPTOR_TYPE_INTERFACE,   /* bDescriptorType */                                                           \
+    bInterfaceNumber,                /* bInterfaceNumber */                                                          \
+    0x00,                            /* bAlternateSetting */                                                         \
+    bNumEndpoints,                   /* bNumEndpoints */                                                             \
+    USB_DEVICE_CLASS_AUDIO,          /* bInterfaceClass */                                                           \
+    AUDIO_SUBCLASS_MIDISTREAMING,    /* bInterfaceSubClass */                                                        \
+    AUDIO_PROTOCOL_UNDEFINED,        /* bInterfaceProtocol */                                                        \
+    0x00                             /* iInterface */
+
+#define MIDI_STANDARD_DESCRIPTOR_LEN 0x09
+
 #define MIDI_CS_HEADER_DESCRIPTOR_INIT(wTotalLength)                                              \
     0x07,                                             /* bLength */                               \
     USB_CS_DESCRIPTOR_TYPE_INTERFACE,                 /* bDescriptorType */                       \

+ 266 - 0
components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.c

@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2022 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_serial.h"
+#include "usbh_cdc_acm.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_cdc_acm"
+#include "usb_log.h"
+
+struct usbh_cdc_acm {
+    struct usb_endpoint_descriptor *intin;
+    struct usbh_urb intin_urb;
+    struct usb_osal_timer *modem_timer;
+    uint16_t modem_status;
+};
+
+static int usbh_cdc_acm_attach(struct usbh_serial *serial)
+{
+    struct usb_endpoint_descriptor *ep_desc;
+    int ret;
+
+    struct usbh_cdc_acm *cdc_acm_class = usb_osal_malloc(sizeof(struct usbh_cdc_acm));
+    if (!cdc_acm_class) {
+        USB_LOG_ERR("No memory for cdc_acm_class\r\n");
+        return -USB_ERR_NOMEM;
+    }
+    memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
+    serial->priv = cdc_acm_class;
+
+    for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
+        ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc;
+
+        if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
+            if (ep_desc->bEndpointAddress & 0x80) {
+                USBH_EP_INIT(cdc_acm_class->intin, ep_desc);
+                break;
+            } else {
+            }
+        }
+    }
+
+    if (!cdc_acm_class->intin) {
+        USB_LOG_ERR("Failed to find interrupt endpoint\r\n");
+        ret = -USB_ERR_NODEV;
+        goto errout;
+    }
+    return 0;
+errout:
+    serial->priv = NULL;
+    usb_osal_free(cdc_acm_class);
+    return ret;
+}
+
+static void usbh_cdc_acm_detach(struct usbh_serial *serial)
+{
+    struct usbh_cdc_acm *cdc_acm_class;
+
+    if (!serial || !serial->priv) {
+        return;
+    }
+
+    cdc_acm_class = (struct usbh_cdc_acm *)serial->priv;
+    if (cdc_acm_class->intin) {
+        usbh_kill_urb(&cdc_acm_class->intin_urb);
+    }
+    serial->priv = NULL;
+    usb_osal_free(cdc_acm_class);
+}
+
+static int usbh_cdc_acm_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CDC_REQUEST_SET_LINE_CODING;
+    setup->wValue = 0;
+    setup->wIndex = serial->intf;
+    setup->wLength = 7;
+
+    memcpy(serial->iobuffer, line_coding, sizeof(struct cdc_line_coding));
+
+    return usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+}
+
+static int usbh_cdc_acm_get_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    struct usb_setup_packet *setup;
+    int ret;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CDC_REQUEST_GET_LINE_CODING;
+    setup->wValue = 0;
+    setup->wIndex = serial->intf;
+    setup->wLength = 7;
+
+    ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(line_coding, serial->iobuffer, sizeof(struct cdc_line_coding));
+    return ret;
+}
+
+static int usbh_cdc_acm_set_line_state(struct usbh_serial *serial, bool dtr, bool rts)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE;
+    setup->wValue = (dtr << 0) | (rts << 1);
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_cdc_acm_get_modem_status(struct usbh_serial *serial)
+{
+    struct usbh_cdc_acm *cdc_acm_class;
+    uintptr_t flags;
+    uint16_t status;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    flags = usb_osal_enter_critical_section();
+
+    cdc_acm_class = (struct usbh_cdc_acm *)serial->priv;
+
+    status = (cdc_acm_class->modem_status & CDC_SERIAL_STATE_DSR ? USBH_SERIAL_TIOCM_DSR : 0) |
+             (cdc_acm_class->modem_status & CDC_SERIAL_STATE_RING ? USBH_SERIAL_TIOCM_RI : 0) |
+             (cdc_acm_class->modem_status & CDC_SERIAL_STATE_DCD ? USBH_SERIAL_TIOCM_CD : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0);
+
+    usb_osal_leave_critical_section(flags);
+
+    return status;
+}
+
+#ifdef CONFIG_USBH_SERIAL_GET_MODEM_STATUS
+static int __usbh_cdc_acm_get_modem_status(struct usbh_serial *serial)
+{
+    struct usbh_cdc_acm *cdc_acm_class;
+    struct cdc_acm_notification *notification;
+    uint16_t difference;
+    uintptr_t flags;
+    int ret;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+    cdc_acm_class = (struct usbh_cdc_acm *)serial->priv;
+
+    usbh_int_urb_fill(&cdc_acm_class->intin_urb, serial->hport, cdc_acm_class->intin, &serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET], cdc_acm_class->intin->wMaxPacketSize, 0xffffffff, NULL, NULL);
+    ret = usbh_submit_urb(&cdc_acm_class->intin_urb);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (cdc_acm_class->intin_urb.actual_length < sizeof(struct cdc_acm_notification)) {
+        return -USB_ERR_INVAL;
+    }
+
+    notification = (struct cdc_acm_notification *)&serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET];
+    if (notification->bNotificationType != CDC_NOTIFICATION_SERIAL_STATE) {
+        return -USB_ERR_INVAL;
+    }
+
+    flags = usb_osal_enter_critical_section();
+
+    difference = cdc_acm_class->modem_status ^ notification->data;
+    cdc_acm_class->modem_status = notification->data;
+
+    if (difference & CDC_SERIAL_STATE_DSR)
+        serial->iocount.dsr++;
+    if (difference & CDC_SERIAL_STATE_DCD)
+        serial->iocount.dcd++;
+    if (notification->data & CDC_SERIAL_STATE_BREAK)
+        serial->iocount.brk++;
+    if (notification->data & CDC_SERIAL_STATE_FRAMING)
+        serial->iocount.frame++;
+    if (notification->data & CDC_SERIAL_STATE_PARITY)
+        serial->iocount.parity++;
+    if (notification->data & CDC_SERIAL_STATE_OVERRUN)
+        serial->iocount.overrun++;
+
+    usb_osal_leave_critical_section(flags);
+
+    return ret;
+}
+#endif
+
+static const struct usbh_serial_driver cdc_acm_driver = {
+    .driver_name = "cdc_acm",
+
+    .ignore_rx_header = 0,
+    .ignore_tx_header = 0,
+
+    .attach = usbh_cdc_acm_attach,
+    .detach = usbh_cdc_acm_detach,
+    .set_flow_control = NULL,
+    .set_line_coding = usbh_cdc_acm_set_line_coding,
+    .get_line_coding = usbh_cdc_acm_get_line_coding,
+    .set_line_state = usbh_cdc_acm_set_line_state,
+    .get_modem_status = usbh_cdc_acm_get_modem_status,
+};
+
+static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+    return usbh_serial_probe(hport, intf, &cdc_acm_driver) ? 0 : -USB_ERR_NOMEM;
+}
+
+static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+    struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv;
+
+    if (serial) {
+        usbh_serial_remove(serial);
+    }
+    return 0;
+}
+
+const struct usbh_class_driver cdc_acm_class_driver = {
+    .driver_name = "cdc_acm",
+    .connect = usbh_cdc_acm_connect,
+    .disconnect = usbh_cdc_acm_disconnect
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_none_class_info = {
+    .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
+    .bInterfaceClass = USB_DEVICE_CLASS_CDC,
+    .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
+    .bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE,
+    .id_table = NULL,
+    .class_driver = &cdc_acm_class_driver
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_at_class_info = {
+    .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
+    .bInterfaceClass = USB_DEVICE_CLASS_CDC,
+    .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
+    .bInterfaceProtocol = CDC_COMMON_PROTOCOL_AT_COMMANDS,
+    .id_table = NULL,
+    .class_driver = &cdc_acm_class_driver
+};

+ 19 - 0
components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_CDC_ACM_H
+#define USBH_CDC_ACM_H
+
+#include "usb_cdc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_CDC_ACM_H */

+ 409 - 0
components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c

@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_serial.h"
+#include "usbh_ch34x.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_ch43x"
+#include "usb_log.h"
+
+struct usbh_ch34x {
+    struct usb_endpoint_descriptor *intin;
+    struct usbh_urb intin_urb;
+    struct usb_osal_timer *modem_timer;
+    uint16_t modem_status;
+};
+
+/* refer to https://github.com/WCHSoftGroup/ch341ser_linux/blob/main/driver/ch341.c */
+
+static int usbh_ch34x_get_baudrate_div(uint32_t baudrate, uint8_t *factor, uint8_t *divisor)
+{
+    uint8_t a;
+    uint8_t b;
+    uint32_t c;
+
+    switch (baudrate) {
+        case 921600:
+            a = 0xf3;
+            b = 7;
+            break;
+
+        case 307200:
+            a = 0xd9;
+            b = 7;
+            break;
+
+        default:
+            if (baudrate > 6000000 / 255) {
+                b = 3;
+                c = 6000000;
+            } else if (baudrate > 750000 / 255) {
+                b = 2;
+                c = 750000;
+            } else if (baudrate > 93750 / 255) {
+                b = 1;
+                c = 93750;
+            } else {
+                b = 0;
+                c = 11719;
+            }
+            a = (uint8_t)(c / baudrate);
+            if (a == 0 || a == 0xFF) {
+                return -USB_ERR_INVAL;
+            }
+            if ((c / a - baudrate) > (baudrate - c / (a + 1))) {
+                a++;
+            }
+            a = (uint8_t)(256 - a);
+            break;
+    }
+
+    *factor = a;
+    *divisor = b;
+
+    return 0;
+}
+
+static int usbh_ch34x_control_out(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = bRequest;
+    setup->wValue = wValue;
+    setup->wIndex = wIndex;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_ch34x_control_in(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t size)
+{
+    struct usb_setup_packet *setup;
+    int ret;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = bRequest;
+    setup->wValue = wValue;
+    setup->wIndex = wIndex;
+    setup->wLength = size;
+
+    ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(data, serial->iobuffer, size);
+
+    return ret;
+}
+
+static int usbh_ch34x_get_version(struct usbh_serial *serial)
+{
+    int ret;
+    uint8_t buf[2];
+
+    ret = usbh_ch34x_control_in(serial, CH34X_READ_VERSION, 0, 0, buf, 2);
+    if (ret < 0) {
+        return ret;
+    }
+
+    USB_LOG_INFO("chip version: 0x%02x\r\n", buf[0]);
+    return ret;
+}
+
+static int usbh_ch34x_attach(struct usbh_serial *serial)
+{
+    struct usb_endpoint_descriptor *ep_desc;
+    int ret;
+
+    struct usbh_ch34x *ch34x_class = usb_osal_malloc(sizeof(struct usbh_ch34x));
+    if (!ch34x_class) {
+        USB_LOG_ERR("No memory for ch34x_class\r\n");
+        return -USB_ERR_NOMEM;
+    }
+    memset(ch34x_class, 0, sizeof(struct usbh_ch34x));
+    serial->priv = ch34x_class;
+
+    for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
+        ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc;
+
+        if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
+            if (ep_desc->bEndpointAddress & 0x80) {
+                USBH_EP_INIT(ch34x_class->intin, ep_desc);
+                break;
+            } else {
+            }
+        }
+    }
+
+    if (!ch34x_class->intin) {
+        USB_LOG_ERR("Failed to find interrupt endpoint\r\n");
+        ret = -USB_ERR_NODEV;
+        goto errout;
+    }
+
+    ret = usbh_ch34x_get_version(serial);
+    ret |= usbh_ch34x_control_out(serial, CH34X_SERIAL_INIT, 0, 0);
+    ret |= usbh_ch34x_control_out(serial, CH34X_WRITE_REG, 0x1312, 0xd982);
+    ret |= usbh_ch34x_control_out(serial, CH34X_WRITE_REG, 0x0f2c, 0x0007);
+    if (ret < 0) {
+        goto errout;
+    }
+
+    return 0;
+errout:
+    serial->priv = NULL;
+    usb_osal_free(ch34x_class);
+    return ret;
+}
+
+static void usbh_ch34x_detach(struct usbh_serial *serial)
+{
+    struct usbh_ch34x *ch34x_class;
+
+    if (!serial || !serial->priv) {
+        return;
+    }
+
+    ch34x_class = (struct usbh_ch34x *)serial->priv;
+    if (ch34x_class->intin) {
+        usbh_kill_urb(&ch34x_class->intin_urb);
+    }
+    serial->priv = NULL;
+    usb_osal_free(ch34x_class);
+}
+
+static int usbh_ch34x_set_flow_ctrl(struct usbh_serial *serial, bool hardctrl)
+{
+    return usbh_ch34x_control_out(serial, CH34X_WRITE_REG, 0x2727, hardctrl ? 0x0101 : 0x0000);
+}
+
+static int usbh_ch34x_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    uint16_t reg_value = 0;
+    uint16_t value = 0;
+    uint16_t index = 0;
+    uint8_t factor = 0;
+    uint8_t divisor = 0;
+
+    switch (line_coding->bParityType) {
+        case 0:
+            break;
+        case 1:
+            reg_value |= CH341_L_PO;
+            break;
+        case 2:
+            reg_value |= CH341_L_PE;
+            break;
+        case 3:
+            reg_value |= CH341_L_PM;
+            break;
+        case 4:
+            reg_value |= CH341_L_PS;
+            break;
+        default:
+            return -USB_ERR_INVAL;
+    }
+
+    switch (line_coding->bDataBits) {
+        case 5:
+            reg_value |= CH341_L_D5;
+            break;
+        case 6:
+            reg_value |= CH341_L_D6;
+            break;
+        case 7:
+            reg_value |= CH341_L_D7;
+            break;
+        case 8:
+            reg_value |= CH341_L_D8;
+            break;
+        default:
+            return -USB_ERR_INVAL;
+    }
+
+    if (line_coding->bCharFormat == 2) {
+        reg_value |= CH341_L_SB;
+    }
+
+    usbh_ch34x_get_baudrate_div(line_coding->dwDTERate, &factor, &divisor);
+
+    reg_value |= 0xC0;
+    value |= 0x9c;
+    value |= reg_value << 8;
+    index |= 0x80 | divisor;
+    index |= (uint16_t)factor << 8;
+
+    return usbh_ch34x_control_out(serial, CH34X_SERIAL_INIT, value, index);
+}
+
+static int usbh_ch34x_set_line_state(struct usbh_serial *serial, bool dtr, bool rts)
+{
+    uint16_t value = 0;
+    uint8_t control = 0;
+
+    control = (dtr << 5) | (rts << 6);
+    value = (uint8_t)~control;
+
+    return usbh_ch34x_control_out(serial, CH34X_MODEM_CTRL, value, 0x0000);
+}
+
+static int usbh_ch34x_get_modem_status(struct usbh_serial *serial)
+{
+    struct usbh_ch34x *ch34x_class;
+    uintptr_t flags;
+    uint16_t status;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    flags = usb_osal_enter_critical_section();
+
+    ch34x_class = (struct usbh_ch34x *)serial->priv;
+
+    status = (ch34x_class->modem_status & CH341_CTI_DS ? USBH_SERIAL_TIOCM_DSR : 0) |
+             (ch34x_class->modem_status & CH341_CTI_C ? USBH_SERIAL_TIOCM_CTS : 0) |
+             (ch34x_class->modem_status & CH341_CTRL_RI ? USBH_SERIAL_TIOCM_RI : 0) |
+             (ch34x_class->modem_status & CH341_CTI_DC ? USBH_SERIAL_TIOCM_CD : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0);
+
+    usb_osal_leave_critical_section(flags);
+
+    return status;
+}
+
+#ifdef CONFIG_USBH_SERIAL_GET_MODEM_STATUS
+static int __usbh_ch34x_get_modem_status(struct usbh_serial *serial, uint16_t *status)
+{
+    struct usbh_ch34x *ch34x_class;
+    uint8_t type = 0;
+    uint8_t data = 0;
+    uint16_t difference;
+    uintptr_t flags;
+    int ret;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+    ch34x_class = (struct usbh_ch34x *)serial->priv;
+
+    usbh_int_urb_fill(&ch34x_class->intin_urb, serial->hport, ch34x_class->intin, &serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET], ch34x_class->intin->wMaxPacketSize, 0xffffffff, NULL, NULL);
+    ret = usbh_submit_urb(&ch34x_class->intin_urb);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (ret < 4) {
+        return -USB_ERR_INVAL;
+    }
+
+    flags = usb_osal_enter_critical_section();
+
+    type = serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET];
+    if (type & CH341_CTT_M) {
+        data = ~serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET + 2] & CH341_CTI_ST;
+        difference = data ^ (ch34x_class->modem_status & CH341_CTI_ST);
+        ch34x_class->modem_status = data;
+
+        if (difference) {
+            if (difference & CH341_CTI_C) {
+                serial->iocount.cts++;
+            }
+            if (difference & CH341_CTI_DS) {
+                serial->iocount.dsr++;
+            }
+            if (difference & CH341_CTRL_RI) {
+                serial->iocount.rng++;
+            }
+            if (difference & CH341_CTI_DC) {
+                serial->iocount.dcd++;
+            }
+        }
+    }
+
+    if (type & CH341_CTT_O) {
+        serial->iocount.overrun++;
+    }
+    if ((type & CH341_CTT_F) == CH341_CTT_F) {
+        serial->iocount.frame++;
+    }
+    if (type & CH341_CTT_P) {
+        serial->iocount.parity++;
+    }
+
+    usb_osal_leave_critical_section(flags);
+
+    return ret;
+}
+#endif
+
+static const struct usbh_serial_driver ch34x_driver = {
+    .driver_name = "ch34x",
+
+    .ignore_rx_header = 0,
+    .ignore_tx_header = 0,
+
+    .attach = usbh_ch34x_attach,
+    .detach = usbh_ch34x_detach,
+    .set_flow_control = usbh_ch34x_set_flow_ctrl,
+    .set_line_coding = usbh_ch34x_set_line_coding,
+    .get_line_coding = NULL,
+    .set_line_state = usbh_ch34x_set_line_state,
+    .get_modem_status = usbh_ch34x_get_modem_status,
+};
+
+static int usbh_ch34x_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+    return usbh_serial_probe(hport, intf, &ch34x_driver) ? 0 : -USB_ERR_NOMEM;
+}
+
+static int usbh_ch34x_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+    struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv;
+
+    if (serial) {
+        usbh_serial_remove(serial);
+    }
+
+    return 0;
+}
+
+static const uint16_t ch34x_id_table[][2] = {
+    { 0x1A86, 0x7523 }, /* ch340 chip */
+    { 0x1A86, 0x7522 }, /* ch340k chip */
+    { 0x1A86, 0x5523 }, /* ch341 chip */
+    { 0x1A86, 0xe523 }, /* ch330 chip */
+    { 0x4348, 0x5523 }, /* ch340 custom chip */
+    { 0, 0 },
+};
+
+const struct usbh_class_driver ch34x_class_driver = {
+    .driver_name = "ch34x",
+    .connect = usbh_ch34x_connect,
+    .disconnect = usbh_ch34x_disconnect
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = {
+    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
+    .bInterfaceClass = 0xff,
+    .bInterfaceSubClass = 0x00,
+    .bInterfaceProtocol = 0x00,
+    .id_table = ch34x_id_table,
+    .class_driver = &ch34x_class_driver
+};

+ 56 - 0
components/drivers/usb/cherryusb/class/serial/usbh_ch34x.h

@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_CH34X_H
+#define USBH_CH34X_H
+
+#include "usb_cdc.h"
+
+/* Requests */
+#define CH34X_READ_VERSION 0x5F
+#define CH34X_WRITE_REG    0x9A
+#define CH34X_READ_REG     0x95
+#define CH34X_SERIAL_INIT  0xA1
+#define CH34X_MODEM_CTRL   0xA4
+
+// modem control bits
+#define CH34X_BIT_RTS (1 << 6)
+#define CH34X_BIT_DTR (1 << 5)
+
+#define CH341_CTO_O   0x10
+#define CH341_CTO_D   0x20
+#define CH341_CTO_R   0x40
+#define CH341_CTI_C   0x01
+#define CH341_CTI_DS  0x02
+#define CH341_CTRL_RI 0x04
+#define CH341_CTI_DC  0x08
+#define CH341_CTI_ST  0x0f
+
+#define CH341_CTT_M BIT(3)
+#define CH341_CTT_F (BIT(2) | BIT(6))
+#define CH341_CTT_P BIT(2)
+#define CH341_CTT_O BIT(1)
+
+#define CH341_L_ER 0x80
+#define CH341_L_ET 0x40
+#define CH341_L_PS 0x38
+#define CH341_L_PM 0x28
+#define CH341_L_PE 0x18
+#define CH341_L_PO 0x08
+#define CH341_L_SB 0x04
+#define CH341_L_D8 0x03
+#define CH341_L_D7 0x02
+#define CH341_L_D6 0x01
+#define CH341_L_D5 0x00
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_CH34X_H */

+ 507 - 0
components/drivers/usb/cherryusb/class/serial/usbh_cp210x.c

@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_serial.h"
+#include "usbh_cp210x.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_cp210x"
+#include "usb_log.h"
+
+struct usbh_cp210x {
+    uint8_t partnum;
+    uint32_t fw_version;
+    uint32_t min_speed;
+    uint32_t max_speed;
+    bool use_actual_rate;
+    bool no_flow_control;
+    bool no_event_mode;
+};
+
+struct cp210x_rate {
+    uint32_t rate;
+    uint32_t high;
+};
+
+static const struct cp210x_rate cp210x_an205_table1[] = {
+    { 300, 300 },
+    { 600, 600 },
+    { 1200, 1200 },
+    { 1800, 1800 },
+    { 2400, 2400 },
+    { 4000, 4000 },
+    { 4800, 4803 },
+    { 7200, 7207 },
+    { 9600, 9612 },
+    { 14400, 14428 },
+    { 16000, 16062 },
+    { 19200, 19250 },
+    { 28800, 28912 },
+    { 38400, 38601 },
+    { 51200, 51558 },
+    { 56000, 56280 },
+    { 57600, 58053 },
+    { 64000, 64111 },
+    { 76800, 77608 },
+    { 115200, 117028 },
+    { 128000, 129347 },
+    { 153600, 156868 },
+    { 230400, 237832 },
+    { 250000, 254234 },
+    { 256000, 273066 },
+    { 460800, 491520 },
+    { 500000, 567138 },
+    { 576000, 670254 },
+    { 921600, 0xffffffff }
+};
+
+/*
+ * Quantises the baud rate as per AN205 Table 1
+ */
+static uint32_t cp210x_get_an205_rate(uint32_t baud)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(cp210x_an205_table1); ++i) {
+        if (baud <= cp210x_an205_table1[i].high)
+            break;
+    }
+
+    return cp210x_an205_table1[i].rate;
+}
+
+static uint32_t cp210x_get_actual_rate(uint32_t baud)
+{
+    unsigned int prescale = 1;
+    unsigned int div;
+
+    if (baud <= 365)
+        prescale = 4;
+
+    div = DIV_ROUND_CLOSEST(48000000, 2 * prescale * baud);
+    baud = 48000000 / (2 * prescale * div);
+
+    return baud;
+}
+
+static void usbh_cp210x_init_max_speed(struct usbh_serial *serial)
+{
+    struct usbh_cp210x *cp210x_class;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return;
+    }
+
+    cp210x_class = (struct usbh_cp210x *)serial->priv;
+
+    bool use_actual_rate = false;
+    uint32_t min = 300;
+    uint32_t max;
+
+    switch (cp210x_class->partnum) {
+        case CP210X_PARTNUM_CP2101:
+            max = 921600;
+            break;
+        case CP210X_PARTNUM_CP2102:
+        case CP210X_PARTNUM_CP2103:
+            max = 1000000;
+            break;
+        case CP210X_PARTNUM_CP2104:
+            use_actual_rate = true;
+            max = 2000000;
+            break;
+        case CP210X_PARTNUM_CP2108:
+            max = 2000000;
+            break;
+        case CP210X_PARTNUM_CP2105:
+            if (serial->intf == 0) {
+                use_actual_rate = true;
+                max = 2000000; /* ECI */
+            } else {
+                min = 2400;
+                max = 921600; /* SCI */
+            }
+            break;
+        case CP210X_PARTNUM_CP2102N_QFN28:
+        case CP210X_PARTNUM_CP2102N_QFN24:
+        case CP210X_PARTNUM_CP2102N_QFN20:
+            use_actual_rate = true;
+            max = 3000000;
+            break;
+        default:
+            max = 2000000;
+            break;
+    }
+
+    cp210x_class->min_speed = min;
+    cp210x_class->max_speed = max;
+    cp210x_class->use_actual_rate = use_actual_rate;
+}
+
+static int usbh_cp210x_control_out(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t size)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = bRequest;
+    setup->wValue = wValue;
+    setup->wIndex = wIndex;
+    setup->wLength = size;
+
+    if (data && size) {
+        memcpy(serial->iobuffer, data, size);
+        return usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    } else {
+        return usbh_control_transfer(serial->hport, setup, NULL);
+    }
+}
+
+static int usbh_cp210x_control_in(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t size)
+{
+    struct usb_setup_packet *setup;
+    int ret;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = bRequest;
+    setup->wValue = wValue;
+    setup->wIndex = wIndex;
+    setup->wLength = size;
+
+    ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(data, serial->iobuffer, size);
+
+    return ret;
+}
+
+static int usbh_cp210x_get_partnum(struct usbh_serial *serial)
+{
+    uint8_t version[3];
+    struct usbh_cp210x *cp210x_class;
+    int ret;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    cp210x_class = (struct usbh_cp210x *)serial->priv;
+
+    ret = usbh_cp210x_control_in(serial, CP210X_VENDOR_SPECIFIC, CP210X_GET_PARTNUM, serial->intf, (uint8_t *)&cp210x_class->partnum, 1);
+    if (ret < 0) {
+        return ret;
+    }
+
+    USB_LOG_INFO("chip partnum: 0x%02x\r\n", cp210x_class->partnum);
+
+    switch (cp210x_class->partnum) {
+        case CP210X_PARTNUM_CP2102:
+            break;
+        case CP210X_PARTNUM_CP2105:
+        case CP210X_PARTNUM_CP2108:
+            ret = usbh_cp210x_control_in(serial, CP210X_VENDOR_SPECIFIC, CP210X_GET_FW_VER_2N, serial->intf, version, 3);
+            if (ret < 0) {
+                return ret;
+            }
+            cp210x_class->fw_version = version[0] << 16 | version[1] << 8 | version[2];
+            break;
+        case CP210X_PARTNUM_CP2102N_QFN28:
+        case CP210X_PARTNUM_CP2102N_QFN24:
+        case CP210X_PARTNUM_CP2102N_QFN20:
+            ret = usbh_cp210x_control_in(serial, CP210X_VENDOR_SPECIFIC, CP210X_GET_FW_VER_2N, serial->intf, version, 3);
+            if (ret < 0) {
+                return ret;
+            }
+            cp210x_class->fw_version = version[0] << 16 | version[1] << 8 | version[2];
+            if (cp210x_class->fw_version <= 0x10004)
+                cp210x_class->no_flow_control = true;
+            break;
+        default:
+            break;
+    }
+    return ret;
+}
+
+static int usbh_cp210x_enable(struct usbh_serial *serial)
+{
+    return usbh_cp210x_control_out(serial, CP210X_IFC_ENABLE, 1, serial->intf, NULL, 0);
+}
+
+static int usbh_cp210x_set_chars(struct usbh_serial *serial)
+{
+    struct cp210x_special_chars chars = { 0 };
+
+    return usbh_cp210x_control_out(serial, CP210X_SET_CHARS, 0, serial->intf, (uint8_t *)&chars, sizeof(struct cp210x_special_chars));
+}
+
+// static int usbh_cp210x_get_common_status(struct usbh_serial *serial, struct cp210x_comm_status *status)
+// {
+//     return usbh_cp210x_control_in(serial, CP210X_GET_COMM_STATUS, 0, serial->intf, (uint8_t *)status, sizeof(struct cp210x_comm_status));
+// }
+
+static int usbh_cp210x_set_baudrate(struct usbh_serial *serial, uint32_t baudrate)
+{
+    struct usb_setup_packet *setup;
+    struct usbh_cp210x *cp210x_class;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+    cp210x_class = (struct usbh_cp210x *)serial->priv;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CP210X_SET_BAUDRATE;
+    setup->wValue = 0;
+    setup->wIndex = serial->intf;
+    setup->wLength = 4;
+
+    if (cp210x_class->use_actual_rate)
+        baudrate = cp210x_get_actual_rate(baudrate);
+    else if (baudrate < 1000000)
+        baudrate = cp210x_get_an205_rate(baudrate);
+
+    memcpy(serial->iobuffer, (uint8_t *)&baudrate, 4);
+    return usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+}
+
+static int usbh_cp210x_set_data_format(struct usbh_serial *serial, uint8_t databits, uint8_t parity, uint8_t stopbits)
+{
+    struct usb_setup_packet *setup;
+    uint16_t value;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    value = ((databits & 0x0F) << 8) | ((parity & 0x0f) << 4) | ((stopbits & 0x03) << 0);
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CP210X_SET_LINE_CTL;
+    setup->wValue = value;
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_cp210x_attach(struct usbh_serial *serial)
+{
+    int ret;
+
+    struct usbh_cp210x *cp210x_class = usb_osal_malloc(sizeof(struct usbh_cp210x));
+    if (!cp210x_class) {
+        return -USB_ERR_NOMEM;
+    }
+    memset(cp210x_class, 0, sizeof(struct usbh_cp210x));
+    serial->priv = cp210x_class;
+
+    ret = usbh_cp210x_get_partnum(serial);
+    usbh_cp210x_init_max_speed(serial);
+    ret |= usbh_cp210x_enable(serial);
+    ret |= usbh_cp210x_set_chars(serial);
+    if (ret < 0) {
+        goto errout;
+    }
+    return 0;
+errout:
+    serial->priv = NULL;
+    usb_osal_free(cp210x_class);
+    return ret;
+}
+
+static void usbh_cp210x_detach(struct usbh_serial *serial)
+{
+    if (serial && serial->priv) {
+        serial->priv = NULL;
+        usb_osal_free(serial->priv);
+    }
+}
+
+int usbh_cp210x_set_flow_ctrl(struct usbh_serial *serial, bool enable)
+{
+    struct cp210x_flow_ctl flow_ctl = { 0 };
+    uint32_t flow_repl;
+    uint32_t ctl_hs;
+    int ret;
+
+    ret = usbh_cp210x_control_in(serial, CP210X_GET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl));
+    if (ret < 0) {
+        return ret;
+    }
+
+    ctl_hs = flow_ctl.lControlHandshake;
+    flow_repl = flow_ctl.lFlowReplace;
+
+    ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE;
+    ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE;
+    ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY;
+    ctl_hs &= ~CP210X_SERIAL_DTR_MASK;
+    ctl_hs |= CP210X_SERIAL_DTR_INACTIVE;
+
+    flow_repl &= ~CP210X_SERIAL_RTS_MASK;
+    flow_repl &= ~CP210X_SERIAL_AUTO_RECEIVE;
+    flow_repl &= ~CP210X_SERIAL_AUTO_TRANSMIT;
+    flow_repl |= CP210X_SERIAL_RTS_INACTIVE;
+
+    flow_repl &= ~CP210X_SERIAL_RTS_MASK;
+    if (enable) {
+        ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE;
+    } else {
+        ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE;
+    }
+    flow_ctl.lControlHandshake = ctl_hs;
+    flow_ctl.lFlowReplace = flow_repl;
+
+    return usbh_cp210x_control_out(serial, CP210X_SET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl));
+}
+
+int usbh_cp210x_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    int ret;
+
+    ret = usbh_cp210x_set_baudrate(serial, line_coding->dwDTERate);
+    if (ret < 0) {
+        return ret;
+    }
+    return usbh_cp210x_set_data_format(serial, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat);
+}
+
+int usbh_cp210x_set_line_state(struct usbh_serial *serial, bool dtr, bool rts)
+{
+    struct cp210x_flow_ctl flow_ctl = { 0 };
+    uint32_t flow_repl;
+    uint32_t ctl_hs;
+    uint16_t control = 0;
+    int ret;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->rtscts) {
+        ret = usbh_cp210x_control_in(serial, CP210X_GET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl));
+        if (ret < 0) {
+            return ret;
+        }
+        ctl_hs = flow_ctl.lControlHandshake;
+        flow_repl = flow_ctl.lFlowReplace;
+
+        ctl_hs &= ~CP210X_SERIAL_DTR_MASK;
+        if (dtr)
+            ctl_hs |= CP210X_SERIAL_DTR_ACTIVE;
+        else
+            ctl_hs |= CP210X_SERIAL_DTR_INACTIVE;
+
+        flow_repl &= ~CP210X_SERIAL_RTS_MASK;
+        if (rts)
+            flow_repl |= CP210X_SERIAL_RTS_FLOW_CTL;
+        else
+            flow_repl |= CP210X_SERIAL_RTS_INACTIVE;
+
+        flow_ctl.lControlHandshake = ctl_hs;
+        flow_ctl.lFlowReplace = flow_repl;
+
+        return usbh_cp210x_control_out(serial, CP210X_SET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl));
+    } else {
+        if (dtr) {
+            control |= CP210X_CONTROL_DTR;
+        }
+        if (rts) {
+            control |= CP210X_CONTROL_RTS;
+        }
+        control |= CP210X_CONTROL_WRITE_DTR;
+        control |= CP210X_CONTROL_WRITE_RTS;
+        return usbh_cp210x_control_out(serial, CP210X_SET_MHS, control, serial->intf, NULL, 0);
+    }
+}
+
+static int usbh_cp210x_get_modem_status(struct usbh_serial *serial)
+{
+    int ret;
+    uint8_t control;
+    uint16_t status;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+
+    ret = usbh_cp210x_control_in(serial, CP210X_GET_MDMSTS, 0, serial->intf, (uint8_t *)&control, 1);
+    if (ret < 0) {
+        return ret;
+    }
+
+    status = ((control & CP210X_CONTROL_DTR) ? USBH_SERIAL_TIOCM_DTR : 0) |
+             ((control & CP210X_CONTROL_RTS) ? USBH_SERIAL_TIOCM_RTS : 0) |
+             ((control & CP210X_CONTROL_CTS) ? USBH_SERIAL_TIOCM_CTS : 0) |
+             ((control & CP210X_CONTROL_DSR) ? USBH_SERIAL_TIOCM_DSR : 0) |
+             ((control & CP210X_CONTROL_RING) ? USBH_SERIAL_TIOCM_RI : 0) |
+             ((control & CP210X_CONTROL_DCD) ? USBH_SERIAL_TIOCM_CD : 0);
+
+    return status;
+}
+
+static const struct usbh_serial_driver cp210x_driver = {
+    .driver_name = "cp210x",
+
+    .ignore_rx_header = 0,
+    .ignore_tx_header = 0,
+
+    .attach = usbh_cp210x_attach,
+    .detach = usbh_cp210x_detach,
+    .set_flow_control = usbh_cp210x_set_flow_ctrl,
+    .set_line_coding = usbh_cp210x_set_line_coding,
+    .get_line_coding = NULL,
+    .set_line_state = usbh_cp210x_set_line_state,
+    .get_modem_status = usbh_cp210x_get_modem_status,
+};
+
+static int usbh_cp210x_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+    return usbh_serial_probe(hport, intf, &cp210x_driver) ? 0 : -USB_ERR_NOMEM;
+}
+
+static int usbh_cp210x_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+    struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv;
+
+    if (serial) {
+        usbh_serial_remove(serial);
+    }
+    return 0;
+}
+
+static const uint16_t cp210x_id_table[][2] = {
+    { 0x10C4, 0xEA60 },
+    { 0, 0 },
+};
+
+const struct usbh_class_driver cp210x_class_driver = {
+    .driver_name = "cp210x",
+    .connect = usbh_cp210x_connect,
+    .disconnect = usbh_cp210x_disconnect
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = {
+    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
+    .bInterfaceClass = 0xff,
+    .bInterfaceSubClass = 0x00,
+    .bInterfaceProtocol = 0x00,
+    .id_table = cp210x_id_table,
+    .class_driver = &cp210x_class_driver
+};

+ 187 - 0
components/drivers/usb/cherryusb/class/serial/usbh_cp210x.h

@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_CP210X_H
+#define USBH_CP210X_H
+
+#include "usb_cdc.h"
+
+/* Requests */
+#define CP210X_IFC_ENABLE      0x00
+#define CP210X_SET_BAUDDIV     0x01
+#define CP210X_GET_BAUDDIV     0x02
+#define CP210X_SET_LINE_CTL    0x03 // Set parity, data bits, stop bits
+#define CP210X_GET_LINE_CTL    0x04
+#define CP210X_SET_BREAK       0x05
+#define CP210X_IMM_CHAR        0x06
+#define CP210X_SET_MHS         0x07 // Set DTR, RTS
+#define CP210X_GET_MDMSTS      0x08
+#define CP210X_SET_XON         0x09
+#define CP210X_SET_XOFF        0x0A
+#define CP210X_SET_EVENTMASK   0x0B
+#define CP210X_GET_EVENTMASK   0x0C
+#define CP210X_SET_CHAR        0x0D
+#define CP210X_GET_CHARS       0x0E
+#define CP210X_GET_PROPS       0x0F
+#define CP210X_GET_COMM_STATUS 0x10
+#define CP210X_RESET           0x11
+#define CP210X_PURGE           0x12
+#define CP210X_SET_FLOW        0x13
+#define CP210X_GET_FLOW        0x14
+#define CP210X_EMBED_EVENTS    0x15
+#define CP210X_GET_EVENTSTATE  0x16
+#define CP210X_SET_CHARS       0x19
+#define CP210X_GET_BAUDRATE    0x1D
+#define CP210X_SET_BAUDRATE    0x1E // Set baudrate
+#define CP210X_VENDOR_SPECIFIC 0xFF
+
+/* CP210X_VENDOR_SPECIFIC values */
+#define CP210X_GET_FW_VER     0x000E
+#define CP210X_READ_2NCONFIG  0x000E
+#define CP210X_GET_FW_VER_2N  0x0010
+#define CP210X_READ_LATCH     0x00C2
+#define CP210X_GET_PARTNUM    0x370B
+#define CP210X_GET_PORTCONFIG 0x370C
+#define CP210X_GET_DEVICEMODE 0x3711
+#define CP210X_WRITE_LATCH    0x37E1
+
+/* CP210X_IFC_ENABLE */
+#define CP210X_UART_ENABLE  0x0001
+#define CP210X_UART_DISABLE 0x0000
+
+/* CP210X_(SET|GET)_BAUDDIV */
+#define CP210X_BAUD_RATE_GEN_FREQ 0x384000
+
+/* CP210X_(SET|GET)_LINE_CTL */
+#define CP210X_BITS_DATA_MASK 0X0f00
+#define CP210X_BITS_DATA_5    0X0500
+#define CP210X_BITS_DATA_6    0X0600
+#define CP210X_BITS_DATA_7    0X0700
+#define CP210X_BITS_DATA_8    0X0800
+#define CP210X_BITS_DATA_9    0X0900
+
+#define CP210X_BITS_PARITY_MASK  0x00f0
+#define CP210X_BITS_PARITY_NONE  0x0000
+#define CP210X_BITS_PARITY_ODD   0x0010
+#define CP210X_BITS_PARITY_EVEN  0x0020
+#define CP210X_BITS_PARITY_MARK  0x0030
+#define CP210X_BITS_PARITY_SPACE 0x0040
+
+#define CP210X_BITS_STOP_MASK 0x000f
+#define CP210X_BITS_STOP_1    0x0000
+#define CP210X_BITS_STOP_1_5  0x0001
+#define CP210X_BITS_STOP_2    0x0002
+
+/* CP210X_SET_BREAK */
+#define CP210X_BREAK_ON  0x0001
+#define CP210X_BREAK_OFF 0x0000
+
+/* CP210X_(SET_MHS|GET_MDMSTS) */
+#define CP210X_CONTROL_DTR       0x0001
+#define CP210X_CONTROL_RTS       0x0002
+#define CP210X_CONTROL_CTS       0x0010
+#define CP210X_CONTROL_DSR       0x0020
+#define CP210X_CONTROL_RING      0x0040
+#define CP210X_CONTROL_DCD       0x0080
+#define CP210X_CONTROL_WRITE_DTR 0x0100
+#define CP210X_CONTROL_WRITE_RTS 0x0200
+
+/* CP210X_(GET|SET)_CHARS */
+struct cp210x_special_chars {
+    uint8_t bEofChar;
+    uint8_t bErrorChar;
+    uint8_t bBreakChar;
+    uint8_t bEventChar;
+    uint8_t bXonChar;
+    uint8_t bXoffChar;
+};
+
+/* CP210X_GET_COMM_STATUS returns these 0x13 bytes */
+struct cp210x_comm_status {
+    uint32_t ulErrors;
+    uint32_t ulHoldReasons;
+    uint32_t ulAmountInInQueue;
+    uint32_t ulAmountInOutQueue;
+    uint8_t bEofReceived;
+    uint8_t bWaitForImmediate;
+    uint8_t bReserved;
+} __PACKED;
+
+/*
+ * CP210X_PURGE - 16 bits passed in wValue of USB request.
+ * SiLabs app note AN571 gives a strange description of the 4 bits:
+ * bit 0 or bit 2 clears the transmit queue and 1 or 3 receive.
+ * writing 1 to all, however, purges cp2108 well enough to avoid the hang.
+ */
+#define PURGE_ALL 0x000f
+
+/* CP210X_EMBED_EVENTS */
+#define CP210X_ESCCHAR 0xec
+
+#define CP210X_LSR_OVERRUN BIT(1)
+#define CP210X_LSR_PARITY  BIT(2)
+#define CP210X_LSR_FRAME   BIT(3)
+#define CP210X_LSR_BREAK   BIT(4)
+
+/* CP210X_GET_FLOW/CP210X_SET_FLOW read/write these 0x10 bytes */
+struct cp210x_flow_ctl {
+    uint32_t lControlHandshake;
+    uint32_t lFlowReplace;
+    uint32_t lXonLimit;
+    uint32_t lXoffLimit;
+};
+
+/* cp210x_flow_ctl::ulControlHandshake */
+#define CP210X_SERIAL_DTR_MASK        (0x03 << 0)
+#define CP210X_SERIAL_DTR_INACTIVE    (0 << 0)
+#define CP210X_SERIAL_DTR_ACTIVE      (1 << 0)
+#define CP210X_SERIAL_DTR_FLOW_CTL    (2 << 0)
+#define CP210X_SERIAL_CTS_HANDSHAKE   BIT(3)
+#define CP210X_SERIAL_DSR_HANDSHAKE   BIT(4)
+#define CP210X_SERIAL_DCD_HANDSHAKE   BIT(5)
+#define CP210X_SERIAL_DSR_SENSITIVITY BIT(6)
+
+/* cp210x_flow_ctl::ulFlowReplace */
+#define CP210X_SERIAL_AUTO_TRANSMIT  BIT(0)
+#define CP210X_SERIAL_AUTO_RECEIVE   BIT(1)
+#define CP210X_SERIAL_ERROR_CHAR     BIT(2)
+#define CP210X_SERIAL_NULL_STRIPPING BIT(3)
+#define CP210X_SERIAL_BREAK_CHAR     BIT(4)
+#define CP210X_SERIAL_RTS_MASK       (0x03 << 6)
+#define CP210X_SERIAL_RTS_INACTIVE   (0 << 6)
+#define CP210X_SERIAL_RTS_ACTIVE     (1 << 6)
+#define CP210X_SERIAL_RTS_FLOW_CTL   (2 << 6)
+#define CP210X_SERIAL_XOFF_CONTINUE  BIT(31)
+
+/* CP210X_VENDOR_SPECIFIC, CP210X_GET_DEVICEMODE call reads these 0x2 bytes. */
+struct cp210x_pin_mode {
+    uint8_t eci;
+    uint8_t sci;
+};
+
+#define CP210X_PIN_MODE_MODEM 0
+#define CP210X_PIN_MODE_GPIO  BIT(0)
+
+/* Part number definitions */
+#define CP210X_PARTNUM_CP2101        0x01
+#define CP210X_PARTNUM_CP2102        0x02
+#define CP210X_PARTNUM_CP2103        0x03
+#define CP210X_PARTNUM_CP2104        0x04
+#define CP210X_PARTNUM_CP2105        0x05
+#define CP210X_PARTNUM_CP2108        0x08
+#define CP210X_PARTNUM_CP2102N_QFN28 0x20
+#define CP210X_PARTNUM_CP2102N_QFN24 0x21
+#define CP210X_PARTNUM_CP2102N_QFN20 0x22
+#define CP210X_PARTNUM_UNKNOWN       0xFF
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_CP210X_H */

+ 407 - 0
components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c

@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_serial.h"
+#include "usbh_ftdi.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_ftdi"
+#include "usb_log.h"
+
+enum ftdi_chip_type {
+    SIO,
+    FT232A,
+    FT232B,
+    FT2232C,
+    FT232R,
+    FT232H,
+    FT2232H,
+    FT4232H,
+    FT4232HA,
+    FT232HP,
+    FT233HP,
+    FT2232HP,
+    FT2233HP,
+    FT4232HP,
+    FT4233HP,
+    FTX,
+};
+
+static const char *ftdi_chip_name[] = {
+    [SIO] = "SIO", /* the serial part of FT8U100AX */
+    [FT232A] = "FT232A",
+    [FT232B] = "FT232B",
+    [FT2232C] = "FT2232C/D",
+    [FT232R] = "FT232R",
+    [FT232H] = "FT232H",
+    [FT2232H] = "FT2232H",
+    [FT4232H] = "FT4232H",
+    [FT4232HA] = "FT4232HA",
+    [FT232HP] = "FT232HP",
+    [FT233HP] = "FT233HP",
+    [FT2232HP] = "FT2232HP",
+    [FT2233HP] = "FT2233HP",
+    [FT4232HP] = "FT4232HP",
+    [FT4233HP] = "FT4233HP",
+    [FTX] = "FT-X",
+};
+
+struct usbh_ftdi {
+    enum ftdi_chip_type chip_type;
+};
+
+static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, int base)
+{
+    static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
+    uint32_t divisor;
+    /* divisor shifted 3 bits to the left */
+    int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud);
+    divisor = divisor3 >> 3;
+    divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14;
+    /* Deal with special cases for highest baud rates. */
+    if (divisor == 1) /* 1.0 */
+        divisor = 0;
+    else if (divisor == 0x4001) /* 1.5 */
+        divisor = 1;
+    return divisor;
+}
+
+static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud)
+{
+    return ftdi_232bm_baud_base_to_divisor(baud, 48000000);
+}
+
+static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, int base)
+{
+    static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
+    uint32_t divisor;
+    int divisor3;
+
+    /* hi-speed baud rate is 10-bit sampling instead of 16-bit */
+    divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud);
+
+    divisor = divisor3 >> 3;
+    divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14;
+    /* Deal with special cases for highest baud rates. */
+    if (divisor == 1) /* 1.0 */
+        divisor = 0;
+    else if (divisor == 0x4001) /* 1.5 */
+        divisor = 1;
+    /*
+     * Set this bit to turn off a divide by 2.5 on baud rate generator
+     * This enables baud rates up to 12Mbaud but cannot reach below 1200
+     * baud with this bit set
+     */
+    divisor |= 0x00020000;
+    return divisor;
+}
+
+static uint32_t ftdi_2232h_baud_to_divisor(uint32_t baud)
+{
+    return ftdi_2232h_baud_base_to_divisor(baud, 120000000);
+}
+
+int usbh_ftdi_reset(struct usbh_serial *serial)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = FTDI_SIO_RESET;
+    setup->wValue = 0;
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_ftdi_set_baudrate(struct usbh_serial *serial, uint32_t baudrate)
+{
+    struct usb_setup_packet *setup;
+    struct usbh_ftdi *ftdi_class;
+    uint32_t div_value;
+    uint16_t value;
+    uint8_t baudrate_high;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+    ftdi_class = (struct usbh_ftdi *)serial->priv;
+
+    switch (ftdi_class->chip_type) {
+        case FT232B:
+        case FT2232C:
+        case FT232R:
+            if (baudrate > 3000000) {
+                return -USB_ERR_INVAL;
+            }
+            div_value = ftdi_232bm_baud_to_divisor(baudrate);
+            break;
+        default:
+            if ((baudrate <= 12000000) && (baudrate >= 1200)) {
+                div_value = ftdi_2232h_baud_to_divisor(baudrate);
+            } else if (baudrate < 1200) {
+                div_value = ftdi_232bm_baud_to_divisor(baudrate);
+            } else {
+                return -USB_ERR_INVAL;
+            }
+            break;
+    }
+
+    value = div_value & 0xFFFF;
+    baudrate_high = (div_value >> 16) & 0xff;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = FTDI_SIO_SET_BAUDRATE;
+    setup->wValue = value;
+    setup->wIndex = (baudrate_high << 8) | serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_ftdi_set_data_format(struct usbh_serial *serial, uint8_t databits, uint8_t parity, uint8_t stopbits, uint8_t isbreak)
+{
+    /**
+     * D0-D7 databits  BITS_7=7, BITS_8=8
+     * D8-D10 parity  NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4
+     * D11-D12 		STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2
+     * D14  		BREAK_OFF=0, BREAK_ON=1
+     **/
+    struct usb_setup_packet *setup;
+    uint16_t value;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    value = ((isbreak & 0x01) << 14) | ((stopbits & 0x03) << 11) | ((parity & 0x0f) << 8) | (databits & 0x0f);
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = FTDI_SIO_SET_DATA;
+    setup->wValue = value;
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_ftdi_set_latency_timer(struct usbh_serial *serial, uint16_t value)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = FTDI_SIO_SET_LATENCY_TIMER;
+    setup->wValue = value;
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_ftdi_attach(struct usbh_serial *serial)
+{
+    uint16_t version;
+    uint8_t chip_type;
+    int ret;
+
+    version = serial->hport->device_desc.bcdDevice;
+
+    switch (version) {
+        case 0x400:
+            chip_type = FT232B;
+            break;
+        case 0x500:
+            chip_type = FT2232C;
+            break;
+        case 0x600:
+            chip_type = FT232R;
+            break;
+        case 0x700:
+            chip_type = FT2232H;
+            break;
+        case 0x900:
+            chip_type = FT232H;
+            break;
+
+        default:
+            USB_LOG_ERR("Unsupported FTDI chip version: 0x%04x\r\n", version);
+            return -USB_ERR_NOTSUPP;
+    }
+
+    USB_LOG_INFO("chip name: %s\r\n", ftdi_chip_name[chip_type]);
+
+    struct usbh_ftdi *ftdi_class = usb_osal_malloc(sizeof(struct usbh_ftdi));
+    if (!ftdi_class) {
+        USB_LOG_ERR("No memory for ftdi_class\r\n");
+        return -USB_ERR_NOMEM;
+    }
+    memset(ftdi_class, 0, sizeof(struct usbh_ftdi));
+    serial->priv = ftdi_class;
+
+    ftdi_class->chip_type = chip_type;
+    ret = usbh_ftdi_set_latency_timer(serial, 0x10);
+    if (ret < 0) {
+        goto errout;
+    }
+    return 0;
+errout:
+    serial->priv = NULL;
+    usb_osal_free(ftdi_class);
+    return ret;
+}
+
+static void usbh_ftdi_detach(struct usbh_serial *serial)
+{
+    if (serial && serial->priv) {
+        serial->priv = NULL;
+        usb_osal_free(serial->priv);
+    }
+}
+
+static int usbh_ftdi_set_flow_ctrl(struct usbh_serial *serial, bool hardctrl)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = FTDI_SIO_SET_FLOW_CTRL;
+    setup->wValue = hardctrl ? FTDI_SIO_RTS_CTS_HS : FTDI_SIO_DISABLE_FLOW_CTRL;
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_ftdi_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    int ret = usbh_ftdi_set_baudrate(serial, line_coding->dwDTERate);
+    if (ret < 0) {
+        return ret;
+    }
+    return usbh_ftdi_set_data_format(serial, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat, 0);
+}
+
+static int usbh_ftdi_set_line_state(struct usbh_serial *serial, bool dtr, bool rts)
+{
+    struct usb_setup_packet *setup;
+    uint16_t value = 0;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    value = ((dtr ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW) | (rts ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW));
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = FTDI_SIO_SET_MODEM_CTRL;
+    setup->wValue = value;
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_ftdi_get_modem_status(struct usbh_serial *serial)
+{
+    struct usb_setup_packet *setup;
+    uint16_t status = 0;
+    int ret;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = FTDI_SIO_GET_MODEM_STATUS;
+    setup->wValue = 0x0000;
+    setup->wIndex = serial->intf;
+    setup->wLength = 2;
+
+    ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    if (ret < 0) {
+        return 0;
+    }
+
+    status = (serial->iobuffer[0] & FTDI_SIO_DSR_MASK ? USBH_SERIAL_TIOCM_DSR : 0) |
+             (serial->iobuffer[0] & FTDI_SIO_CTS_MASK ? USBH_SERIAL_TIOCM_CTS : 0) |
+             (serial->iobuffer[0] & FTDI_SIO_RI_MASK ? USBH_SERIAL_TIOCM_RI : 0) |
+             (serial->iobuffer[0] & FTDI_SIO_RLSD_MASK ? USBH_SERIAL_TIOCM_CD : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0);
+
+    return status;
+}
+
+static const struct usbh_serial_driver ftdi_driver = {
+    .driver_name = "ftdi",
+
+    .ignore_rx_header = 2,
+    .ignore_tx_header = 0,
+
+    .attach = usbh_ftdi_attach,
+    .detach = usbh_ftdi_detach,
+    .set_flow_control = usbh_ftdi_set_flow_ctrl,
+    .set_line_coding = usbh_ftdi_set_line_coding,
+    .get_line_coding = NULL,
+    .set_line_state = usbh_ftdi_set_line_state,
+    .get_modem_status = usbh_ftdi_get_modem_status,
+};
+
+static int usbh_ftdi_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+    return usbh_serial_probe(hport, intf, &ftdi_driver) ? 0 : -USB_ERR_NOMEM;
+}
+
+static int usbh_ftdi_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+    struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv;
+
+    if (serial) {
+        usbh_serial_remove(serial);
+    }
+    return 0;
+}
+
+static const uint16_t ftdi_id_table[][2] = {
+    { 0x0403, 0x6001 },
+    { 0x0403, 0x6010 },
+    { 0x0403, 0x6014 },
+    { 0, 0 },
+};
+
+const struct usbh_class_driver ftdi_class_driver = {
+    .driver_name = "ftdi",
+    .connect = usbh_ftdi_connect,
+    .disconnect = usbh_ftdi_disconnect
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = {
+    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
+    .bInterfaceClass = 0xff,
+    .bInterfaceSubClass = 0x00,
+    .bInterfaceProtocol = 0x00,
+    .id_table = ftdi_id_table,
+    .class_driver = &ftdi_class_driver
+};

+ 341 - 0
components/drivers/usb/cherryusb/class/serial/usbh_ftdi.h

@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_FTDI_H
+#define USBH_FTDI_H
+
+#include "usb_cdc.h"
+
+#define FTDI_VID 0x0403 /* Vendor Id */
+
+/* FTDI device PIDs */
+#define FTDI_8U232AM_PID     0x6001 /* Similar device to SIO above */
+#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
+#define FTDI_8U2232C_PID     0x6010 /* Dual channel device */
+#define FTDI_4232H_PID       0x6011 /* Quad channel hi-speed device */
+#define FTDI_232H_PID        0x6014 /* Single channel hi-speed device */
+#define FTDI_FTX_PID         0x6015 /* FT-X series (FT201X, FT230X, FT231X, etc) */
+#define FTDI_FT2233HP_PID    0x6040 /* Dual channel hi-speed device with PD */
+#define FTDI_FT4233HP_PID    0x6041 /* Quad channel hi-speed device with PD */
+#define FTDI_FT2232HP_PID    0x6042 /* Dual channel hi-speed device with PD */
+#define FTDI_FT4232HP_PID    0x6043 /* Quad channel hi-speed device with PD */
+#define FTDI_FT233HP_PID     0x6044 /* Dual channel hi-speed device with PD */
+#define FTDI_FT232HP_PID     0x6045 /* Dual channel hi-speed device with PD */
+#define FTDI_FT4232HA_PID    0x6048 /* Quad channel automotive grade hi-speed device */
+#define FTDI_SIO_PID         0x8372 /* Product Id SIO application of 8U100AX */
+#define FTDI_232RL_PID       0xFBFA /* Product ID for FT232RL */
+
+/* Requests */
+#define FTDI_SIO_RESET             0x00 /* Reset the port */
+#define FTDI_SIO_SET_MODEM_CTRL    0x01 /* Set the modem control register */
+#define FTDI_SIO_SET_FLOW_CTRL     0x02 /* Set flow control register */
+#define FTDI_SIO_SET_BAUDRATE      0x03 /* Set baud rate */
+#define FTDI_SIO_SET_DATA          0x04 /* Set the data characteristics of the port */
+#define FTDI_SIO_GET_MODEM_STATUS  0x05
+#define FTDI_SIO_SET_EVENT_CHAR    0x06
+#define FTDI_SIO_SET_ERROR_CHAR    0x07
+#define FTDI_SIO_SET_LATENCY_TIMER 0x09
+#define FTDI_SIO_GET_LATENCY_TIMER 0x0A
+#define FTDI_SIO_SET_BITMODE       0x0B
+#define FTDI_SIO_READ_PINS         0x0C
+#define FTDI_SIO_READ_EEPROM       0x90
+#define FTDI_SIO_WRITE_EEPROM      0x91
+#define FTDI_SIO_ERASE_EEPROM      0x92
+
+/* Channel indices for FT2232, FT2232H and FT4232H devices */
+#define FTDI_SIO_CHANNEL_A 1
+#define FTDI_SIO_CHANNEL_B 2
+#define FTDI_SIO_CHANNEL_C 3
+#define FTDI_SIO_CHANNEL_D 4
+
+/*
+ * BmRequestType:  0100 0000B
+ * bRequest:       FTDI_SIO_RESET
+ * wValue:         Control Value
+ *                   0 = Reset SIO
+ *                   1 = Purge RX buffer
+ *                   2 = Purge TX buffer
+ * wIndex:         Port
+ * wLength:        0
+ * Data:           None
+ *
+ * The Reset SIO command has this effect:
+ *
+ *    Sets flow control set to 'none'
+ *    Event char = $0D
+ *    Event trigger = disabled
+ *    Purge RX buffer
+ *    Purge TX buffer
+ *    Clear DTR
+ *    Clear RTS
+ *    baud and data format not reset
+ *
+ * The Purge RX and TX buffer commands affect nothing except the buffers
+ *
+   */
+
+#define FTDI_SIO_RESET_SIO      0
+#define FTDI_SIO_RESET_PURGE_RX 1
+#define FTDI_SIO_RESET_PURGE_TX 2
+
+/*
+ * BmRequestType:  0100 0000B
+ * bRequest:       FTDI_SIO_SET_BAUDRATE
+ * wValue:         BaudDivisor value - see below
+ * wIndex:         Port
+ * wLength:        0
+ * Data:           None
+ * The BaudDivisor values are calculated as follows:
+ * - BaseClock is either 12000000 or 48000000 depending on the device.
+ *   FIXME: I wish I knew how to detect old chips to select proper base clock!
+ * - BaudDivisor is a fixed point number encoded in a funny way.
+ *   (--WRONG WAY OF THINKING--)
+ *   BaudDivisor is a fixed point number encoded with following bit weighs:
+ *   (-2)(-1)(13..0). It is a radical with a denominator of 4, so values
+ *   end with 0.0 (00...), 0.25 (10...), 0.5 (01...), and 0.75 (11...).
+ *   (--THE REALITY--)
+ *   The both-bits-set has quite different meaning from 0.75 - the chip
+ *   designers have decided it to mean 0.125 instead of 0.75.
+ *   This info looked up in FTDI application note "FT8U232 DEVICES \ Data Rates
+ *   and Flow Control Consideration for USB to RS232".
+ * - BaudDivisor = (BaseClock / 16) / BaudRate, where the (=) operation should
+ *   automagically re-encode the resulting value to take fractions into
+ *   consideration.
+ * As all values are integers, some bit twiddling is in order:
+ *   BaudDivisor = (BaseClock / 16 / BaudRate) |
+ *   (((BaseClock / 2 / BaudRate) & 4) ? 0x4000    // 0.5
+ *    : ((BaseClock / 2 / BaudRate) & 2) ? 0x8000  // 0.25
+ *    : ((BaseClock / 2 / BaudRate) & 1) ? 0xc000  // 0.125
+ *    : 0)
+ *
+ * For the FT232BM, a 17th divisor bit was introduced to encode the multiples
+ * of 0.125 missing from the FT8U232AM.  Bits 16 to 14 are coded as follows
+ * (the first four codes are the same as for the FT8U232AM, where bit 16 is
+ * always 0):
+ *   000 - add .000 to divisor
+ *   001 - add .500 to divisor
+ *   010 - add .250 to divisor
+ *   011 - add .125 to divisor
+ *   100 - add .375 to divisor
+ *   101 - add .625 to divisor
+ *   110 - add .750 to divisor
+ *   111 - add .875 to divisor
+ * Bits 15 to 0 of the 17-bit divisor are placed in the urb value.  Bit 16 is
+ * placed in bit 0 of the urb index.
+ *
+ * Note that there are a couple of special cases to support the highest baud
+ * rates.  If the calculated divisor value is 1, this needs to be replaced with
+ * 0.  Additionally for the FT232BM, if the calculated divisor value is 0x4001
+ * (1.5), this needs to be replaced with 0x0001 (1) (but this divisor value is
+ * not supported by the FT8U232AM).
+ */
+
+enum ftdi_sio_baudrate {
+    ftdi_sio_b300 = 0,
+    ftdi_sio_b600 = 1,
+    ftdi_sio_b1200 = 2,
+    ftdi_sio_b2400 = 3,
+    ftdi_sio_b4800 = 4,
+    ftdi_sio_b9600 = 5,
+    ftdi_sio_b19200 = 6,
+    ftdi_sio_b38400 = 7,
+    ftdi_sio_b57600 = 8,
+    ftdi_sio_b115200 = 9
+};
+
+/*
+ * BmRequestType:  0100 0000B
+ * bRequest:       FTDI_SIO_SET_DATA
+ * wValue:         Data characteristics (see below)
+ * wIndex:         Port
+ * wLength:        0
+ * Data:           No
+ *
+ * Data characteristics
+ *
+ *   B0..7   Number of data bits
+ *   B8..10  Parity
+ *           0 = None
+ *           1 = Odd
+ *           2 = Even
+ *           3 = Mark
+ *           4 = Space
+ *   B11..13 Stop Bits
+ *           0 = 1
+ *           1 = 1.5
+ *           2 = 2
+ *   B14
+ *           1 = TX ON (break)
+ *           0 = TX OFF (normal state)
+ *   B15 Reserved
+ *
+ */
+
+#define FTDI_SIO_SET_DATA_PARITY_NONE  (0x0 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_ODD   (0x1 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_EVEN  (0x2 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_MARK  (0x3 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
+#define FTDI_SIO_SET_DATA_STOP_BITS_1  (0x0 << 11)
+#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
+#define FTDI_SIO_SET_DATA_STOP_BITS_2  (0x2 << 11)
+#define FTDI_SIO_SET_BREAK             (0x1 << 14)
+
+/*
+ * BmRequestType:   0100 0000B
+ * bRequest:        FTDI_SIO_MODEM_CTRL
+ * wValue:          ControlValue (see below)
+ * wIndex:          Port
+ * wLength:         0
+ * Data:            None
+ *
+ * NOTE: If the device is in RTS/CTS flow control, the RTS set by this
+ * command will be IGNORED without an error being returned
+ * Also - you can not set DTR and RTS with one control message
+ *
+ * ControlValue
+ * B0    DTR state
+ *          0 = reset
+ *          1 = set
+ * B1    RTS state
+ *          0 = reset
+ *          1 = set
+ * B2..7 Reserved
+ * B8    DTR state enable
+ *          0 = ignore
+ *          1 = use DTR state
+ * B9    RTS state enable
+ *          0 = ignore
+ *          1 = use RTS state
+ * B10..15 Reserved
+ *
+ */
+
+#define FTDI_SIO_SET_DTR_MASK 0x1
+#define FTDI_SIO_SET_DTR_HIGH ((FTDI_SIO_SET_DTR_MASK << 8) | 1)
+#define FTDI_SIO_SET_DTR_LOW  ((FTDI_SIO_SET_DTR_MASK << 8) | 0)
+#define FTDI_SIO_SET_RTS_MASK 0x2
+#define FTDI_SIO_SET_RTS_HIGH ((FTDI_SIO_SET_RTS_MASK << 8) | 2)
+#define FTDI_SIO_SET_RTS_LOW  ((FTDI_SIO_SET_RTS_MASK << 8) | 0)
+
+/*
+ *   BmRequestType:  0100 0000b
+ *   bRequest:       FTDI_SIO_SET_FLOW_CTRL
+ *   wValue:         Xoff/Xon
+ *   wIndex:         Protocol/Port - hIndex is protocol / lIndex is port
+ *   wLength:        0
+ *   Data:           None
+ *
+ * hIndex protocol is:
+ *   B0 Output handshaking using RTS/CTS
+ *       0 = disabled
+ *       1 = enabled
+ *   B1 Output handshaking using DTR/DSR
+ *       0 = disabled
+ *       1 = enabled
+ *   B2 Xon/Xoff handshaking
+ *       0 = disabled
+ *       1 = enabled
+ *
+ * A value of zero in the hIndex field disables handshaking
+ *
+ * If Xon/Xoff handshaking is specified, the hValue field should contain the
+ * XOFF character and the lValue field contains the XON character.
+ */
+
+#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
+#define FTDI_SIO_RTS_CTS_HS        (0x1 << 8)
+#define FTDI_SIO_DTR_DSR_HS        (0x2 << 8)
+#define FTDI_SIO_XON_XOFF_HS       (0x4 << 8)
+
+/*
+ *   BmRequestType:   1100 0000b
+ *   bRequest:        FTDI_SIO_GET_MODEM_STATUS
+ *   wValue:          zero
+ *   wIndex:          Port
+ *   wLength:         1
+ *   Data:            Status
+ *
+ * One byte of data is returned
+ * B0..3 0
+ * B4    CTS
+ *         0 = inactive
+ *         1 = active
+ * B5    DSR
+ *         0 = inactive
+ *         1 = active
+ * B6    Ring Indicator (RI)
+ *         0 = inactive
+ *         1 = active
+ * B7    Receive Line Signal Detect (RLSD)
+ *         0 = inactive
+ *         1 = active
+ */
+
+#define FTDI_SIO_CTS_MASK  0x10
+#define FTDI_SIO_DSR_MASK  0x20
+#define FTDI_SIO_RI_MASK   0x40
+#define FTDI_SIO_RLSD_MASK 0x80
+
+/* Possible bitmodes for FTDI_SIO_SET_BITMODE_REQUEST */
+#define FTDI_SIO_BITMODE_RESET 0x00
+#define FTDI_SIO_BITMODE_CBUS  0x20
+
+/*
+ * IN Endpoint
+ *
+ * The device reserves the first two bytes of data on this endpoint to contain
+ * the current values of the modem and line status registers. In the absence of
+ * data, the device generates a message consisting of these two status bytes
+ * every 40 ms
+ *
+ * Byte 0: Modem Status
+ *
+ * Offset	Description
+ * B0	Reserved - must be 1
+ * B1	Reserved - must be 0
+ * B2	Reserved - must be 0
+ * B3	Reserved - must be 0
+ * B4	Clear to Send (CTS)
+ * B5	Data Set Ready (DSR)
+ * B6	Ring Indicator (RI)
+ * B7	Receive Line Signal Detect (RLSD)
+ *
+ * Byte 1: Line Status
+ *
+ * Offset	Description
+ * B0	Data Ready (DR)
+ * B1	Overrun Error (OE)
+ * B2	Parity Error (PE)
+ * B3	Framing Error (FE)
+ * B4	Break Interrupt (BI)
+ * B5	Transmitter Holding Register (THRE)
+ * B6	Transmitter Empty (TEMT)
+ * B7	Error in RCVR FIFO
+ *
+ */
+#define FTDI_RS0_CTS  (1 << 4)
+#define FTDI_RS0_DSR  (1 << 5)
+#define FTDI_RS0_RI   (1 << 6)
+#define FTDI_RS0_RLSD (1 << 7)
+
+#define FTDI_RS_DR   1
+#define FTDI_RS_OE   (1 << 1)
+#define FTDI_RS_PE   (1 << 2)
+#define FTDI_RS_FE   (1 << 3)
+#define FTDI_RS_BI   (1 << 4)
+#define FTDI_RS_THRE (1 << 5)
+#define FTDI_RS_TEMT (1 << 6)
+#define FTDI_RS_FIFO (1 << 7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_FTDI_H */

+ 131 - 0
components/drivers/usb/cherryusb/class/serial/usbh_gsm.c

@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_serial.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_gsm"
+#include "usb_log.h"
+
+struct usbh_gsm {
+    struct usb_endpoint_descriptor *intin;
+    struct usbh_urb intin_urb;
+    struct usb_osal_timer *modem_timer;
+    uint16_t modem_status;
+};
+
+static int usbh_gsm_attach(struct usbh_serial *serial)
+{
+    struct usb_endpoint_descriptor *ep_desc;
+
+    struct usbh_gsm *gsm_class = usb_osal_malloc(sizeof(struct usbh_gsm));
+    if (!gsm_class) {
+        USB_LOG_ERR("No memory for gsm_class\r\n");
+        return -USB_ERR_NOMEM;
+    }
+    memset(gsm_class, 0, sizeof(struct usbh_gsm));
+    serial->priv = gsm_class;
+
+    for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
+        ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc;
+
+        if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
+            if (ep_desc->bEndpointAddress & 0x80) {
+                USBH_EP_INIT(gsm_class->intin, ep_desc);
+                break;
+            } else {
+            }
+        }
+    }
+
+    if (!gsm_class->intin) {
+        USB_LOG_WRN("Do not find interrupt endpoint, so disable modem status monitor\r\n");
+    }
+    return 0;
+}
+
+static void usbh_gsm_detach(struct usbh_serial *serial)
+{
+    struct usbh_gsm *gsm_class;
+
+    if (!serial || !serial->priv) {
+        return;
+    }
+
+    gsm_class = (struct usbh_gsm *)serial->priv;
+    if (gsm_class->intin) {
+        usbh_kill_urb(&gsm_class->intin_urb);
+    }
+    serial->priv = NULL;
+    usb_osal_free(gsm_class);
+}
+
+static int usbh_gsm_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    return 0;
+}
+
+static int usbh_gsm_set_line_state(struct usbh_serial *serial, bool dtr, bool rts)
+{
+    return 0;
+}
+
+static const struct usbh_serial_driver gsm_driver = {
+    .driver_name = "gsm",
+
+    .ignore_rx_header = 0,
+    .ignore_tx_header = 0,
+
+    .attach = usbh_gsm_attach,
+    .detach = usbh_gsm_detach,
+    .set_flow_control = NULL,
+    .set_line_coding = usbh_gsm_set_line_coding,
+    .get_line_coding = NULL,
+    .set_line_state = usbh_gsm_set_line_state,
+    .get_modem_status = NULL,
+};
+
+static int usbh_gsm_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+    return usbh_serial_probe(hport, intf, &gsm_driver) ? 0 : -USB_ERR_NOMEM;
+}
+
+static int usbh_gsm_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+    struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv;
+
+    if (serial) {
+        usbh_serial_remove(serial);
+    }
+    return 0;
+}
+
+const struct usbh_class_driver gsm_class_driver = {
+    .driver_name = "gsm",
+    .connect = usbh_gsm_connect,
+    .disconnect = usbh_gsm_disconnect
+};
+
+static const uint16_t gsm_id_table[][2] = {
+    { 0x2C7C, 0x0120 }, /* Quectel EC20 */
+    { 0x2C7C, 0x0121 }, /* Quectel EC21 */
+    { 0x2C7C, 0x0125 }, /* Quectel EC25 */
+    { 0x2C7C, 0x0191 }, /* Quectel EG91 */
+    { 0x2C7C, 0x0195 }, /* Quectel EG95 */
+    { 0x2C7C, 0x6002 }, /* Quectel EC200/EC600/EC800/EG91x */
+    { 0x1E0E, 0x9001 }, /* SIMCOM SIM7600 */
+    { 0x2ECC, 0x3012 }, /* Chinamobile ML307R */
+    { 0, 0 },
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info gsm_class_info = {
+    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
+    .bInterfaceClass = 0xff,
+    .bInterfaceSubClass = 0x00,
+    .bInterfaceProtocol = 0x00,
+    .id_table = gsm_id_table,
+    .class_driver = &gsm_class_driver
+};

+ 726 - 0
components/drivers/usb/cherryusb/class/serial/usbh_pl2303.c

@@ -0,0 +1,726 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ * Copyright (c) 2024, Derek Konigsberg
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_serial.h"
+#include "usbh_pl2303.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_pl2303"
+#include "usb_log.h"
+
+#define UART_STATE_INDEX          8
+#define UART_STATE_MSR_MASK       0x8b
+#define UART_STATE_TRANSIENT_MASK 0x74
+#define UART_DCD                  0x01
+#define UART_DSR                  0x02
+#define UART_BREAK_ERROR          0x04
+#define UART_RING                 0x08
+#define UART_FRAME_ERROR          0x10
+#define UART_PARITY_ERROR         0x20
+#define UART_OVERRUN_ERROR        0x40
+#define UART_CTS                  0x80
+
+struct pl2303_type_data {
+    const char *name;
+    uint32_t max_baud_rate;
+    unsigned long quirks;
+    unsigned int no_autoxonxoff : 1;
+    unsigned int no_divisors    : 1;
+    unsigned int alt_divisors   : 1;
+};
+
+enum pl2303_type {
+    TYPE_H,
+    TYPE_HX,
+    TYPE_TA,
+    TYPE_TB,
+    TYPE_HXD,
+    TYPE_HXN,
+    TYPE_COUNT
+};
+
+struct usbh_pl2303 {
+    enum pl2303_type chip_type;
+    uint32_t quirks;
+    struct usb_endpoint_descriptor *intin;
+    struct usbh_urb intin_urb;
+    struct usb_osal_timer *modem_timer;
+    uint16_t modem_status;
+};
+
+static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
+    [TYPE_H] = {
+        .name = "PL2303H",
+        .max_baud_rate = 1228800,
+        .quirks = PL2303_QUIRK_LEGACY,
+        .no_autoxonxoff = true,
+    },
+    [TYPE_HX] = {
+        .name = "PL2303HX",
+        .max_baud_rate = 6000000,
+    },
+    [TYPE_TA] = {
+        .name = "PL2303TA",
+        .max_baud_rate = 6000000,
+        .alt_divisors = true,
+    },
+    [TYPE_TB] = {
+        .name = "PL2303TB",
+        .max_baud_rate = 12000000,
+        .alt_divisors = true,
+    },
+    [TYPE_HXD] = {
+        .name = "PL2303HXD",
+        .max_baud_rate = 12000000,
+    },
+    [TYPE_HXN] = {
+        .name = "PL2303G",
+        .max_baud_rate = 12000000,
+        .no_divisors = true,
+    },
+};
+
+/*
+ * Returns the nearest supported baud rate that can be set directly without
+ * using divisors.
+ */
+static uint32_t pl2303_get_supported_baud_rate(uint32_t baud)
+{
+    static const uint32_t baud_sup[] = {
+        75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600,
+        14400, 19200, 28800, 38400, 57600, 115200, 230400, 460800,
+        614400, 921600, 1228800, 2457600, 3000000, 6000000
+    };
+
+    unsigned i;
+
+    for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) {
+        if (baud_sup[i] > baud)
+            break;
+    }
+
+    if (i == ARRAY_SIZE(baud_sup))
+        baud = baud_sup[i - 1];
+    else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1]))
+        baud = baud_sup[i - 1];
+    else
+        baud = baud_sup[i];
+
+    return baud;
+}
+
+/*
+ * NOTE: If unsupported baud rates are set directly, the PL2303 seems to
+ *       use 9600 baud.
+ */
+static uint32_t pl2303_encode_baud_rate_direct(unsigned char buf[4],
+                                               uint32_t baud)
+{
+    memcpy(buf, &baud, 4);
+
+    return baud;
+}
+
+static uint32_t pl2303_encode_baud_rate_divisor_alt(unsigned char buf[4],
+                                                    uint32_t baud)
+{
+    unsigned int baseline, mantissa, exponent;
+
+    /*
+     * Apparently, for the TA version the formula is:
+     *   baudrate = 12M * 32 / (mantissa * 2^exponent)
+     * where
+     *   mantissa = buf[10:0]
+     *   exponent = buf[15:13 16]
+     */
+    baseline = 12000000 * 32;
+    mantissa = baseline / baud;
+    if (mantissa == 0)
+        mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */
+    exponent = 0;
+    while (mantissa >= 2048) {
+        if (exponent < 15) {
+            mantissa >>= 1; /* divide by 2 */
+            exponent++;
+        } else {
+            /* Exponent is maxed. Trim mantissa and leave. */
+            mantissa = 2047;
+            break;
+        }
+    }
+
+    buf[3] = 0x80;
+    buf[2] = exponent & 0x01;
+    buf[1] = (exponent & ~0x01) << 4 | mantissa >> 8;
+    buf[0] = mantissa & 0xff;
+
+    /* Calculate and return the exact baud rate. */
+    baud = (baseline / mantissa) >> exponent;
+
+    return baud;
+}
+
+static uint32_t pl2303_encode_baud_rate_divisor(unsigned char buf[4],
+                                                uint32_t baud)
+{
+    unsigned int baseline, mantissa, exponent;
+
+    /*
+    * Apparently the formula is:
+    *   baudrate = 12M * 32 / (mantissa * 4^exponent)
+    * where
+    *   mantissa = buf[8:0]
+    *   exponent = buf[11:9]
+    */
+    baseline = 12000000 * 32;
+    mantissa = baseline / baud;
+    if (mantissa == 0)
+        mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */
+    exponent = 0;
+    while (mantissa >= 512) {
+        if (exponent < 7) {
+            mantissa >>= 2; /* divide by 4 */
+            exponent++;
+        } else {
+            /* Exponent is maxed. Trim mantissa and leave. */
+            mantissa = 511;
+            break;
+        }
+    }
+
+    buf[3] = 0x80;
+    buf[2] = 0;
+    buf[1] = exponent << 1 | mantissa >> 8;
+    buf[0] = mantissa & 0xff;
+
+    /* Calculate and return the exact baud rate. */
+    baud = (baseline / mantissa) >> (exponent << 1);
+
+    return baud;
+}
+
+static int pl2303_vendor_write(struct usbh_serial *serial, uint16_t wValue, uint16_t wIndex)
+{
+    struct usb_setup_packet *setup;
+    struct usbh_pl2303 *pl2303_class;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = pl2303_class->chip_type == TYPE_HXN ? PL2303_VENDOR_WRITE_NREQUEST : PL2303_VENDOR_WRITE_REQUEST;
+    setup->wValue = wValue;
+    setup->wIndex = wIndex;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int pl2303_vendor_read(struct usbh_serial *serial, uint16_t wValue, uint8_t *data)
+{
+    struct usb_setup_packet *setup;
+    struct usbh_pl2303 *pl2303_class;
+    int ret;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+
+    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = pl2303_class->chip_type == TYPE_HXN ? PL2303_VENDOR_READ_NREQUEST : PL2303_VENDOR_READ_REQUEST;
+    setup->wValue = wValue;
+    setup->wIndex = 0;
+    setup->wLength = 1;
+
+    ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(data, serial->iobuffer, 1);
+
+    return ret;
+}
+
+static bool pl2303_supports_hx_status(struct usbh_serial *serial)
+{
+    int ret;
+    uint8_t buf;
+
+    ret = pl2303_vendor_read(serial, PL2303_READ_TYPE_HX_STATUS, &buf);
+    if (ret < 0) {
+        return false;
+    }
+
+    return true;
+}
+
+static bool pl2303_is_hxd_clone(struct usbh_serial *serial)
+{
+    struct usb_setup_packet *setup;
+    int ret;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
+    setup->bRequest = CDC_REQUEST_GET_LINE_CODING;
+    setup->wValue = 0;
+    setup->wIndex = 0;
+    setup->wLength = 7;
+
+    ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    if (ret < 0) {
+        return false;
+    }
+    return true;
+}
+
+static int pl2303_update_reg(struct usbh_serial *serial, uint8_t reg, uint8_t mask, uint8_t val)
+{
+    int ret;
+    uint8_t buf[1];
+    struct usbh_pl2303 *pl2303_class;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+
+    if (pl2303_class->chip_type == TYPE_HXN)
+        ret = pl2303_vendor_read(serial, reg, buf);
+    else
+        ret = pl2303_vendor_read(serial, reg | 0x80, buf);
+
+    if (ret < 0) {
+        return ret;
+    }
+
+    *buf &= ~mask;
+    *buf |= val & mask;
+
+    return pl2303_vendor_write(serial, reg, *buf);
+}
+
+static int usbh_pl2303_get_chiptype(struct usbh_serial *serial)
+{
+    if (serial->hport->device_desc.bDeviceClass == 0x02) {
+        return TYPE_H; /* variant 0 */
+    }
+
+    if (serial->hport->device_desc.bMaxPacketSize0 != 0x40) {
+        if (serial->hport->device_desc.bDeviceClass == 0x00 || serial->hport->device_desc.bDeviceClass == 0xff)
+            return TYPE_H; /* variant 1 */
+
+        return TYPE_H; /* variant 0 */
+    }
+
+    switch (serial->hport->device_desc.bcdUSB) {
+        case 0x101:
+            /* USB 1.0.1? Let's assume they meant 1.1... */
+        case 0x110:
+            switch (serial->hport->device_desc.bcdDevice) {
+                case 0x300:
+                    return TYPE_HX;
+                case 0x400:
+                    return TYPE_HXD;
+                default:
+                    return TYPE_HX;
+            }
+            break;
+        case 0x200:
+            switch (serial->hport->device_desc.bcdDevice) {
+                case 0x100: /* GC */
+                case 0x105:
+                    return TYPE_HXN;
+                case 0x300: /* GT / TA */
+                    if (pl2303_supports_hx_status(serial))
+                        return TYPE_TA;
+                    __attribute__((fallthrough));
+                case 0x305:
+                case 0x400: /* GL */
+                case 0x405:
+                    return TYPE_HXN;
+                case 0x500: /* GE / TB */
+                    if (pl2303_supports_hx_status(serial))
+                        return TYPE_TB;
+                    __attribute__((fallthrough));
+                case 0x505:
+                case 0x600: /* GS */
+                case 0x605:
+                case 0x700: /* GR */
+                case 0x705:
+                case 0x905:  /* GT-2AB */
+                case 0x1005: /* GC-Q20 */
+                    return TYPE_HXN;
+            }
+            break;
+    }
+
+    USB_LOG_ERR("Unsupported PL2303 Device\r\n");
+    return -USB_ERR_NOTSUPP;
+}
+
+static int usbh_pl2303_attach(struct usbh_serial *serial)
+{
+    struct usbh_pl2303 *pl2303_class;
+    struct usb_endpoint_descriptor *ep_desc;
+    uint8_t type;
+    int ret;
+
+    ret = usbh_pl2303_get_chiptype(serial);
+    if (ret < 0) {
+        return ret;
+    }
+
+    pl2303_class = usb_osal_malloc(sizeof(struct usbh_pl2303));
+    if (pl2303_class == NULL) {
+        USB_LOG_ERR("Fail to alloc pl2303_class\r\n");
+        return -USB_ERR_NOMEM;
+    }
+    memset(pl2303_class, 0, sizeof(struct usbh_pl2303));
+    serial->priv = pl2303_class;
+
+    for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
+        ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc;
+
+        if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
+            if (ep_desc->bEndpointAddress & 0x80) {
+                USBH_EP_INIT(pl2303_class->intin, ep_desc);
+                break;
+            } else {
+            }
+        }
+    }
+
+    if (!pl2303_class->intin) {
+        USB_LOG_ERR("Failed to find interrupt endpoint\r\n");
+        ret = -USB_ERR_NODEV;
+        goto errout;
+    }
+
+    type = (uint8_t)ret;
+    pl2303_class->chip_type = type;
+    pl2303_class->quirks = pl2303_type_data[pl2303_class->chip_type].quirks;
+
+    USB_LOG_INFO("chip type: %s\r\n", pl2303_type_data[pl2303_class->chip_type].name);
+
+    if (type == TYPE_HXD && pl2303_is_hxd_clone(serial)) {
+        pl2303_class->quirks |= PL2303_QUIRK_NO_BREAK_GETLINE;
+    }
+
+    if (type != TYPE_HXN) {
+        uint8_t buf[1];
+        ret = pl2303_vendor_read(serial, 0x8484, buf);
+        ret |= pl2303_vendor_write(serial, 0x0404, 0);
+        ret |= pl2303_vendor_read(serial, 0x8484, buf);
+        ret |= pl2303_vendor_read(serial, 0x8383, buf);
+        ret |= pl2303_vendor_read(serial, 0x8484, buf);
+        ret |= pl2303_vendor_write(serial, 0x0404, 1);
+        ret |= pl2303_vendor_read(serial, 0x8484, buf);
+        ret |= pl2303_vendor_read(serial, 0x8383, buf);
+        ret |= pl2303_vendor_write(serial, 0, 1);
+        ret |= pl2303_vendor_write(serial, 1, 0);
+        if (pl2303_class->quirks & PL2303_QUIRK_LEGACY)
+            ret |= pl2303_vendor_write(serial, 2, 0x24);
+        else
+            ret |= pl2303_vendor_write(serial, 2, 0x44);
+    } else {
+        ret = 0;
+    }
+
+    if (ret < 0) {
+        USB_LOG_ERR("pl2303 init failed\r\n");
+        goto errout;
+    }
+
+    return 0;
+errout:
+    serial->priv = NULL;
+    usb_osal_free(pl2303_class);
+    return ret;
+}
+
+static void usbh_pl2303_detach(struct usbh_serial *serial)
+{
+    struct usbh_pl2303 *pl2303_class;
+
+    if (!serial || !serial->priv) {
+        return;
+    }
+
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+    if (pl2303_class->intin) {
+        usbh_kill_urb(&pl2303_class->intin_urb);
+    }
+    serial->priv = NULL;
+    usb_osal_free(pl2303_class);
+}
+
+static int usbh_pl2303_set_flow_ctrl(struct usbh_serial *serial, bool hardctrl)
+{
+    struct usbh_pl2303 *pl2303_class;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+
+    if (hardctrl) {
+        if (pl2303_class->quirks & PL2303_QUIRK_LEGACY) {
+            return pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x40);
+        } else if (pl2303_class->chip_type == TYPE_HXN) {
+            return pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
+                                     PL2303_HXN_FLOWCTRL_MASK,
+                                     PL2303_HXN_FLOWCTRL_RTS_CTS);
+        } else {
+            return pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x60);
+        }
+    } else {
+        if (pl2303_class->chip_type == TYPE_HXN) {
+            return pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
+                                     PL2303_HXN_FLOWCTRL_MASK,
+                                     PL2303_HXN_FLOWCTRL_NONE);
+        } else {
+            return pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0);
+        }
+    }
+}
+
+static int usbh_pl2303_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    struct usb_setup_packet *setup;
+    struct usbh_pl2303 *pl2303_class;
+    uint32_t baud;
+    uint32_t baud_sup;
+    uint8_t buf[7];
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    setup = serial->hport->setup;
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CDC_REQUEST_SET_LINE_CODING;
+    setup->wValue = 0;
+    setup->wIndex = serial->intf;
+    setup->wLength = 7;
+
+    baud = line_coding->dwDTERate;
+    if (pl2303_type_data[pl2303_class->chip_type].max_baud_rate) {
+        baud = MIN(baud, pl2303_type_data[pl2303_class->chip_type].max_baud_rate);
+    }
+    /*
+     * Use direct method for supported baud rates, otherwise use divisors.
+     * Newer chip types do not support divisor encoding.
+     */
+    if (pl2303_type_data[pl2303_class->chip_type].no_divisors)
+        baud_sup = baud;
+    else
+        baud_sup = pl2303_get_supported_baud_rate(baud);
+
+    if (baud == baud_sup)
+        baud = pl2303_encode_baud_rate_direct(buf, baud);
+    else if (pl2303_type_data[pl2303_class->chip_type].alt_divisors)
+        baud = pl2303_encode_baud_rate_divisor_alt(buf, baud);
+    else
+        baud = pl2303_encode_baud_rate_divisor(buf, baud);
+
+    buf[4] = line_coding->bCharFormat;
+    buf[5] = line_coding->bParityType;
+    buf[6] = line_coding->bDataBits;
+
+    memcpy(serial->iobuffer, buf, sizeof(struct cdc_line_coding));
+
+    return usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+}
+
+static int usbh_pl2303_get_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding)
+{
+    struct usb_setup_packet *setup;
+    int ret;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CDC_REQUEST_GET_LINE_CODING;
+    setup->wValue = 0;
+    setup->wIndex = serial->intf;
+    setup->wLength = 7;
+
+    ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer);
+    if (ret < 0) {
+        return ret;
+    }
+    memcpy(line_coding, serial->iobuffer, sizeof(struct cdc_line_coding));
+    return ret;
+}
+
+static int usbh_pl2303_set_line_state(struct usbh_serial *serial, bool dtr, bool rts)
+{
+    struct usb_setup_packet *setup;
+
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+    setup = serial->hport->setup;
+
+    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
+    setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE;
+    setup->wValue = (dtr << 0) | (rts << 1);
+    setup->wIndex = serial->intf;
+    setup->wLength = 0;
+
+    return usbh_control_transfer(serial->hport, setup, NULL);
+}
+
+static int usbh_pl2303_get_modem_status(struct usbh_serial *serial)
+{
+    struct usbh_pl2303 *pl2303_class;
+    uintptr_t flags;
+    uint16_t status;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+
+    flags = usb_osal_enter_critical_section();
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+
+    status = (pl2303_class->modem_status & UART_DSR ? USBH_SERIAL_TIOCM_DSR : 0) |
+             (pl2303_class->modem_status & UART_CTS ? USBH_SERIAL_TIOCM_CTS : 0) |
+             (pl2303_class->modem_status & UART_RING ? USBH_SERIAL_TIOCM_RI : 0) |
+             (pl2303_class->modem_status & UART_DCD ? USBH_SERIAL_TIOCM_CD : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) |
+             (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0);
+
+    usb_osal_leave_critical_section(flags);
+
+    return status;
+}
+
+#ifdef CONFIG_USBH_SERIAL_GET_MODEM_STATUS
+static int __usbh_pl2303_get_modem_status(struct usbh_serial *serial)
+{
+    struct usbh_pl2303 *pl2303_class;
+    uint8_t status = 0;
+    uint16_t difference;
+    uintptr_t flags;
+    int ret;
+
+    if (!serial || !serial->hport || !serial->priv) {
+        return -USB_ERR_INVAL;
+    }
+    pl2303_class = (struct usbh_pl2303 *)serial->priv;
+
+    usbh_int_urb_fill(&pl2303_class->intin_urb, serial->hport, pl2303_class->intin, &serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET], pl2303_class->intin->wMaxPacketSize, 0xffffffff, NULL, NULL);
+    ret = usbh_submit_urb(&pl2303_class->intin_urb);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (ret < 1) {
+        return -USB_ERR_INVAL;
+    }
+
+    flags = usb_osal_enter_critical_section();
+
+    status = serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET];
+    difference = pl2303_class->modem_status ^ status;
+    pl2303_class->modem_status = status;
+
+    if (status & UART_BREAK_ERROR)
+        serial->iocount.brk++;
+
+    if (difference & UART_STATE_MSR_MASK) {
+        if (difference & UART_CTS)
+            serial->iocount.cts++;
+        if (difference & UART_DSR)
+            serial->iocount.dsr++;
+        if (difference & UART_RING)
+            serial->iocount.rng++;
+        if (difference & UART_DCD) {
+            serial->iocount.dcd++;
+        }
+    }
+
+    usb_osal_leave_critical_section(flags);
+
+    return ret;
+}
+#endif
+
+static const struct usbh_serial_driver pl2303_driver = {
+    .driver_name = "pl2303",
+
+    .ignore_rx_header = 0,
+    .ignore_tx_header = 0,
+
+    .attach = usbh_pl2303_attach,
+    .detach = usbh_pl2303_detach,
+    .set_flow_control = usbh_pl2303_set_flow_ctrl,
+    .set_line_coding = usbh_pl2303_set_line_coding,
+    .get_line_coding = usbh_pl2303_get_line_coding,
+    .set_line_state = usbh_pl2303_set_line_state,
+    .get_modem_status = usbh_pl2303_get_modem_status,
+};
+
+static int usbh_pl2303_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+    return usbh_serial_probe(hport, intf, &pl2303_driver) ? 0 : -USB_ERR_NOMEM;
+}
+
+static int usbh_pl2303_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+    struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv;
+
+    if (serial) {
+        usbh_serial_remove(serial);
+    }
+
+    return 0;
+}
+
+static const uint16_t pl2303_id_table[][2] = {
+    { 0x067B, 0x2303 }, // PL2303 Serial (ATEN/IOGEAR UC232A)
+    { 0x067B, 0x2304 }, // PL2303HXN Serial, type TB
+    { 0x067B, 0x23A3 }, // PL2303HXN Serial, type GC
+    { 0x067B, 0x23B3 }, // PL2303HXN Serial, type GB
+    { 0x067B, 0x23C3 }, // PL2303HXN Serial, type GT
+    { 0x067B, 0x23D3 }, // PL2303HXN Serial, type GL
+    { 0x067B, 0x23E3 }, // PL2303HXN Serial, type GE
+    { 0x067B, 0x23F3 }, // PL2303HXN Serial, type GS
+    { 0, 0 },
+};
+
+const struct usbh_class_driver pl2303_class_driver = {
+    .driver_name = "pl2303",
+    .connect = usbh_pl2303_connect,
+    .disconnect = usbh_pl2303_disconnect
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info pl2303_class_info = {
+    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
+    .bInterfaceClass = 0xff,
+    .bInterfaceSubClass = 0x00,
+    .bInterfaceProtocol = 0x00,
+    .id_table = pl2303_id_table,
+    .class_driver = &pl2303_class_driver
+};

+ 43 - 0
components/drivers/usb/cherryusb/class/serial/usbh_pl2303.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024 ~ 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_PL2303_H
+#define USBH_PL2303_H
+
+#include "usb_cdc.h"
+
+#define PL2303_VENDOR_WRITE_REQUEST  0x01
+#define PL2303_VENDOR_WRITE_NREQUEST 0x80
+#define PL2303_VENDOR_READ_REQUEST   0x01
+#define PL2303_VENDOR_READ_NREQUEST  0x81
+
+#define PL2303_FLOWCTRL_MASK 0xf0
+
+#define PL2303_READ_TYPE_HX_STATUS 0x8080
+
+#define PL2303_HXN_RESET_REG             0x07
+#define PL2303_HXN_RESET_UPSTREAM_PIPE   0x02
+#define PL2303_HXN_RESET_DOWNSTREAM_PIPE 0x01
+
+#define PL2303_HXN_FLOWCTRL_REG      0x0a
+#define PL2303_HXN_FLOWCTRL_MASK     0x1c
+#define PL2303_HXN_FLOWCTRL_NONE     0x1c
+#define PL2303_HXN_FLOWCTRL_RTS_CTS  0x18
+#define PL2303_HXN_FLOWCTRL_XON_XOFF 0x0c
+
+#define PL2303_QUIRK_UART_STATE_IDX0  BIT(0)
+#define PL2303_QUIRK_LEGACY           BIT(1)
+#define PL2303_QUIRK_ENDPOINT_HACK    BIT(2)
+#define PL2303_QUIRK_NO_BREAK_GETLINE BIT(3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_PL2303_H */

+ 743 - 0
components/drivers/usb/cherryusb/class/serial/usbh_serial.c

@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ * Copyright (c) 2025, MDLZCOOL
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_serial.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_serial"
+#include "usb_log.h"
+
+#define DEV_FORMAT_VENDOR  "/dev/ttyUSB%d"
+#define DEV_FORMAT_CDC_ACM "/dev/ttyACM%d"
+
+#define CONFIG_USBHOST_MAX_SERIAL_CLASS 4
+
+static struct usbh_serial g_serial_class[CONFIG_USBHOST_MAX_SERIAL_CLASS];
+
+static uint32_t g_devinuse = 0;
+static uint32_t g_cdcacm_devinuse = 0;
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_serial_iobuffer[CONFIG_USBHOST_MAX_SERIAL_CLASS][USB_ALIGN_UP((USBH_SERIAL_RX2_NOCACHE_OFFSET + USBH_SERIAL_RX2_NOCACHE_SIZE), CONFIG_USB_ALIGN_SIZE)];
+
+/* refer to cherryrb */
+static int usbh_serial_ringbuffer_init(usbh_serial_ringbuf_t *rb, void *pool, uint32_t size)
+{
+    if (NULL == rb) {
+        return -1;
+    }
+
+    if (NULL == pool) {
+        return -1;
+    }
+
+    if ((size < 2) || (size & (size - 1))) {
+        return -1;
+    }
+
+    rb->in = 0;
+    rb->out = 0;
+    rb->mask = size - 1;
+    rb->pool = pool;
+
+    return 0;
+}
+
+static void usbh_serial_ringbuffer_reset(usbh_serial_ringbuf_t *rb)
+{
+    rb->in = 0;
+    rb->out = 0;
+}
+
+static uint32_t usbh_serial_ringbuffer_get_used(usbh_serial_ringbuf_t *rb)
+{
+    return rb->in - rb->out;
+}
+
+static uint32_t usbh_serial_ringbuffer_write(usbh_serial_ringbuf_t *rb, void *data, uint32_t size)
+{
+    uint32_t unused;
+    uint32_t offset;
+    uint32_t remain;
+
+    unused = (rb->mask + 1) - (rb->in - rb->out);
+
+    if (size > unused) {
+        size = unused;
+    }
+
+    offset = rb->in & rb->mask;
+
+    remain = rb->mask + 1 - offset;
+    remain = remain > size ? size : remain;
+
+    memcpy(((uint8_t *)(rb->pool)) + offset, data, remain);
+    memcpy(rb->pool, (uint8_t *)data + remain, size - remain);
+
+    rb->in += size;
+
+    return size;
+}
+
+static uint32_t usbh_serial_ringbuffer_peek(usbh_serial_ringbuf_t *rb, void *data, uint32_t size)
+{
+    uint32_t used;
+    uint32_t offset;
+    uint32_t remain;
+
+    used = rb->in - rb->out;
+    if (size > used) {
+        size = used;
+    }
+
+    offset = rb->out & rb->mask;
+
+    remain = rb->mask + 1 - offset;
+    remain = remain > size ? size : remain;
+
+    memcpy(data, ((uint8_t *)(rb->pool)) + offset, remain);
+    memcpy((uint8_t *)data + remain, rb->pool, size - remain);
+
+    return size;
+}
+
+static uint32_t usbh_serial_ringbuffer_read(usbh_serial_ringbuf_t *rb, void *data, uint32_t size)
+{
+    size = usbh_serial_ringbuffer_peek(rb, data, size);
+    rb->out += size;
+    return size;
+}
+
+static struct usbh_serial *usbh_serial_alloc(bool is_cdcacm)
+{
+    uint8_t devno;
+    uint8_t devno2;
+
+    for (devno = 0; devno < CONFIG_USBHOST_MAX_SERIAL_CLASS; devno++) {
+        if ((g_devinuse & (1U << devno)) == 0) {
+            g_devinuse |= (1U << devno);
+            memset(&g_serial_class[devno], 0, sizeof(struct usbh_serial));
+            g_serial_class[devno].minor = devno;
+            g_serial_class[devno].cdc_minor = -1;
+            g_serial_class[devno].iobuffer = g_serial_iobuffer[devno];
+            g_serial_class[devno].rx_complete_sem = usb_osal_sem_create(0);
+
+            if (is_cdcacm) {
+                for (devno2 = 0; devno2 < CONFIG_USBHOST_MAX_SERIAL_CLASS; devno2++) {
+                    if ((g_cdcacm_devinuse & (1U << devno2)) == 0) {
+                        g_cdcacm_devinuse |= (1U << devno2);
+                        g_serial_class[devno].cdc_minor = devno2;
+                        return &g_serial_class[devno];
+                    }
+                }
+
+                g_devinuse &= ~(1U << devno);
+                return NULL;
+            } else {
+                return &g_serial_class[devno];
+            }
+        }
+    }
+    return NULL;
+}
+
+static void usbh_serial_free(struct usbh_serial *serial)
+{
+    uint8_t devno = serial->minor;
+    if (devno < 32) {
+        g_devinuse &= ~(1U << devno);
+    }
+
+    if (serial->cdc_minor >= 0) {
+        g_cdcacm_devinuse &= ~(1U << serial->cdc_minor);
+    }
+
+    if (g_serial_class[devno].rx_complete_sem) {
+        usb_osal_sem_delete(g_serial_class[devno].rx_complete_sem);
+    }
+}
+
+static void usbh_serial_callback(void *arg, int nbytes)
+{
+    struct usbh_serial *serial = (struct usbh_serial *)arg;
+    int ret;
+
+    if (nbytes < 0) {
+        if (nbytes != -USB_ERR_SHUTDOWN) {
+            USB_LOG_ERR("serial transfer error: %d\n", nbytes);
+        }
+        serial->rx_errorcode = nbytes;
+        usb_osal_sem_give(serial->rx_complete_sem);
+        return;
+    }
+
+    if (nbytes < serial->driver->ignore_rx_header) {
+        USB_LOG_ERR("serial rx short packet: %d\n", nbytes);
+        serial->rx_errorcode = -USB_ERR_IO;
+        usb_osal_sem_give(serial->rx_complete_sem);
+        return;
+    }
+
+    if (nbytes >= serial->driver->ignore_rx_header) {
+        /* resubmit the read urb */
+        usbh_bulk_urb_fill(&serial->bulkin_urb, serial->hport, serial->bulkin, &serial->iobuffer[serial->rx_buf_index ? USBH_SERIAL_RX_NOCACHE_OFFSET : USBH_SERIAL_RX2_NOCACHE_OFFSET], serial->bulkin->wMaxPacketSize,
+                           0, usbh_serial_callback, serial);
+        ret = usbh_submit_urb(&serial->bulkin_urb);
+        if (ret < 0) {
+            USB_LOG_ERR("serial submit failed: %d\n", ret);
+            serial->rx_errorcode = ret;
+            usb_osal_sem_give(serial->rx_complete_sem);
+            return;
+        }
+
+        usbh_serial_ringbuffer_write(&serial->rx_rb,
+                                     &serial->iobuffer[(serial->rx_buf_index ? USBH_SERIAL_RX2_NOCACHE_OFFSET : USBH_SERIAL_RX_NOCACHE_OFFSET) + serial->driver->ignore_rx_header],
+                                     (nbytes - serial->driver->ignore_rx_header));
+
+        if (serial->rx_complete_callback) {
+            serial->rx_complete_callback(serial, nbytes - serial->driver->ignore_rx_header);
+        }
+        serial->rx_buf_index ^= 1;
+        serial->rx_errorcode = 0;
+        usb_osal_sem_give(serial->rx_complete_sem);
+    }
+}
+
+struct usbh_serial *usbh_serial_probe(struct usbh_hubport *hport, uint8_t intf,
+                                      const struct usbh_serial_driver *driver)
+{
+    struct usb_endpoint_descriptor *ep_desc;
+    struct usbh_serial *serial;
+    bool is_cdcacm = false;
+    int ret;
+
+    if (strcmp(driver->driver_name, "cdc_acm") == 0) {
+        is_cdcacm = true;
+    }
+
+    serial = usbh_serial_alloc(is_cdcacm);
+    if (serial == NULL) {
+        USB_LOG_ERR("Fail to alloc serial class\r\n");
+        return NULL;
+    }
+
+    serial->hport = hport;
+    serial->intf = intf;
+    serial->driver = driver;
+
+    if (driver->attach) {
+        ret = driver->attach(serial);
+        if (ret < 0) {
+            USB_LOG_ERR("Serial attach failed: %d\r\n", ret);
+            usbh_serial_free(serial);
+            return NULL;
+        }
+    }
+
+    if (is_cdcacm) {
+        intf = intf + 1; /* data interface */
+    }
+
+    for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
+        ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
+
+        if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_BULK) {
+            if (ep_desc->bEndpointAddress & 0x80) {
+                USBH_EP_INIT(serial->bulkin, ep_desc);
+            } else {
+                USBH_EP_INIT(serial->bulkout, ep_desc);
+            }
+        }
+    }
+
+    if (is_cdcacm) {
+        intf = intf - 1; /* data interface */
+    }
+
+    if (!serial->bulkin || !serial->bulkout) {
+        USB_LOG_ERR("Serial bulk in/out endpoint not found\r\n");
+        usbh_serial_free(serial);
+        return NULL;
+    }
+
+    if (is_cdcacm) {
+        snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->cdc_minor);
+    } else {
+        snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_VENDOR, serial->minor);
+    }
+
+    hport->config.intf[intf].priv = serial;
+    USB_LOG_INFO("Register Serial Class: %s (%s)\r\n", hport->config.intf[intf].devname, driver->driver_name);
+
+    usbh_serial_run(serial);
+
+    return serial;
+}
+
+void usbh_serial_remove(struct usbh_serial *serial)
+{
+    if (!serial || !serial->hport)
+        return;
+
+    usbh_serial_close(serial);
+
+    if (serial->driver && serial->driver->detach) {
+        serial->driver->detach(serial);
+    }
+
+    if (serial->hport->config.intf[serial->intf].priv) {
+        usb_osal_thread_schedule_other();
+        USB_LOG_INFO("Unregister Serial Class: %s (%s)\r\n", serial->hport->config.intf[serial->intf].devname, serial->driver->driver_name);
+        usbh_serial_stop(serial);
+    }
+
+    usbh_serial_free(serial);
+}
+
+struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags)
+{
+    struct usbh_serial *serial;
+    int ret;
+
+    serial = usbh_find_class_instance(devname);
+    if (!serial) {
+        return NULL;
+    }
+
+    if (serial->ref_count != 0) {
+        USB_LOG_ERR("Device busy: %s\r\n", devname);
+        return NULL;
+    }
+
+    if (serial && serial->driver && serial->driver->open) {
+        ret = serial->driver->open(serial);
+        if (ret < 0) {
+            return NULL;
+        }
+    }
+
+    usbh_serial_ringbuffer_init(&serial->rx_rb, serial->rx_rb_pool, CONFIG_USBHOST_SERIAL_RX_SIZE);
+
+    serial->ref_count++;
+    serial->open_flags = open_flags;
+
+    return serial;
+}
+
+int usbh_serial_close(struct usbh_serial *serial)
+{
+    if (!serial || !serial->hport) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->ref_count == 0) {
+        return 0;
+    }
+
+    if (serial->bulkin) {
+        usbh_kill_urb(&serial->bulkin_urb);
+    }
+    if (serial->bulkout) {
+        usbh_kill_urb(&serial->bulkout_urb);
+    }
+
+    if (serial && serial->driver && serial->driver->set_flow_control && serial->rtscts) {
+        serial->driver->set_flow_control(serial, false);
+    }
+
+    if (serial && serial->driver && serial->driver->close) {
+        serial->driver->close(serial);
+    }
+
+    serial->ref_count--;
+    serial->rtscts = false;
+
+    return 0;
+}
+
+static int usbh_serial_tiocmset(struct usbh_serial *serial, uint32_t set, uint32_t clear)
+{
+    int ret;
+    uint16_t line_state;
+    bool dtr;
+    bool rts;
+
+    if (!serial || !serial->hport || !serial->hport->connected) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->ref_count == 0) {
+        return -USB_ERR_NODEV;
+    }
+
+    line_state = serial->line_state;
+    clear &= ~set; /* 'set' takes precedence over 'clear' */
+
+    if (set & USBH_SERIAL_TIOCM_DTR) {
+        line_state |= USBH_SERIAL_TIOCM_DTR;
+    }
+    if (set & USBH_SERIAL_TIOCM_RTS) {
+        line_state |= USBH_SERIAL_TIOCM_RTS;
+    }
+    if (clear & USBH_SERIAL_TIOCM_DTR) {
+        line_state &= ~USBH_SERIAL_TIOCM_DTR;
+    }
+    if (clear & USBH_SERIAL_TIOCM_RTS) {
+        line_state &= ~USBH_SERIAL_TIOCM_RTS;
+    }
+
+    dtr = (line_state & USBH_SERIAL_TIOCM_DTR) ? true : false;
+    rts = (line_state & USBH_SERIAL_TIOCM_RTS) ? true : false;
+
+    if (serial && serial->driver && serial->driver->set_line_state) {
+        ret = serial->driver->set_line_state(serial, dtr, rts);
+    } else {
+        return -USB_ERR_NOTSUPP;
+    }
+    serial->line_state = line_state;
+
+    return ret;
+}
+
+int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg)
+{
+    int ret;
+
+    if (!serial || !serial->hport || !serial->hport->connected) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->ref_count == 0) {
+        return -USB_ERR_NODEV;
+    }
+
+    switch (cmd) {
+        case USBH_SERIAL_CMD_SET_ATTR: {
+            struct usbh_serial_termios *termios = (struct usbh_serial_termios *)arg;
+            struct cdc_line_coding line_coding;
+
+            line_coding.dwDTERate = termios->baudrate;
+            line_coding.bCharFormat = termios->stopbits;
+            line_coding.bParityType = termios->parity;
+            line_coding.bDataBits = termios->databits;
+
+            if (serial->bulkin) {
+                usbh_kill_urb(&serial->bulkin_urb);
+            }
+            if (serial->bulkout) {
+                usbh_kill_urb(&serial->bulkout_urb);
+            }
+
+            if (serial && serial->driver && serial->driver->set_line_coding) {
+                ret = serial->driver->set_line_coding(serial, &line_coding);
+                if (ret < 0) {
+                    return ret;
+                }
+            } else {
+                return -USB_ERR_NOTSUPP;
+            }
+
+            memcpy(&serial->line_coding, &line_coding, sizeof(struct cdc_line_coding));
+
+            if (serial && serial->driver && serial->driver->set_flow_control) {
+                ret = serial->driver->set_flow_control(serial, termios->rtscts);
+            }
+
+            serial->rtscts = termios->rtscts;
+            serial->rx_timeout_ms = termios->rx_timeout;
+
+            ret = usbh_serial_tiocmset(serial, USBH_SERIAL_TIOCM_DTR | USBH_SERIAL_TIOCM_RTS, 0);
+            if (ret < 0) {
+                return ret;
+            }
+
+            usbh_serial_ringbuffer_reset(&serial->rx_rb);
+            usb_osal_sem_reset(serial->rx_complete_sem);
+            serial->rx_buf_index = 0;
+            usbh_bulk_urb_fill(&serial->bulkin_urb, serial->hport, serial->bulkin, &serial->iobuffer[serial->rx_buf_index ? USBH_SERIAL_RX2_NOCACHE_OFFSET : USBH_SERIAL_RX_NOCACHE_OFFSET], serial->bulkin->wMaxPacketSize,
+                               0, usbh_serial_callback, serial);
+            ret = usbh_submit_urb(&serial->bulkin_urb);
+
+            return ret;
+        } break;
+        case USBH_SERIAL_CMD_GET_ATTR: {
+            struct usbh_serial_termios *termios = (struct usbh_serial_termios *)arg;
+            struct cdc_line_coding line_coding;
+
+            if (serial && serial->driver && serial->driver->get_line_coding) {
+                return serial->driver->get_line_coding(serial, &line_coding);
+            } else {
+                memcpy(&line_coding, &serial->line_coding, sizeof(struct cdc_line_coding));
+            }
+
+            termios->baudrate = line_coding.dwDTERate;
+            termios->stopbits = line_coding.bCharFormat;
+            termios->parity = line_coding.bParityType;
+            termios->databits = line_coding.bDataBits;
+            termios->rtscts = serial->rtscts;
+            termios->rx_timeout = serial->rx_timeout_ms;
+            return 0;
+        } break;
+        case USBH_SERIAL_CMD_IOCMBIS: {
+            uint32_t flags = *(uint32_t *)arg;
+
+            return usbh_serial_tiocmset(serial, flags, 0);
+        } break;
+        case USBH_SERIAL_CMD_IOCMBIC: {
+            uint32_t flags = *(uint32_t *)arg;
+
+            return usbh_serial_tiocmset(serial, 0, flags);
+        } break;
+        case USBH_SERIAL_CMD_TIOCMSET: {
+            uint32_t flags = *(uint32_t *)arg;
+
+            uint32_t set = 0;
+            uint32_t clear = 0;
+
+            set |= (flags & USBH_SERIAL_TIOCM_DTR) ? USBH_SERIAL_TIOCM_DTR : 0;
+            set |= (flags & USBH_SERIAL_TIOCM_RTS) ? USBH_SERIAL_TIOCM_RTS : 0;
+            clear |= !(flags & USBH_SERIAL_TIOCM_DTR) ? USBH_SERIAL_TIOCM_DTR : 0;
+            clear |= !(flags & USBH_SERIAL_TIOCM_RTS) ? USBH_SERIAL_TIOCM_RTS : 0;
+
+            return usbh_serial_tiocmset(serial, set, clear);
+        } break;
+        case USBH_SERIAL_CMD_TIOCMGET: {
+            uint32_t *flags = (uint32_t *)arg;
+            int status;
+
+            if (serial && serial->driver && serial->driver->get_modem_status) {
+                status = serial->driver->get_modem_status(serial);
+                if (status < 0) {
+                    return status;
+                }
+            } else {
+                return -USB_ERR_NOTSUPP;
+            }
+            *flags = status;
+        } break;
+        default:
+            break;
+    }
+
+    return -USB_ERR_NOTSUPP;
+}
+
+int usbh_serial_write(struct usbh_serial *serial, const void *buffer, uint32_t buflen)
+{
+    int ret;
+    struct usbh_urb *urb;
+
+    if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkout) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->ref_count == 0) {
+        return -USB_ERR_NODEV;
+    }
+
+    urb = &serial->bulkout_urb;
+
+    usbh_bulk_urb_fill(urb, serial->hport, serial->bulkout, (uint8_t *)buffer, buflen, 0xffffffff, NULL, NULL);
+    ret = usbh_submit_urb(urb);
+    if (ret == 0) {
+        ret = urb->actual_length;
+    }
+    return ret;
+}
+
+int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen)
+{
+    int ret;
+
+    if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkin || !serial->line_coding.dwDTERate) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->ref_count == 0) {
+        return -USB_ERR_NODEV;
+    }
+
+    if (serial->open_flags & USBH_SERIAL_O_NONBLOCK) {
+        return usbh_serial_ringbuffer_read(&serial->rx_rb, buffer, buflen);
+    } else {
+        if (usbh_serial_ringbuffer_get_used(&serial->rx_rb) == 0) {
+            ret = usb_osal_sem_take(serial->rx_complete_sem, serial->rx_timeout_ms == 0 ? USB_OSAL_WAITING_FOREVER : serial->rx_timeout_ms);
+            if (ret < 0) {
+                return ret;
+            }
+            if (serial->rx_errorcode < 0) {
+                return serial->rx_errorcode;
+            }
+        }
+        return usbh_serial_ringbuffer_read(&serial->rx_rb, buffer, buflen);
+    }
+}
+
+int usbh_serial_cdc_write_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg)
+{
+    struct usbh_urb *urb;
+
+    if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkout || !complete || serial->line_coding.dwDTERate) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->ref_count == 0) {
+        return -USB_ERR_NODEV;
+    }
+
+    urb = &serial->bulkout_urb;
+
+    usbh_bulk_urb_fill(urb, serial->hport, serial->bulkout, buffer, buflen,
+                       0, complete, serial);
+    return usbh_submit_urb(urb);
+}
+
+int usbh_serial_cdc_read_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg)
+{
+    struct usbh_urb *urb;
+
+    if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkin || !complete || serial->line_coding.dwDTERate) {
+        return -USB_ERR_INVAL;
+    }
+
+    if (serial->ref_count == 0) {
+        return -USB_ERR_NODEV;
+    }
+
+    if (buflen % serial->bulkin->wMaxPacketSize) {
+        return -USB_ERR_INVAL;
+    }
+
+    urb = &serial->bulkin_urb;
+
+    usbh_bulk_urb_fill(urb, serial->hport, serial->bulkin, buffer, MIN(buflen, serial->bulkin->wMaxPacketSize),
+                       0, complete, serial);
+    return usbh_submit_urb(urb);
+}
+
+void usbh_serial_help(void)
+{
+    USB_LOG_RAW("USB host serial test\r\n"
+                "Usage: usbh_serial <ttypath> [options]...\r\n"
+                "\r\n"
+                "-b <baud>             set serial baudrate\r\n"
+                "-t <dtr> <rts>        set rts and dtr\r\n"
+                "-w string             write string\r\n"
+                "-r                    read data and dump\r\n"
+                "-x                    close serial device\r\n"
+                "\r\n");
+}
+
+static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_serial_testbuffer[512];
+
+int usbh_serial(int argc, char **argv)
+{
+    static struct usbh_serial *serial;
+    int ret;
+
+    if (argc < 3) {
+        usbh_serial_help();
+        return 0;
+    }
+
+    if (serial) {
+        if (!serial->hport || !serial->hport->connected) {
+            serial = NULL;
+        }
+    }
+
+    if (!serial) {
+        serial = usbh_serial_open(argv[1], USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
+        if (!serial) {
+            USB_LOG_ERR("Fail to open serial device: %s\r\n", argv[1]);
+            return -USB_ERR_INVAL;
+        }
+    }
+
+    if (strncmp(argv[2], "-b", 2) == 0 && argc >= 4) {
+        struct usbh_serial_termios termios;
+
+        memset(&termios, 0, sizeof(termios));
+        termios.baudrate = atoi(argv[3]);
+        termios.stopbits = 0;
+        termios.parity = 0;
+        termios.databits = 8;
+        termios.rtscts = false;
+        termios.rx_timeout = 0;
+        usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios);
+    } else if (strncmp(argv[2], "-t", 2) == 0 && argc >= 5) {
+        uint32_t flags;
+
+        flags = atoi(argv[3]) ? USBH_SERIAL_TIOCM_DTR : 0;
+        flags |= atoi(argv[4]) ? USBH_SERIAL_TIOCM_RTS : 0;
+
+        usbh_serial_control(serial, USBH_SERIAL_CMD_TIOCMSET, &flags);
+        USB_LOG_INFO("Set DTR: %d, RTS: %d\r\n", atoi(argv[3]), atoi(argv[4]));
+    } else if (strncmp(argv[2], "-w", 2) == 0 && argc >= 4) {
+        memcpy(g_serial_testbuffer, argv[3], MIN(strlen(argv[3]), sizeof(g_serial_testbuffer)));
+        uint32_t len = snprintf((char *)g_serial_testbuffer, sizeof(g_serial_testbuffer), "%s\r\n", argv[3]);
+        ret = usbh_serial_write(serial, g_serial_testbuffer, len);
+        if (ret >= 0) {
+            USB_LOG_INFO("Write %d bytes\r\n", ret);
+        } else {
+            USB_LOG_ERR("Write failed: %d\r\n", ret);
+        }
+    } else if (strncmp(argv[2], "-r", 2) == 0) {
+        ret = usbh_serial_read(serial, g_serial_testbuffer, sizeof(g_serial_testbuffer));
+        if (ret >= 0) {
+            usb_hexdump(g_serial_testbuffer, ret);
+            USB_LOG_INFO("Read %d bytes\r\n", ret);
+        } else {
+            USB_LOG_ERR("Read failed: %d\r\n", ret);
+        }
+    } else if (strncmp(argv[2], "-x", 2) == 0) {
+        usbh_serial_close(serial);
+        serial = NULL;
+    } else {
+        usbh_serial_help();
+    }
+
+    return 0;
+}
+
+__WEAK void usbh_serial_run(struct usbh_serial *serial)
+{
+    (void)serial;
+}
+
+__WEAK void usbh_serial_stop(struct usbh_serial *serial)
+{
+    (void)serial;
+}
+
+static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+    (void)hport;
+    (void)intf;
+    return 0;
+}
+
+static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+    (void)hport;
+    (void)intf;
+    return 0;
+}
+
+const struct usbh_class_driver cdc_data_class_driver = {
+    .driver_name = "cdc_data",
+    .connect = usbh_cdc_data_connect,
+    .disconnect = usbh_cdc_data_disconnect
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = {
+    .match_flags = USB_CLASS_MATCH_INTF_CLASS,
+    .bInterfaceClass = USB_DEVICE_CLASS_CDC_DATA,
+    .bInterfaceSubClass = 0x00,
+    .bInterfaceProtocol = 0x00,
+    .id_table = NULL,
+    .class_driver = &cdc_data_class_driver
+};

+ 182 - 0
components/drivers/usb/cherryusb/class/serial/usbh_serial.h

@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ * Copyright (c) 2025, MDLZCOOL
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_SERIAL_H
+#define USBH_SERIAL_H
+
+#include "usb_cdc.h"
+
+#define USBH_SERIAL_CTRL_NOCACHE_OFFSET 0
+#define USBH_SERIAL_CTRL_NOCACHE_SIZE   32
+#define USBH_SERIAL_INT_NOCACHE_OFFSET  USB_ALIGN_UP(USBH_SERIAL_CTRL_NOCACHE_SIZE, CONFIG_USB_ALIGN_SIZE)
+#define USBH_SERIAL_INT_NOCACHE_SIZE    32
+#define USBH_SERIAL_RX_NOCACHE_OFFSET   USB_ALIGN_UP((USBH_SERIAL_INT_NOCACHE_OFFSET + USBH_SERIAL_INT_NOCACHE_SIZE), CONFIG_USB_ALIGN_SIZE)
+#define USBH_SERIAL_RX_NOCACHE_SIZE     512
+#define USBH_SERIAL_RX2_NOCACHE_OFFSET  USB_ALIGN_UP((USBH_SERIAL_RX_NOCACHE_OFFSET + USBH_SERIAL_RX_NOCACHE_SIZE), CONFIG_USB_ALIGN_SIZE)
+#define USBH_SERIAL_RX2_NOCACHE_SIZE    512
+
+#define USBH_SERIAL_DATABITS_5 5
+#define USBH_SERIAL_DATABITS_6 6
+#define USBH_SERIAL_DATABITS_7 7
+#define USBH_SERIAL_DATABITS_8 8
+
+#define USBH_SERIAL_PARITY_NONE  0
+#define USBH_SERIAL_PARITY_ODD   1
+#define USBH_SERIAL_PARITY_EVEN  2
+#define USBH_SERIAL_PARITY_MARK  3
+#define USBH_SERIAL_PARITY_SPACE 4
+
+#define USBH_SERIAL_STOPBITS_1   0
+#define USBH_SERIAL_STOPBITS_1_5 1
+#define USBH_SERIAL_STOPBITS_2   2
+
+/* modem lines */
+#define USBH_SERIAL_TIOCM_LE   0x001 /* line enable */
+#define USBH_SERIAL_TIOCM_DTR  0x002 /* data terminal ready */
+#define USBH_SERIAL_TIOCM_RTS  0x004 /* request to send */
+#define USBH_SERIAL_TIOCM_ST   0x010 /* secondary transmit */
+#define USBH_SERIAL_TIOCM_SR   0x020 /* secondary receive */
+#define USBH_SERIAL_TIOCM_CTS  0x040 /* clear to send */
+#define USBH_SERIAL_TIOCM_CAR  0x100 /* carrier detect */
+#define USBH_SERIAL_TIOCM_CD   USBH_SERIAL_TIOCM_CAR
+#define USBH_SERIAL_TIOCM_RNG  0x200 /* ring */
+#define USBH_SERIAL_TIOCM_RI   USBH_SERIAL_TIOCM_RNG
+#define USBH_SERIAL_TIOCM_DSR  0x400 /* data set ready */
+#define USBH_SERIAL_TIOCM_OUT1 0x2000
+#define USBH_SERIAL_TIOCM_OUT2 0x4000
+#define USBH_SERIAL_TIOCM_LOOP 0x8000
+
+#define USBH_SERIAL_O_RDONLY 0x0000 /* open for reading only */
+#define USBH_SERIAL_O_WRONLY 0x0001 /* open for writing only */
+#define USBH_SERIAL_O_RDWR   0x0002 /* open for reading and writing */
+
+#define USBH_SERIAL_O_ACCMODE  0x0003 /* mask for above modes, from 4.4BSD https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/include/sys/fcntl.h */
+#define USBH_SERIAL_O_NONBLOCK 0x0004 /* non-blocking I/O, from BSD apple https://opensource.apple.com/source/xnu/xnu-1228.0.2/bsd/sys/fcntl.h */
+
+#define USBH_SERIAL_CMD_SET_ATTR 0
+#define USBH_SERIAL_CMD_GET_ATTR 1
+#define USBH_SERIAL_CMD_IOCMBIS  2
+#define USBH_SERIAL_CMD_IOCMBIC  3
+#define USBH_SERIAL_CMD_TIOCMSET 4
+#define USBH_SERIAL_CMD_TIOCMGET 5
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    uint32_t in;   /*!< Define the write pointer.               */
+    uint32_t out;  /*!< Define the read pointer.                */
+    uint32_t mask; /*!< Define the write and read pointer mask. */
+    void *pool;    /*!< Define the memory pointer.              */
+} usbh_serial_ringbuf_t;
+
+/*
+ * Counters of the input lines (CTS, DSR, RI, CD) interrupts
+ */
+
+struct usbh_serial_async_icount {
+    uint32_t cts, dsr, rng, dcd, tx, rx;
+    uint32_t frame, parity, overrun, brk;
+    uint32_t buf_overrun;
+};
+
+struct usbh_serial_termios {
+    uint32_t baudrate;
+    uint8_t databits;
+    uint8_t parity;
+    uint8_t stopbits;
+    bool rtscts; /* hardware flow control */
+    uint32_t rx_timeout;
+};
+
+struct usbh_serial;
+
+typedef void (*usbh_serial_rx_complete_callback_t)(struct usbh_serial *serial, int nbytes);
+
+/**
+ * @brief Serial Driver Operations
+ */
+struct usbh_serial_driver {
+    const char *driver_name;
+
+    uint8_t ignore_tx_header;
+    uint8_t ignore_rx_header;
+
+    int (*attach)(struct usbh_serial *serial);
+    void (*detach)(struct usbh_serial *serial);
+
+    int (*open)(struct usbh_serial *serial);
+    void (*close)(struct usbh_serial *serial);
+    int (*set_flow_control)(struct usbh_serial *serial, bool enable);
+    int (*set_line_coding)(struct usbh_serial *serial, struct cdc_line_coding *line_coding);
+    int (*get_line_coding)(struct usbh_serial *serial, struct cdc_line_coding *line_coding);
+    int (*set_line_state)(struct usbh_serial *serial, bool dtr, bool rts);
+    int (*get_modem_status)(struct usbh_serial *serial);
+};
+
+/**
+ * @brief Serial Instance
+ */
+struct usbh_serial {
+    struct usbh_hubport *hport;
+    uint8_t intf;      /* Interface Number */
+    int minor;         /* Serial Port Number (/dev/ttyUSBx or /dev/ttyACMx) */
+    int cdc_minor;     /* Serial Port Number (/dev/ttyACMx) */
+    uint8_t *iobuffer; /* I/O buffer for serial transfers */
+    uint8_t ref_count; /* Reference Count */
+    uint32_t open_flags;
+    uint32_t rx_timeout_ms;
+
+    struct cdc_line_coding line_coding;
+    uint16_t line_state;
+    bool rtscts; /* hardware flow control */
+    struct usbh_serial_async_icount iocount;
+
+    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
+    struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
+    struct usbh_urb bulkout_urb;
+    struct usbh_urb bulkin_urb;
+
+    const struct usbh_serial_driver *driver;
+
+    usbh_serial_ringbuf_t rx_rb;
+    uint8_t rx_rb_pool[CONFIG_USBHOST_SERIAL_RX_SIZE];
+    usb_osal_sem_t rx_complete_sem;
+    uint8_t rx_buf_index;
+    int rx_errorcode;
+    usbh_serial_rx_complete_callback_t rx_complete_callback;
+
+    void *priv;      /* Private Data */
+    void *user_data; /* User Data */
+};
+
+/* internal api */
+struct usbh_serial *usbh_serial_probe(struct usbh_hubport *hport, uint8_t intf, const struct usbh_serial_driver *driver);
+void usbh_serial_remove(struct usbh_serial *serial);
+
+/* public api */
+struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags);
+int usbh_serial_close(struct usbh_serial *serial);
+int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg);
+int usbh_serial_write(struct usbh_serial *serial, const void *buffer, uint32_t buflen);
+int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen);
+
+/* cdc only api */
+int usbh_serial_cdc_write_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg);
+int usbh_serial_cdc_read_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg);
+
+/* public weak api */
+void usbh_serial_run(struct usbh_serial *serial);
+void usbh_serial_stop(struct usbh_serial *serial);
+
+int usbh_serial(int argc, char **argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_SERIAL_H */

+ 0 - 10
components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c

@@ -795,16 +795,6 @@ int usbh_asix_eth_output(uint32_t buflen)
     return usbh_submit_urb(&g_asix_class.bulkout_urb);
 }
 
-__WEAK void usbh_asix_run(struct usbh_asix *asix_class)
-{
-    (void)asix_class;
-}
-
-__WEAK void usbh_asix_stop(struct usbh_asix *asix_class)
-{
-    (void)asix_class;
-}
-
 static const uint16_t asix_id_table[][2] = {
     { 0x0B95, 0x772B },
     { 0x0B95, 0x7720 },

+ 5 - 15
components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c

@@ -1034,17 +1034,17 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si
 static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t byteen,
                              uint16_t size, void *data, uint16_t type)
 {
-    int ret;
+    int ret = -USB_ERR_INVAL;
     uint16_t byteen_start, byteen_end, byen;
     uint16_t limit = 512;
     uint8_t *buf = data;
 
     /* both size and indix must be 4 bytes align */
     if ((size & 3) || !size || (index & 3) || !buf)
-        return -USB_ERR_INVAL;
+        return ret;
 
     if ((uint32_t)index + (uint32_t)size > 0xffff)
-        return -USB_ERR_INVAL;
+        return ret;
 
     byteen_start = byteen & BYTE_EN_START_MASK;
     byteen_end = byteen & BYTE_EN_END_MASK;
@@ -1596,8 +1596,8 @@ static void r8153_teredo_off(struct usbh_rtl8152 *tp)
         case RTL_VER_15:
         default:
             /* The bit 0 ~ 7 are relative with teredo settings. They are
-		 * W1C (write 1 to clear), so set all 1 to disable it.
-		 */
+             * W1C (write 1 to clear), so set all 1 to disable it.
+             */
             ocp_write_byte(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, 0xff);
             break;
     }
@@ -2251,16 +2251,6 @@ int usbh_rtl8152_eth_output(uint32_t buflen)
     return usbh_submit_urb(&g_rtl8152_class.bulkout_urb);
 }
 
-__WEAK void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
-{
-    (void)rtl8152_class;
-}
-
-__WEAK void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
-{
-    (void)rtl8152_class;
-}
-
 static const uint16_t rtl_id_table[][2] = {
     { 0x0BDA, 0x8152 },
     { 0, 0 },

+ 0 - 379
components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c

@@ -1,379 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbh_core.h"
-#include "usbh_ch34x.h"
-
-#define DEV_FORMAT "/dev/ttyUSB%d"
-
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_ch34x_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
-
-#define CONFIG_USBHOST_MAX_CP210X_CLASS 1
-
-static struct usbh_ch34x g_ch34x_class[CONFIG_USBHOST_MAX_CP210X_CLASS];
-static uint32_t g_devinuse = 0;
-
-static struct usbh_ch34x *usbh_ch34x_class_alloc(void)
-{
-    uint8_t devno;
-
-    for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) {
-        if ((g_devinuse & (1U << devno)) == 0) {
-            g_devinuse |= (1U << devno);
-            memset(&g_ch34x_class[devno], 0, sizeof(struct usbh_ch34x));
-            g_ch34x_class[devno].minor = devno;
-            return &g_ch34x_class[devno];
-        }
-    }
-    return NULL;
-}
-
-static void usbh_ch34x_class_free(struct usbh_ch34x *ch34x_class)
-{
-    uint8_t devno = ch34x_class->minor;
-
-    if (devno < 32) {
-        g_devinuse &= ~(1U << devno);
-    }
-    memset(ch34x_class, 0, sizeof(struct usbh_ch34x));
-}
-
-static int usbh_ch34x_get_baudrate_div(uint32_t baudrate, uint8_t *factor, uint8_t *divisor)
-{
-    uint8_t a;
-    uint8_t b;
-    uint32_t c;
-
-    switch (baudrate) {
-        case 921600:
-            a = 0xf3;
-            b = 7;
-            break;
-
-        case 307200:
-            a = 0xd9;
-            b = 7;
-            break;
-
-        default:
-            if (baudrate > 6000000 / 255) {
-                b = 3;
-                c = 6000000;
-            } else if (baudrate > 750000 / 255) {
-                b = 2;
-                c = 750000;
-            } else if (baudrate > 93750 / 255) {
-                b = 1;
-                c = 93750;
-            } else {
-                b = 0;
-                c = 11719;
-            }
-            a = (uint8_t)(c / baudrate);
-            if (a == 0 || a == 0xFF) {
-                return -USB_ERR_INVAL;
-            }
-            if ((c / a - baudrate) > (baudrate - c / (a + 1))) {
-                a++;
-            }
-            a = (uint8_t)(256 - a);
-            break;
-    }
-
-    *factor = a;
-    *divisor = b;
-
-    return 0;
-}
-
-static int usbh_ch34x_get_version(struct usbh_ch34x *ch34x_class)
-{
-    struct usb_setup_packet *setup;
-    int ret;
-
-    if (!ch34x_class || !ch34x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ch34x_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = CH34X_READ_VERSION;
-    setup->wValue = 0;
-    setup->wIndex = 0;
-    setup->wLength = 2;
-
-    ret = usbh_control_transfer(ch34x_class->hport, setup, g_ch34x_buf);
-    if (ret < 0) {
-        return ret;
-    }
-
-    USB_LOG_INFO("Ch34x chip version %02x:%02x\r\n", g_ch34x_buf[0], g_ch34x_buf[1]);
-    return ret;
-}
-
-static int usbh_ch34x_flow_ctrl(struct usbh_ch34x *ch34x_class)
-{
-    struct usb_setup_packet *setup;
-
-    if (!ch34x_class || !ch34x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ch34x_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = CH34X_WRITE_REG;
-    setup->wValue = 0x2727;
-    setup->wIndex = 0;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ch34x_class->hport, setup, NULL);
-}
-
-int usbh_ch34x_set_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding)
-{
-    struct usb_setup_packet *setup;
-    uint16_t reg_value = 0;
-    uint16_t value = 0;
-    uint8_t factor = 0;
-    uint8_t divisor = 0;
-
-    if (!ch34x_class || !ch34x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ch34x_class->hport->setup;
-
-    memcpy((uint8_t *)&ch34x_class->line_coding, line_coding, sizeof(struct cdc_line_coding));
-
-    /* refer to https://github.com/WCHSoftGroup/ch341ser_linux/blob/main/driver/ch341.c */
-
-    switch (line_coding->bParityType) {
-        case 0:
-            break;
-        case 1:
-            reg_value |= CH341_L_PO;
-            break;
-        case 2:
-            reg_value |= CH341_L_PE;
-            break;
-        case 3:
-            reg_value |= CH341_L_PM;
-            break;
-        case 4:
-            reg_value |= CH341_L_PS;
-            break;
-        default:
-            return -USB_ERR_INVAL;
-    }
-
-    switch (line_coding->bDataBits) {
-        case 5:
-            reg_value |= CH341_L_D5;
-            break;
-        case 6:
-            reg_value |= CH341_L_D6;
-            break;
-        case 7:
-            reg_value |= CH341_L_D7;
-            break;
-        case 8:
-            reg_value |= CH341_L_D8;
-            break;
-        default:
-            return -USB_ERR_INVAL;
-    }
-
-    if (line_coding->bCharFormat == 2) {
-        reg_value |= CH341_L_SB;
-    }
-
-    reg_value |= 0xC0;
-
-    value |= 0x9c;
-    value |= reg_value << 8;
-
-    usbh_ch34x_get_baudrate_div(line_coding->dwDTERate, &factor, &divisor);
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = CH34X_SERIAL_INIT;
-    setup->wValue = value;
-    setup->wIndex = (factor << 8) | 0x80 | divisor;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ch34x_class->hport, setup, NULL);
-}
-
-int usbh_ch34x_get_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding)
-{
-    memcpy(line_coding, (uint8_t *)&ch34x_class->line_coding, sizeof(struct cdc_line_coding));
-    return 0;
-}
-
-int usbh_ch34x_set_line_state(struct usbh_ch34x *ch34x_class, bool dtr, bool rts)
-{
-    struct usb_setup_packet *setup;
-
-    if (!ch34x_class || !ch34x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ch34x_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = CH34X_MODEM_CTRL;
-    setup->wValue = 0x0f | (dtr << 5) | (rts << 6);
-    setup->wIndex = 0;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ch34x_class->hport, setup, NULL);
-}
-
-static int usbh_ch34x_connect(struct usbh_hubport *hport, uint8_t intf)
-{
-    struct usb_endpoint_descriptor *ep_desc;
-    int ret = 0;
-
-    struct usbh_ch34x *ch34x_class = usbh_ch34x_class_alloc();
-    if (ch34x_class == NULL) {
-        USB_LOG_ERR("Fail to alloc ch34x_class\r\n");
-        return -USB_ERR_NOMEM;
-    }
-
-    ch34x_class->hport = hport;
-    ch34x_class->intf = intf;
-
-    hport->config.intf[intf].priv = ch34x_class;
-
-    usbh_ch34x_get_version(ch34x_class);
-    usbh_ch34x_flow_ctrl(ch34x_class);
-
-    for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
-        ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
-        if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
-            continue;
-        } else {
-            if (ep_desc->bEndpointAddress & 0x80) {
-                USBH_EP_INIT(ch34x_class->bulkin, ep_desc);
-            } else {
-                USBH_EP_INIT(ch34x_class->bulkout, ep_desc);
-            }
-        }
-    }
-
-    snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, ch34x_class->minor);
-
-    USB_LOG_INFO("Register CH34X Class:%s\r\n", hport->config.intf[intf].devname);
-
-#if 0
-    USB_LOG_INFO("Test ch34x rx and tx and rx for 5 times, baudrate is 115200\r\n");
-
-    struct cdc_line_coding linecoding;
-    uint8_t count = 5;
-
-    linecoding.dwDTERate = 115200;
-    linecoding.bDataBits = 8;
-    linecoding.bParityType = 0;
-    linecoding.bCharFormat = 0;
-    usbh_ch34x_set_line_coding(ch34x_class, &linecoding);
-    usbh_ch34x_set_line_state(ch34x_class, true, false);
-
-    memset(g_ch34x_buf, 'a', sizeof(g_ch34x_buf));
-    ret = usbh_ch34x_bulk_out_transfer(ch34x_class, g_ch34x_buf, sizeof(g_ch34x_buf), 0xfffffff);
-    USB_LOG_RAW("out ret:%d\r\n", ret);
-    while (count--) {
-        ret = usbh_ch34x_bulk_in_transfer(ch34x_class, g_ch34x_buf, sizeof(g_ch34x_buf), 0xfffffff);
-        USB_LOG_RAW("in ret:%d\r\n", ret);
-        if (ret > 0) {
-            for (uint32_t i = 0; i < ret; i++) {
-                USB_LOG_RAW("%02x ", g_ch34x_buf[i]);
-            }
-            USB_LOG_RAW("\r\n");
-        }
-    }
-#endif
-    usbh_ch34x_run(ch34x_class);
-    return ret;
-}
-
-static int usbh_ch34x_disconnect(struct usbh_hubport *hport, uint8_t intf)
-{
-    int ret = 0;
-
-    struct usbh_ch34x *ch34x_class = (struct usbh_ch34x *)hport->config.intf[intf].priv;
-
-    if (ch34x_class) {
-        if (ch34x_class->bulkin) {
-            usbh_kill_urb(&ch34x_class->bulkin_urb);
-        }
-
-        if (ch34x_class->bulkout) {
-            usbh_kill_urb(&ch34x_class->bulkout_urb);
-        }
-
-        if (hport->config.intf[intf].devname[0] != '\0') {
-            usb_osal_thread_schedule_other();
-            USB_LOG_INFO("Unregister CH34X Class:%s\r\n", hport->config.intf[intf].devname);
-            usbh_ch34x_stop(ch34x_class);
-        }
-
-        usbh_ch34x_class_free(ch34x_class);
-    }
-
-    return ret;
-}
-
-int usbh_ch34x_bulk_in_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &ch34x_class->bulkin_urb;
-
-    usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-int usbh_ch34x_bulk_out_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &ch34x_class->bulkout_urb;
-
-    usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkout, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-__WEAK void usbh_ch34x_run(struct usbh_ch34x *ch34x_class)
-{
-    (void)ch34x_class;
-}
-
-__WEAK void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class)
-{
-    (void)ch34x_class;
-}
-
-static const uint16_t ch34x_id_table[][2] = {
-    { 0x1A86, 0x7523 },
-    { 0, 0 },
-};
-
-const struct usbh_class_driver ch34x_class_driver = {
-    .driver_name = "ch34x",
-    .connect = usbh_ch34x_connect,
-    .disconnect = usbh_ch34x_disconnect
-};
-
-CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = {
-    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
-    .bInterfaceClass = 0xff,
-    .bInterfaceSubClass = 0x00,
-    .bInterfaceProtocol = 0x00,
-    .id_table = ch34x_id_table,
-    .class_driver = &ch34x_class_driver
-};

+ 0 - 76
components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.h

@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef USBH_CH34X_H
-#define USBH_CH34X_H
-
-#include "usb_cdc.h"
-
-/* Requests */
-#define CH34X_READ_VERSION 0x5F
-#define CH34X_WRITE_REG    0x9A
-#define CH34X_READ_REG     0x95
-#define CH34X_SERIAL_INIT  0xA1
-#define CH34X_MODEM_CTRL   0xA4
-
-// modem control bits
-#define CH34X_BIT_RTS (1 << 6)
-#define CH34X_BIT_DTR (1 << 5)
-
-#define CH341_CTO_O   0x10
-#define CH341_CTO_D   0x20
-#define CH341_CTO_R   0x40
-#define CH341_CTI_C   0x01
-#define CH341_CTI_DS  0x02
-#define CH341_CTRL_RI 0x04
-#define CH341_CTI_DC  0x08
-#define CH341_CTI_ST  0x0f
-
-#define CH341_L_ER 0x80
-#define CH341_L_ET 0x40
-#define CH341_L_PS 0x38
-#define CH341_L_PM 0x28
-#define CH341_L_PE 0x18
-#define CH341_L_PO 0x08
-#define CH341_L_SB 0x04
-#define CH341_L_D8 0x03
-#define CH341_L_D7 0x02
-#define CH341_L_D6 0x01
-#define CH341_L_D5 0x00
-
-struct usbh_ch34x {
-    struct usbh_hubport *hport;
-    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
-    struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
-    struct usbh_urb bulkout_urb;
-    struct usbh_urb bulkin_urb;
-
-    struct cdc_line_coding line_coding;
-
-    uint8_t intf;
-    uint8_t minor;
-
-    void *user_data;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int usbh_ch34x_set_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding);
-int usbh_ch34x_get_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding);
-int usbh_ch34x_set_line_state(struct usbh_ch34x *ch34x_class, bool dtr, bool rts);
-
-int usbh_ch34x_bulk_in_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-int usbh_ch34x_bulk_out_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-
-void usbh_ch34x_run(struct usbh_ch34x *ch34x_class);
-void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* USBH_CH34X_H */

+ 0 - 328
components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c

@@ -1,328 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbh_core.h"
-#include "usbh_cp210x.h"
-
-#define DEV_FORMAT "/dev/ttyUSB%d"
-
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cp210x_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
-
-#define CONFIG_USBHOST_MAX_CP210X_CLASS 1
-
-static struct usbh_cp210x g_cp210x_class[CONFIG_USBHOST_MAX_CP210X_CLASS];
-static uint32_t g_devinuse = 0;
-
-static struct usbh_cp210x *usbh_cp210x_class_alloc(void)
-{
-    uint8_t devno;
-
-    for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) {
-        if ((g_devinuse & (1U << devno)) == 0) {
-            g_devinuse |= (1U << devno);
-            memset(&g_cp210x_class[devno], 0, sizeof(struct usbh_cp210x));
-            g_cp210x_class[devno].minor = devno;
-            return &g_cp210x_class[devno];
-        }
-    }
-    return NULL;
-}
-
-static void usbh_cp210x_class_free(struct usbh_cp210x *cp210x_class)
-{
-    uint8_t devno = cp210x_class->minor;
-
-    if (devno < 32) {
-        g_devinuse &= ~(1U << devno);
-    }
-    memset(cp210x_class, 0, sizeof(struct usbh_cp210x));
-}
-
-static int usbh_cp210x_enable(struct usbh_cp210x *cp210x_class)
-{
-    struct usb_setup_packet *setup;
-
-    if (!cp210x_class || !cp210x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = cp210x_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CP210X_IFC_ENABLE;
-    setup->wValue = 1;
-    setup->wIndex = cp210x_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(cp210x_class->hport, setup, NULL);
-}
-
-static int usbh_cp210x_set_flow(struct usbh_cp210x *cp210x_class)
-{
-    struct usb_setup_packet *setup;
-
-    if (!cp210x_class || !cp210x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = cp210x_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CP210X_SET_FLOW;
-    setup->wValue = 0;
-    setup->wIndex = cp210x_class->intf;
-    setup->wLength = 16;
-
-    memset(g_cp210x_buf, 0, 16);
-    g_cp210x_buf[13] = 0x20;
-    return usbh_control_transfer(cp210x_class->hport, setup, g_cp210x_buf);
-}
-
-static int usbh_cp210x_set_chars(struct usbh_cp210x *cp210x_class)
-{
-    struct usb_setup_packet *setup;
-
-    if (!cp210x_class || !cp210x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = cp210x_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CP210X_SET_CHARS;
-    setup->wValue = 0;
-    setup->wIndex = cp210x_class->intf;
-    setup->wLength = 6;
-
-    memset(g_cp210x_buf, 0, 6);
-    g_cp210x_buf[0] = 0x80;
-    g_cp210x_buf[4] = 0x88;
-    g_cp210x_buf[5] = 0x28;
-    return usbh_control_transfer(cp210x_class->hport, setup, g_cp210x_buf);
-}
-
-static int usbh_cp210x_set_baudrate(struct usbh_cp210x *cp210x_class, uint32_t baudrate)
-{
-    struct usb_setup_packet *setup;
-
-    if (!cp210x_class || !cp210x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = cp210x_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CP210X_SET_BAUDRATE;
-    setup->wValue = 0;
-    setup->wIndex = cp210x_class->intf;
-    setup->wLength = 4;
-
-    memcpy(g_cp210x_buf, (uint8_t *)&baudrate, 4);
-    return usbh_control_transfer(cp210x_class->hport, setup, g_cp210x_buf);
-}
-
-static int usbh_cp210x_set_data_format(struct usbh_cp210x *cp210x_class, uint8_t databits, uint8_t parity, uint8_t stopbits)
-{
-    struct usb_setup_packet *setup;
-    uint16_t value;
-
-    if (!cp210x_class || !cp210x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = cp210x_class->hport->setup;
-
-    value = ((databits & 0x0F) << 8) | ((parity & 0x0f) << 4) | ((stopbits & 0x03) << 0);
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CP210X_SET_LINE_CTL;
-    setup->wValue = value;
-    setup->wIndex = cp210x_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(cp210x_class->hport, setup, NULL);
-}
-
-static int usbh_cp210x_set_mhs(struct usbh_cp210x *cp210x_class, uint8_t dtr, uint8_t rts, uint8_t dtr_mask, uint8_t rts_mask)
-{
-    struct usb_setup_packet *setup;
-    uint16_t value;
-
-    if (!cp210x_class || !cp210x_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = cp210x_class->hport->setup;
-
-    value = ((dtr & 0x01) << 0) | ((rts & 0x01) << 1) | ((dtr_mask & 0x01) << 8) | ((rts_mask & 0x01) << 9);
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CP210X_SET_MHS;
-    setup->wValue = value;
-    setup->wIndex = cp210x_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(cp210x_class->hport, setup, NULL);
-}
-
-int usbh_cp210x_set_line_coding(struct usbh_cp210x *cp210x_class, struct cdc_line_coding *line_coding)
-{
-    memcpy((uint8_t *)&cp210x_class->line_coding, line_coding, sizeof(struct cdc_line_coding));
-    usbh_cp210x_set_baudrate(cp210x_class, line_coding->dwDTERate);
-    return usbh_cp210x_set_data_format(cp210x_class, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat);
-}
-
-int usbh_cp210x_get_line_coding(struct usbh_cp210x *cp210x_class, struct cdc_line_coding *line_coding)
-{
-    memcpy(line_coding, (uint8_t *)&cp210x_class->line_coding, sizeof(struct cdc_line_coding));
-    return 0;
-}
-
-int usbh_cp210x_set_line_state(struct usbh_cp210x *cp210x_class, bool dtr, bool rts)
-{
-    return usbh_cp210x_set_mhs(cp210x_class, dtr, rts, 1, 1);
-}
-
-static int usbh_cp210x_connect(struct usbh_hubport *hport, uint8_t intf)
-{
-    struct usb_endpoint_descriptor *ep_desc;
-    int ret = 0;
-
-    struct usbh_cp210x *cp210x_class = usbh_cp210x_class_alloc();
-    if (cp210x_class == NULL) {
-        USB_LOG_ERR("Fail to alloc cp210x_class\r\n");
-        return -USB_ERR_NOMEM;
-    }
-
-    cp210x_class->hport = hport;
-    cp210x_class->intf = intf;
-
-    hport->config.intf[intf].priv = cp210x_class;
-
-    usbh_cp210x_enable(cp210x_class);
-    usbh_cp210x_set_flow(cp210x_class);
-    usbh_cp210x_set_chars(cp210x_class);
-
-    for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
-        ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
-
-        if (ep_desc->bEndpointAddress & 0x80) {
-            USBH_EP_INIT(cp210x_class->bulkin, ep_desc);
-        } else {
-            USBH_EP_INIT(cp210x_class->bulkout, ep_desc);
-        }
-    }
-
-    snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, cp210x_class->minor);
-
-    USB_LOG_INFO("Register CP210X Class:%s\r\n", hport->config.intf[intf].devname);
-
-#if 0
-    USB_LOG_INFO("Test cp2102 rx and tx and rx for 5 times, baudrate is 115200\r\n");
-
-    struct cdc_line_coding linecoding;
-    uint8_t count = 5;
-
-    linecoding.dwDTERate = 115200;
-    linecoding.bDataBits = 8;
-    linecoding.bParityType = 0;
-    linecoding.bCharFormat = 0;
-    usbh_cp210x_set_line_coding(cp210x_class, &linecoding);
-    usbh_cp210x_set_line_state(cp210x_class, true, false);
-
-    memset(g_cp210x_buf, 'a', sizeof(g_cp210x_buf));
-    ret = usbh_cp210x_bulk_out_transfer(cp210x_class, g_cp210x_buf, sizeof(g_cp210x_buf), 0xfffffff);
-    USB_LOG_RAW("out ret:%d\r\n", ret);
-    while (count--) {
-        ret = usbh_cp210x_bulk_in_transfer(cp210x_class, g_cp210x_buf, sizeof(g_cp210x_buf), 0xfffffff);
-        USB_LOG_RAW("in ret:%d\r\n", ret);
-        if (ret > 0) {
-            for (uint32_t i = 0; i < ret; i++) {
-                USB_LOG_RAW("%02x ", g_cp210x_buf[i]);
-            }
-            USB_LOG_RAW("\r\n");
-        }
-    }
-#endif
-    usbh_cp210x_run(cp210x_class);
-    return ret;
-}
-
-static int usbh_cp210x_disconnect(struct usbh_hubport *hport, uint8_t intf)
-{
-    int ret = 0;
-
-    struct usbh_cp210x *cp210x_class = (struct usbh_cp210x *)hport->config.intf[intf].priv;
-
-    if (cp210x_class) {
-        if (cp210x_class->bulkin) {
-            usbh_kill_urb(&cp210x_class->bulkin_urb);
-        }
-
-        if (cp210x_class->bulkout) {
-            usbh_kill_urb(&cp210x_class->bulkout_urb);
-        }
-
-        if (hport->config.intf[intf].devname[0] != '\0') {
-            usb_osal_thread_schedule_other();
-            USB_LOG_INFO("Unregister CP210X Class:%s\r\n", hport->config.intf[intf].devname);
-            usbh_cp210x_stop(cp210x_class);
-        }
-
-        usbh_cp210x_class_free(cp210x_class);
-    }
-
-    return ret;
-}
-
-int usbh_cp210x_bulk_in_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &cp210x_class->bulkin_urb;
-
-    usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-int usbh_cp210x_bulk_out_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &cp210x_class->bulkout_urb;
-
-    usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkout, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-__WEAK void usbh_cp210x_run(struct usbh_cp210x *cp210x_class)
-{
-    (void)cp210x_class;
-}
-
-__WEAK void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class)
-{
-    (void)cp210x_class;
-}
-
-static const uint16_t cp210x_id_table[][2] = {
-    { 0x10C4, 0xEA60 },
-    { 0, 0 },
-};
-
-const struct usbh_class_driver cp210x_class_driver = {
-    .driver_name = "cp210x",
-    .connect = usbh_cp210x_connect,
-    .disconnect = usbh_cp210x_disconnect
-};
-
-CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = {
-    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
-    .bInterfaceClass = 0xff,
-    .bInterfaceSubClass = 0x00,
-    .bInterfaceProtocol = 0x00,
-    .id_table = cp210x_id_table,
-    .class_driver = &cp210x_class_driver
-};

+ 0 - 73
components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.h

@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef USBH_CP210X_H
-#define USBH_CP210X_H
-
-#include "usb_cdc.h"
-
-/* Requests */
-#define CP210X_IFC_ENABLE      0x00
-#define CP210X_SET_BAUDDIV     0x01
-#define CP210X_GET_BAUDDIV     0x02
-#define CP210X_SET_LINE_CTL    0x03 // Set parity, data bits, stop bits
-#define CP210X_GET_LINE_CTL    0x04
-#define CP210X_SET_BREAK       0x05
-#define CP210X_IMM_CHAR        0x06
-#define CP210X_SET_MHS         0x07 // Set DTR, RTS
-#define CP210X_GET_MDMSTS      0x08
-#define CP210X_SET_XON         0x09
-#define CP210X_SET_XOFF        0x0A
-#define CP210X_SET_EVENTMASK   0x0B
-#define CP210X_GET_EVENTMASK   0x0C
-#define CP210X_SET_CHAR        0x0D
-#define CP210X_GET_CHARS       0x0E
-#define CP210X_GET_PROPS       0x0F
-#define CP210X_GET_COMM_STATUS 0x10
-#define CP210X_RESET           0x11
-#define CP210X_PURGE           0x12
-#define CP210X_SET_FLOW        0x13
-#define CP210X_GET_FLOW        0x14
-#define CP210X_EMBED_EVENTS    0x15
-#define CP210X_GET_EVENTSTATE  0x16
-#define CP210X_SET_CHARS       0x19
-#define CP210X_GET_BAUDRATE    0x1D
-#define CP210X_SET_BAUDRATE    0x1E // Set baudrate
-#define CP210X_VENDOR_SPECIFIC 0xFF
-
-struct usbh_cp210x {
-    struct usbh_hubport *hport;
-    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
-    struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
-    struct usbh_urb bulkout_urb;
-    struct usbh_urb bulkin_urb;
-
-    struct cdc_line_coding line_coding;
-
-    uint8_t intf;
-    uint8_t minor;
-
-    void *user_data;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int usbh_cp210x_set_line_coding(struct usbh_cp210x *ftdi_class, struct cdc_line_coding *line_coding);
-int usbh_cp210x_get_line_coding(struct usbh_cp210x *ftdi_class, struct cdc_line_coding *line_coding);
-int usbh_cp210x_set_line_state(struct usbh_cp210x *ftdi_class, bool dtr, bool rts);
-
-int usbh_cp210x_bulk_in_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-int usbh_cp210x_bulk_out_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-
-void usbh_cp210x_run(struct usbh_cp210x *cp210x_class);
-void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* USBH_CP210X_H */

+ 0 - 510
components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c

@@ -1,510 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbh_core.h"
-#include "usbh_ftdi.h"
-
-#define DEV_FORMAT "/dev/ttyUSB%d"
-
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_ftdi_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
-
-#define CONFIG_USBHOST_MAX_FTDI_CLASS 1
-
-static struct usbh_ftdi g_ftdi_class[CONFIG_USBHOST_MAX_FTDI_CLASS];
-static uint32_t g_devinuse = 0;
-
-static const char *ftdi_chip_name[] = {
-    [SIO] = "SIO", /* the serial part of FT8U100AX */
-    [FT232A] = "FT232A",
-    [FT232B] = "FT232B",
-    [FT2232C] = "FT2232C/D",
-    [FT232R] = "FT232R",
-    [FT232H] = "FT232H",
-    [FT2232H] = "FT2232H",
-    [FT4232H] = "FT4232H",
-    [FT4232HA] = "FT4232HA",
-    [FT232HP] = "FT232HP",
-    [FT233HP] = "FT233HP",
-    [FT2232HP] = "FT2232HP",
-    [FT2233HP] = "FT2233HP",
-    [FT4232HP] = "FT4232HP",
-    [FT4233HP] = "FT4233HP",
-    [FTX] = "FT-X",
-};
-
-static struct usbh_ftdi *usbh_ftdi_class_alloc(void)
-{
-    uint8_t devno;
-
-    for (devno = 0; devno < CONFIG_USBHOST_MAX_FTDI_CLASS; devno++) {
-        if ((g_devinuse & (1U << devno)) == 0) {
-            g_devinuse |= (1U << devno);
-            memset(&g_ftdi_class[devno], 0, sizeof(struct usbh_ftdi));
-            g_ftdi_class[devno].minor = devno;
-            return &g_ftdi_class[devno];
-        }
-    }
-    return NULL;
-}
-
-static void usbh_ftdi_class_free(struct usbh_ftdi *ftdi_class)
-{
-    uint8_t devno = ftdi_class->minor;
-
-    if (devno < 32) {
-        g_devinuse &= ~(1U << devno);
-    }
-    memset(ftdi_class, 0, sizeof(struct usbh_ftdi));
-}
-
-/*
- * Divide positive or negative dividend by positive or negative divisor
- * and round to closest integer. Result is undefined for negative
- * divisors if the dividend variable type is unsigned and for negative
- * dividends if the divisor variable type is unsigned.
- */
-#define DIV_ROUND_CLOSEST(x, divisor) (       \
-    {                                         \
-        typeof(x) __x = x;                    \
-        typeof(divisor) __d = divisor;        \
-        (((typeof(x))-1) > 0 ||               \
-         ((typeof(divisor))-1) > 0 ||         \
-         (((__x) > 0) == ((__d) > 0))) ?      \
-            (((__x) + ((__d) / 2)) / (__d)) : \
-            (((__x) - ((__d) / 2)) / (__d));  \
-    })
-
-static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, int base)
-{
-    static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
-    uint32_t divisor;
-    /* divisor shifted 3 bits to the left */
-    int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud);
-    divisor = divisor3 >> 3;
-    divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14;
-    /* Deal with special cases for highest baud rates. */
-    if (divisor == 1) /* 1.0 */
-        divisor = 0;
-    else if (divisor == 0x4001) /* 1.5 */
-        divisor = 1;
-    return divisor;
-}
-
-static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud)
-{
-    return ftdi_232bm_baud_base_to_divisor(baud, 48000000);
-}
-
-static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, int base)
-{
-    static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
-    uint32_t divisor;
-    int divisor3;
-
-    /* hi-speed baud rate is 10-bit sampling instead of 16-bit */
-    divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud);
-
-    divisor = divisor3 >> 3;
-    divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14;
-    /* Deal with special cases for highest baud rates. */
-    if (divisor == 1) /* 1.0 */
-        divisor = 0;
-    else if (divisor == 0x4001) /* 1.5 */
-        divisor = 1;
-    /*
-	 * Set this bit to turn off a divide by 2.5 on baud rate generator
-	 * This enables baud rates up to 12Mbaud but cannot reach below 1200
-	 * baud with this bit set
-	 */
-    divisor |= 0x00020000;
-    return divisor;
-}
-
-static uint32_t ftdi_2232h_baud_to_divisor(uint32_t baud)
-{
-    return ftdi_2232h_baud_base_to_divisor(baud, 120000000);
-}
-
-int usbh_ftdi_reset(struct usbh_ftdi *ftdi_class)
-{
-    struct usb_setup_packet *setup;
-
-    if (!ftdi_class || !ftdi_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ftdi_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = SIO_RESET_REQUEST;
-    setup->wValue = 0;
-    setup->wIndex = ftdi_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ftdi_class->hport, setup, NULL);
-}
-
-static int usbh_ftdi_set_modem(struct usbh_ftdi *ftdi_class, uint16_t value)
-{
-    struct usb_setup_packet *setup;
-
-    if (!ftdi_class || !ftdi_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ftdi_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = SIO_SET_MODEM_CTRL_REQUEST;
-    setup->wValue = value;
-    setup->wIndex = ftdi_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ftdi_class->hport, setup, NULL);
-}
-
-static int usbh_ftdi_set_baudrate(struct usbh_ftdi *ftdi_class, uint32_t baudrate)
-{
-    struct usb_setup_packet *setup;
-    uint32_t div_value;
-    uint16_t value;
-    uint8_t baudrate_high;
-
-    if (!ftdi_class || !ftdi_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ftdi_class->hport->setup;
-
-    switch (ftdi_class->chip_type) {
-        case FT232B:
-        case FT2232C:
-        case FT232R:
-            if (baudrate > 3000000) {
-                return -USB_ERR_INVAL;
-            }
-            div_value = ftdi_232bm_baud_to_divisor(baudrate);
-            break;
-        default:
-            if ((baudrate <= 12000000) && (baudrate >= 1200)) {
-                div_value = ftdi_2232h_baud_to_divisor(baudrate);
-            } else {
-                return -USB_ERR_INVAL;
-            }
-            break;
-    }
-
-    value = div_value & 0xFFFF;
-    baudrate_high = (div_value >> 16) & 0xff;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = SIO_SET_BAUDRATE_REQUEST;
-    setup->wValue = value;
-    setup->wIndex = (baudrate_high << 8) | ftdi_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ftdi_class->hport, setup, NULL);
-}
-
-static int usbh_ftdi_set_data_format(struct usbh_ftdi *ftdi_class, uint8_t databits, uint8_t parity, uint8_t stopbits, uint8_t isbreak)
-{
-    /**
-     * D0-D7 databits  BITS_7=7, BITS_8=8
-     * D8-D10 parity  NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4
-     * D11-D12 		STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2
-     * D14  		BREAK_OFF=0, BREAK_ON=1
-     **/
-    struct usb_setup_packet *setup;
-    uint16_t value;
-
-    if (!ftdi_class || !ftdi_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ftdi_class->hport->setup;
-
-    value = ((isbreak & 0x01) << 14) | ((stopbits & 0x03) << 11) | ((parity & 0x0f) << 8) | (databits & 0x0f);
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = SIO_SET_DATA_REQUEST;
-    setup->wValue = value;
-    setup->wIndex = ftdi_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ftdi_class->hport, setup, NULL);
-}
-
-static int usbh_ftdi_set_latency_timer(struct usbh_ftdi *ftdi_class, uint16_t value)
-{
-    struct usb_setup_packet *setup;
-
-    if (!ftdi_class || !ftdi_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ftdi_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = SIO_SET_LATENCY_TIMER_REQUEST;
-    setup->wValue = value;
-    setup->wIndex = ftdi_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ftdi_class->hport, setup, NULL);
-}
-
-static int usbh_ftdi_set_flow_ctrl(struct usbh_ftdi *ftdi_class, uint16_t value)
-{
-    struct usb_setup_packet *setup;
-
-    if (!ftdi_class || !ftdi_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ftdi_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = SIO_SET_FLOW_CTRL_REQUEST;
-    setup->wValue = value;
-    setup->wIndex = ftdi_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(ftdi_class->hport, setup, NULL);
-}
-
-static int usbh_ftdi_read_modem_status(struct usbh_ftdi *ftdi_class)
-{
-    struct usb_setup_packet *setup;
-    int ret;
-
-    if (!ftdi_class || !ftdi_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = ftdi_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
-    setup->bRequest = SIO_POLL_MODEM_STATUS_REQUEST;
-    setup->wValue = 0x0000;
-    setup->wIndex = ftdi_class->intf;
-    setup->wLength = 2;
-
-    ret = usbh_control_transfer(ftdi_class->hport, setup, g_ftdi_buf);
-    if (ret < 0) {
-        return ret;
-    }
-    memcpy(ftdi_class->modem_status, g_ftdi_buf, 2);
-    return ret;
-}
-
-int usbh_ftdi_set_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding)
-{
-    memcpy((uint8_t *)&ftdi_class->line_coding, line_coding, sizeof(struct cdc_line_coding));
-
-    int ret = usbh_ftdi_set_baudrate(ftdi_class, line_coding->dwDTERate);
-    if (ret < 0) {
-        return ret;
-    }
-    return usbh_ftdi_set_data_format(ftdi_class, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat, 0);
-}
-
-int usbh_ftdi_get_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding)
-{
-    memcpy(line_coding, (uint8_t *)&ftdi_class->line_coding, sizeof(struct cdc_line_coding));
-    return 0;
-}
-
-int usbh_ftdi_set_line_state(struct usbh_ftdi *ftdi_class, bool dtr, bool rts)
-{
-    int ret;
-
-    if (dtr) {
-        usbh_ftdi_set_modem(ftdi_class, SIO_SET_DTR_HIGH);
-    } else {
-        usbh_ftdi_set_modem(ftdi_class, SIO_SET_DTR_LOW);
-    }
-
-    if (rts) {
-        ret = usbh_ftdi_set_modem(ftdi_class, SIO_SET_RTS_HIGH);
-    } else {
-        ret = usbh_ftdi_set_modem(ftdi_class, SIO_SET_RTS_LOW);
-    }
-
-    return ret;
-}
-
-static int usbh_ftdi_connect(struct usbh_hubport *hport, uint8_t intf)
-{
-    struct usb_endpoint_descriptor *ep_desc;
-    int ret = 0;
-    uint16_t version;
-
-    struct usbh_ftdi *ftdi_class = usbh_ftdi_class_alloc();
-    if (ftdi_class == NULL) {
-        USB_LOG_ERR("Fail to alloc ftdi_class\r\n");
-        return -USB_ERR_NOMEM;
-    }
-
-    ftdi_class->hport = hport;
-    ftdi_class->intf = intf;
-
-    hport->config.intf[intf].priv = ftdi_class;
-
-    version = hport->device_desc.bcdDevice;
-
-    switch (version) {
-        case 0x400:
-            ftdi_class->chip_type = FT232B;
-            break;
-        case 0x500:
-            ftdi_class->chip_type = FT2232C;
-            break;
-        case 0x600:
-            ftdi_class->chip_type = FT232R;
-            break;
-        case 0x700:
-            ftdi_class->chip_type = FT2232H;
-            break;
-        case 0x800:
-            ftdi_class->chip_type = FT4232H;
-            break;
-        case 0x900:
-            ftdi_class->chip_type = FT232H;
-            break;
-
-        default:
-            USB_LOG_ERR("Unknown FTDI chip version:%04x\r\n", version);
-            return -USB_ERR_NOTSUPP;
-    }
-
-    USB_LOG_INFO("FTDI chip name:%s\r\n", ftdi_chip_name[ftdi_class->chip_type]);
-
-    usbh_ftdi_reset(ftdi_class);
-    usbh_ftdi_set_flow_ctrl(ftdi_class, SIO_DISABLE_FLOW_CTRL);
-    usbh_ftdi_set_latency_timer(ftdi_class, 0x10);
-    usbh_ftdi_read_modem_status(ftdi_class);
-    USB_LOG_INFO("modem status:%02x:%02x\r\n", ftdi_class->modem_status[0], ftdi_class->modem_status[1]);
-
-    for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
-        ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
-
-        if (ep_desc->bEndpointAddress & 0x80) {
-            USBH_EP_INIT(ftdi_class->bulkin, ep_desc);
-        } else {
-            USBH_EP_INIT(ftdi_class->bulkout, ep_desc);
-        }
-    }
-
-    snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, ftdi_class->minor);
-
-    USB_LOG_INFO("Register FTDI Class:%s\r\n", hport->config.intf[intf].devname);
-
-#if 0
-    USB_LOG_INFO("Test ftdi rx and tx and rx for 5 times, baudrate is 115200\r\n");
-
-    struct cdc_line_coding linecoding;
-    uint8_t count = 5;
-
-    linecoding.dwDTERate = 115200;
-    linecoding.bDataBits = 8;
-    linecoding.bParityType = 0;
-    linecoding.bCharFormat = 0;
-    usbh_ftdi_set_line_coding(ftdi_class, &linecoding);
-    usbh_ftdi_set_line_state(ftdi_class, true, false);
-
-    memset(g_ftdi_buf, 'a', sizeof(g_ftdi_buf));
-    ret = usbh_ftdi_bulk_out_transfer(ftdi_class, g_ftdi_buf, sizeof(g_ftdi_buf), 0xfffffff);
-    USB_LOG_RAW("out ret:%d\r\n", ret);
-    while (count--) {
-        ret = usbh_ftdi_bulk_in_transfer(ftdi_class, g_ftdi_buf, sizeof(g_ftdi_buf), 0xfffffff);
-        USB_LOG_RAW("in ret:%d\r\n", ret);
-        if (ret > 0) {
-            for (uint32_t i = 0; i < ret; i++) {
-                USB_LOG_RAW("%02x ", g_ftdi_buf[i]);
-            }
-        }
-        USB_LOG_RAW("\r\n");
-    }
-#endif
-    usbh_ftdi_run(ftdi_class);
-    return ret;
-}
-
-static int usbh_ftdi_disconnect(struct usbh_hubport *hport, uint8_t intf)
-{
-    int ret = 0;
-
-    struct usbh_ftdi *ftdi_class = (struct usbh_ftdi *)hport->config.intf[intf].priv;
-
-    if (ftdi_class) {
-        if (ftdi_class->bulkin) {
-            usbh_kill_urb(&ftdi_class->bulkin_urb);
-        }
-
-        if (ftdi_class->bulkout) {
-            usbh_kill_urb(&ftdi_class->bulkout_urb);
-        }
-
-        if (hport->config.intf[intf].devname[0] != '\0') {
-            usb_osal_thread_schedule_other();
-            USB_LOG_INFO("Unregister FTDI Class:%s\r\n", hport->config.intf[intf].devname);
-            usbh_ftdi_stop(ftdi_class);
-        }
-
-        usbh_ftdi_class_free(ftdi_class);
-    }
-
-    return ret;
-}
-
-int usbh_ftdi_bulk_in_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &ftdi_class->bulkin_urb;
-
-    usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-int usbh_ftdi_bulk_out_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &ftdi_class->bulkout_urb;
-
-    usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkout, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-__WEAK void usbh_ftdi_run(struct usbh_ftdi *ftdi_class)
-{
-    (void)ftdi_class;
-}
-
-__WEAK void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class)
-{
-    (void)ftdi_class;
-}
-
-static const uint16_t ftdi_id_table[][2] = {
-    { 0x0403, 0x6001 },
-    { 0x0403, 0x6010 },
-    { 0, 0 },
-};
-
-const struct usbh_class_driver ftdi_class_driver = {
-    .driver_name = "ftdi",
-    .connect = usbh_ftdi_connect,
-    .disconnect = usbh_ftdi_disconnect
-};
-
-CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = {
-    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
-    .bInterfaceClass = 0xff,
-    .bInterfaceSubClass = 0x00,
-    .bInterfaceProtocol = 0x00,
-    .id_table = ftdi_id_table,
-    .class_driver = &ftdi_class_driver
-};

+ 0 - 96
components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.h

@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef USBH_FTDI_H
-#define USBH_FTDI_H
-
-#include "usb_cdc.h"
-
-/* Requests */
-#define SIO_RESET_REQUEST             0x00 /* Reset the port */
-#define SIO_SET_MODEM_CTRL_REQUEST    0x01 /* Set the modem control register */
-#define SIO_SET_FLOW_CTRL_REQUEST     0x02 /* Set flow control register */
-#define SIO_SET_BAUDRATE_REQUEST      0x03 /* Set baud rate */
-#define SIO_SET_DATA_REQUEST          0x04 /* Set the data characteristics of the port */
-#define SIO_POLL_MODEM_STATUS_REQUEST 0x05
-#define SIO_SET_EVENT_CHAR_REQUEST    0x06
-#define SIO_SET_ERROR_CHAR_REQUEST    0x07
-#define SIO_SET_LATENCY_TIMER_REQUEST 0x09
-#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A
-#define SIO_SET_BITMODE_REQUEST       0x0B
-#define SIO_READ_PINS_REQUEST         0x0C
-#define SIO_READ_EEPROM_REQUEST       0x90
-#define SIO_WRITE_EEPROM_REQUEST      0x91
-#define SIO_ERASE_EEPROM_REQUEST      0x92
-
-#define SIO_DISABLE_FLOW_CTRL 0x0
-#define SIO_RTS_CTS_HS        (0x1 << 8)
-#define SIO_DTR_DSR_HS        (0x2 << 8)
-#define SIO_XON_XOFF_HS       (0x4 << 8)
-
-#define SIO_SET_DTR_MASK 0x1
-#define SIO_SET_DTR_HIGH (1 | (SIO_SET_DTR_MASK << 8))
-#define SIO_SET_DTR_LOW  (0 | (SIO_SET_DTR_MASK << 8))
-#define SIO_SET_RTS_MASK 0x2
-#define SIO_SET_RTS_HIGH (2 | (SIO_SET_RTS_MASK << 8))
-#define SIO_SET_RTS_LOW  (0 | (SIO_SET_RTS_MASK << 8))
-
-#define SIO_RTS_CTS_HS (0x1 << 8)
-
-enum ftdi_chip_type {
-    SIO,
-    FT232A,
-    FT232B,
-    FT2232C,
-    FT232R,
-    FT232H,
-    FT2232H,
-    FT4232H,
-    FT4232HA,
-    FT232HP,
-    FT233HP,
-    FT2232HP,
-    FT2233HP,
-    FT4232HP,
-    FT4233HP,
-    FTX,
-};
-
-struct usbh_ftdi {
-    struct usbh_hubport *hport;
-    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
-    struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
-    struct usbh_urb bulkout_urb;
-    struct usbh_urb bulkin_urb;
-
-    struct cdc_line_coding line_coding;
-
-    uint8_t intf;
-    uint8_t minor;
-    uint8_t modem_status[2];
-    enum ftdi_chip_type chip_type;
-
-    void *user_data;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int usbh_ftdi_set_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding);
-int usbh_ftdi_get_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding);
-int usbh_ftdi_set_line_state(struct usbh_ftdi *ftdi_class, bool dtr, bool rts);
-
-int usbh_ftdi_bulk_in_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-int usbh_ftdi_bulk_out_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-
-void usbh_ftdi_run(struct usbh_ftdi *ftdi_class);
-void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* USBH_FTDI_H */

+ 0 - 449
components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c

@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- * Copyright (c) 2024, Derek Konigsberg
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbh_core.h"
-#include "usbh_pl2303.h"
-
-#undef USB_DBG_TAG
-#define USB_DBG_TAG "usbh_pl2303"
-#include "usb_log.h"
-
-#define DEV_FORMAT "/dev/ttyUSB%d"
-
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_pl2303_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
-
-#define CONFIG_USBHOST_MAX_PL2303_CLASS 1
-
-#define UT_WRITE_VENDOR_DEVICE   (USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE)
-#define UT_READ_VENDOR_DEVICE    (USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE)
-
-static struct usbh_pl2303 g_pl2303_class[CONFIG_USBHOST_MAX_PL2303_CLASS];
-static uint32_t g_devinuse = 0;
-
-static struct usbh_pl2303 *usbh_pl2303_class_alloc(void)
-{
-    uint8_t devno;
-
-    for (devno = 0; devno < CONFIG_USBHOST_MAX_PL2303_CLASS; devno++) {
-        if ((g_devinuse & (1U << devno)) == 0) {
-            g_devinuse |= (1U << devno);
-            memset(&g_pl2303_class[devno], 0, sizeof(struct usbh_pl2303));
-            g_pl2303_class[devno].minor = devno;
-            return &g_pl2303_class[devno];
-        }
-    }
-    return NULL;
-}
-
-static void usbh_pl2303_class_free(struct usbh_pl2303 *pl2303_class)
-{
-    uint8_t devno = pl2303_class->minor;
-
-    if (devno < 32) {
-        g_devinuse &= ~(1U << devno);
-    }
-    memset(pl2303_class, 0, sizeof(struct usbh_pl2303));
-}
-
-static int usbh_pl2303_get_chiptype(struct usbh_pl2303 *pl2303_class)
-{
-    int ret = 0;
-
-    switch (pl2303_class->hport->device_desc.bcdDevice) {
-        case 0x0300:
-            pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HX;
-            /* or TA, that is HX with external crystal */
-            break;
-        case 0x0400:
-            pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HXD;
-            /* or EA, that is HXD with ESD protection */
-            /* or RA, that has internal voltage level converter that works only up to 1Mbaud (!) */
-            break;
-        case 0x0500:
-            pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HXD;
-            /* in fact it's TB, that is HXD with external crystal */
-            break;
-        default:
-            /* NOTE: I have no info about the bcdDevice for the base PL2303 (up to 1.2Mbaud,
-           only fixed rates) and for PL2303SA (8-pin chip, up to 115200 baud */
-            /* Determine the chip type.  This algorithm is taken from Linux. */
-            if (pl2303_class->hport->device_desc.bDeviceClass == 0x02) {
-                pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303;
-            } else if (pl2303_class->hport->device_desc.bMaxPacketSize0 == 0x40) {
-                pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HX;
-            } else {
-                pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303;
-            }
-            break;
-    }
-
-    /*
-     * The new chip revision PL2303HXN is only compatible with the new
-     * PLCOM_SET_REQUEST_PL2303HXN command. Issuing the old command
-     * PLCOM_SET_REQUEST to the new chip raises an error. Thus, PL2303HX
-     * and PL2303HXN can be distinguished by issuing an old-style request
-     * (on a status register) to the new chip and checking the error.
-     */
-    if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HX) {
-        struct usb_setup_packet *setup = pl2303_class->hport->setup;
-
-        setup->bmRequestType = UT_READ_VENDOR_DEVICE;
-        setup->bRequest = PL2303_SET_REQUEST;
-        setup->wValue = PL2303_STATUS_REG_PL2303HX;
-        setup->wIndex = 0;
-        setup->wLength = 1;
-
-        ret = usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf);
-        if (ret == -USB_ERR_STALL) {
-            pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HXN;
-            ret = 0;
-        } else if (ret < 0) {
-            USB_LOG_WRN("Error checking chip type: %d\r\n", ret);
-            return ret;
-        }
-    }
-
-    switch (pl2303_class->chiptype) {
-        case USBH_PL2303_TYPE_PL2303:
-            USB_LOG_INFO("chiptype = 2303\r\n");
-            break;
-        case USBH_PL2303_TYPE_PL2303HX:
-            USB_LOG_INFO("chiptype = 2303HX/TA\r\n");
-            break;
-        case USBH_PL2303_TYPE_PL2303HXN:
-            USB_LOG_INFO("chiptype = 2303HXN\r\n");
-            break;
-        case USBH_PL2303_TYPE_PL2303HXD:
-            USB_LOG_INFO("chiptype = 2303HXD/TB/RA/EA\r\n");
-            break;
-        default:
-            USB_LOG_INFO("chiptype = [%d]\r\n", pl2303_class->chiptype);
-            break;
-    }
-
-    return ret;
-}
-
-static int usbh_pl2303_do(struct usbh_pl2303 *pl2303_class,
-                          uint8_t req_type, uint8_t request, uint16_t value, uint16_t index,
-                          uint16_t length)
-{
-    struct usb_setup_packet *setup;
-
-    if (!pl2303_class || !pl2303_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = pl2303_class->hport->setup;
-
-    setup->bmRequestType = req_type;
-    setup->bRequest = request;
-    setup->wValue = value;
-    setup->wIndex = index;
-    setup->wLength = length;
-
-    return usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf);
-}
-
-int usbh_pl2303_set_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding)
-{
-    struct usb_setup_packet *setup;
-
-    if (!pl2303_class || !pl2303_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = pl2303_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CDC_REQUEST_SET_LINE_CODING;
-    setup->wValue = 0;
-    setup->wIndex = pl2303_class->intf;
-    setup->wLength = 7;
-
-    memcpy(g_pl2303_buf, line_coding, sizeof(struct cdc_line_coding));
-
-    return usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf);
-}
-
-int usbh_pl2303_get_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding)
-{
-    struct usb_setup_packet *setup;
-    int ret;
-
-    if (!pl2303_class || !pl2303_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = pl2303_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CDC_REQUEST_GET_LINE_CODING;
-    setup->wValue = 0;
-    setup->wIndex = pl2303_class->intf;
-    setup->wLength = 7;
-
-    ret = usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf);
-    if (ret < 0) {
-        return ret;
-    }
-    memcpy(line_coding, g_pl2303_buf, sizeof(struct cdc_line_coding));
-    return ret;
-}
-
-int usbh_pl2303_set_line_state(struct usbh_pl2303 *pl2303_class, bool dtr, bool rts)
-{
-    struct usb_setup_packet *setup;
-
-    if (!pl2303_class || !pl2303_class->hport) {
-        return -USB_ERR_INVAL;
-    }
-    setup = pl2303_class->hport->setup;
-
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE;
-    setup->wValue = (dtr << 0) | (rts << 1);
-    setup->wIndex = pl2303_class->intf;
-    setup->wLength = 0;
-
-    return usbh_control_transfer(pl2303_class->hport, setup, NULL);
-}
-
-static int usbh_pl2303_connect(struct usbh_hubport *hport, uint8_t intf)
-{
-    struct usb_endpoint_descriptor *ep_desc;
-    int ret = 0;
-
-    struct usbh_pl2303 *pl2303_class = usbh_pl2303_class_alloc();
-    if (pl2303_class == NULL) {
-        USB_LOG_ERR("Fail to alloc pl2303_class\r\n");
-        return -USB_ERR_NOMEM;
-    }
-
-    pl2303_class->hport = hport;
-    pl2303_class->intf = intf;
-
-    hport->config.intf[intf].priv = pl2303_class;
-
-    do {
-        ret = usbh_pl2303_get_chiptype(pl2303_class);
-        if (ret < 0) {
-            break;
-        }
-
-        /* Startup reset sequence, if necessary for the chip type */
-        if (pl2303_class->chiptype != USBH_PL2303_TYPE_PL2303HXN) {
-            struct usb_setup_packet *setup = pl2303_class->hport->setup;
-
-            setup->bmRequestType = UT_WRITE_VENDOR_DEVICE;
-            setup->bRequest = PL2303_SET_REQUEST;
-            setup->wValue = 0;
-            setup->wIndex = pl2303_class->intf;
-            setup->wLength = 0;
-
-            ret = usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf);
-            if (ret < 0) {
-                USB_LOG_WRN("Initialization reset failed: %d\r\n", ret);
-                break;
-            }
-        }
-
-        if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303) {
-            /* HX variants seem to lock up after a clear stall request. */
-            /*
-             * The FreeBSD code sets the stall flags on the in and out pipes
-             * here. Have no idea exactly how to do this, or if it is necessary.
-             * May just leave this code unwritten until test hardware is available.
-             */
-        } else if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HX || pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HXD) {
-            /* Reset upstream data pipes */
-            ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 8, 0, 0);
-            if (ret < 0) {
-                USB_LOG_WRN("Could not reset upstream data pipes (8,0): %d\r\n", ret);
-                break;
-            }
-            ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 9, 0, 0);
-            if (ret < 0) {
-                USB_LOG_WRN("Could not reset upstream data pipes (9,0): %d\r\n", ret);
-                break;
-            }
-        } else if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HXN) {
-            /* Reset upstream data pipes */
-            ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST_PL2303HXN, 0x07, 0x03, 0);
-            if (ret < 0) {
-                USB_LOG_WRN("Could not reset upstream data pipes (7,3): %d\r\n", ret);
-                break;
-            }
-        }
-
-        /* Final device initialization, if necessary for the chip type */
-        if (pl2303_class->chiptype != USBH_PL2303_TYPE_PL2303HXN) {
-            if (usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x0404, 0, 0) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8383, 0, 1) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x0404, 1, 0) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8383, 0, 1) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 0, 1, 0) < 0 ||
-                usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 1, 0, 0) < 0) {
-                USB_LOG_WRN("Could not complete init sequence\r\n");
-                ret = -USB_ERR_INVAL;
-                break;
-            }
-
-            if (pl2303_class->chiptype != USBH_PL2303_TYPE_PL2303) {
-                ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 2, 0x44, 0);
-            } else {
-                ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 2, 0x24, 0);
-            }
-            if (ret < 0) {
-                USB_LOG_WRN("Could not complete final init request: %d\r\n", ret);
-                break;
-            }
-        }
-    } while (0);
-
-    if (ret < 0) {
-        USB_LOG_ERR("Failed to initialize PL2303 device: %d\r\n", ret);
-        return ret;
-    }
-
-    for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
-        ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
-        if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
-            continue;
-        } else {
-            if (ep_desc->bEndpointAddress & 0x80) {
-                USBH_EP_INIT(pl2303_class->bulkin, ep_desc);
-            } else {
-                USBH_EP_INIT(pl2303_class->bulkout, ep_desc);
-            }
-        }
-    }
-
-    snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, pl2303_class->minor);
-
-    USB_LOG_INFO("Register PL2303 Class:%s\r\n", hport->config.intf[intf].devname);
-
-#if 0
-    USB_LOG_INFO("Test pl2303 rx and tx and rx for 5 times, baudrate is 115200\r\n");
-
-    struct cdc_line_coding linecoding;
-    uint8_t count = 5;
-
-    linecoding.dwDTERate = 115200;
-    linecoding.bDataBits = 8;
-    linecoding.bParityType = 0;
-    linecoding.bCharFormat = 0;
-    usbh_pl2303_set_line_coding(pl2303_class, &linecoding);
-    usbh_pl2303_set_line_state(pl2303_class, true, false);
-
-    memset(g_pl2303_buf, 'a', sizeof(g_pl2303_buf));
-    ret = usbh_pl2303_bulk_out_transfer(pl2303_class, g_pl2303_buf, sizeof(g_pl2303_buf), 0xfffffff);
-    USB_LOG_RAW("out ret:%d\r\n", ret);
-    while (count--) {
-        ret = usbh_pl2303_bulk_in_transfer(pl2303_class, g_pl2303_buf, sizeof(g_pl2303_buf), 0xfffffff);
-        USB_LOG_RAW("in ret:%d\r\n", ret);
-        if (ret > 0) {
-            for (uint32_t i = 0; i < ret; i++) {
-                USB_LOG_RAW("%02x ", g_pl2303_buf[i]);
-            }
-        }
-        USB_LOG_RAW("\r\n");
-    }
-#endif
-
-    usbh_pl2303_run(pl2303_class);
-    return ret;
-}
-
-static int usbh_pl2303_disconnect(struct usbh_hubport *hport, uint8_t intf)
-{
-    int ret = 0;
-
-    struct usbh_pl2303 *pl2303_class = (struct usbh_pl2303 *)hport->config.intf[intf].priv;
-
-    if (pl2303_class) {
-        if (pl2303_class->bulkin) {
-            usbh_kill_urb(&pl2303_class->bulkin_urb);
-        }
-
-        if (pl2303_class->bulkout) {
-            usbh_kill_urb(&pl2303_class->bulkout_urb);
-        }
-
-        if (hport->config.intf[intf].devname[0] != '\0') {
-            usb_osal_thread_schedule_other();
-            USB_LOG_INFO("Unregister PL2303 Class:%s\r\n", hport->config.intf[intf].devname);
-            usbh_pl2303_stop(pl2303_class);
-        }
-
-        usbh_pl2303_class_free(pl2303_class);
-    }
-
-    return ret;
-}
-
-int usbh_pl2303_bulk_in_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &pl2303_class->bulkin_urb;
-
-    usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-int usbh_pl2303_bulk_out_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &pl2303_class->bulkout_urb;
-
-    usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkout, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-__WEAK void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class)
-{
-    (void)pl2303_class;
-}
-
-__WEAK void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
-{
-    (void)pl2303_class;
-}
-
-static const uint16_t pl2303_id_table[][2] = {
-    { 0x067B, 0x2303 }, // PL2303 Serial (ATEN/IOGEAR UC232A)
-    { 0x067B, 0x23A3 }, // PL2303HXN Serial, type GC
-    { 0x067B, 0x23B3 }, // PL2303HXN Serial, type GB
-    { 0x067B, 0x23C3 }, // PL2303HXN Serial, type GT
-    { 0x067B, 0x23D3 }, // PL2303HXN Serial, type GL
-    { 0x067B, 0x23E3 }, // PL2303HXN Serial, type GE
-    { 0x067B, 0x23F3 }, // PL2303HXN Serial, type GS
-    { 0, 0 },
-};
-
-const struct usbh_class_driver pl2303_class_driver = {
-    .driver_name = "pl2303",
-    .connect = usbh_pl2303_connect,
-    .disconnect = usbh_pl2303_disconnect
-};
-
-CLASS_INFO_DEFINE const struct usbh_class_info pl2303_class_info = {
-    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
-    .bInterfaceClass = 0xff,
-    .bInterfaceSubClass = 0x00,
-    .bInterfaceProtocol = 0x00,
-    .id_table = pl2303_id_table,
-    .class_driver = &pl2303_class_driver
-};

+ 0 - 62
components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.h

@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef USBH_PL2303_H
-#define USBH_PL2303_H
-
-#include "usb_cdc.h"
-
-#define PL2303_SET_REQUEST             0x01
-#define PL2303_SET_REQUEST_PL2303HXN   0x80
-#define PL2303_SET_CRTSCTS             0x41
-#define PL2303_SET_CRTSCTS_PL2303X     0x61
-#define PL2303_SET_CRTSCTS_PL2303HXN   0xFA
-#define PL2303_CLEAR_CRTSCTS_PL2303HXN 0xFF
-#define PL2303_CRTSCTS_REG_PL2303HXN   0x0A
-#define PL2303_STATUS_REG_PL2303HX     0x8080
-
-/* Different PL2303 IC types */
-#define USBH_PL2303_TYPE_UNKNOWN   0
-#define USBH_PL2303_TYPE_PL2303    1
-#define USBH_PL2303_TYPE_PL2303HX  2
-#define USBH_PL2303_TYPE_PL2303HXD 3
-#define USBH_PL2303_TYPE_PL2303HXN 4
-
-struct usbh_pl2303 {
-    struct usbh_hubport *hport;
-    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
-    struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
-
-    struct usbh_urb bulkout_urb;
-    struct usbh_urb bulkin_urb;
-
-    struct cdc_line_coding linecoding;
-
-    uint8_t intf;
-    uint8_t minor;
-    uint8_t chiptype;
-
-    void *user_data;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int usbh_pl2303_set_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding);
-int usbh_pl2303_get_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding);
-int usbh_pl2303_set_line_state(struct usbh_pl2303 *pl2303_class, bool dtr, bool rts);
-
-int usbh_pl2303_bulk_in_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-int usbh_pl2303_bulk_out_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
-
-void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class);
-void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* USBH_PL2303_H */

+ 0 - 0
components/drivers/usb/cherryusb/class/vendor/wifi/.gitkeep


+ 0 - 6
components/drivers/usb/cherryusb/class/vendor/wifi/README.md

@@ -1,6 +0,0 @@
-# BL616 USB WIFI
-
-Usbwifi firmware please contact bouffalolab. You can purchase a module in the following ways:
-
-- https://iot.mi.com/moduleBrowser.html
-- https://docs.ai-thinker.com/ai_m61

+ 0 - 513
components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c

@@ -1,513 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbh_core.h"
-#include "usbh_bl616.h"
-
-#undef USB_DBG_TAG
-#define USB_DBG_TAG "usbh_bl616"
-#include "usb_log.h"
-
-#define DEV_FORMAT "/dev/wifi/bl616"
-
-#define MAC_FMT      "%02X:%02X:%02X:%02X:%02X:%02X"
-#define ARR_ELE_6(e) (e)[0], (e)[1], (e)[2], (e)[3], (e)[4], (e)[5]
-
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_tx_buffer[2048 + 512];
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_rx_buffer[2048 + 512];
-
-static struct usbh_bl616 g_bl616_class;
-
-static const char *auth_to_str(uint8_t auth)
-{
-    const char *table[RNM_WIFI_AUTH_MAX] = {
-        [RNM_WIFI_AUTH_UNKNOWN] = "UNKNOWN",
-        [RNM_WIFI_AUTH_OPEN] = "OPEN",
-        [RNM_WIFI_AUTH_WEP] = "WEP",
-        [RNM_WIFI_AUTH_WPA_PSK] = "WPA-PSK",
-        [RNM_WIFI_AUTH_WPA2_PSK] = "WPA2-PSK",
-        [RNM_WIFI_AUTH_WPA_WPA2_PSK] = "WPA2-PSK/WPA-PSK",
-        [RNM_WIFI_AUTH_WPA_ENTERPRISE] = "WPA-ENT",
-        [RNM_WIFI_AUTH_WPA3_SAE] = "WPA3-SAE",
-        [RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE] = "WPA2-PSK/WPA3-SAE",
-    };
-    if (auth < RNM_WIFI_AUTH_MAX)
-        return table[auth];
-    else
-        return table[RNM_WIFI_AUTH_UNKNOWN];
-}
-
-static const char *cipher_to_str(uint8_t cipher)
-{
-    const char *table[RNM_WIFI_CIPHER_MAX] = {
-        [RNM_WIFI_CIPHER_UNKNOWN] = "UNKNOWN",
-        [RNM_WIFI_CIPHER_NONE] = "NONE",
-        [RNM_WIFI_CIPHER_WEP] = "WEP",
-        [RNM_WIFI_CIPHER_AES] = "AES",
-        [RNM_WIFI_CIPHER_TKIP] = "TKIP",
-        [RNM_WIFI_CIPHER_TKIP_AES] = "TKIP/AES",
-    };
-    if (cipher < RNM_WIFI_CIPHER_MAX)
-        return table[cipher];
-    else
-        return table[RNM_WIFI_CIPHER_UNKNOWN];
-}
-
-static int parse_get_mac_rsp_msg(struct usbh_bl616 *bl616_class, void *buf, int buf_len)
-{
-    usb_data_t *usb_hdr = buf;
-    rnm_mac_addr_ind_msg_t *rsp = buf + sizeof(usb_data_t);
-
-    if (buf_len != sizeof(usb_data_t) + sizeof(rnm_mac_addr_ind_msg_t)) {
-        return -1;
-    }
-    if (usb_hdr->type != USBWIFI_DATA_TYPE_CMD || usb_hdr->length != sizeof(rnm_mac_addr_ind_msg_t)) {
-        return -1;
-    }
-    if (rsp->hdr.cmd != BFLB_CMD_GET_MAC_ADDR || !(rsp->hdr.flags & RNM_MSG_FLAG_ACK)) {
-        return -1;
-    }
-    memcpy(bl616_class->sta_mac, rsp->sta_mac, 6);
-    memcpy(bl616_class->ap_mac, rsp->ap_mac, 6);
-
-    return 0;
-}
-
-static int usbh_bl616_bulk_in_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &bl616_class->bulkin_urb;
-
-    usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkin, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-static int usbh_bl616_bulk_out_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
-{
-    int ret;
-    struct usbh_urb *urb = &bl616_class->bulkout_urb;
-
-    usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkout, buffer, buflen, timeout, NULL, NULL);
-    ret = usbh_submit_urb(urb);
-    if (ret == 0) {
-        ret = urb->actual_length;
-    }
-    return ret;
-}
-
-static int usbh_bl616_get_wifi_mac(struct usbh_bl616 *bl616_class)
-{
-    int ret;
-    uint32_t msg_len;
-    usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    rnm_base_msg_t *rnm_msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
-
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-    memset(rnm_msg, 0, sizeof(rnm_base_msg_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
-    usb_hdr->length = sizeof(rnm_base_msg_t);
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    rnm_msg->cmd = BFLB_CMD_GET_MAC_ADDR;
-
-    msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
-
-    ret = usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
-    if (ret < 0) {
-        return ret;
-    }
-    ret = usbh_bl616_bulk_in_transfer(bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), 500);
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = parse_get_mac_rsp_msg(bl616_class, g_bl616_rx_buffer, ret);
-    return ret;
-}
-
-static int usbh_bl616_wifi_open(struct usbh_bl616 *bl616_class)
-{
-    uint32_t msg_len;
-    usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
-
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-    memset(msg, 0, sizeof(rnm_base_msg_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
-    usb_hdr->length = sizeof(rnm_base_msg_t);
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    msg->cmd = BFLB_CMD_HELLO;
-
-    msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
-
-    return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
-}
-
-static int usbh_bl616_wifi_close(struct usbh_bl616 *bl616_class)
-{
-    uint32_t msg_len;
-    usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
-
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-    memset(msg, 0, sizeof(rnm_base_msg_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
-    usb_hdr->length = sizeof(rnm_base_msg_t);
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    msg->cmd = BFLB_CMD_UNLOAD_DRV;
-
-    msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
-
-    return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
-}
-
-int usbh_bl616_wifi_sta_connect(const char *ssid,
-                                const int ssid_len,
-                                const char *password,
-                                const int pwd_len)
-{
-    uint32_t msg_len;
-    usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    rnm_sta_connect_msg_t *msg = (rnm_sta_connect_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
-
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-    memset(msg, 0, sizeof(rnm_sta_connect_msg_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
-    usb_hdr->length = sizeof(rnm_sta_connect_msg_t);
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    msg->hdr.cmd = BFLB_CMD_STA_CONNECT;
-    msg->hdr.msg_id = 0x0001;
-    msg->hdr.session_id = 0x0002;
-    msg->ssid_len = ssid_len;
-    memcpy(msg->ssid, ssid, ssid_len);
-    if (password) {
-        memcpy(msg->password, password, pwd_len);
-    }
-
-    msg_len = sizeof(usb_data_t) + sizeof(rnm_sta_connect_msg_t);
-
-    return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
-}
-
-int usbh_bl616_wifi_sta_disconnect(void)
-{
-    uint32_t msg_len;
-    usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
-
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-    memset(msg, 0, sizeof(rnm_base_msg_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
-    usb_hdr->length = sizeof(rnm_base_msg_t);
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    msg->cmd = BFLB_CMD_STA_DISCONNECT;
-
-    msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
-
-    return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
-}
-
-int usbh_bl616_get_wifi_scan_result(void)
-{
-    uint32_t msg_len;
-    usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
-
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-    memset(msg, 0, sizeof(rnm_base_msg_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
-    usb_hdr->length = sizeof(rnm_base_msg_t);
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    msg->cmd = BFLB_CMD_SCAN_RESULTS;
-
-    msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
-
-    return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
-}
-
-int usbh_bl616_wifi_scan(void)
-{
-    int ret;
-    uint32_t msg_len;
-    usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
-
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-    memset(msg, 0, sizeof(rnm_base_msg_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
-    usb_hdr->length = sizeof(rnm_base_msg_t);
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    msg->cmd = BFLB_CMD_SCAN;
-
-    msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
-
-    ret = usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
-    if (ret < 0) {
-        return ret;
-    }
-
-    usb_osal_msleep(500);
-    return usbh_bl616_get_wifi_scan_result();
-}
-
-static int usbh_bl616_connect(struct usbh_hubport *hport, uint8_t intf)
-{
-    struct usb_endpoint_descriptor *ep_desc;
-    int ret = 0;
-
-    struct usbh_bl616 *bl616_class = &g_bl616_class;
-
-    memset(bl616_class, 0, sizeof(struct usbh_bl616));
-
-    bl616_class->hport = hport;
-    bl616_class->intf = intf;
-
-    hport->config.intf[intf].priv = bl616_class;
-
-    for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
-        ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
-
-        if (ep_desc->bEndpointAddress & 0x80) {
-            USBH_EP_INIT(bl616_class->bulkin, ep_desc);
-        } else {
-            USBH_EP_INIT(bl616_class->bulkout, ep_desc);
-        }
-    }
-
-    usbh_bl616_get_wifi_mac(bl616_class);
-    usbh_bl616_wifi_close(bl616_class);
-    usbh_bl616_wifi_open(bl616_class);
-
-    USB_LOG_INFO("BL616 WIFI STA MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
-                 bl616_class->sta_mac[0],
-                 bl616_class->sta_mac[1],
-                 bl616_class->sta_mac[2],
-                 bl616_class->sta_mac[3],
-                 bl616_class->sta_mac[4],
-                 bl616_class->sta_mac[5]);
-
-    USB_LOG_INFO("BL616 WIFI AP MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
-                 bl616_class->ap_mac[0],
-                 bl616_class->ap_mac[1],
-                 bl616_class->ap_mac[2],
-                 bl616_class->ap_mac[3],
-                 bl616_class->ap_mac[4],
-                 bl616_class->ap_mac[5]);
-
-    strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
-
-    USB_LOG_INFO("Register BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname);
-
-    usbh_bl616_run(bl616_class);
-    return ret;
-}
-
-static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf)
-{
-    int ret = 0;
-
-    struct usbh_bl616 *bl616_class = (struct usbh_bl616 *)hport->config.intf[intf].priv;
-
-    if (bl616_class) {
-        if (bl616_class->bulkin) {
-            usbh_kill_urb(&bl616_class->bulkin_urb);
-        }
-
-        if (bl616_class->bulkout) {
-            usbh_kill_urb(&bl616_class->bulkout_urb);
-        }
-
-        if (hport->config.intf[intf].devname[0] != '\0') {
-            usb_osal_thread_schedule_other();
-            USB_LOG_INFO("Unregister BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname);
-            usbh_bl616_stop(bl616_class);
-        }
-
-        memset(bl616_class, 0, sizeof(struct usbh_bl616));
-    }
-
-    return ret;
-}
-
-void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
-{
-    int ret;
-    usb_data_t *usb_hdr;
-    rnm_base_msg_t *msg;
-    rnm_sta_ip_update_ind_msg_t *ipmsg;
-    rnm_scan_ind_msg_t *scanmsg;
-    uint8_t *data;
-
-    (void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
-    USB_LOG_INFO("Create bl616 wifi rx thread\r\n");
-
-    while (1) {
-        ret = usbh_bl616_bulk_in_transfer(&g_bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), USB_OSAL_WAITING_FOREVER);
-        if (ret < 0) {
-            break;
-        }
-
-        usb_hdr = (usb_data_t *)g_bl616_rx_buffer;
-
-        if (usb_hdr->type == USBWIFI_DATA_TYPE_CMD) {
-            msg = (rnm_base_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
-
-            switch (msg->cmd) {
-                case BFLB_CMD_STA_CONNECTED_IND:
-                    USB_LOG_INFO("AP connected\n");
-                    g_bl616_class.connect_status = true;
-                    usbh_bl616_sta_connect_callback();
-
-                    break;
-                case BFLB_CMD_STA_DISCONNECTED_IND:
-                    if (g_bl616_class.connect_status == true) {
-                        g_bl616_class.connect_status = false;
-                        USB_LOG_INFO("AP disconnected\n");
-                        usbh_bl616_sta_disconnect_callback();
-                    }
-                    break;
-                case BFLB_CMD_STA_IP_UPDATE_IND:
-                    ipmsg = (rnm_sta_ip_update_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
-
-                    USB_LOG_INFO("WIFI IP update\r\n");
-                    USB_LOG_INFO("WIFI IPv4 Address     : %d:%d:%d:%d\r\n",
-                                 ipmsg->ip4_addr[0],
-                                 ipmsg->ip4_addr[1],
-                                 ipmsg->ip4_addr[2],
-                                 ipmsg->ip4_addr[3]);
-                    USB_LOG_INFO("WIFI IPv4 Mask        : %d:%d:%d:%d\r\n",
-                                 ipmsg->ip4_mask[0],
-                                 ipmsg->ip4_mask[1],
-                                 ipmsg->ip4_mask[2],
-                                 ipmsg->ip4_mask[3]);
-                    USB_LOG_INFO("WIFI IPv4 Gateway     : %d:%d:%d:%d\r\n\r\n",
-                                 ipmsg->ip4_gw[0],
-                                 ipmsg->ip4_gw[1],
-                                 ipmsg->ip4_gw[2],
-                                 ipmsg->ip4_gw[3]);
-
-                    g_bl616_class.mode = BL_MODE_STA;
-                    usbh_bl616_sta_update_ip(ipmsg->ip4_addr, ipmsg->ip4_mask, ipmsg->ip4_gw);
-                    break;
-                case BFLB_CMD_SCAN_RESULTS:
-                    scanmsg = (rnm_scan_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
-                    USB_LOG_INFO("WIFI scan result:\r\n");
-                    for (uint32_t i = 0; i < scanmsg->num; ++i) {
-                        struct bf1b_wifi_scan_record *r = &scanmsg->records[i];
-                        USB_LOG_INFO("BSSID " MAC_FMT ", channel %u, rssi %d, auth %s, cipher %s, SSID %s\r\n",
-                                     ARR_ELE_6(r->bssid), r->channel, r->rssi,
-                                     auth_to_str(r->auth_mode), cipher_to_str(r->cipher), r->ssid);
-                    }
-                    break;
-                default:
-                    break;
-            }
-        } else if (usb_hdr->type == USBWIFI_DATA_TYPE_PKT) {
-            data = (uint8_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
-            usbh_bl616_eth_input(data, usb_hdr->length);
-        } else {
-        }
-    }
-
-    USB_LOG_INFO("Delete bl616 wifi rx thread\r\n");
-    usb_osal_thread_delete(NULL);
-}
-
-uint8_t *usbh_bl616_get_eth_txbuf(void)
-{
-    return (g_bl616_tx_buffer + sizeof(usb_data_t));
-}
-
-int usbh_bl616_eth_output(uint32_t buflen)
-{
-    usb_data_t *usb_hdr;
-    uint32_t txlen;
-
-    if (g_bl616_class.connect_status == false) {
-        return -USB_ERR_NOTCONN;
-    }
-
-    usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
-    memset(usb_hdr, 0, sizeof(usb_data_t));
-
-    usb_hdr->type = USBWIFI_DATA_TYPE_PKT;
-    usb_hdr->length = buflen;
-    usb_hdr->payload_offset = sizeof(usb_data_t);
-
-    txlen = buflen + sizeof(usb_data_t);
-    if (!(txlen % USB_GET_MAXPACKETSIZE(g_bl616_class.bulkout->wMaxPacketSize))) {
-        txlen += 1;
-    }
-    USB_LOG_DBG("txlen:%d\r\n", txlen);
-
-    usbh_bulk_urb_fill(&g_bl616_class.bulkout_urb, g_bl616_class.hport, g_bl616_class.bulkout, g_bl616_tx_buffer, txlen, USB_OSAL_WAITING_FOREVER, NULL, NULL);
-    return usbh_submit_urb(&g_bl616_class.bulkout_urb);
-}
-
-int wifi_sta_connect(int argc, char **argv)
-{
-    if (argc < 3) {
-        USB_LOG_ERR("Usage: %s <ssid> <password>\r\n", argv[0]);
-        return -1;
-    }
-    usbh_bl616_wifi_sta_connect(argv[1], strlen(argv[1]), argv[2], strlen(argv[2]));
-    return 0;
-}
-
-int wifi_scan(int argc, char **argv)
-{
-    (void)argc;
-    (void)argv;
-
-    usbh_bl616_wifi_scan();
-    return 0;
-}
-
-__WEAK void usbh_bl616_run(struct usbh_bl616 *bl616_class)
-{
-    (void)bl616_class;
-}
-
-__WEAK void usbh_bl616_stop(struct usbh_bl616 *bl616_class)
-{
-    (void)bl616_class;
-}
-
-static const uint16_t bl616_id_table[][2] = {
-    { 0x349b, 0x616f },
-    { 0, 0 },
-};
-
-static const struct usbh_class_driver bl616_class_driver = {
-    .driver_name = "bl616_wifi",
-    .connect = usbh_bl616_connect,
-    .disconnect = usbh_bl616_disconnect
-};
-
-CLASS_INFO_DEFINE const struct usbh_class_info bl616_class_info = {
-    .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
-    .bInterfaceClass = 0xff,
-    .bInterfaceSubClass = 0x00,
-    .bInterfaceProtocol = 0x00,
-    .id_table = bl616_id_table,
-    .class_driver = &bl616_class_driver
-};

+ 0 - 220
components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h

@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef USBH_BL616_H
-#define USBH_BL616_H
-
-#define USBWIFI_DATA_TYPE_CMD 0xA55A
-#define USBWIFI_DATA_TYPE_PKT 0x6996
-
-#define USB_DATA_FLAG_AP_PKT (1u << 0)
-
-typedef enum {
-    BFLB_CMD_REBOOT = 0,
-    BFLB_CMD_RESET,
-    BFLB_CMD_HELLO,
-    BFLB_CMD_PING,
-
-    BFLB_CMD_GET_MAC_ADDR,
-
-    // Scan
-    BFLB_CMD_SCAN,
-    BFLB_CMD_SCAN_RESULTS,
-
-    // STA
-    BFLB_CMD_STA_CONNECT,
-    BFLB_CMD_STA_DISCONNECT,
-    BFLB_CMD_STA_CONNECTED_IND,
-    BFLB_CMD_STA_DISCONNECTED_IND,
-    BFLB_CMD_STA_IP_UPDATE_IND,
-    BFLB_CMD_STA_SET_AUTO_RECONNECT,
-    BFLB_CMD_STA_GET_LINK_STATUS,
-
-    // AP
-    BFLB_CMD_AP_START,
-    BFLB_CMD_AP_STOP,
-    BFLB_CMD_AP_STARTED_IND,
-    BFLB_CMD_AP_STOPPED_IND,
-    BFLB_CMD_AP_GET_STA_LIST,
-
-    // Monitor
-    BFLB_CMD_MONITOR_START,
-    BFLB_CMD_MONITOR_STOP,
-    BFLB_CMD_MONITOR_SET_CHANNEL,
-    BFLB_CMD_MONITOR_GET_CHANNEL,
-
-    BFLB_CMD_SET_LPM_MODE,
-
-    // OTA
-    BFLB_CMD_GET_DEV_VERSION,
-    BFLB_CMD_OTA,
-
-    BFLB_CMD_EXT,
-
-    BFLB_CMD_USER_EXT,
-    BFLB_CMD_UNLOAD_DRV,
-
-    BFLB_CMD_MAX,
-} bflb_cmd_t;
-
-typedef enum {
-    STATUS_OK,
-    STATUS_NOMEM = 128,
-    STATUS_INVALID_INPUT,
-    STATUS_INVALID_MODE,
-    STATUS_ERR_UNSPECIFIED,
-    STATUS_NOT_IMPLEMENTED,
-} cmd_status_t;
-
-typedef enum {
-    RNM_WIFI_AUTH_UNKNOWN = 0,
-    RNM_WIFI_AUTH_OPEN,
-    RNM_WIFI_AUTH_WEP,
-    RNM_WIFI_AUTH_WPA_PSK,
-    RNM_WIFI_AUTH_WPA2_PSK,
-    RNM_WIFI_AUTH_WPA_WPA2_PSK,
-    RNM_WIFI_AUTH_WPA_ENTERPRISE,
-    RNM_WIFI_AUTH_WPA3_SAE,
-    RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE,
-    RNM_WIFI_AUTH_MAX,
-} rnm_wifi_auth_mode_t;
-
-typedef enum {
-    RNM_WIFI_CIPHER_UNKNOWN = 0,
-    RNM_WIFI_CIPHER_NONE,
-    RNM_WIFI_CIPHER_WEP,
-    RNM_WIFI_CIPHER_AES,
-    RNM_WIFI_CIPHER_TKIP,
-    RNM_WIFI_CIPHER_TKIP_AES,
-    RNM_WIFI_CIPHER_MAX,
-} rnm_wifi_cipher_t;
-
-/* common header */
-typedef struct {
-    uint16_t cmd;
-    // flag ACK is used by server to indicate a response to client
-#define RNM_MSG_FLAG_ACK         (1 << 0)
-    // flag TRANSPARENT is never transfered to peer but used locally
-#define RNM_MSG_FLAG_TRANSPARENT (1 << 1)
-    // flag ASYNC is used by server to notify client events such as STA_CONNECTED
-#define RNM_MSG_FLAG_ASYNC       (1 << 2)
-    uint16_t flags;
-    uint16_t status;
-    uint16_t msg_id;
-    uint16_t session_id;
-    uint16_t msg_id_replying;
-} rnm_base_msg_t;
-
-typedef struct {
-    rnm_base_msg_t hdr;
-} rnm_ack_msg_t;
-
-typedef struct {
-    rnm_base_msg_t hdr;
-    uint8_t sta_mac[6];
-    uint8_t ap_mac[6];
-} rnm_mac_addr_ind_msg_t;
-
-typedef struct {
-    rnm_base_msg_t hdr;
-    uint16_t ssid_len;
-    uint8_t ssid[32];
-    uint8_t password[64];
-} rnm_sta_connect_msg_t;
-
-typedef struct {
-    rnm_base_msg_t hdr;
-    uint8_t ip4_addr[4];
-    uint8_t ip4_mask[4];
-    uint8_t ip4_gw[4];
-    uint8_t ip4_dns1[4];
-    uint8_t ip4_dns2[4];
-    uint8_t gw_mac[6];
-} rnm_sta_ip_update_ind_msg_t;
-
-struct bf1b_wifi_scan_record {
-    uint8_t bssid[6];
-    // TODO use compressed SSID encoding to save room
-    uint8_t ssid[32 + 1];
-    uint16_t channel;
-    int8_t rssi;
-    uint8_t auth_mode;
-    uint8_t cipher;
-} __PACKED;
-
-typedef struct {
-    rnm_base_msg_t hdr;
-    uint16_t num;
-    struct bf1b_wifi_scan_record records[];
-} rnm_scan_ind_msg_t;
-
-typedef enum {
-    BL_MODE_NONE,
-    BL_MODE_STA,      // card is STA
-    BL_MODE_AP,       // card is AP
-    BL_MODE_STA_AP,   // card is STA&AP
-    BL_MODE_SNIFFER,  // card is sniffer
-    BL_MODE_MAX,
-} bl_wifi_mode_t;
-
-typedef struct {
-    uint16_t type;
-    uint16_t length;
-    uint16_t flags;
-    uint16_t payload_offset;
-    uint32_t rsvd[8];
-    uint8_t payload[];
-} __attribute__((aligned(4))) usb_data_t;
-
-struct usbh_bl616 {
-    struct usbh_hubport *hport;
-    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
-    struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
-
-    struct usbh_urb bulkout_urb;
-    struct usbh_urb bulkin_urb;
-
-    uint8_t intf;
-
-    uint8_t sta_mac[6];
-    uint8_t ap_mac[6];
-    uint8_t mode;
-    bool connect_status;
-
-    void *user_data;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int usbh_bl616_wifi_sta_connect(const char *ssid,
-                                const int ssid_len,
-                                const char *password,
-                                const int pwd_len);
-
-int usbh_bl616_wifi_sta_disconnect(void);
-int usbh_bl616_wifi_scan(void);
-
-void usbh_bl616_sta_connect_callback(void);
-void usbh_bl616_sta_disconnect_callback(void);
-void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4]);
-
-uint8_t *usbh_bl616_get_eth_txbuf(void);
-int usbh_bl616_eth_output(uint32_t buflen);
-void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen);
-void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
-
-void usbh_bl616_run(struct usbh_bl616 *bl616_class);
-void usbh_bl616_stop(struct usbh_bl616 *bl616_class);
-
-int wifi_sta_connect(int argc, char **argv);
-int wifi_scan(int argc, char **argv);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* USBH_BL616_H */

+ 74 - 64
components/drivers/usb/cherryusb/class/video/usbh_video.c

@@ -122,12 +122,12 @@ int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class)
     return usbh_video_get(video_class, VIDEO_REQUEST_GET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
 }
 
-int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
+int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwFrameInterval)
 {
     video_class->probe.bFormatIndex = formatindex;
     video_class->probe.bFrameIndex = frameindex;
     video_class->probe.dwMaxPayloadTransferSize = 0;
-    video_class->probe.dwFrameInterval = 333333;
+    video_class->probe.dwFrameInterval = dwFrameInterval;
     return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
 }
 
@@ -136,7 +136,6 @@ int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t f
     memcpy(&video_class->commit, &video_class->probe, sizeof(struct video_probe_and_commit_controls));
     video_class->commit.bFormatIndex = formatindex;
     video_class->commit.bFrameIndex = frameindex;
-    video_class->commit.dwFrameInterval = 333333;
     return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26);
 }
 
@@ -154,6 +153,7 @@ int usbh_video_open(struct usbh_video *video_class,
     bool found = false;
     uint8_t formatidx = 0;
     uint8_t frameidx = 0;
+    uint32_t dwDefaultFrameInterval = 0;
     uint8_t step;
 
     if (!video_class || !video_class->hport) {
@@ -172,6 +172,7 @@ int usbh_video_open(struct usbh_video *video_class,
                 if ((wWidth == video_class->format[i].frame[j].wWidth) &&
                     (wHeight == video_class->format[i].frame[j].wHeight)) {
                     frameidx = j + 1;
+                    dwDefaultFrameInterval = video_class->format[i].frame[j].dwDefaultFrameInterval;
                     found = true;
                     break;
                 }
@@ -204,7 +205,7 @@ int usbh_video_open(struct usbh_video *video_class,
     }
 
     step = 1;
-    ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
+    ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval);
     if (ret < 0) {
         goto errout;
     }
@@ -228,7 +229,7 @@ int usbh_video_open(struct usbh_video *video_class,
     }
 
     step = 5;
-    ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
+    ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval);
     if (ret < 0) {
         goto errout;
     }
@@ -246,26 +247,30 @@ int usbh_video_open(struct usbh_video *video_class,
     }
 
     step = 8;
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = USB_REQUEST_SET_INTERFACE;
-    setup->wValue = altsetting;
-    setup->wIndex = video_class->data_intf;
-    setup->wLength = 0;
-
-    ret = usbh_control_transfer(video_class->hport, setup, NULL);
-    if (ret < 0) {
-        goto errout;
-    }
+    if (!video_class->is_bulk) {
+        setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
+        setup->bRequest = USB_REQUEST_SET_INTERFACE;
+        setup->wValue = altsetting;
+        setup->wIndex = video_class->data_intf;
+        setup->wLength = 0;
+
+        ret = usbh_control_transfer(video_class->hport, setup, NULL);
+        if (ret < 0) {
+            goto errout;
+        }
 
-    ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc;
-    mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
-    mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
-    if (ep_desc->bEndpointAddress & 0x80) {
-        video_class->isoin_mps = mps * (mult + 1);
-        USBH_EP_INIT(video_class->isoin, ep_desc);
+        ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc;
+        mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
+        mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
+        if (ep_desc->bEndpointAddress & 0x80) {
+            video_class->isoin_mps = mps * (mult + 1);
+            USBH_EP_INIT(video_class->isoin, ep_desc);
+        } else {
+            return -USB_ERR_NODEV;
+        }
     } else {
-        video_class->isoout_mps = mps * (mult + 1);
-        USBH_EP_INIT(video_class->isoout, ep_desc);
+        ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc;
+        USBH_EP_INIT(video_class->bulkin, ep_desc);
     }
 
     USB_LOG_INFO("Open video and select formatidx:%u, frameidx:%u, altsetting:%u\r\n", formatidx, frameidx, altsetting);
@@ -292,54 +297,62 @@ int usbh_video_close(struct usbh_video *video_class)
 
     video_class->is_opened = false;
 
-    if (video_class->isoin) {
-        video_class->isoin = NULL;
-    }
-
-    if (video_class->isoout) {
-        video_class->isoout = NULL;
+    if (video_class->is_bulk) {
+        setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_ENDPOINT;
+        setup->bRequest = USB_REQUEST_CLEAR_FEATURE;
+        setup->wValue = USB_FEATURE_ENDPOINT_HALT;
+        setup->wIndex = video_class->bulkin->bEndpointAddress;
+        setup->wLength = 0;
+    } else {
+        setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
+        setup->bRequest = USB_REQUEST_SET_INTERFACE;
+        setup->wValue = 0;
+        setup->wIndex = video_class->data_intf;
+        setup->wLength = 0;
     }
 
-    setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = USB_REQUEST_SET_INTERFACE;
-    setup->wValue = 0;
-    setup->wIndex = video_class->data_intf;
-    setup->wLength = 0;
-
     ret = usbh_control_transfer(video_class->hport, setup, NULL);
     if (ret < 0) {
         return ret;
     }
+
     return ret;
 }
 
 void usbh_video_list_info(struct usbh_video *video_class)
 {
     struct usb_endpoint_descriptor *ep_desc;
-    uint8_t mult;
-    uint16_t mps;
 
     USB_LOG_INFO("============= Video device information ===================\r\n");
     USB_LOG_RAW("bcdVDC:%04x\r\n", video_class->bcdVDC);
-    USB_LOG_RAW("Num of altsettings:%u\r\n", video_class->num_of_intf_altsettings);
-
-    for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) {
-        if (i == 0) {
-            USB_LOG_RAW("Ingore altsetting 0\r\n");
-            continue;
+    USB_LOG_RAW("Num of altsettings:%u (%s mode)\r\n", video_class->num_of_intf_altsettings, video_class->num_of_intf_altsettings == 1 ? "bulk" : "iso");
+
+    video_class->is_bulk = video_class->num_of_intf_altsettings == 1 ? true : false;
+
+    if (video_class->is_bulk) {
+        ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc;
+        USB_LOG_RAW("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
+                    ep_desc->bEndpointAddress,
+                    ep_desc->bmAttributes,
+                    USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize),
+                    ep_desc->bInterval,
+                    USB_GET_MULT(ep_desc->wMaxPacketSize));
+    } else {
+        for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) {
+            if (i == 0) {
+                USB_LOG_RAW("Ingore altsetting 0\r\n");
+                continue;
+            }
+            ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc;
+
+            USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
+                        i,
+                        ep_desc->bEndpointAddress,
+                        ep_desc->bmAttributes,
+                        USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize),
+                        ep_desc->bInterval,
+                        USB_GET_MULT(ep_desc->wMaxPacketSize));
         }
-        ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc;
-
-        mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
-        mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
-
-        USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
-                     i,
-                     ep_desc->bEndpointAddress,
-                     ep_desc->bmAttributes,
-                     mps,
-                     ep_desc->bInterval,
-                     mult);
     }
 
     USB_LOG_RAW("bNumFormats:%u\r\n", video_class->num_of_formats);
@@ -350,9 +363,10 @@ void usbh_video_list_info(struct usbh_video *video_class)
         USB_LOG_RAW("  Resolution:\r\n");
         for (uint8_t j = 0; j < video_class->format[i].num_of_frames; j++) {
             USB_LOG_RAW("      FrameIndex:%u\r\n", j + 1);
-            USB_LOG_RAW("      wWidth: %d, wHeight: %d\r\n",
-                         video_class->format[i].frame[j].wWidth,
-                         video_class->format[i].frame[j].wHeight);
+            USB_LOG_RAW("      wWidth: %d, wHeight: %d, fps: %d\r\n",
+                        video_class->format[i].frame[j].wWidth,
+                        video_class->format[i].frame[j].wHeight,
+                        (1000 / (video_class->format[i].frame[j].dwDefaultFrameInterval / 10000)));
         }
     }
 
@@ -438,12 +452,14 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
 
                             video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wWidth;
                             video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wHeight;
+                            video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->dwDefaultFrameInterval;
                             break;
                         case VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE:
                             frame_index = p[DESC_bFrameIndex];
 
                             video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wWidth;
                             video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wHeight;
+                            video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->dwDefaultFrameInterval;
                             break;
                         default:
                             break;
@@ -476,12 +492,6 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
     struct usbh_video *video_class = (struct usbh_video *)hport->config.intf[intf].priv;
 
     if (video_class) {
-        if (video_class->isoin) {
-        }
-
-        if (video_class->isoout) {
-        }
-
         if (hport->config.intf[intf].devname[0] != '\0') {
             usb_osal_thread_schedule_other();
             USB_LOG_INFO("Unregister Video Class:%s\r\n", hport->config.intf[intf].devname);

+ 3 - 2
components/drivers/usb/cherryusb/class/video/usbh_video.h

@@ -14,6 +14,7 @@
 struct usbh_video_resolution {
     uint16_t wWidth;
     uint16_t wHeight;
+    uint32_t dwDefaultFrameInterval;
 };
 
 struct usbh_video_format {
@@ -40,7 +41,7 @@ struct usbh_videostreaming {
 struct usbh_video {
     struct usbh_hubport *hport;
     struct usb_endpoint_descriptor *isoin;  /* ISO IN endpoint */
-    struct usb_endpoint_descriptor *isoout; /* ISO OUT endpoint */
+    struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
 
     uint8_t ctrl_intf; /* interface number */
     uint8_t data_intf; /* interface number */
@@ -48,9 +49,9 @@ struct usbh_video {
     struct video_probe_and_commit_controls probe;
     struct video_probe_and_commit_controls commit;
     uint16_t isoin_mps;
-    uint16_t isoout_mps;
     bool is_opened;
     uint8_t current_format;
+    bool is_bulk;
     uint16_t bcdVDC;
     uint8_t num_of_intf_altsettings;
     uint8_t num_of_formats;

+ 9 - 10
components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c

@@ -578,16 +578,6 @@ int usbh_rndis_eth_output(uint32_t buflen)
     return usbh_submit_urb(&g_rndis_class.bulkout_urb);
 }
 
-__WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class)
-{
-    (void)rndis_class;
-}
-
-__WEAK void usbh_rndis_stop(struct usbh_rndis *rndis_class)
-{
-    (void)rndis_class;
-}
-
 static const struct usbh_class_driver rndis_class_driver = {
     .driver_name = "rndis",
     .connect = usbh_rndis_connect,
@@ -602,3 +592,12 @@ CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = {
     .id_table = NULL,
     .class_driver = &rndis_class_driver
 };
+
+CLASS_INFO_DEFINE const struct usbh_class_info rndis_cdcacm_class_info = {
+    .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
+    .bInterfaceClass = USB_DEVICE_CLASS_CDC,
+    .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
+    .bInterfaceProtocol = 0xff,
+    .id_table = NULL,
+    .class_driver = &rndis_class_driver
+};

+ 163 - 43
components/drivers/usb/cherryusb/common/usb_def.h

@@ -318,24 +318,24 @@
 /* Setup packet definition used to read raw data from USB line */
 struct usb_setup_packet {
     /** Request type. Bits 0:4 determine recipient, see
-	 * \ref usb_request_recipient. Bits 5:6 determine type, see
-	 * \ref usb_request_type. Bit 7 determines data transfer direction, see
-	 * \ref usb_endpoint_direction.
-	 */
+     * \ref usb_request_recipient. Bits 5:6 determine type, see
+     * \ref usb_request_type. Bit 7 determines data transfer direction, see
+     * \ref usb_endpoint_direction.
+     */
     uint8_t bmRequestType;
 
     /** Request. If the type bits of bmRequestType are equal to
-	 * \ref usb_request_type::LIBUSB_REQUEST_TYPE_STANDARD
-	 * "USB_REQUEST_TYPE_STANDARD" then this field refers to
-	 * \ref usb_standard_request. For other cases, use of this field is
-	 * application-specific. */
+     * \ref usb_request_type::LIBUSB_REQUEST_TYPE_STANDARD
+     * "USB_REQUEST_TYPE_STANDARD" then this field refers to
+     * \ref usb_standard_request. For other cases, use of this field is
+     * application-specific. */
     uint8_t bRequest;
 
     /** Value. Varies according to request */
     uint16_t wValue;
 
     /** Index. Varies according to request, typically used to pass an index
-	 * or offset */
+     * or offset */
     uint16_t wIndex;
 
     /** Number of bytes to transfer */
@@ -556,7 +556,7 @@ struct usb_bos_header_descriptor {
 } __PACKED;
 
 /* BOS Capability platform Descriptor */
-struct usb_bos_capability_platform_descriptor {
+struct usb_bos_capability_platform_common_descriptor {
     uint8_t bLength;
     uint8_t bDescriptorType;
     uint8_t bDevCapabilityType;
@@ -564,16 +564,26 @@ struct usb_bos_capability_platform_descriptor {
     uint8_t PlatformCapabilityUUID[16];
 } __PACKED;
 
-/* BOS Capability MS OS Descriptors version 2 */
-struct usb_bos_capability_msosv2_descriptor {
+/* Microsoft OS 2.0 Platform Capability Descriptor
+* See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/
+* microsoft-defined-usb-descriptors
+* Adapted from the source:
+* https://github.com/sowbug/weblight/blob/master/firmware/webusb.c
+* (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c
+*/
+struct usb_bos_capability_platform_winusb_descriptor {
+    struct usb_bos_capability_platform_common_descriptor common;
     uint32_t dwWindowsVersion;
     uint16_t wMSOSDescriptorSetTotalLength;
     uint8_t bVendorCode;
     uint8_t bAltEnumCode;
 } __PACKED;
 
-/* BOS Capability webusb */
-struct usb_bos_capability_webusb_descriptor {
+/* WebUSB Platform Capability Descriptor:
+* https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
+*/
+struct usb_bos_capability_platform_webusb_descriptor {
+    struct usb_bos_capability_platform_common_descriptor common;
     uint16_t bcdVersion;
     uint8_t bVendorCode;
     uint8_t iLandingPage;
@@ -587,26 +597,6 @@ struct usb_bos_capability_extension_descriptor {
     uint32_t bmAttributes;
 } __PACKED;
 
-/* Microsoft OS 2.0 Platform Capability Descriptor
-* See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/
-* microsoft-defined-usb-descriptors
-* Adapted from the source:
-* https://github.com/sowbug/weblight/blob/master/firmware/webusb.c
-* (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c
-*/
-struct usb_bos_capability_platform_msosv2_descriptor {
-    struct usb_bos_capability_platform_descriptor platform_msos;
-    struct usb_bos_capability_msosv2_descriptor data_msosv2;
-} __PACKED;
-
-/* WebUSB Platform Capability Descriptor:
-* https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
-*/
-struct usb_bos_capability_platform_webusb_descriptor {
-    struct usb_bos_capability_platform_descriptor platform_webusb;
-    struct usb_bos_capability_webusb_descriptor data_webusb;
-} __PACKED;
-
 struct usb_webusb_url_descriptor {
     uint8_t bLength;
     uint8_t bDescriptorType;
@@ -625,18 +615,12 @@ struct usb_bos_descriptor {
     uint32_t string_len;
 };
 
-/* USB Device Capability Descriptor */
-struct usb_device_capability_descriptor {
-    uint8_t bLength;
-    uint8_t bDescriptorType;
-    uint8_t bDevCapabilityType;
-} __PACKED;
-
 /** USB descriptor header */
 struct usb_desc_header {
     uint8_t bLength;         /**< descriptor length */
     uint8_t bDescriptorType; /**< descriptor type */
 };
+
 // clang-format off
 #define USB_DEVICE_DESCRIPTOR_INIT(bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct, bcdDevice, bNumConfigurations) \
     0x12,                       /* bLength */                                                                                              \
@@ -705,7 +689,7 @@ struct usb_desc_header {
     WBVAL(wMaxPacketSize),        /* wMaxPacketSize */                                      \
     bInterval                     /* bInterval */
 
-#define USB_IAD_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \
+#define USB_IAD_DESCRIPTOR_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \
     0x08,                                      /* bLength */                                             \
     USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */                                     \
     bFirstInterface,                           /* bFirstInterface */                                     \
@@ -716,9 +700,145 @@ struct usb_desc_header {
     0x00                                       /* iFunction */
 
 #define USB_LANGID_INIT(id)                           \
-    0x04,                           /* bLength */     \
+    0x04,                       /* bLength */         \
     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \
     WBVAL(id)                   /* wLangID0 */
+
+#define USB_BOS_HEADER_DESCRIPTOR_INIT(wTotalLength, bNumDeviceCaps) \
+    0x05,                       /* bLength */                        \
+    USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE,    /* bDescriptorType */\
+    WBVAL(wTotalLength),        /* wTotalLength */                   \
+    bNumDeviceCaps              /* bNumDeviceCaps */
+
+#define USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_INIT(bVendorCode, iLandingPage)   \
+    0x18,                                           /* bLength */                \
+    USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY,          /* bDescriptorType */        \
+    USB_DEVICE_CAPABILITY_PLATFORM,                 /* bDevCapabilityType */     \
+    0x00,                                           /* bReserved */              \
+    0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, /* PlatformCapabilityUUID */ \
+    0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,                              \
+    WBVAL(0x0100),                                  /* bcdVersion */             \
+    bVendorCode,                                    /* bVendorCode */            \
+    iLandingPage                                    /* iLandingPage */
+
+#define USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(bVendorCode, wMSOSDescriptorSetTotalLength) \
+    0x1C,                                           /* bLength */                \
+    USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY,          /* bDescriptorType */        \
+    USB_DEVICE_CAPABILITY_PLATFORM,                 /* bDevCapabilityType */     \
+    0x00,                                           /* bReserved */              \
+    0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, /* PlatformCapabilityUUID */ \
+    0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,                              \
+    DBVAL(0x06030000),                              /* dwWindowsVersion */       \
+    WBVAL(wMSOSDescriptorSetTotalLength),           /* wMSOSDescriptorSetTotalLength */ \
+    bVendorCode,                                    /* bVendorCode */            \
+    0x00                                            /* bAltEnumCode */
+
+#define USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_LEN 24
+#define USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN 28
+
+#define USB_MSOSV1_STRING_DESCRIPTOR_INIT(vendor_code) \
+    0x12,                       /* bLength */                             \
+    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */                     \
+    'M', 0,                     /* bString[0] */                          \
+    'S', 0,                     /* bString[1] */                          \
+    'F', 0,                     /* bString[2] */                          \
+    'T', 0,                     /* bString[3] */                          \
+    '1', 0,                     /* bString[4] */                          \
+    '0', 0,                     /* bString[5] */                          \
+    '0', 0,                     /* bString[6] */                          \
+    vendor_code,                /* bMS_VendorCode */                      \
+    0x00                        /* bPad */
+
+#define USB_MSOSV1_COMP_ID_HEADER_DESCRIPTOR_INIT(bCount) \
+    DBVAL((sizeof(struct usb_msosv1_compat_id_header_descriptor) + sizeof(struct usb_msosv1_comp_id_function_descriptor) * bCount)), /* dwLength */ \
+    WBVAL(0x0100),            /* bcdVersion */                     \
+    WBVAL(0x0004),            /* wIndex */                         \
+    bCount,                   /* bCount */                         \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved[7] */
+
+#define USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(bFirstInterfaceNumber) \
+    bFirstInterfaceNumber,                          /* bFirstInterfaceNumber */\
+    0x01,                                           /* reserved1 */            \
+    'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,       /* compatibleID[8] */      \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */   \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00              /* reserved2[6] */
+
+#define USB_MSOSV1_COMP_ID_FUNCTION_MTP_DESCRIPTOR_INIT(bFirstInterfaceNumber)\
+    bFirstInterfaceNumber,                          /* bFirstInterfaceNumber */\
+    0x01,                                           /* reserved1 */            \
+    'M', 'T', 'P', 'U', 'S', 'B', 0x00, 0x00,       /* compatibleID[8] */      \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */   \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00              /* reserved2[6] */
+
+#define USB_MSOSV1_COMP_ID_FUNCTION_ADB_DESCRIPTOR_INIT(bFirstInterfaceNumber)\
+    bFirstInterfaceNumber,                          * bFirstInterfaceNumber */\
+    0x01,                                           /* reserved1 */            \
+    'A', 'D', 'B', 0x00, 0x00, 0x00, 0x00, 0x00,    /* compatibleID[8] */      \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */   \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00              /* reserved2[6] */
+
+#define USB_MSOSV1_COMP_ID_DESCRIPTOR_LEN(bCount) \
+    (sizeof(struct usb_msosv1_compat_id_header_descriptor) + sizeof(struct usb_msosv1_comp_id_function_descriptor) * (bCount))
+
+#define USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(wDescriptorSetTotalLength)   \
+    WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE),               /* wLength */          \
+    WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE),               /* wDescriptorType */  \
+    DBVAL(0x06030000),                                      /* dwWindowsVersion */ \
+    WBVAL(wDescriptorSetTotalLength)                        /* wDescriptorSetTotalLength */
+
+#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_INIT()                                           \
+    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  /* wLength */                                                  \
+    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  /* wDescriptorType */                                          \
+    'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        /* CompatibleId*/                                              \
+    0, 0, 0, 0, 0, 0, 0, 0,                    /* SubCompatibleId*/                                           \
+    WBVAL(132),                                /* wLength */                                                  \
+    WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   /* wDescriptorType */                                          \
+    WBVAL(WINUSB_PROP_DATA_TYPE_REG_SZ),       /* wPropertyDataType */                                        \
+    WBVAL(42),                                 /* wPropertyNameLength bPropertyName: "DeviceInterfaceGUID" */ \
+    'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,                                                           \
+    'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,                                   \
+    'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,                                                             \
+    WBVAL(80), /* wPropertyDataLength */                                                                      \
+    '{', 0,                                                                                                   \
+    'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,                                   \
+    '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,                                                                   \
+    '4', 0, '6', 0, '6', 0, '3', 0, '-', 0,                                                                   \
+    'A', 0, 'A', 0, '3', 0, '6', 0, '-',                                                                      \
+    0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,        \
+    '}', 0, 0, 0, 0, 0
+
+#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_LEN \
+    (WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132)
+
+#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(bFirstInterfaceNumber)                       \
+    WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */                                                  \
+    WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */                                          \
+    bFirstInterfaceNumber,                     /* bFirstInterface*/                                           \
+    0,                                         /* bReserved */                                                \
+    WBVAL((WINUSB_FUNCTION_SUBSET_HEADER_SIZE + WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132)), /* wSubsetLength */\
+    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  /* wLength */                                                  \
+    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  /* wDescriptorType */                                          \
+    'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        /* CompatibleId*/                                              \
+    0, 0, 0, 0, 0, 0, 0, 0,                    /* SubCompatibleId*/                                           \
+    WBVAL(132),                                /* wLength */                                                  \
+    WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   /* wDescriptorType */                                          \
+    WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */                                        \
+    WBVAL(42),                                 /* wPropertyNameLength bPropertyName: "DeviceInterfaceGUID" */ \
+    'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,                                                           \
+    'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,                                   \
+    'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,                                                             \
+    WBVAL(80), /* wPropertyDataLength */                                                                      \
+    '{', 0,                                                                                                   \
+    'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,                                   \
+    '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,                                                                   \
+    '4', 0, '6', 0, '6', 0, '3', 0, '-', 0,                                                                   \
+    'A', 0, 'A', 0, '3', 0, '6', 0, '-',                                                                      \
+    0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,        \
+    '}', 0, 0, 0, 0, 0
+
+#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN \
+    (WINUSB_FUNCTION_SUBSET_HEADER_SIZE + WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132)
+
 // clang-format on
 
 #endif /* USB_DEF_H */

+ 39 - 0
components/drivers/usb/cherryusb/common/usb_otg.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USB_OTG_H
+#define USB_OTG_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define USBOTG_MODE_HOST   0
+#define USBOTG_MODE_DEVICE 1
+#define USBOTG_MODE_OTG    2
+
+/**
+ * @brief usb otg controller hardware or gpio id simulator init.
+ *
+ * @return On success will return 0, and others indicate fail.
+ */
+int usb_otg_init(uint8_t busid);
+/**
+ * @brief usb otg controller hardware or gpio id simulator deinit.
+ *
+ * @return On success will return 0, and others indicate fail.
+ */
+int usb_otg_deinit(uint8_t busid);
+
+/* called by user */
+void USBOTG_IRQHandler(uint8_t busid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USB_OTG_H */

+ 19 - 2
components/drivers/usb/cherryusb/common/usb_util.h

@@ -185,8 +185,8 @@
         (field)[3] = (uint8_t)((value) >> 0);  \
     } while (0)
 
-#define WBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF)
-#define DBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF), ((x >> 16) & 0xFF), ((x >> 24) & 0xFF)
+#define WBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF)
+#define DBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF), (((x) >> 24) & 0xFF)
 
 #define PP_NARG(...) \
     PP_NARG_(__VA_ARGS__, PP_RSEQ_N())
@@ -209,6 +209,23 @@
         19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
         9, 8, 7, 6, 5, 4, 3, 2, 1, 0
 
+/*
+ * Divide positive or negative dividend by positive or negative divisor
+ * and round to closest integer. Result is undefined for negative
+ * divisors if the dividend variable type is unsigned and for negative
+ * dividends if the divisor variable type is unsigned.
+ */
+#define DIV_ROUND_CLOSEST(x, divisor) (       \
+    {                                         \
+        typeof(x) __x = x;                    \
+        typeof(divisor) __d = divisor;        \
+        (((typeof(x))-1) > 0 ||               \
+         ((typeof(divisor))-1) > 0 ||         \
+         (((__x) > 0) == ((__d) > 0))) ?      \
+            (((__x) + ((__d) / 2)) / (__d)) : \
+            (((__x) - ((__d) / 2)) / (__d));  \
+    })
+
 #define USB_MEM_ALIGNX __attribute__((aligned(CONFIG_USB_ALIGN_SIZE)))
 
 #define USB_ALIGN_UP(size, align) (((size) + (align)-1) & ~((align)-1))

+ 2 - 2
components/drivers/usb/cherryusb/common/usb_version.h

@@ -15,7 +15,7 @@
 #undef CHERRYUSB_VERSION_STR
 #endif
 
-#define CHERRYUSB_VERSION     0x010502
-#define CHERRYUSB_VERSION_STR "v1.5.2"
+#define CHERRYUSB_VERSION     0x010600
+#define CHERRYUSB_VERSION_STR "v1.6.0"
 
 #endif

+ 18 - 220
components/drivers/usb/cherryusb/core/usbd_core.c

@@ -48,16 +48,10 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
     uint32_t ep0_data_buf_len;
     /** Zero length packet flag of control transfer */
     bool zlp_flag;
+
     /** Pointer to registered descriptors */
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     const struct usb_descriptor *descriptors;
-#else
-    const uint8_t *descriptors;
-    struct usb_msosv1_descriptor *msosv1_desc;
-    struct usb_msosv2_descriptor *msosv2_desc;
-    struct usb_bos_descriptor *bos_desc;
-    struct usb_webusb_descriptor *webusb_url_desc;
-#endif
+
     /* Buffer used for storing standard, class and vendor request data */
     USB_MEM_ALIGNX uint8_t req_data[USB_ALIGN_UP(CONFIG_USBDEV_REQUEST_BUFFER_LEN, CONFIG_USB_ALIGN_SIZE)];
 
@@ -69,9 +63,7 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
     bool remote_wakeup_support;
     bool remote_wakeup_enabled;
     bool is_suspend;
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     uint8_t speed;
-#endif
 #ifdef CONFIG_USBDEV_TEST_MODE
     bool test_req;
 #endif
@@ -180,7 +172,6 @@ static bool usbd_reset_endpoint(uint8_t busid, const struct usb_endpoint_descrip
  *
  * @return true if the descriptor was found, false otherwise
  */
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **data, uint32_t *len)
 {
     uint8_t type = 0U;
@@ -326,93 +317,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
     }
     return found;
 }
-#else
-static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **data, uint32_t *len)
-{
-    uint8_t type = 0U;
-    uint8_t index = 0U;
-    uint8_t *p = NULL;
-    uint32_t cur_index = 0U;
-    bool found = false;
-
-    type = HI_BYTE(type_index);
-    index = LO_BYTE(type_index);
-
-    if ((type == USB_DESCRIPTOR_TYPE_STRING) && (index == USB_OSDESC_STRING_DESC_INDEX)) {
-        if (!g_usbd_core[busid].msosv1_desc) {
-            return false;
-        }
-
-        *data = (uint8_t *)g_usbd_core[busid].msosv1_desc->string;
-        //memcpy(*data, (uint8_t *)g_usbd_core[busid].msosv1_desc->string, g_usbd_core[busid].msosv1_desc->string[0]);
-        *len = g_usbd_core[busid].msosv1_desc->string[0];
-
-        return true;
-    } else if (type == USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE) {
-        if (!g_usbd_core[busid].bos_desc) {
-            return false;
-        }
-
-        *data = (uint8_t *)g_usbd_core[busid].bos_desc->string;
-        //memcpy(*data, (uint8_t *)g_usbd_core[busid].bos_desc->string, g_usbd_core[busid].bos_desc->string_len);
-        *len = g_usbd_core[busid].bos_desc->string_len;
-        return true;
-    }
-    /*
-     * Invalid types of descriptors,
-     * see USB Spec. Revision 2.0, 9.4.3 Get Descriptor
-     */
-    else if ((type == USB_DESCRIPTOR_TYPE_INTERFACE) || (type == USB_DESCRIPTOR_TYPE_ENDPOINT) ||
-#ifndef CONFIG_USB_HS
-             (type > USB_DESCRIPTOR_TYPE_ENDPOINT)) {
-#else
-             (type > USB_DESCRIPTOR_TYPE_OTHER_SPEED)) {
-#endif
-        return false;
-    }
-
-    p = (uint8_t *)g_usbd_core[busid].descriptors;
-
-    cur_index = 0U;
-
-    while (p[DESC_bLength] != 0U) {
-        if (p[DESC_bDescriptorType] == type) {
-            if (cur_index == index) {
-                found = true;
-                break;
-            }
-
-            cur_index++;
-        }
-
-        /* skip to next descriptor */
-        p += p[DESC_bLength];
-    }
-
-    if (found) {
-        if ((type == USB_DESCRIPTOR_TYPE_CONFIGURATION) || ((type == USB_DESCRIPTOR_TYPE_OTHER_SPEED))) {
-            /* configuration or other speed descriptor is an
-             * exception, length is at offset 2 and 3
-             */
-            *len = (p[CONF_DESC_wTotalLength]) |
-                   (p[CONF_DESC_wTotalLength + 1] << 8);
-
-            g_usbd_core[busid].self_powered = (p[7] & USB_CONFIG_POWERED_MASK) ? true : false;
-            g_usbd_core[busid].remote_wakeup_support = (p[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false;
-        } else {
-            /* normally length is at offset 0 */
-            *len = p[DESC_bLength];
-        }
-        *data = p;
-        //memcpy(*data, p, *len);
-    } else {
-        /* nothing found */
-        USB_LOG_ERR("descriptor <type:0x%02x,index:0x%02x> not found!\r\n", type, index);
-    }
-
-    return found;
-}
-#endif
 
 /**
  * @brief set USB configuration
@@ -436,11 +340,8 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t
     uint32_t desc_len = 0;
     uint32_t current_desc_len = 0;
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed);
-#else
-    p = (uint8_t *)g_usbd_core[busid].descriptors;
-#endif
+
     /* configure endpoints for this configuration/altsetting */
     while (p[DESC_bLength] != 0U) {
         switch (p[DESC_bDescriptorType]) {
@@ -508,11 +409,8 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
     uint32_t desc_len = 0;
     uint32_t current_desc_len = 0;
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed);
-#else
-    p = (uint8_t *)g_usbd_core[busid].descriptors;
-#endif
+
     USB_LOG_DBG("iface %u alt_setting %u\r\n", iface, alt_setting);
 
     while (p[DESC_bLength] != 0U) {
@@ -683,11 +581,7 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
     uint32_t current_desc_len = 0;
     uint8_t cur_iface = 0xFF;
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed);
-#else
-    p = (uint8_t *)g_usbd_core[busid].descriptors;
-#endif
 
     /* Only when device is configured, then interface requests can be valid. */
     if (!is_device_configured(busid)) {
@@ -925,7 +819,7 @@ static int usbd_class_request_handler(uint8_t busid, struct usb_setup_packet *se
 static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
 {
     uint32_t desclen;
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
+
     if (g_usbd_core[busid].descriptors->msosv1_descriptor) {
         if (setup->bRequest == g_usbd_core[busid].descriptors->msosv1_descriptor->vendor_code) {
             switch (setup->wIndex) {
@@ -982,61 +876,7 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
             }
         }
     }
-#else
-    if (g_usbd_core[busid].msosv1_desc) {
-        if (setup->bRequest == g_usbd_core[busid].msosv1_desc->vendor_code) {
-            switch (setup->wIndex) {
-                case 0x04:
-                    *data = (uint8_t *)g_usbd_core[busid].msosv1_desc->compat_id;
-                    desclen = g_usbd_core[busid].msosv1_desc->compat_id[0] +
-                              (g_usbd_core[busid].msosv1_desc->compat_id[1] << 8) +
-                              (g_usbd_core[busid].msosv1_desc->compat_id[2] << 16) +
-                              (g_usbd_core[busid].msosv1_desc->compat_id[3] << 24);
-                    //memcpy(*data, g_usbd_core[busid].msosv1_desc->compat_id, desclen);
-                    *len = desclen;
-                    return 0;
-                case 0x05:
-                    *data = (uint8_t *)g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue];
-                    desclen = g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][0] +
-                              (g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][1] << 8) +
-                              (g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][2] << 16) +
-                              (g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][3] << 24);
-                    //memcpy(*data, g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue], desclen);
-                    *len = desclen;
-                    return 0;
-                default:
-                    return -1;
-            }
-        }
-    } else if (g_usbd_core[busid].msosv2_desc) {
-        if (setup->bRequest == g_usbd_core[busid].msosv2_desc->vendor_code) {
-            switch (setup->wIndex) {
-                case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
-                    *data = (uint8_t *)g_usbd_core[busid].msosv2_desc->compat_id;
-                    //memcpy(*data, g_usbd_core[busid].msosv2_desc->compat_id, g_usbd_core[busid].msosv2_desc->compat_id_len);
-                    *len = g_usbd_core[busid].msosv2_desc->compat_id_len;
-                    return 0;
-                default:
-                    return -1;
-            }
-        }
-    }
 
-    if (g_usbd_core[busid].webusb_url_desc) {
-        if (setup->bRequest == g_usbd_core[busid].webusb_url_desc->vendor_code) {
-            switch (setup->wIndex) {
-                case WEBUSB_REQUEST_GET_URL:
-                    desclen = g_usbd_core[busid].webusb_url_desc->string_len;
-                    *data = (uint8_t *)g_usbd_core[busid].webusb_url_desc->string;
-                    //memcpy(*data, g_usbd_core[busid].webusb_url_desc->string, desclen);
-                    *len = desclen;
-                    return 0;
-                default:
-                    return -1;
-            }
-        }
-    }
-#endif
     for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) {
         struct usbd_interface *intf = g_usbd_core[busid].intf[i];
 
@@ -1145,18 +985,22 @@ void usbd_event_suspend_handler(uint8_t busid)
 
 void usbd_event_reset_handler(uint8_t busid)
 {
+    struct usb_endpoint_descriptor ep0;
+
     usbd_set_address(busid, 0);
     g_usbd_core[busid].device_address = 0;
     g_usbd_core[busid].configuration = 0;
     g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     g_usbd_core[busid].speed = USB_SPEED_UNKNOWN;
-#endif
-    struct usb_endpoint_descriptor ep0;
+
+    USB_ASSERT_MSG(g_usbd_core[busid].descriptors->device_descriptor_callback != NULL,
+                   "device_descriptor_callback is NULL\r\n");
+
+    struct usb_device_descriptor *device_desc = (struct usb_device_descriptor *)g_usbd_core[busid].descriptors->device_descriptor_callback(g_usbd_core[busid].speed);
+    ep0.wMaxPacketSize = device_desc->bMaxPacketSize0;
 
     ep0.bLength = 7;
     ep0.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT;
-    ep0.wMaxPacketSize = USB_CTRL_EP_MPS;
     ep0.bmAttributes = USB_ENDPOINT_TYPE_CONTROL;
     ep0.bEndpointAddress = USB_CONTROL_IN_EP0;
     ep0.bInterval = 0;
@@ -1369,7 +1213,6 @@ void usbd_event_ep_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
     }
 }
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 void usbd_desc_register(uint8_t busid, const struct usb_descriptor *desc)
 {
     memset(&g_usbd_core[busid], 0, sizeof(struct usbd_core_priv));
@@ -1382,42 +1225,6 @@ void usbd_desc_register(uint8_t busid, const struct usb_descriptor *desc)
     g_usbd_core[busid].rx_msg[0].ep = 0x00;
     g_usbd_core[busid].rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
 }
-#else
-void usbd_desc_register(uint8_t busid, const uint8_t *desc)
-{
-    memset(&g_usbd_core[busid], 0, sizeof(struct usbd_core_priv));
-
-    g_usbd_core[busid].descriptors = desc;
-    g_usbd_core[busid].intf_offset = 0;
-
-    g_usbd_core[busid].tx_msg[0].ep = 0x80;
-    g_usbd_core[busid].tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
-    g_usbd_core[busid].rx_msg[0].ep = 0x00;
-    g_usbd_core[busid].rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
-}
-
-/* Register MS OS Descriptors version 1 */
-void usbd_msosv1_desc_register(uint8_t busid, struct usb_msosv1_descriptor *desc)
-{
-    g_usbd_core[busid].msosv1_desc = desc;
-}
-
-/* Register MS OS Descriptors version 2 */
-void usbd_msosv2_desc_register(uint8_t busid, struct usb_msosv2_descriptor *desc)
-{
-    g_usbd_core[busid].msosv2_desc = desc;
-}
-
-void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc)
-{
-    g_usbd_core[busid].bos_desc = desc;
-}
-
-void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc)
-{
-    g_usbd_core[busid].webusb_url_desc = desc;
-}
-#endif
 
 void usbd_add_interface(uint8_t busid, struct usbd_interface *intf)
 {
@@ -1536,11 +1343,7 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
     int ret;
     struct usbd_bus *bus;
 
-    if (busid >= CONFIG_USBDEV_MAX_BUS) {
-        USB_LOG_ERR("bus overflow\r\n");
-        while (1) {
-        }
-    }
+    USB_ASSERT_MSG(busid < CONFIG_USBDEV_MAX_BUS, "bus overflow\r\n");
 
     bus = &g_usbdev_bus[busid];
     bus->reg_base = reg_base;
@@ -1569,23 +1372,18 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
 
 int usbd_deinitialize(uint8_t busid)
 {
-    if (busid >= CONFIG_USBDEV_MAX_BUS) {
-        USB_LOG_ERR("bus overflow\r\n");
-        while (1) {
-        }
-    }
+    USB_ASSERT_MSG(busid < CONFIG_USBDEV_MAX_BUS, "bus overflow\r\n");
 
     g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT);
     usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
     usb_dc_deinit(busid);
-    g_usbd_core[busid].intf_offset = 0;
 #ifdef CONFIG_USBDEV_EP0_THREAD
-    if (g_usbd_core[busid].usbd_ep0_mq) {
-        usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq);
-    }
     if (g_usbd_core[busid].usbd_ep0_thread) {
         usb_osal_thread_delete(g_usbd_core[busid].usbd_ep0_thread);
     }
+    if (g_usbd_core[busid].usbd_ep0_mq) {
+        usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq);
+    }
 #endif
 
     return 0;

+ 2 - 9
components/drivers/usb/cherryusb/core/usbd_core.h

@@ -56,6 +56,7 @@ enum usbd_event_type {
 typedef int (*usbd_request_handler)(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len);
 typedef void (*usbd_endpoint_callback)(uint8_t busid, uint8_t ep, uint32_t nbytes);
 typedef void (*usbd_notify_handler)(uint8_t busid, uint8_t event, void *arg);
+typedef void (*usbd_event_handler_t)(uint8_t busid, uint8_t event);
 
 struct usbd_endpoint {
     uint8_t ep_addr;
@@ -95,15 +96,7 @@ extern struct usbd_bus g_usbdev_bus[];
 #error USBD_IRQHandler is obsolete, please call USBD_IRQHandler(xxx) in your irq
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 void usbd_desc_register(uint8_t busid, const struct usb_descriptor *desc);
-#else
-void usbd_desc_register(uint8_t busid, const uint8_t *desc);
-void usbd_msosv1_desc_register(uint8_t busid, struct usb_msosv1_descriptor *desc);
-void usbd_msosv2_desc_register(uint8_t busid, struct usb_msosv2_descriptor *desc);
-void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc);
-void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc);
-#endif
 
 void usbd_add_interface(uint8_t busid, struct usbd_interface *intf);
 void usbd_add_endpoint(uint8_t busid, struct usbd_endpoint *ep);
@@ -115,7 +108,7 @@ bool usb_device_is_suspend(uint8_t busid);
 int usbd_send_remote_wakeup(uint8_t busid);
 uint8_t usbd_get_ep0_next_state(uint8_t busid);
 
-int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event));
+int usbd_initialize(uint8_t busid, uintptr_t reg_base, usbd_event_handler_t event_handler);
 int usbd_deinitialize(uint8_t busid);
 
 #ifdef __cplusplus

+ 394 - 200
components/drivers/usb/cherryusb/core/usbh_core.c

@@ -31,31 +31,38 @@ struct usbh_bus g_usbhost_bus[CONFIG_USBHOST_MAX_BUS];
 #define USB_DEV_ADDR_MARK_OFFSET 5
 #define USB_DEV_ADDR_MARK_MASK   0x1f
 
+static void dummy_event_handler(uint8_t busid, uint8_t hub_index, uint8_t hub_port, uint8_t intf, uint8_t event)
+{
+    (void)busid;
+    (void)hub_index;
+    (void)hub_port;
+    (void)intf;
+    (void)event;
+}
+
 static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
 {
-    uint8_t startaddr = devgen->next;
-    uint8_t devaddr;
+    uint8_t lastaddr = devgen->last;
+    uint8_t devaddr = lastaddr;
     int index;
     int bitno;
 
     for (;;) {
-        devaddr = devgen->next;
-        if (devgen->next >= 0x7f) {
-            devgen->next = 2;
-        } else {
-            devgen->next++;
+        devaddr++;
+        if (devaddr > 0x7f) {
+            devaddr = 2;
+        }
+        if (devaddr == lastaddr) {
+            return -USB_ERR_NOMEM;
         }
 
         index = devaddr >> 5;
         bitno = devaddr & 0x1f;
-        if ((devgen->alloctab[index] & (1 << bitno)) == 0) {
-            devgen->alloctab[index] |= (1 << bitno);
+        if ((devgen->alloctab[index] & (1ul << bitno)) == 0) {
+            devgen->alloctab[index] |= (1ul << bitno);
+            devgen->last = devaddr;
             return (int)devaddr;
         }
-
-        if (startaddr == devaddr) {
-            return -USB_ERR_NOMEM;
-        }
     }
 }
 
@@ -69,15 +76,11 @@ static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
         bitno = devaddr & USB_DEV_ADDR_MARK_MASK;
 
         /* Free the address  */
-        if ((devgen->alloctab[index] |= (1 << bitno)) != 0) {
-            devgen->alloctab[index] &= ~(1 << bitno);
+        if ((devgen->alloctab[index] & (1ul << bitno)) != 0) {
+            devgen->alloctab[index] &= ~(1ul << bitno);
         } else {
             return -1;
         }
-
-        if (devaddr < devgen->next) {
-            devgen->next = devaddr;
-        }
     }
 
     return 0;
@@ -91,7 +94,7 @@ static int usbh_free_devaddr(struct usbh_hubport *hport)
     return 0;
 }
 
-static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol,
+static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, uint8_t intf,
                                                               uint16_t vid, uint16_t pid)
 {
     struct usbh_class_info *index = NULL;
@@ -106,6 +109,9 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
         if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) {
             continue;
         }
+        if ((index->match_flags & USB_CLASS_MATCH_INTF_NUM) && !(index->bInterfaceNumber == intf)) {
+            continue;
+        }
         if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) {
             /* scan id table */
             uint32_t i;
@@ -275,60 +281,6 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
     return 0;
 }
 
-static void usbh_print_hubport_info(struct usbh_hubport *hport)
-{
-    USB_LOG_RAW("Device Descriptor:\r\n");
-    USB_LOG_RAW("bLength: 0x%02x           \r\n", hport->device_desc.bLength);
-    USB_LOG_RAW("bDescriptorType: 0x%02x   \r\n", hport->device_desc.bDescriptorType);
-    USB_LOG_RAW("bcdUSB: 0x%04x            \r\n", hport->device_desc.bcdUSB);
-    USB_LOG_RAW("bDeviceClass: 0x%02x      \r\n", hport->device_desc.bDeviceClass);
-    USB_LOG_RAW("bDeviceSubClass: 0x%02x   \r\n", hport->device_desc.bDeviceSubClass);
-    USB_LOG_RAW("bDeviceProtocol: 0x%02x   \r\n", hport->device_desc.bDeviceProtocol);
-    USB_LOG_RAW("bMaxPacketSize0: 0x%02x   \r\n", hport->device_desc.bMaxPacketSize0);
-    USB_LOG_RAW("idVendor: 0x%04x          \r\n", hport->device_desc.idVendor);
-    USB_LOG_RAW("idProduct: 0x%04x         \r\n", hport->device_desc.idProduct);
-    USB_LOG_RAW("bcdDevice: 0x%04x         \r\n", hport->device_desc.bcdDevice);
-    USB_LOG_RAW("iManufacturer: 0x%02x     \r\n", hport->device_desc.iManufacturer);
-    USB_LOG_RAW("iProduct: 0x%02x          \r\n", hport->device_desc.iProduct);
-    USB_LOG_RAW("iSerialNumber: 0x%02x     \r\n", hport->device_desc.iSerialNumber);
-    USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
-
-    USB_LOG_RAW("Config Descriptor:\r\n");
-    USB_LOG_RAW("bLength: 0x%02x             \r\n", hport->config.config_desc.bLength);
-    USB_LOG_RAW("bDescriptorType: 0x%02x     \r\n", hport->config.config_desc.bDescriptorType);
-    USB_LOG_RAW("wTotalLength: 0x%04x        \r\n", hport->config.config_desc.wTotalLength);
-    USB_LOG_RAW("bNumInterfaces: 0x%02x      \r\n", hport->config.config_desc.bNumInterfaces);
-    USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
-    USB_LOG_RAW("iConfiguration: 0x%02x      \r\n", hport->config.config_desc.iConfiguration);
-    USB_LOG_RAW("bmAttributes: 0x%02x        \r\n", hport->config.config_desc.bmAttributes);
-    USB_LOG_RAW("bMaxPower: 0x%02x           \r\n", hport->config.config_desc.bMaxPower);
-
-    for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
-        for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
-            USB_LOG_RAW("\tInterface Descriptor:\r\n");
-            USB_LOG_RAW("\tbLength: 0x%02x            \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
-            USB_LOG_RAW("\tbDescriptorType: 0x%02x    \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
-            USB_LOG_RAW("\tbInterfaceNumber: 0x%02x   \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
-            USB_LOG_RAW("\tbAlternateSetting: 0x%02x  \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
-            USB_LOG_RAW("\tbNumEndpoints: 0x%02x      \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
-            USB_LOG_RAW("\tbInterfaceClass: 0x%02x    \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
-            USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
-            USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
-            USB_LOG_RAW("\tiInterface: 0x%02x         \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
-
-            for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
-                USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n");
-                USB_LOG_RAW("\t\tbLength: 0x%02x          \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
-                USB_LOG_RAW("\t\tbDescriptorType: 0x%02x  \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
-                USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
-                USB_LOG_RAW("\t\tbmAttributes: 0x%02x     \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
-                USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x   \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
-                USB_LOG_RAW("\t\tbInterval: 0x%02x        \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
-            }
-        }
-    }
-}
-
 static void usbh_print_setup(struct usb_setup_packet *setup)
 {
     (void)setup;
@@ -466,7 +418,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
 
     USB_LOG_INFO("The device has %d bNumConfigurations\r\n", ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumConfigurations);
 
-    config_index = 0;
+    config_index = usbh_get_hport_active_config_index(hport);
     USB_LOG_DBG("The device selects config %d\r\n", config_index);
 
     /* Read the first 9 bytes of the config descriptor */
@@ -599,23 +551,35 @@ int usbh_enumerate(struct usbh_hubport *hport)
     }
 #endif
     USB_LOG_INFO("Enumeration success, start loading class driver\r\n");
+    hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_CONFIGURED);
     /*search supported class driver*/
     for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
         intf_desc = &hport->config.intf[i].altsetting[0].intf_desc;
 
-        struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol, hport->device_desc.idVendor, hport->device_desc.idProduct);
+        USB_ASSERT_MSG(intf_desc->bInterfaceNumber == i, "Interface number mismatch, do not support non-standard device\r\n");
+
+        struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass,
+                                                                                                    intf_desc->bInterfaceSubClass,
+                                                                                                    intf_desc->bInterfaceProtocol,
+                                                                                                    intf_desc->bInterfaceNumber,
+                                                                                                    hport->device_desc.idVendor,
+                                                                                                    hport->device_desc.idProduct);
 
         if (class_driver == NULL) {
-            USB_LOG_ERR("do not support Class:0x%02x,Subclass:0x%02x,Protocl:0x%02x\r\n",
+            USB_LOG_ERR("Do not support Class:0x%02x, Subclass:0x%02x, Protocl:0x%02x on interface %u\r\n",
                         intf_desc->bInterfaceClass,
                         intf_desc->bInterfaceSubClass,
-                        intf_desc->bInterfaceProtocol);
-
+                        intf_desc->bInterfaceProtocol,
+                        i);
+            hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, i, USBH_EVENT_INTERFACE_UNSUPPORTED);
             continue;
         }
         hport->config.intf[i].class_driver = class_driver;
-        USB_LOG_INFO("Loading %s class driver\r\n", class_driver->driver_name);
+        USB_LOG_INFO("Loading %s class driver on interface %u\r\n", class_driver->driver_name, i);
         ret = CLASS_CONNECT(hport, i);
+        if (ret >= 0) {
+            hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, i, USBH_EVENT_INTERFACE_START);
+        }
     }
 
 errout:
@@ -630,17 +594,20 @@ void usbh_hubport_release(struct usbh_hubport *hport)
 {
     if (hport->connected) {
         hport->connected = false;
+        usbh_kill_urb(&hport->ep0_urb);
         usbh_free_devaddr(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);
             }
+            hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, i, USBH_EVENT_INTERFACE_STOP);
         }
         hport->config.config_desc.bNumInterfaces = 0;
-        usbh_kill_urb(&hport->ep0_urb);
         if (hport->mutex) {
             usb_osal_mutex_delete(hport->mutex);
         }
+        USB_LOG_INFO("Device on Bus %u, Hub %u, Port %u disconnected\r\n", hport->bus->busid, hport->parent->index, hport->port);
+        hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_DISCONNECTED);
     }
 }
 
@@ -652,25 +619,27 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_bas
     bus->hcd.reg_base = reg_base;
 
     /* devaddr 1 is for roothub */
-    bus->devgen.next = 2;
+    bus->devgen.last = 0x7f;
 
     usb_slist_add_tail(&g_bus_head, &bus->list);
 }
 
-int usbh_initialize(uint8_t busid, uintptr_t reg_base)
+int usbh_initialize(uint8_t busid, uintptr_t reg_base, usbh_event_handler_t event_handler)
 {
     struct usbh_bus *bus;
 
-    if (busid >= CONFIG_USBHOST_MAX_BUS) {
-        USB_LOG_ERR("bus overflow\r\n");
-        while (1) {
-        }
-    }
+    USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
 
     bus = &g_usbhost_bus[busid];
 
     usbh_bus_init(bus, busid, reg_base);
 
+    if (event_handler) {
+        bus->event_handler = event_handler;
+    } else {
+        bus->event_handler = dummy_event_handler;
+    }
+
 #ifdef __ARMCC_VERSION /* ARM C Compiler */
     extern const int usbh_class_info$$Base;
     extern const int usbh_class_info$$Limit;
@@ -693,14 +662,12 @@ int usbh_deinitialize(uint8_t busid)
 {
     struct usbh_bus *bus;
 
-    if (busid >= CONFIG_USBHOST_MAX_BUS) {
-        USB_LOG_ERR("bus overflow\r\n");
-        while (1) {
-        }
-    }
+    USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
 
     bus = &g_usbhost_bus[busid];
 
+    bus->event_handler(bus->busid, USB_HUB_INDEX_ANY, USB_HUB_PORT_ANY, USB_INTERFACE_ANY, USBH_EVENT_DEINIT);
+
     usbh_hub_deinitialize(bus);
 
     usb_slist_remove(&g_bus_head, &bus->list);
@@ -711,6 +678,7 @@ int usbh_deinitialize(uint8_t busid)
 int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
 {
     struct usbh_urb *urb;
+    volatile uint8_t retry = 3;
     int ret;
 
     if (!hport || !setup) {
@@ -723,12 +691,21 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
 
     usbh_print_setup(setup);
 
+resubmit:
     usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
     ret = usbh_submit_urb(urb);
     if (ret == 0) {
         ret = urb->actual_length;
     }
 
+    if (ret < 0 && (ret != -USB_ERR_TIMEOUT)) {
+        retry--;
+        if (retry > 0) {
+            USB_LOG_WRN("Control transfer failed, errorcode %d, retrying...\r\n", ret);
+            goto resubmit;
+        }
+    }
+
     usb_osal_mutex_give(hport->mutex);
     return ret;
 }
@@ -816,73 +793,6 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn
     return NULL;
 }
 
-static void usbh_list_all_interface_driver(struct usbh_hub *hub)
-{
-    struct usbh_hubport *hport;
-    struct usbh_hub *hub_next;
-    const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
-
-    for (uint8_t port = 0; port < hub->nports; port++) {
-        hport = &hub->child[port];
-        if (hport->connected) {
-            for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
-                if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
-                    for (uint8_t j = 0; j < hub->index; j++) {
-                        USB_LOG_RAW("\t");
-                    }
-
-                    USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n",
-                                hport->port,
-                                hport->dev_addr,
-                                itf,
-                                hport->config.intf[itf].class_driver->driver_name,
-                                speed_table[hport->speed]);
-
-                    if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
-                        hub_next = hport->config.intf[itf].priv;
-
-                        if (hub_next && hub_next->connected) {
-                            usbh_list_all_interface_driver(hub_next);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *hub)
-{
-    struct usbh_hubport *hport;
-    struct usbh_hub *hub_next;
-
-    for (uint8_t port = 0; port < hub->nports; port++) {
-        hport = &hub->child[port];
-        if (hport->connected) {
-            USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
-                        bus->busid,
-                        hub->index,
-                        hport->port,
-                        hport->dev_addr,
-                        hport->device_desc.idVendor,
-                        hport->device_desc.idProduct);
-            usbh_print_hubport_info(hport);
-
-            for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
-                if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
-                    if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
-                        hub_next = hport->config.intf[itf].priv;
-
-                        if (hub_next && hub_next->connected) {
-                            usbh_list_all_interface_desc(bus, hub_next);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
 static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port)
 {
     struct usbh_hubport *hport;
@@ -960,64 +870,348 @@ struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t
     return hport;
 }
 
+static void usbh_print_hubport_info(struct usbh_hubport *hport)
+{
+    USB_LOG_RAW("Device Descriptor:\r\n");
+    USB_LOG_RAW("  bLength: 0x%02x           \r\n", hport->device_desc.bLength);
+    USB_LOG_RAW("  bDescriptorType: 0x%02x   \r\n", hport->device_desc.bDescriptorType);
+    USB_LOG_RAW("  bcdUSB: 0x%04x            \r\n", hport->device_desc.bcdUSB);
+    USB_LOG_RAW("  bDeviceClass: 0x%02x      \r\n", hport->device_desc.bDeviceClass);
+    USB_LOG_RAW("  bDeviceSubClass: 0x%02x   \r\n", hport->device_desc.bDeviceSubClass);
+    USB_LOG_RAW("  bDeviceProtocol: 0x%02x   \r\n", hport->device_desc.bDeviceProtocol);
+    USB_LOG_RAW("  bMaxPacketSize0: 0x%02x   \r\n", hport->device_desc.bMaxPacketSize0);
+    USB_LOG_RAW("  idVendor: 0x%04x          \r\n", hport->device_desc.idVendor);
+    USB_LOG_RAW("  idProduct: 0x%04x         \r\n", hport->device_desc.idProduct);
+    USB_LOG_RAW("  bcdDevice: 0x%04x         \r\n", hport->device_desc.bcdDevice);
+    USB_LOG_RAW("  iManufacturer: 0x%02x     \r\n", hport->device_desc.iManufacturer);
+    USB_LOG_RAW("  iProduct: 0x%02x          \r\n", hport->device_desc.iProduct);
+    USB_LOG_RAW("  iSerialNumber: 0x%02x     \r\n", hport->device_desc.iSerialNumber);
+    USB_LOG_RAW("  bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
+
+    USB_LOG_RAW("  Config Descriptor:\r\n");
+    USB_LOG_RAW("    bLength: 0x%02x             \r\n", hport->config.config_desc.bLength);
+    USB_LOG_RAW("    bDescriptorType: 0x%02x     \r\n", hport->config.config_desc.bDescriptorType);
+    USB_LOG_RAW("    wTotalLength: 0x%04x        \r\n", hport->config.config_desc.wTotalLength);
+    USB_LOG_RAW("    bNumInterfaces: 0x%02x      \r\n", hport->config.config_desc.bNumInterfaces);
+    USB_LOG_RAW("    bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
+    USB_LOG_RAW("    iConfiguration: 0x%02x      \r\n", hport->config.config_desc.iConfiguration);
+    USB_LOG_RAW("    bmAttributes: 0x%02x        \r\n", hport->config.config_desc.bmAttributes);
+    USB_LOG_RAW("    bMaxPower: 0x%02x           \r\n", hport->config.config_desc.bMaxPower);
+
+    for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
+        for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
+            USB_LOG_RAW("    Interface Descriptor:\r\n");
+            USB_LOG_RAW("      bLength: 0x%02x            \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
+            USB_LOG_RAW("      bDescriptorType: 0x%02x    \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
+            USB_LOG_RAW("      bInterfaceNumber: 0x%02x   \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
+            USB_LOG_RAW("      bAlternateSetting: 0x%02x  \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
+            USB_LOG_RAW("      bNumEndpoints: 0x%02x      \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
+            USB_LOG_RAW("      bInterfaceClass: 0x%02x    \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
+            USB_LOG_RAW("      bInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
+            USB_LOG_RAW("      bInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
+            USB_LOG_RAW("      iInterface: 0x%02x         \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
+
+            for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
+                USB_LOG_RAW("      Endpoint Descriptor:\r\n");
+                USB_LOG_RAW("        bLength: 0x%02x          \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
+                USB_LOG_RAW("        bDescriptorType: 0x%02x  \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
+                USB_LOG_RAW("        bEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
+                USB_LOG_RAW("        bmAttributes: 0x%02x     \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
+                USB_LOG_RAW("        wMaxPacketSize: 0x%04x   \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
+                USB_LOG_RAW("        bInterval: 0x%02x        \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
+            }
+        }
+    }
+}
+
+static void usbh_list_device(struct usbh_hub *hub, bool astree, bool verbose, int dev_addr, int vid, int pid)
+{
+    static const char *speed_table[] = {
+        "UNKNOWN",
+        "low-speed",
+        "full-speed",
+        "high-speed",
+        "wireless",
+        "super-speed",
+        "super-speed-plus",
+    };
+
+    static const char *root_speed_table[] = {
+        "UNKNOWN",
+        "1.1",
+        "1.1",
+        "2.0",
+        "2.5",
+        "3.0",
+        "3.0",
+    };
+
+    static const uint16_t speed_baud[] = {
+        0,
+        12,
+        12,
+        480,
+        480,
+        5000,
+        10000,
+    };
+
+    struct usbh_bus *bus;
+    struct usbh_hubport *hport;
+    struct usbh_hub *hub_next;
+
+    uint8_t imbuf[64];
+    uint8_t ipbuf[64];
+
+    const char *pimstr;
+    const char *pipstr;
+
+    bool imvalid = false;
+    bool ipvalid = false;
+
+    int ret;
+
+    bus = hub->bus;
+
+    (void)speed_table;
+
+    if (hub->is_roothub) {
+        if (astree) {
+            USB_LOG_RAW("/:  Bus %02u.Port 1: Dev %u, Class=root_hub, Driver=hcd, %uM\r\n",
+                        bus->busid, hub->hub_addr, speed_baud[hub->speed]);
+
+        } else {
+            if ((dev_addr < 0) || (hub->hub_addr == dev_addr)) {
+                if (((vid < 0) || (vid == 0xffff)) && ((pid < 0) || (pid == 0xffff))) {
+                    USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s root hub\r\n",
+                                bus->busid, hub->hub_addr, 0xffff, 0xffff,
+                                "Cherry-Embedded", root_speed_table[hub->speed]);
+                }
+            }
+        }
+    }
+
+    for (uint8_t port = 0; port < hub->nports; port++) {
+        hport = &hub->child[port];
+        if (hport->connected) {
+            ret = 0;
+            if (hport->device_desc.iManufacturer) {
+                memset(imbuf, 0, sizeof(imbuf));
+                ret = usbh_get_string_desc(hport, hport->device_desc.iManufacturer, imbuf, sizeof(imbuf));
+                if (ret == 0) {
+                    imvalid = true;
+                }
+            }
+
+            if (hport->device_desc.iProduct) {
+                memset(ipbuf, 0, sizeof(ipbuf));
+                ret = usbh_get_string_desc(hport, hport->device_desc.iProduct, ipbuf, sizeof(ipbuf));
+                if (ret == 0) {
+                    ipvalid = true;
+                }
+            }
+
+            if (imvalid) {
+                pimstr = (const char *)imbuf;
+            } else {
+                pimstr = "Not specified Manufacturer";
+            }
+
+            if (ipvalid) {
+                pipstr = (const char *)ipbuf;
+            } else {
+                pipstr = "Not specified Product";
+            }
+
+            if (!astree) {
+                if ((dev_addr < 0) || (hport->dev_addr == dev_addr)) {
+                    if (((vid < 0) || (vid == hport->device_desc.idVendor)) && ((pid < 0) || (pid == hport->device_desc.idProduct))) {
+                        USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s\r\n",
+                                    bus->busid, hport->dev_addr, hport->device_desc.idVendor, hport->device_desc.idProduct,
+                                    pimstr, pipstr);
+
+                        if (verbose) {
+                            usbh_print_hubport_info(hport);
+                        }
+                    }
+                }
+            }
+
+            for (uint8_t intf = 0; intf < hport->config.config_desc.bNumInterfaces; intf++) {
+                if (hport->config.intf[intf].class_driver && hport->config.intf[intf].class_driver->driver_name) {
+                    if (astree) {
+                        for (uint8_t j = 0; j < hub->index; j++) {
+                            USB_LOG_RAW("    ");
+                        }
+
+                        USB_LOG_RAW("|__ Port %u: Dev %u, If %u, ClassDriver=%s, %uM\r\n",
+                                    hport->port, hport->dev_addr, intf, hport->config.intf[intf].class_driver->driver_name, speed_baud[hport->speed]);
+                    }
+
+                    if (!strcmp(hport->config.intf[intf].class_driver->driver_name, "hub")) {
+                        hub_next = hport->config.intf[intf].priv;
+
+                        if (hub_next && hub_next->connected) {
+                            usbh_list_device(hub_next, astree, verbose, dev_addr, vid, pid);
+                        }
+                    }
+                } else if (astree) {
+                    for (uint8_t j = 0; j < hub->index; j++) {
+                        USB_LOG_RAW("    ");
+                    }
+
+                    USB_LOG_RAW("|__ Port %u: Dev %u, If 0 ClassDriver=none, %uM\r\n",
+                                hport->port, hport->dev_addr, speed_baud[hport->speed]);
+                }
+            }
+        }
+    }
+}
+
+void lsusb_help(void)
+{
+    USB_LOG_RAW("List USB Devices\r\n"
+                "Usage: lsusb [options]...\r\n"
+                "\r\n"
+                "-v, --verbose\r\n"
+                "    - increase verbosity (show descriptors)\r\n"
+                "-s [[bus]:][dev_addr]\r\n"
+                "    - show only devices with specified device and/or\r\n"
+                "      bus numbers (in decimal)\r\n"
+                "-d vendor:[product]\r\n"
+                "    - show only devices with the specified vendor and\r\n"
+                "      product ID numbers (in hexadecimal)\r\n"
+                "-t, --tree\r\n"
+                "    - dump the physical USB device hierarchy as a tree\r\n"
+                "-V, --version\r\n"
+                "    - show version of the cherryusb\r\n"
+                "-h, --help\r\n"
+                "    - show usage and help information\r\n");
+}
+
 int lsusb(int argc, char **argv)
 {
     usb_slist_t *bus_list;
-    struct usbh_hub *hub;
     struct usbh_bus *bus;
-    size_t flags;
+
+    int busid = -1;
+    int dev_addr = -1;
+    int vid = -1;
+    int pid = -1;
+    bool astree = false;
+    bool verbose = false;
 
     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("  -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");
-        USB_LOG_RAW("      Show version of program\r\n");
-        USB_LOG_RAW("  -h, --help\r\n");
-        USB_LOG_RAW("      Show usage and help\r\n");
-        return 0;
-    }
-    if (argc > 3) {
+        lsusb_help();
         return 0;
     }
 
-    flags = usb_osal_enter_critical_section();
+    while (argc > 1) {
+        argc--;
+        argv++;
 
-    if (strcmp(argv[1], "-V") == 0) {
-        USB_LOG_RAW("CherryUSB Version %s\r\n", CHERRYUSB_VERSION_STR);
-    }
+        if (!strcmp(*argv, "-V") || !strcmp(*argv, "--version")) {
+            USB_LOG_RAW("CherryUSB version %s\r\n", CHERRYUSB_VERSION_STR);
+            return 0;
+        } else if (!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) {
+            lsusb_help();
+            return 0;
+        } else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) {
+            verbose = true;
+        } else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--tree")) {
+            astree = true;
+        } else if (!strcmp(*argv, "-s")) {
+            if (argc > 1) {
+                argc--;
+                argv++;
+
+                if (*argv[0] == '-') {
+                    continue;
+                }
 
-    if (strcmp(argv[1], "-t") == 0) {
-        usb_slist_for_each(bus_list, &g_bus_head)
-        {
-            bus = usb_slist_entry(bus_list, struct usbh_bus, list);
-            hub = &bus->hcd.roothub;
+                char *endptr;
+                const char *colon = strchr(*argv, ':');
+                (void)endptr;
 
-            USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
-                        bus->busid,
-                        hub->index,
-                        hub->nports);
-            usbh_list_all_interface_driver(hub);
+                if (colon != NULL) {
+                    const char *str;
+                    if (colon > *argv) {
+                        busid = strtol(*argv, &endptr, 10);
+                    }
+                    str = colon + 1;
+                    if (*str != '\0') {
+                        dev_addr = strtol(str, &endptr, 10);
+                        if (dev_addr <= 0 || dev_addr >= 128) {
+                            dev_addr = -1;
+                        }
+                    }
+                } else {
+                    dev_addr = strtol(*argv, &endptr, 10);
+                    if (dev_addr <= 0 || dev_addr >= 128) {
+                        dev_addr = -1;
+                    }
+                }
+            }
+        } else if (!strcmp(*argv, "-d")) {
+            if (argc > 1) {
+                argc--;
+                argv++;
+
+                if (*argv[0] == '-') {
+                    continue;
+                }
+
+                char *endptr;
+                const char *colon = strchr(*argv, ':');
+                (void)endptr;
+
+                if (colon == NULL) {
+                    continue;
+                }
+                const char *str;
+
+                vid = strtol(*argv, &endptr, 16);
+                if (vid < 0 || vid > 0xffff) {
+                    vid = -1;
+                    continue;
+                }
+                str = colon + 1;
+                if (*str != '\0') {
+                    pid = strtol(str, &endptr, 16);
+                    if (pid < 0 || pid > 0xffff) {
+                        pid = -1;
+                    }
+                }
+            }
         }
     }
 
-    if (strcmp(argv[1], "-v") == 0) {
-        usb_slist_for_each(bus_list, &g_bus_head)
-        {
-            bus = usb_slist_entry(bus_list, struct usbh_bus, list);
-            hub = &bus->hcd.roothub;
+    if (astree) {
+        busid = -1;
+        dev_addr = -1;
+        vid = -1;
+        pid = -1;
+        verbose = false;
+    }
 
-            usbh_list_all_interface_desc(bus, hub);
+    usb_slist_for_each(bus_list, &g_bus_head)
+    {
+        bus = usb_slist_entry(bus_list, struct usbh_bus, list);
+        if (busid >= 0) {
+            if (bus->busid != busid) {
+                continue;
+            }
         }
+
+        usbh_list_device(&bus->hcd.roothub, astree, verbose, dev_addr, vid, pid);
     }
 
-    usb_osal_leave_critical_section(flags);
     return 0;
 }
+
+__WEAK uint8_t usbh_get_hport_active_config_index(struct usbh_hubport *hport)
+{
+    ARG_UNUSED(hport);
+
+    return 0; // Default to configuration index 0
+}

+ 39 - 3
components/drivers/usb/cherryusb/core/usbh_core.h

@@ -28,11 +28,41 @@
 extern "C" {
 #endif
 
+enum usbh_event_type {
+    /* USB HCD IRQ */
+    USBH_EVENT_ERROR,
+    USBH_EVENT_SOF,
+
+    /* USB DEVICE STATUS */
+    USBH_EVENT_DEVICE_RESET,
+    USBH_EVENT_DEVICE_CONNECTED,
+    USBH_EVENT_DEVICE_DISCONNECTED,
+    USBH_EVENT_DEVICE_CONFIGURED,
+    USBH_EVENT_DEVICE_WAKEUP,
+    USBH_EVENT_DEVICE_SUSPEND,
+    USBH_EVENT_DEVICE_RESUME,
+
+    /* USB DEVICE INTERFACE STATUS */
+    USBH_EVENT_INTERFACE_UNSUPPORTED,
+    USBH_EVENT_INTERFACE_START,
+    USBH_EVENT_INTERFACE_STOP,
+
+    /* USB FRAMEWORK STATUS */
+    USBH_EVENT_INIT,
+    USBH_EVENT_DEINIT,
+    USBH_EVENT_UNKNOWN,
+};
+
+#define USB_HUB_PORT_ANY  0
+#define USB_HUB_INDEX_ANY 0
+#define USB_INTERFACE_ANY 0xff
+
 #define USB_CLASS_MATCH_VENDOR        0x0001
 #define USB_CLASS_MATCH_PRODUCT       0x0002
 #define USB_CLASS_MATCH_INTF_CLASS    0x0004
 #define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008
 #define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010
+#define USB_CLASS_MATCH_INTF_NUM      0x0020
 #define USB_CLASS_MATCH_VID_PID       (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT)
 
 #define CLASS_CONNECT(hport, i)    ((hport)->config.intf[i].class_driver->connect(hport, i))
@@ -60,11 +90,14 @@ extern "C" {
                      USB_GET_MULT(ep_desc->wMaxPacketSize));                 \
     } while (0)
 
+typedef void (*usbh_event_handler_t)(uint8_t busid, uint8_t hub_index, uint8_t hub_port, uint8_t intf, uint8_t event);
+
 struct usbh_class_info {
     uint8_t match_flags;           /* Used for product specific matches; range is inclusive */
     uint8_t bInterfaceClass;       /* Base device class code */
     uint8_t bInterfaceSubClass;    /* Sub-class, depends on base class. Eg. */
     uint8_t bInterfaceProtocol;    /* Protocol, depends on base class. Eg. */
+    uint8_t bInterfaceNumber;      /* Interface number */
     const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */
     const struct usbh_class_driver *class_driver;
 };
@@ -131,7 +164,7 @@ struct usbh_hub {
     uint8_t powerdelay;
     uint8_t tt_think;
     bool ismtt;
-    struct usb_hub_descriptor hub_desc; /* USB 2.0 only */
+    struct usb_hub_descriptor hub_desc;       /* USB 2.0 only */
     struct usb_hub_ss_descriptor hub_ss_desc; /* USB 3.0 only */
     struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS];
     struct usbh_hubport *parent;
@@ -150,7 +183,7 @@ struct usbh_devaddr_map {
      * alloctab[3]:addr from 96~127
      *
      */
-    uint8_t next;         /* Next device address */
+    uint8_t last;         /* Last device address */
     uint32_t alloctab[4]; /* Bit allocation table */
 };
 
@@ -168,6 +201,8 @@ struct usbh_bus {
     struct usbh_devaddr_map devgen;
     usb_osal_thread_t hub_thread;
     usb_osal_mq_t hub_mq;
+    usb_osal_mutex_t mutex;
+    usbh_event_handler_t event_handler;
 };
 
 static inline void usbh_control_urb_fill(struct usbh_urb *urb,
@@ -274,10 +309,11 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
  */
 int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting);
 
-int usbh_initialize(uint8_t busid, uintptr_t reg_base);
+int usbh_initialize(uint8_t busid, uintptr_t reg_base, usbh_event_handler_t event_handler);
 int usbh_deinitialize(uint8_t busid);
 void *usbh_find_class_instance(const char *devname);
 struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port);
+uint8_t usbh_get_hport_active_config_index(struct usbh_hubport *hport);
 
 int lsusb(int argc, char **argv);
 

+ 155 - 0
components/drivers/usb/cherryusb/core/usbotg_core.c

@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbotg_core.h"
+
+#ifdef CONFIG_USB_OTG_ENABLE
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbotg_core"
+#include "usb_log.h"
+
+#define CONFIG_USB_OTG_MAX_BUS CONFIG_USBHOST_MAX_BUS
+
+struct usbotg_core_priv {
+    uint8_t busid;
+    uint32_t reg_base;
+    bool usbh_initialized;
+    bool usbd_initialized;
+    usbd_event_handler_t device_event_callback;
+    usbh_event_handler_t host_event_callback;
+    uint8_t request_mode;
+    usb_osal_sem_t change_sem;
+    usb_osal_thread_t change_thread;
+} g_usbotg_core[CONFIG_USB_OTG_MAX_BUS];
+
+static void usbotg_host_initialize(uint8_t busid)
+{
+    if (g_usbotg_core[busid].usbh_initialized) {
+        return;
+    }
+
+    if (g_usbotg_core[busid].usbd_initialized) {
+        usbd_deinitialize(busid);
+        g_usbotg_core[busid].usbd_initialized = false;
+    }
+
+    USB_LOG_INFO("Switch to HOST mode\r\n");
+
+    g_usbotg_core[busid].usbh_initialized = true;
+    usbh_initialize(busid, g_usbotg_core[busid].reg_base);
+}
+
+static void usbotg_device_initialize(uint8_t busid)
+{
+    if (g_usbotg_core[busid].usbd_initialized) {
+        return;
+    }
+
+    if (g_usbotg_core[busid].usbh_initialized) {
+        usbh_deinitialize(busid);
+        g_usbotg_core[busid].usbh_initialized = false;
+    }
+
+    USB_LOG_INFO("Switch to DEVICE mode\r\n");
+
+    g_usbotg_core[busid].usbd_initialized = true;
+    usbd_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base, g_usbotg_core[busid].device_event_callback);
+}
+
+static void usbotg_rolechange_thread(void *argument)
+{
+    uint8_t busid = (uint8_t)(uintptr_t)argument;
+
+    usb_otg_init(busid);
+
+    while (1) {
+        if (usb_osal_sem_take(g_usbotg_core[busid].change_sem, USB_OSAL_WAITING_FOREVER) == 0) {
+            if (g_usbotg_core[busid].request_mode == USBOTG_MODE_HOST) {
+                usbotg_host_initialize(busid);
+            } else if (g_usbotg_core[busid].request_mode == USBOTG_MODE_DEVICE) {
+                usbotg_device_initialize(busid);
+            }
+        }
+    }
+}
+
+int usbotg_initialize(uint8_t busid, uint32_t reg_base, usbd_event_handler_t device_event_callback, usbh_event_handler_t host_event_callback, uint8_t default_role)
+{
+    char thread_name[32] = { 0 };
+
+    USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
+
+    g_usbotg_core[busid].busid = busid;
+    g_usbotg_core[busid].reg_base = reg_base;
+    g_usbotg_core[busid].device_event_callback = device_event_callback;
+    g_usbotg_core[busid].host_event_callback = host_event_callback;
+
+    g_usbotg_core[busid].change_sem = usb_osal_sem_create(0);
+    if (g_usbotg_core[busid].change_sem == NULL) {
+        USB_LOG_ERR("Failed to create change_sem\r\n");
+        while (1) {
+        }
+    }
+
+    snprintf(thread_name, 32, "usbotg%u", busid);
+    g_usbotg_core[busid].change_thread = usb_osal_thread_create(thread_name, 2048, 10, usbotg_rolechange_thread, (void *)(uintptr_t)busid);
+    if (g_usbotg_core[busid].change_thread == NULL) {
+        USB_LOG_ERR("Failed to create usbotg thread\r\n");
+        while (1) {
+        }
+    }
+
+    usbotg_trigger_role_change(busid, default_role);
+    return 0;
+}
+
+int usbotg_deinitialize(uint8_t busid)
+{
+    USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
+
+    if (g_usbotg_core[busid].usbd_initialized) {
+        usbd_deinitialize(busid);
+        g_usbotg_core[busid].usbd_initialized = false;
+    }
+
+    if (g_usbotg_core[busid].usbh_initialized) {
+        usbh_deinitialize(busid);
+        g_usbotg_core[busid].usbh_initialized = false;
+    }
+
+    if (g_usbotg_core[busid].change_thread) {
+        usb_osal_thread_delete(g_usbotg_core[busid].change_thread);
+    }
+
+    if (g_usbotg_core[busid].change_sem) {
+        usb_otg_deinit(busid);
+        usb_osal_sem_delete(g_usbotg_core[busid].change_sem);
+    }
+
+    return 0;
+}
+
+void usbotg_trigger_role_change(uint8_t busid, uint8_t mode)
+{
+    USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
+
+    g_usbotg_core[busid].request_mode = mode;
+
+    if (g_usbotg_core[busid].change_sem) {
+        usb_osal_sem_give(g_usbotg_core[busid].change_sem);
+    }
+}
+
+void USBOTG_IRQHandler(uint8_t busid)
+{
+    USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
+
+    if (g_usbotg_core[busid].usbh_initialized) {
+        USBH_IRQHandler(busid);
+    } else if (g_usbotg_core[busid].usbd_initialized) {
+        USBD_IRQHandler(busid);
+    }
+}
+#endif /* CONFIG_USB_OTG_ENABLE */

+ 27 - 0
components/drivers/usb/cherryusb/core/usbotg_core.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBOTG_CORE_H
+#define USBOTG_CORE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "usbd_core.h"
+#include "usbh_core.h"
+#include "usb_otg.h"
+
+int usbotg_initialize(uint8_t busid, uint32_t reg_base, usbd_event_handler_t device_event_callback, usbh_event_handler_t host_event_callback, uint8_t default_role);
+int usbotg_deinitialize(uint8_t busid);
+
+/* called by user */
+void usbotg_trigger_role_change(uint8_t busid, uint8_t mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBOTG_CORE_H */

+ 4 - 84
components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c

@@ -108,7 +108,6 @@ struct usb_msosv1_descriptor msosv1_desc = {
     .comp_id_property = WINUSB_IFx_WCIDProperties,
 };
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -171,80 +170,6 @@ const struct usb_descriptor adb_descriptor = {
     .string_descriptor_callback = string_descriptor_callback,
     .msosv1_descriptor = &msosv1_desc
 };
-#else
-/*!< global descriptor */
-static const uint8_t adb_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'A', 0x00,                  /* wcChar6 */
-    'D', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x1C,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'A', 0x00,                  /* wcChar6 */
-    'D', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    '2', 0x00,                  /* wcChar9 */
-    '0', 0x00,                  /* wcChar10 */
-    '2', 0x00,                  /* wcChar11 */
-    '4', 0x00,                  /* wcChar12 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static void usbd_event_handler(uint8_t busid, uint8_t event)
 {
@@ -288,20 +213,15 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base)
     /* shell_init() must be called in-task */
     if (0 != shell_init(false)) {
         /* shell failed to be initialized */
-        printf("Failed to initialize shell\r\n");
+        USB_LOG_RAW("Failed to initialize shell\r\n");
         for (;;) {
             ;
         }
     }
 #endif
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
+
     usbd_desc_register(busid, &adb_descriptor);
-#else
-    usbd_desc_register(busid, adb_descriptor);
-#endif
-#ifndef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_msosv1_desc_register(busid, &msosv1_desc);
-#endif
+
     usbd_add_interface(busid, usbd_adb_init_intf(busid, &intf0, WINUSB_IN_EP, WINUSB_OUT_EP));
     usbd_initialize(busid, reg_base, usbd_event_handler);
-}
+}

+ 17 - 101
components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c

@@ -21,14 +21,15 @@
 
 #define AUDIO_IN_FU_ID 0x02
 
-/* AUDIO Class Config */
-#define AUDIO_FREQ 16000U
+#define AUDIO_MIC_FREQ            16000U
+#define AUDIO_MIC_FRAME_SIZE_BYTE 2u
+#define AUDIO_MIC_RESOLUTION_BIT  16u
 
-#define IN_CHANNEL_NUM 1
+#define IN_CHANNEL_NUM 2
 
 #if IN_CHANNEL_NUM == 1
 #define INPUT_CTRL      0x03, 0x03
-#define INPUT_CH_ENABLE 0x0000
+#define INPUT_CH_ENABLE 0x0001
 #elif IN_CHANNEL_NUM == 2
 #define INPUT_CTRL      0x03, 0x03, 0x03
 #define INPUT_CH_ENABLE 0x0003
@@ -54,32 +55,31 @@
 
 /* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 1) */
 /* 16bit(2 Bytes) 单声道(Mono:1) */
-#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * 2 * IN_CHANNEL_NUM) / 1000))
+#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_MIC_FREQ * 2 * IN_CHANNEL_NUM) / 1000))
 
-#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 +                                                    \
-                                                  AUDIO_AC_DESCRIPTOR_INIT_LEN(1) +                      \
-                                                  AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                  \
-                                                  AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
-                                                  AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +                 \
-                                                  AUDIO_AS_DESCRIPTOR_INIT_LEN(1))
+#define USB_CONFIG_SIZE (unsigned long)(9 +                                                    \
+                                        AUDIO_AC_DESCRIPTOR_LEN(1) +                           \
+                                        AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                  \
+                                        AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
+                                        AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +                 \
+                                        AUDIO_AS_DESCRIPTOR_LEN(1))
 
 #define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(1) +                       \
                       AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                  \
                       AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
                       AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
     AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
     AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE),
     AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL),
     AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID),
-    AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ))
+    AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ))
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -134,89 +134,6 @@ const struct usb_descriptor audio_v1_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t audio_v1_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
-    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE),
-    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL),
-    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID),
-    AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'A', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '0' + IN_CHANNEL_NUM, 0x00, /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 volatile bool tx_flag = 0;
 volatile bool ep_tx_busy_flag = false;
@@ -301,13 +218,12 @@ struct audio_entity_info audio_entity_table[] = {
       .ep = AUDIO_IN_EP },
 };
 
+// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
+
 void audio_v1_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &audio_v1_descriptor);
-#else
-    usbd_desc_register(busid, audio_v1_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 1));
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 1));
     usbd_add_endpoint(busid, &audio_in_ep);

+ 103 - 147
components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c

@@ -21,13 +21,69 @@
 #define FEEDBACK_ENDP_PACKET_SIZE 0x03
 #endif
 
-#define AUDIO_IN_EP  0x81
-#define AUDIO_OUT_EP 0x02
+#define AUDIO_IN_EP           0x81
+#define AUDIO_OUT_EP          0x02
 #define AUDIO_OUT_FEEDBACK_EP 0x83
 
 #define AUDIO_IN_FU_ID  0x02
 #define AUDIO_OUT_FU_ID 0x05
 
+#define IN_CHANNEL_NUM 2
+
+#if IN_CHANNEL_NUM == 1
+#define INPUT_CTRL      0x03, 0x03
+#define INPUT_CH_ENABLE 0x0001
+#elif IN_CHANNEL_NUM == 2
+#define INPUT_CTRL      0x03, 0x03, 0x03
+#define INPUT_CH_ENABLE 0x0003
+#elif IN_CHANNEL_NUM == 3
+#define INPUT_CTRL      0x03, 0x03, 0x03, 0x03
+#define INPUT_CH_ENABLE 0x0007
+#elif IN_CHANNEL_NUM == 4
+#define INPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03
+#define INPUT_CH_ENABLE 0x000f
+#elif IN_CHANNEL_NUM == 5
+#define INPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define INPUT_CH_ENABLE 0x001f
+#elif IN_CHANNEL_NUM == 6
+#define INPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define INPUT_CH_ENABLE 0x003F
+#elif IN_CHANNEL_NUM == 7
+#define INPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define INPUT_CH_ENABLE 0x007f
+#elif IN_CHANNEL_NUM == 8
+#define INPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define INPUT_CH_ENABLE 0x00ff
+#endif
+
+#define OUT_CHANNEL_NUM 2
+
+#if OUT_CHANNEL_NUM == 1
+#define OUTPUT_CTRL      0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x0001
+#elif OUT_CHANNEL_NUM == 2
+#define OUTPUT_CTRL      0x03, 0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x0003
+#elif OUT_CHANNEL_NUM == 3
+#define OUTPUT_CTRL      0x03, 0x03, 0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x0007
+#elif OUT_CHANNEL_NUM == 4
+#define OUTPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x000f
+#elif OUT_CHANNEL_NUM == 5
+#define OUTPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x001f
+#elif OUT_CHANNEL_NUM == 6
+#define OUTPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x003F
+#elif OUT_CHANNEL_NUM == 7
+#define OUTPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x007f
+#elif OUT_CHANNEL_NUM == 8
+#define OUTPUT_CTRL      0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+#define OUTPUT_CH_ENABLE 0x00ff
+#endif
+
 /* AUDIO Class Config */
 #define AUDIO_SPEAKER_FREQ            16000U
 #define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u
@@ -44,60 +100,59 @@
 #define AUDIO_IN_PACKET ((uint32_t)((AUDIO_MIC_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * 2) / 1000))
 
 #if USING_FEEDBACK == 0
-#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 +                                       \
-                                                  AUDIO_AC_DESCRIPTOR_INIT_LEN(2) +         \
-                                                  AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
-                                                  AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
-                                                  AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +    \
-                                                  AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
-                                                  AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
-                                                  AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +    \
-                                                  AUDIO_AS_DESCRIPTOR_INIT_LEN(1) +         \
-                                                  AUDIO_AS_DESCRIPTOR_INIT_LEN(1))
+#define USB_CONFIG_SIZE (unsigned long)(9 +                                                     \
+                                        AUDIO_AC_DESCRIPTOR_LEN(2) +                            \
+                                        AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                   \
+                                        AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) +  \
+                                        AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +                  \
+                                        AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                   \
+                                        AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \
+                                        AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +                  \
+                                        AUDIO_AS_DESCRIPTOR_LEN(1) +                            \
+                                        AUDIO_AS_DESCRIPTOR_LEN(1))
 #else
-#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 +                                       \
-                                                  AUDIO_AC_DESCRIPTOR_INIT_LEN(2) +         \
-                                                  AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
-                                                  AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
-                                                  AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +    \
-                                                  AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
-                                                  AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
-                                                  AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +    \
-                                                  AUDIO_AS_DESCRIPTOR_INIT_LEN(1) +         \
-                                                  AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(1))
+#define USB_CONFIG_SIZE (unsigned long)(9 +                                                     \
+                                        AUDIO_AC_DESCRIPTOR_LEN(2) +                            \
+                                        AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                   \
+                                        AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) +  \
+                                        AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +                  \
+                                        AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                   \
+                                        AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \
+                                        AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +                  \
+                                        AUDIO_AS_DESCRIPTOR_LEN(1) +                            \
+                                        AUDIO_AS_FEEDBACK_DESCRIPTOR_LEN(1))
 #endif
 
-#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) +          \
-                      AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
-                      AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
-                      AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +    \
-                      AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
-                      AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
+#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) +                        \
+                      AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                   \
+                      AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) +  \
+                      AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +                  \
+                      AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +                   \
+                      AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \
                       AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
     AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02),
-    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003),
-    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00),
-    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
-    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
-    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
-    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
+    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE),
+    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL),
+    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID),
+    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE),
+    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x04, 0x01, OUTPUT_CTRL),
+    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID),
+    AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
+                             EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
 #if USING_FEEDBACK == 0
-    AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
+    AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
                              EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
 #else
-    AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,
-                             EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
+    AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,
+                                      EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
 #endif
-    AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
-                             EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ))
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -152,104 +207,6 @@ const struct usb_descriptor audio_v1_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t audio_v1_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02),
-    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003),
-    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00),
-    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
-    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
-    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
-    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
-#if USING_FEEDBACK == 0
-    AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
-                             EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
-#else
-    AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,
-                             EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
-#endif
-    AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
-                             EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'A', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-#if USING_FEEDBACK == 0
-    '1', 0x00,                  /* wcChar9 */
-#else
-    '2', 0x00,                  /* wcChar9 */
-#endif
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
@@ -297,11 +254,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
         AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value); /* uac1 can only use 10.14 */
         usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
 #endif
-        printf("OPEN1\r\n");
+        USB_LOG_INFO("OPEN1\r\n");
     } else {
         tx_flag = 1;
         ep_tx_busy_flag = false;
-        printf("OPEN2\r\n");
+        USB_LOG_INFO("OPEN2\r\n");
     }
 }
 
@@ -309,11 +266,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
 {
     if (intf == 1) {
         rx_flag = 0;
-        printf("CLOSE1\r\n");
+        USB_LOG_INFO("CLOSE1\r\n");
     } else {
         tx_flag = 0;
         ep_tx_busy_flag = false;
-        printf("CLOSE2\r\n");
+        USB_LOG_INFO("CLOSE2\r\n");
     }
 }
 
@@ -393,13 +350,12 @@ struct audio_entity_info audio_entity_table[] = {
       .ep = AUDIO_OUT_EP },
 };
 
+// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
+
 void audio_v1_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &audio_v1_descriptor);
-#else
-    usbd_desc_register(busid, audio_v1_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 2));
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 2));
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0100, audio_entity_table, 2));

+ 36 - 110
components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c

@@ -22,17 +22,17 @@
 #define AUDIO_IN_CLOCK_ID 0x01
 #define AUDIO_IN_FU_ID    0x03
 
-#define AUDIO_IN_MAX_FREQ 16000
-#define HALF_WORD_BYTES   2  //2 half word (one channel)
-#define SAMPLE_BITS       16 //16 bit per channel
+#define AUDIO_IN_MAX_FREQ         96000
+#define AUDIO_MIC_FRAME_SIZE_BYTE 2u
+#define AUDIO_MIC_RESOLUTION_BIT  16u
 
-#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
+#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME)
 
 #define IN_CHANNEL_NUM 2
 
 #if IN_CHANNEL_NUM == 1
 #define INPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL)
-#define INPUT_CH_ENABLE 0x00000000
+#define INPUT_CH_ENABLE 0x00000001
 #elif IN_CHANNEL_NUM == 2
 #define INPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
 #define INPUT_CH_ENABLE 0x00000003
@@ -56,15 +56,15 @@
 #define INPUT_CH_ENABLE 0x000000ff
 #endif
 
-#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
+#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * IN_CHANNEL_NUM) / 1000))
 
-#define USB_AUDIO_CONFIG_DESC_SIZ (9 +                                                    \
-                                   AUDIO_V2_AC_DESCRIPTOR_INIT_LEN +                      \
-                                   AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                 \
-                                   AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +               \
-                                   AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
-                                   AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +              \
-                                   AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
+#define USB_CONFIG_SIZE (9 +                                                    \
+                         AUDIO_V2_AC_DESCRIPTOR_LEN +                           \
+                         AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                 \
+                         AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +               \
+                         AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
+                         AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +              \
+                         AUDIO_V2_AS_DESCRIPTOR_LEN)
 
 #define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC +                       \
                       AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                 \
@@ -72,19 +72,18 @@
                       AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
                       AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
     AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00),
-    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, 0x01, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
-    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, INPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x03, 0x01, 0x0000),
-    AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
+    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03),
+    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
+    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x02, INPUT_CTRL),
+    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 0x0000),
+    AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -139,96 +138,24 @@ const struct usb_descriptor audio_v2_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t audio_v2_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00),
-    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, 0x01, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
-    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, INPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x03, 0x01, 0x0000),
-    AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'A', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-    '4', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static const uint8_t mic_default_sampling_freq_table[] = {
-    AUDIO_SAMPLE_FREQ_NUM(1),
+    AUDIO_SAMPLE_FREQ_NUM(5),
+    AUDIO_SAMPLE_FREQ_4B(8000),
+    AUDIO_SAMPLE_FREQ_4B(8000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
     AUDIO_SAMPLE_FREQ_4B(16000),
     AUDIO_SAMPLE_FREQ_4B(16000),
-    AUDIO_SAMPLE_FREQ_4B(0x00)
+    AUDIO_SAMPLE_FREQ_4B(0x00),
+    AUDIO_SAMPLE_FREQ_4B(32000),
+    AUDIO_SAMPLE_FREQ_4B(32000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
+    AUDIO_SAMPLE_FREQ_4B(48000),
+    AUDIO_SAMPLE_FREQ_4B(48000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
+    AUDIO_SAMPLE_FREQ_4B(96000),
+    AUDIO_SAMPLE_FREQ_4B(96000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
 };
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
@@ -323,13 +250,12 @@ struct audio_entity_info audio_entity_table[] = {
       .ep = AUDIO_IN_EP },
 };
 
+// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
+
 void audio_v2_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &audio_v2_descriptor);
-#else
-    usbd_desc_register(busid, audio_v2_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2));
     usbd_add_endpoint(busid, &audio_in_ep);

+ 63 - 148
components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c

@@ -30,19 +30,21 @@
 #define AUDIO_IN_CLOCK_ID  0x05
 #define AUDIO_IN_FU_ID     0x07
 
-#define AUDIO_OUT_MAX_FREQ 96000
-#define AUDIO_IN_MAX_FREQ  16000
+#define AUDIO_OUT_MAX_FREQ            96000
+#define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u
+#define AUDIO_SPEAKER_RESOLUTION_BIT  16u
 
-#define HALF_WORD_BYTES 2  //2 half word (one channel)
-#define SAMPLE_BITS     16 //16 bit per channel
+#define AUDIO_IN_MAX_FREQ         96000
+#define AUDIO_MIC_FRAME_SIZE_BYTE 2u
+#define AUDIO_MIC_RESOLUTION_BIT  16u
 
-#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
+#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME)
 
 #define IN_CHANNEL_NUM 2
 
 #if IN_CHANNEL_NUM == 1
 #define INPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL)
-#define INPUT_CH_ENABLE 0x00000000
+#define INPUT_CH_ENABLE 0x00000001
 #elif IN_CHANNEL_NUM == 2
 #define INPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
 #define INPUT_CH_ENABLE 0x00000003
@@ -70,7 +72,7 @@
 
 #if OUT_CHANNEL_NUM == 1
 #define OUTPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL)
-#define OUTPUT_CH_ENABLE 0x00000000
+#define OUTPUT_CH_ENABLE 0x00000001
 #elif OUT_CHANNEL_NUM == 2
 #define OUTPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
 #define OUTPUT_CH_ENABLE 0x00000003
@@ -95,35 +97,35 @@
 #endif
 
 /* AudioFreq * DataSize (2 bytes) * NumChannels */
-#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
-#define AUDIO_IN_PACKET  ((uint32_t)((AUDIO_IN_MAX_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
+#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * AUDIO_SPEAKER_FRAME_SIZE_BYTE * OUT_CHANNEL_NUM) / 1000))
+#define AUDIO_IN_PACKET  ((uint32_t)((AUDIO_IN_MAX_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * IN_CHANNEL_NUM) / 1000))
 
 #if USING_FEEDBACK == 0
-#define USB_AUDIO_CONFIG_DESC_SIZ (9 +                                                     \
-                                   AUDIO_V2_AC_DESCRIPTOR_INIT_LEN +                       \
-                                   AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
-                                   AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
-                                   AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
-                                   AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
-                                   AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
-                                   AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
-                                   AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) +  \
-                                   AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
-                                   AUDIO_V2_AS_DESCRIPTOR_INIT_LEN +                       \
-                                   AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
+#define USB_CONFIG_SIZE (9 +                                                     \
+                         AUDIO_V2_AC_DESCRIPTOR_LEN +                            \
+                         AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
+                         AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
+                         AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
+                         AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
+                         AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
+                         AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
+                         AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) +  \
+                         AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
+                         AUDIO_V2_AS_DESCRIPTOR_LEN +                            \
+                         AUDIO_V2_AS_DESCRIPTOR_LEN)
 #else
-#define USB_AUDIO_CONFIG_DESC_SIZ (9 +                                                     \
-                                   AUDIO_V2_AC_DESCRIPTOR_INIT_LEN +                       \
-                                   AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
-                                   AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
-                                   AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
-                                   AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
-                                   AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
-                                   AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
-                                   AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) +  \
-                                   AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
-                                   AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN +              \
-                                   AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
+#define USB_CONFIG_SIZE (9 +                                                     \
+                         AUDIO_V2_AC_DESCRIPTOR_LEN +                            \
+                         AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
+                         AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
+                         AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
+                         AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
+                         AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
+                         AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
+                         AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) +  \
+                         AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
+                         AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN +                   \
+                         AUDIO_V2_AS_DESCRIPTOR_LEN)
 #endif
 
 #define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC +                        \
@@ -136,28 +138,27 @@
                       AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) +  \
                       AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
     AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00),
-    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
-    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
-    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
-    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000),
+    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
+    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
+    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
+    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 0x0000),
+    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03),
+    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
+    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x06, INPUT_CTRL),
+    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 0x0000),
 #if USING_FEEDBACK == 0
-    AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
+    AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
 #else
-    AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
+    AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
 #endif
-    AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
+    AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -212,103 +213,6 @@ const struct usb_descriptor audio_v2_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-uint8_t audio_v2_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00),
-    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
-    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
-    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
-    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000),
-#if USING_FEEDBACK == 0
-    AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
-#else
-    AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
-#endif
-    AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'A', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-#if USING_FEEDBACK == 0
-    '3', 0x00,                  /* wcChar9 */
-#else
-    '4', 0x00, /* wcChar9 */
-#endif
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static const uint8_t speaker_default_sampling_freq_table[] = {
     AUDIO_SAMPLE_FREQ_NUM(5),
@@ -330,9 +234,21 @@ static const uint8_t speaker_default_sampling_freq_table[] = {
 };
 
 static const uint8_t mic_default_sampling_freq_table[] = {
-    AUDIO_SAMPLE_FREQ_NUM(1),
+    AUDIO_SAMPLE_FREQ_NUM(5),
+    AUDIO_SAMPLE_FREQ_4B(8000),
+    AUDIO_SAMPLE_FREQ_4B(8000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
     AUDIO_SAMPLE_FREQ_4B(16000),
     AUDIO_SAMPLE_FREQ_4B(16000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
+    AUDIO_SAMPLE_FREQ_4B(32000),
+    AUDIO_SAMPLE_FREQ_4B(32000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
+    AUDIO_SAMPLE_FREQ_4B(48000),
+    AUDIO_SAMPLE_FREQ_4B(48000),
+    AUDIO_SAMPLE_FREQ_4B(0x00),
+    AUDIO_SAMPLE_FREQ_4B(96000),
+    AUDIO_SAMPLE_FREQ_4B(96000),
     AUDIO_SAMPLE_FREQ_4B(0x00)
 };
 
@@ -501,13 +417,12 @@ struct audio_entity_info audio_entity_table[] = {
       .ep = AUDIO_IN_EP },
 };
 
+// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
+
 void audio_v2_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &audio_v2_descriptor);
-#else
-    usbd_desc_register(busid, audio_v2_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4));
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 4));
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0200, audio_entity_table, 4));

+ 22 - 116
components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c

@@ -31,13 +31,13 @@
 #define HALF_WORD_BYTES    2  //2 half word (one channel)
 #define SAMPLE_BITS        16 //16 bit per channel
 
-#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
+#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME)
 
 #define OUT_CHANNEL_NUM 2
 
 #if OUT_CHANNEL_NUM == 1
 #define OUTPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL)
-#define OUTPUT_CH_ENABLE 0x00000000
+#define OUTPUT_CH_ENABLE 0x00000001
 #elif OUT_CHANNEL_NUM == 2
 #define OUTPUT_CTRL      DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
 #define OUTPUT_CH_ENABLE 0x00000003
@@ -64,21 +64,21 @@
 #define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
 
 #if USING_FEEDBACK == 0
-#define USB_AUDIO_CONFIG_DESC_SIZ (9 +                                                     \
-                                   AUDIO_V2_AC_DESCRIPTOR_INIT_LEN +                       \
-                                   AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
-                                   AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
-                                   AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
-                                   AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
-                                   AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
+#define USB_CONFIG_SIZE (9 +                                                     \
+                         AUDIO_V2_AC_DESCRIPTOR_LEN +                            \
+                         AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
+                         AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
+                         AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
+                         AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
+                         AUDIO_V2_AS_DESCRIPTOR_LEN)
 #else
-#define USB_AUDIO_CONFIG_DESC_SIZ (9 +                                                     \
-                                   AUDIO_V2_AC_DESCRIPTOR_INIT_LEN +                       \
-                                   AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
-                                   AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
-                                   AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
-                                   AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
-                                   AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN)
+#define USB_CONFIG_SIZE (9 +                                                     \
+                         AUDIO_V2_AC_DESCRIPTOR_LEN +                            \
+                         AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC +                  \
+                         AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC +                \
+                         AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
+                         AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC +               \
+                         AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN)
 #endif
 
 #define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC +                        \
@@ -87,18 +87,17 @@
                       AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
                       AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
     AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00),
     AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
+    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
     AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
+    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 0x0000),
 #if USING_FEEDBACK == 0
     AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
 #else
@@ -158,98 +157,6 @@ const struct usb_descriptor audio_v2_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t audio_v2_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00),
-    AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
-    AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
-    AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
-    AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
-#if USING_FEEDBACK == 0
-    AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
-#else
-    AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
-#endif
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'A', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-#if USING_FEEDBACK == 0
-    '3', 0x00,                  /* wcChar9 */
-#else
-    '4', 0x00, /* wcChar9 */
-#endif
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static const uint8_t default_sampling_freq_table[] = {
     AUDIO_SAMPLE_FREQ_NUM(5),
@@ -397,13 +304,12 @@ struct audio_entity_info audio_entity_table[] = {
       .ep = AUDIO_OUT_EP },
 };
 
+// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
+
 void audio_v2_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &audio_v2_descriptor);
-#else
-    usbd_desc_register(busid, audio_v2_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
     usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2));
     usbd_add_endpoint(busid, &audio_out_ep);

+ 2 - 84
components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c

@@ -23,7 +23,6 @@
 #define MSC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
 };
@@ -85,85 +84,6 @@ const struct usb_descriptor msc_bootuf2_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t msc_bootuf2_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'F', 0x00,                  /* wcChar11 */
-    '2', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static void usbd_event_handler(uint8_t busid, uint8_t event)
 {
@@ -215,11 +135,9 @@ static struct usbd_interface intf0;
 void msc_bootuf2_init(uint8_t busid, uintptr_t reg_base)
 {
     boot2uf2_flash_init();
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
+
     usbd_desc_register(busid, &msc_bootuf2_descriptor);
-#else
-    usbd_desc_register(busid, msc_bootuf2_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
 
     usbd_initialize(busid, reg_base, usbd_event_handler);

+ 2 - 147
components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c

@@ -43,7 +43,6 @@
 #define MSC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
 };
@@ -52,37 +51,7 @@ static const uint8_t config_descriptor[] = {
     USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
     CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
     MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x03,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
+    HID_MOUSE_DESCRIPTOR_INIT(0x03, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -137,117 +106,6 @@ const struct usb_descriptor cdc_acm_hid_msc_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t cdc_acm_hid_msc_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
-    MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x03,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'C', 0x00,                  /* wcChar10 */
-    'M', 0x00,                  /* wcChar11 */
-    'H', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 /*!< hid mouse report descriptor */
 static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -399,11 +257,8 @@ struct usbd_interface intf3;
 
 void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &cdc_acm_hid_msc_descriptor);
-#else
-    usbd_desc_register(busid, cdc_acm_hid_msc_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
     usbd_add_endpoint(busid, &cdc_out_ep);

+ 2 - 85
components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c

@@ -27,7 +27,6 @@
 #define CDC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -89,86 +88,6 @@ const struct usb_descriptor cdc_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t cdc_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'C', 0x00,                  /* wcChar10 */
-    'D', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 chry_ringbuffer_t usb_rx_rb;
 uint8_t usb_rx_buffer[2048];
@@ -243,11 +162,9 @@ static struct usbd_interface intf1;
 void cdc_acm_mavlink_init(uint8_t busid, uintptr_t reg_base)
 {
     chry_ringbuffer_init(&usb_rx_rb, usb_rx_buffer, sizeof(usb_rx_buffer));
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
+
     usbd_desc_register(busid, &cdc_descriptor);
-#else
-    usbd_desc_register(busid, cdc_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
     usbd_add_endpoint(busid, &cdc_out_ep);

+ 1 - 86
components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c

@@ -35,7 +35,6 @@
 #define MSC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -98,87 +97,6 @@ const struct usb_descriptor cdc_msc_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t cdc_msc_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
-    MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x00),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'C', 0x00,                  /* wcChar10 */
-    '-', 0x00,                  /* wcChar11 */
-    'M', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -249,11 +167,8 @@ struct usbd_interface intf2;
 
 void cdc_acm_msc_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &cdc_msc_descriptor);
-#else
-    usbd_desc_register(busid, cdc_msc_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
     usbd_add_endpoint(busid, &cdc_out_ep);

+ 1 - 88
components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c

@@ -37,7 +37,6 @@
 #define CDC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -102,89 +101,6 @@ const struct usb_descriptor cdc_multi_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t cdc_multi_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x08, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
-    CDC_ACM_DESCRIPTOR_INIT(0x02, CDC_INT_EP2, CDC_OUT_EP2, CDC_IN_EP2, CDC_MAX_MPS, 0x02),
-    CDC_ACM_DESCRIPTOR_INIT(0x04, CDC_INT_EP3, CDC_OUT_EP3, CDC_IN_EP3, CDC_MAX_MPS, 0x02),
-    CDC_ACM_DESCRIPTOR_INIT(0x06, CDC_INT_EP4, CDC_OUT_EP4, CDC_IN_EP4, CDC_MAX_MPS, 0x02),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'C', 0x00,                  /* wcChar10 */
-    'D', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[4][2048];
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[4][2048];
@@ -292,11 +208,8 @@ struct usbd_interface intf7;
 
 void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &cdc_multi_descriptor);
-#else
-    usbd_desc_register(busid, cdc_multi_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
     usbd_add_endpoint(busid, &cdc_out_ep1);

+ 26 - 86
components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c

@@ -25,7 +25,6 @@
 #define CDC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -87,86 +86,6 @@ const struct usb_descriptor cdc_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t cdc_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'C', 0x00,                  /* wcChar10 */
-    'D', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static void usbd_event_handler(uint8_t busid, uint8_t event)
 {
@@ -198,11 +117,32 @@ extern void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_e
 
 void cdc_acm_chardev_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &cdc_descriptor);
-#else
-    usbd_desc_register(busid, cdc_descriptor);
-#endif
+
     usbd_cdc_acm_serial_init(busid, CDC_IN_EP, CDC_OUT_EP);
     usbd_initialize(busid, reg_base, usbd_event_handler);
-}
+}
+
+static int cdc_acm_enter(int argc, char **argv)
+{
+    (void)argc;
+    (void)argv;
+
+    finsh_set_device("usb-acm0");
+    rt_console_set_device("usb-acm0");
+
+    return 0;
+}
+MSH_CMD_EXPORT(cdc_acm_enter, cdc_acm_enter);
+
+static int cdc_acm_exit(int argc, char **argv)
+{
+    (void)argc;
+    (void)argv;
+
+    finsh_set_device(RT_CONSOLE_DEVICE_NAME);
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+
+    return 0;
+}
+MSH_CMD_EXPORT(cdc_acm_exit, cdc_acm_exit);

+ 1 - 85
components/drivers/usb/cherryusb/demo/cdc_acm_template.c

@@ -25,7 +25,6 @@
 #define CDC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -87,86 +86,6 @@ const struct usb_descriptor cdc_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t cdc_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'C', 0x00,                  /* wcChar10 */
-    'D', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -245,11 +164,8 @@ void cdc_acm_init(uint8_t busid, uintptr_t reg_base)
     memcpy(&write_buffer[0], data, 10);
     memset(&write_buffer[10], 'a', 2038);
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &cdc_descriptor);
-#else
-    usbd_desc_register(busid, cdc_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
     usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
     usbd_add_endpoint(busid, &cdc_out_ep);

+ 5 - 114
components/drivers/usb/cherryusb/demo/cdc_ecm_template.c

@@ -29,22 +29,16 @@
 #define CDC_MAX_MPS 64
 #endif
 
-#define CDC_ECM_ETH_STATISTICS_BITMAP 0x00000000
-
 /* str idx = 4 is for mac address: aa:bb:cc:dd:ee:ff*/
 #define CDC_ECM_MAC_STRING_INDEX 4
 
-/* Ethernet Maximum Segment size, typically 1514 bytes */
-#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U
-
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
     USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_ETH_STATISTICS_BITMAP, CONFIG_CDC_ECM_ETH_MAX_SEGSZE, 0, 0, CDC_ECM_MAC_STRING_INDEX)
+    CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_MAC_STRING_INDEX)
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -68,6 +62,7 @@ static const char *string_descriptors[] = {
     "CherryUSB",                  /* Manufacturer */
     "CherryUSB CDC ECM DEMO",     /* Product */
     "2022123456",                 /* Serial Number */
+    "aabbccddeeff",               /* ecm mac address */
 };
 
 static const uint8_t *device_descriptor_callback(uint8_t speed)
@@ -87,7 +82,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
 
 static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
 {
-    if (index > 3) {
+    if (index > 4) {
         return NULL;
     }
     return string_descriptors[index];
@@ -99,107 +94,6 @@ const struct usb_descriptor cdc_ecm_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t cdc_ecm_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_ETH_STATISTICS_BITMAP, CONFIG_CDC_ECM_ETH_MAX_SEGSZE, 0, 0, CDC_ECM_MAC_STRING_INDEX),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x2E,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'C', 0x00,                  /* wcChar10 */
-    'D', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'E', 0x00,                  /* wcChar14 */
-    'C', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    ' ', 0x00,                  /* wcChar17 */
-    'D', 0x00,                  /* wcChar18 */
-    'E', 0x00,                  /* wcChar19 */
-    'M', 0x00,                  /* wcChar20 */
-    'O', 0x00,                  /* wcChar21 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-    ///////////////////////////////////////
-    /// string4 descriptor
-    ///////////////////////////////////////
-    0x1A,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'a', 0x00,                  /* wcChar0 */
-    'a', 0x00,                  /* wcChar1 */
-    'b', 0x00,                  /* wcChar2 */
-    'b', 0x00,                  /* wcChar3 */
-    'c', 0x00,                  /* wcChar4 */
-    'c', 0x00,                  /* wcChar5 */
-    'd', 0x00,                  /* wcChar6 */
-    'd', 0x00,                  /* wcChar7 */
-    'e', 0x00,                  /* wcChar8 */
-    'e', 0x00,                  /* wcChar9 */
-    'f', 0x00,                  /* wcChar10 */
-    'f', 0x00,                  /* wcChar11 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
 
@@ -463,12 +357,9 @@ void cdc_ecm_init(uint8_t busid, uintptr_t reg_base)
 {
     cdc_ecm_lwip_init();
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &cdc_ecm_descriptor);
-#else
-    usbd_desc_register(busid, cdc_ecm_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf0, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
     usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf1, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
     usbd_initialize(busid, reg_base, usbd_event_handler);
-}
+}

+ 1 - 87
components/drivers/usb/cherryusb/demo/cdc_rndis_template.c

@@ -29,7 +29,6 @@
 #define CDC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -91,88 +90,6 @@ const struct usb_descriptor cdc_rndis_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t cdc_rndis_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x2A,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'R', 0x00,                  /* wcChar10 */
-    'N', 0x00,                  /* wcChar11 */
-    'D', 0x00,                  /* wcChar12 */
-    'I', 0x00,                  /* wcChar13 */
-    'S', 0x00,                  /* wcChar14 */
-    ' ', 0x00,                  /* wcChar15 */
-    'D', 0x00,                  /* wcChar16 */
-    'E', 0x00,                  /* wcChar17 */
-    'M', 0x00,                  /* wcChar18 */
-    'O', 0x00,                  /* wcChar19 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
 
@@ -438,11 +355,8 @@ void cdc_rndis_init(uint8_t busid, uintptr_t reg_base)
 {
     rndis_lwip_init();
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &cdc_rndis_descriptor);
-#else
-    usbd_desc_register(busid, cdc_rndis_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, (uint8_t *)mac));
     usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, (uint8_t *)mac));
     usbd_initialize(busid, reg_base, usbd_event_handler);

+ 1 - 133
components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c

@@ -15,7 +15,6 @@
 
 #define USB_CONFIG_SIZE (9 + 9 + 9)
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
 };
@@ -77,134 +76,6 @@ const struct usb_descriptor dfu_flash_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t dfu_flash_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    DFU_DESCRIPTOR_INIT(),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x1e,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'D', 0x00,                  /* wcChar0 */
-    'F', 0x00,                  /* wcChar1 */
-    'U', 0x00,                  /* wcChar2 */
-    'W', 0x00,                  /* wcChar3 */
-    'i', 0x00,                  /* wcChar4 */
-    't', 0x00,                  /* wcChar5 */
-    'h', 0x00,                  /* wcChar6 */
-    's', 0x00,                  /* wcChar7 */
-    't', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    't', 0x00,                  /* wcChar10 */
-    'o', 0x00,                  /* wcChar11 */
-    'o', 0x00,                  /* wcChar12 */
-    'l', 0x00,                  /* wcChar13 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-    ///////////////////////////////////////
-    /// string4 descriptor
-    ///////////////////////////////////////
-    0x60,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '@', 0x00,                  /* wcChar0 */
-    'I', 0x00,                  /* wcChar1 */
-    'n', 0x00,                  /* wcChar2 */
-    't', 0x00,                  /* wcChar3 */
-    'e', 0x00,                  /* wcChar4 */
-    'r', 0x00,                  /* wcChar5 */
-    'n', 0x00,                  /* wcChar6 */
-    'a', 0x00,                  /* wcChar7 */
-    'l', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'F', 0x00,                  /* wcChar10 */
-    'l', 0x00,                  /* wcChar11*/
-    'a', 0x00,                  /* wcChar12 */
-    's', 0x00,                  /* wcChar13 */
-    'h', 0x00,                  /* wcChar14 */
-    ' ', 0x00,                  /* wcChar15 */
-    ' ', 0x00,                  /* wcChar16 */
-    ' ', 0x00,                  /* wcChar17 */
-    '/', 0x00,                  /* wcChar18 */
-    '0', 0x00,                  /* wcChar19 */
-    'x', 0x00,                  /* wcChar20 */
-    '0', 0x00,                  /* wcChar21*/
-    '8', 0x00,                  /* wcChar22 */
-    '0', 0x00,                  /* wcChar23 */
-    '0', 0x00,                  /* wcChar24 */
-    '0', 0x00,                  /* wcChar25 */
-    '0', 0x00,                  /* wcChar26 */
-    '0', 0x00,                  /* wcChar27 */
-    '0', 0x00,                  /* wcChar28 */
-    '/', 0x00,                  /* wcChar29 */
-    '1', 0x00,                  /* wcChar30 */
-    '6', 0x00,                  /* wcChar31*/
-    '*', 0x00,                  /* wcChar32 */
-    '0', 0x00,                  /* wcChar33 */
-    '0', 0x00,                  /* wcChar34 */
-    '1', 0x00,                  /* wcChar35 */
-    'K', 0x00,                  /* wcChar36 */
-    'a', 0x00,                  /* wcChar37 */
-    ',', 0x00,                  /* wcChar38 */
-    '1', 0x00,                  /* wcChar39 */
-    '1', 0x00,                  /* wcChar40 */
-    '2', 0x00,                  /* wcChar41*/
-    '*', 0x00,                  /* wcChar42 */
-    '0', 0x00,                  /* wcChar43 */
-    '1', 0x00,                  /* wcChar44 */
-    'K', 0x00,                  /* wcChar45 */
-    'g', 0x00,                  /* wcChar46 */
-
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static void usbd_event_handler(uint8_t busid, uint8_t event)
 {
@@ -235,11 +106,8 @@ struct usbd_interface intf0;
 
 void dfu_flash_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &dfu_flash_descriptor);
-#else
-    usbd_desc_register(busid, dfu_flash_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_dfu_init_intf(&intf0));
     usbd_initialize(busid, reg_base, usbd_event_handler);
 }

+ 250 - 0
components/drivers/usb/cherryusb/demo/gamepad_template.c

@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2026, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usbd_gamepad.h"
+
+#define GAMEPAD_IN_EP  0x81
+#define GAMEPAD_OUT_EP 0x02
+
+#define USBD_MAX_POWER 500
+
+static const uint8_t xinput_device_descriptor[] = {
+    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, XINPUT_VID, XINPUT_PID, XINPUT_BCD_DEVICE, 0x01)
+};
+
+static const uint8_t switch_device_descriptor[] = {
+    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, SWITCH_VID, SWITCH_PID, SWITCH_BCD_DEVICE, 0x01)
+};
+
+static const uint8_t xinput_config_descriptor[] = {
+    USB_CONFIG_DESCRIPTOR_INIT((9 + XINPUT_DESCRIPTOR_LEN), 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    XINPUT_DESCRIPTOR_INIT(0x00, GAMEPAD_OUT_EP, GAMEPAD_IN_EP)
+};
+
+static const uint8_t switch_config_descriptor[] = {
+    USB_CONFIG_DESCRIPTOR_INIT((9 + SWITCH_DESCRIPTOR_LEN), 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    SWITCH_DESCRIPTOR_INIT(0x00, GAMEPAD_OUT_EP, GAMEPAD_IN_EP)
+};
+
+static const char *xinput_string_descriptors[] = {
+    (const char[]){ 0x09, 0x04 }, /* Langid */
+    "Microsoft",                  /* Manufacturer */
+    "XInput STANDARD GAMEPAD",    /* Product */
+    "1.0",                        /* Serial Number */
+};
+
+static const char *switch_string_descriptors[] = {
+    (const char[]){ 0x09, 0x04 }, /* Langid */
+    "HORI",                       /* Manufacturer */
+    "Switch Pro Controller",      /* Product */
+    "1.0",                        /* Serial Number */
+};
+
+uint8_t gamepad_mode = USBD_GAMEPAD_MODE_XINPUT;
+bool gamepad_init_flag = false;
+
+static const uint8_t *device_descriptor_callback(uint8_t speed)
+{
+    switch (gamepad_mode) {
+        case USBD_GAMEPAD_MODE_XINPUT:
+            return xinput_device_descriptor;
+        case USBD_GAMEPAD_MODE_SWITCH:
+            return switch_device_descriptor;
+        case USBD_GAMEPAD_MODE_XBOXONE:
+            break;
+        case USBD_GAMEPAD_MODE_PS4:
+            break;
+
+        default:
+            break;
+    }
+    return NULL;
+}
+
+static const uint8_t *config_descriptor_callback(uint8_t speed)
+{
+    switch (gamepad_mode) {
+        case USBD_GAMEPAD_MODE_XINPUT:
+            return xinput_config_descriptor;
+        case USBD_GAMEPAD_MODE_SWITCH:
+            return switch_config_descriptor;
+        case USBD_GAMEPAD_MODE_XBOXONE:
+            break;
+        case USBD_GAMEPAD_MODE_PS4:
+            break;
+
+        default:
+            break;
+    }
+    return NULL;
+}
+
+static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
+{
+    return NULL;
+}
+
+static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
+{
+    if (index > 3) {
+        return NULL;
+    }
+
+    switch (gamepad_mode) {
+        case USBD_GAMEPAD_MODE_XINPUT:
+            return xinput_string_descriptors[index];
+        case USBD_GAMEPAD_MODE_SWITCH:
+            return switch_string_descriptors[index];
+        case USBD_GAMEPAD_MODE_XBOXONE:
+            break;
+        case USBD_GAMEPAD_MODE_PS4:
+            break;
+
+        default:
+            break;
+    }
+    return NULL;
+}
+
+const struct usb_descriptor gamepad_descriptor = {
+    .device_descriptor_callback = device_descriptor_callback,
+    .config_descriptor_callback = config_descriptor_callback,
+    .device_quality_descriptor_callback = device_quality_descriptor_callback,
+    .string_descriptor_callback = string_descriptor_callback
+};
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t gamepad_read_buffer[64];
+struct usb_gamepad_report gamepad_report;
+
+#define GAMEPAD_STATE_IDLE 0
+#define GAMEPAD_STATE_BUSY 1
+
+volatile uint8_t gamepad_state = GAMEPAD_STATE_IDLE;
+
+static void usbd_event_handler(uint8_t busid, uint8_t event)
+{
+    switch (event) {
+        case USBD_EVENT_RESET:
+            break;
+        case USBD_EVENT_CONNECTED:
+            break;
+        case USBD_EVENT_DISCONNECTED:
+            break;
+        case USBD_EVENT_RESUME:
+            break;
+        case USBD_EVENT_SUSPEND:
+            break;
+        case USBD_EVENT_CONFIGURED:
+            usbd_ep_start_read(busid, GAMEPAD_OUT_EP, gamepad_read_buffer, usbd_get_ep_mps(busid, GAMEPAD_OUT_EP));
+            break;
+        case USBD_EVENT_SET_REMOTE_WAKEUP:
+            break;
+        case USBD_EVENT_CLR_REMOTE_WAKEUP:
+            break;
+
+        default:
+            break;
+    }
+}
+
+static void usbd_gamepad_int_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+    gamepad_state = GAMEPAD_STATE_IDLE;
+}
+
+void usbd_gamepad_int_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+    usbd_ep_start_read(busid, GAMEPAD_OUT_EP, gamepad_read_buffer, usbd_get_ep_mps(busid, GAMEPAD_OUT_EP));
+}
+
+/*!< endpoint call back */
+static struct usbd_endpoint gamepad_in_ep = {
+    .ep_cb = usbd_gamepad_int_in_callback,
+    .ep_addr = GAMEPAD_IN_EP
+};
+
+static struct usbd_endpoint gamepad_out_ep = {
+    .ep_cb = usbd_gamepad_int_out_callback,
+    .ep_addr = GAMEPAD_OUT_EP
+};
+
+static struct usbd_interface intf0;
+
+void gamepad_init(uint8_t busid, uintptr_t reg_base)
+{
+    if (gamepad_init_flag) {
+        return;
+    }
+
+    gamepad_init_flag = true;
+
+    usbd_desc_register(busid, &gamepad_descriptor);
+
+    switch (gamepad_mode) {
+        case USBD_GAMEPAD_MODE_XINPUT:
+            usbd_add_interface(busid, usbd_gamepad_xinput_init_intf(&intf0));
+            break;
+        case USBD_GAMEPAD_MODE_SWITCH:
+            usbd_add_interface(busid, usbd_gamepad_switch_init_intf(&intf0));
+            break;
+        case USBD_GAMEPAD_MODE_XBOXONE:
+            break;
+        case USBD_GAMEPAD_MODE_PS4:
+            break;
+
+        default:
+            break;
+    }
+
+    usbd_add_endpoint(busid, &gamepad_in_ep);
+    usbd_add_endpoint(busid, &gamepad_out_ep);
+    usbd_initialize(busid, reg_base, usbd_event_handler);
+}
+
+void gamepad_change_mode(uint8_t mode, uintptr_t reg_base)
+{
+    gamepad_mode = mode;
+
+    if (gamepad_init_flag) {
+        usbd_deinitialize(0);
+    }
+    gamepad_init_flag = false;
+    gamepad_init(0, reg_base);
+}
+
+void gamepad_test(uint8_t busid)
+{
+    static uint32_t test_counter = 0;
+
+    if (usb_device_is_configured(busid) == false) {
+        return;
+    }
+
+    gamepad_state = GAMEPAD_STATE_BUSY;
+    memset(&gamepad_report, 0, sizeof(gamepad_report));
+
+    gamepad_report.buttons = (1 << (test_counter % 18));
+
+    switch (gamepad_mode) {
+        case USBD_GAMEPAD_MODE_XINPUT:
+            usbd_gamepad_xinput_send_report(GAMEPAD_IN_EP, &gamepad_report);
+            break;
+        case USBD_GAMEPAD_MODE_SWITCH:
+            usbd_gamepad_switch_send_report(GAMEPAD_IN_EP, &gamepad_report);
+            break;
+        case USBD_GAMEPAD_MODE_XBOXONE:
+            break;
+        case USBD_GAMEPAD_MODE_PS4:
+            break;
+
+        default:
+            break;
+    }
+
+    test_counter++;
+    while (gamepad_state == GAMEPAD_STATE_BUSY) {
+    }
+}

+ 41 - 202
components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c

@@ -8,25 +8,8 @@
 #include "usbd_core.h"
 #include "usbd_hid.h"
 
-
-/*!< hidraw in endpoint */
-#define HIDRAW_IN_EP       0x81
-#ifdef CONFIG_USB_HS
-#define HIDRAW_IN_EP_SIZE  1024
-#define HIDRAW_IN_INTERVAL 4
-#else
-#define HIDRAW_IN_EP_SIZE  64
-#define HIDRAW_IN_INTERVAL 10
-#endif
-/*!< hidraw out endpoint */
-#define HIDRAW_OUT_EP          0x02
-#ifdef CONFIG_USB_HS
-#define HIDRAW_OUT_EP_SIZE     1024
-#define HIDRAW_OUT_EP_INTERVAL 4
-#else
-#define HIDRAW_OUT_EP_SIZE     64
-#define HIDRAW_OUT_EP_INTERVAL 10
-#endif
+#define HIDRAW_IN_EP  0x81
+#define HIDRAW_OUT_EP 0x02
 
 #define USBD_VID           0xffff
 #define USBD_PID           0xffff
@@ -34,53 +17,26 @@
 #define USBD_LANGID_STRING 1033
 
 /*!< config descriptor size */
-#define USB_HID_CONFIG_DESC_SIZ (9 + 9 + 9 + 7 + 7)
+#define USB_CONFIG_SIZE (9 + 9 + 9 + 7 + 7)
 
 /*!< custom hid report descriptor size */
 #define HID_CUSTOM_REPORT_DESC_SIZE 38
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
+#ifdef CONFIG_USB_HS
+#define HID_MAX_MPS        1024
+#define HIDRAW_IN_INTERVAL 1
+#else
+#define HID_MAX_MPS        64
+#define HIDRAW_IN_INTERVAL 1
+#endif
+
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    /************** Descriptor of Custom interface *****************/
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x02,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x00,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Custom HID ********************/
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                        /* bCountryCode: Hardware target country */
-    0x01,                        /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                        /* bDescriptorType */
-    HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Custom in endpoint ********************/
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HIDRAW_IN_EP,                 /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    WBVAL(HIDRAW_IN_EP_SIZE),     /* wMaxPacketSize: 4 Byte max */
-    HIDRAW_IN_INTERVAL,           /* bInterval: Polling Interval */
-    /******************** Descriptor of Custom out endpoint ********************/
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HIDRAW_OUT_EP,                /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    WBVAL(HIDRAW_OUT_EP_SIZE),    /* wMaxPacketSize: 4 Byte max */
-    HIDRAW_OUT_EP_INTERVAL,       /* bInterval: Polling Interval */
-    /* 73 */
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    HID_CUSTOM_INOUT_DESCRIPTOR_INIT(0x00, 0x01, HID_CUSTOM_REPORT_DESC_SIZE, HIDRAW_OUT_EP, HIDRAW_IN_EP, HID_MAX_MPS, HIDRAW_IN_INTERVAL),
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -135,120 +91,6 @@ const struct usb_descriptor hid_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-static const uint8_t hid_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    /************** Descriptor of Custom interface *****************/
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x02,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x00,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Custom HID ********************/
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                        /* bCountryCode: Hardware target country */
-    0x01,                        /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                        /* bDescriptorType */
-    HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Custom in endpoint ********************/
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HIDRAW_IN_EP,                 /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    WBVAL(HIDRAW_IN_EP_SIZE),     /* wMaxPacketSize: 4 Byte max */
-    HIDRAW_IN_INTERVAL,           /* bInterval: Polling Interval */
-    /******************** Descriptor of Custom out endpoint ********************/
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HIDRAW_OUT_EP,                /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    WBVAL(HIDRAW_OUT_EP_SIZE),    /* wMaxPacketSize: 4 Byte max */
-    HIDRAW_OUT_EP_INTERVAL,       /* bInterval: Polling Interval */
-    /* 73 */
-    /*
-     * string0 descriptor
-     */
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    /*
-     * string1 descriptor
-     */
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    /*
-     * string2 descriptor
-     */
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'H', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'D', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    /*
-     * string3 descriptor
-     */
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    /*
-     * device qualifier descriptor
-     */
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 /*!< custom hid report descriptor */
 static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
@@ -261,16 +103,16 @@ static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
     0x09, 0x02,       /*   USAGE (Vendor Usage 1) */
     0x15, 0x00,       /*   LOGICAL_MINIMUM (0) */
     0x25, 0xff,       /*LOGICAL_MAXIMUM (255) */
-    0x75, 0x08,        /*   REPORT_SIZE (8) */
+    0x75, 0x08,       /*   REPORT_SIZE (8) */
     0x96, 0xff, 0x03, /*   REPORT_COUNT (63) */
     0x81, 0x02,       /*   INPUT (Data,Var,Abs) */
     /* <___________________________________________________> */
     0x85, 0x01,       /*   REPORT ID (0x01) */
     0x09, 0x03,       /*   USAGE (Vendor Usage 1) */
     0x15, 0x00,       /*   LOGICAL_MINIMUM (0) */
-    0x25, 0xff, /*   LOGICAL_MAXIMUM (255) */
+    0x25, 0xff,       /*   LOGICAL_MAXIMUM (255) */
     0x75, 0x08,       /*   REPORT_SIZE (8) */
-    0x96, 0xff, 0x03,   /*   REPORT_COUNT (63) */
+    0x96, 0xff, 0x03, /*   REPORT_COUNT (63) */
     0x91, 0x02,       /*   OUTPUT (Data,Var,Abs) */
     /* USER CODE END 0 */
     0xC0 /*     END_COLLECTION	             */
@@ -299,8 +141,8 @@ static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
 #endif
 };
 
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[HIDRAW_OUT_EP_SIZE];
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t send_buffer[HIDRAW_IN_EP_SIZE];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[HID_MAX_MPS];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t send_buffer[HID_MAX_MPS];
 
 #define HID_STATE_IDLE 0
 #define HID_STATE_BUSY 1
@@ -311,27 +153,27 @@ static volatile uint8_t custom_state;
 static void usbd_event_handler(uint8_t busid, uint8_t event)
 {
     switch (event) {
-    case USBD_EVENT_RESET:
-        break;
-    case USBD_EVENT_CONNECTED:
-        break;
-    case USBD_EVENT_DISCONNECTED:
-        break;
-    case USBD_EVENT_RESUME:
-        break;
-    case USBD_EVENT_SUSPEND:
-        break;
-    case USBD_EVENT_CONFIGURED:
-        /* setup first out ep read transfer */
-        usbd_ep_start_read(busid, HIDRAW_OUT_EP, read_buffer, HIDRAW_OUT_EP_SIZE);
-        break;
-    case USBD_EVENT_SET_REMOTE_WAKEUP:
-        break;
-    case USBD_EVENT_CLR_REMOTE_WAKEUP:
-        break;
-
-    default:
-        break;
+        case USBD_EVENT_RESET:
+            break;
+        case USBD_EVENT_CONNECTED:
+            break;
+        case USBD_EVENT_DISCONNECTED:
+            break;
+        case USBD_EVENT_RESUME:
+            break;
+        case USBD_EVENT_SUSPEND:
+            break;
+        case USBD_EVENT_CONFIGURED:
+            /* setup first out ep read transfer */
+            usbd_ep_start_read(busid, HIDRAW_OUT_EP, read_buffer, HID_MAX_MPS);
+            break;
+        case USBD_EVENT_SET_REMOTE_WAKEUP:
+            break;
+        case USBD_EVENT_CLR_REMOTE_WAKEUP:
+            break;
+
+        default:
+            break;
     }
 }
 
@@ -346,7 +188,7 @@ static void usbd_hid_custom_in_callback(uint8_t busid, uint8_t ep, uint32_t nbyt
 static void usbd_hid_custom_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
 {
     USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
-    usbd_ep_start_read(busid, ep, read_buffer, HIDRAW_IN_EP_SIZE);
+    usbd_ep_start_read(busid, ep, read_buffer, HID_MAX_MPS);
     read_buffer[0] = 0x02; /* IN: report id */
     usbd_ep_start_write(busid, HIDRAW_IN_EP, read_buffer, nbytes);
 }
@@ -372,11 +214,8 @@ struct usbd_interface intf0;
 
 void hid_custom_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &hid_descriptor);
-#else
-    usbd_desc_register(busid, hid_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE));
     usbd_add_endpoint(busid, &custom_in_ep);
     usbd_add_endpoint(busid, &custom_out_ep);

+ 4 - 151
components/drivers/usb/cherryusb/demo/hid_keyboard_template.c

@@ -15,49 +15,16 @@
 #define HID_INT_EP_SIZE     8
 #define HID_INT_EP_INTERVAL 10
 
-#define USB_HID_CONFIG_DESC_SIZ       34
+#define USB_CONFIG_SIZE       34
 #define HID_KEYBOARD_REPORT_DESC_SIZE 63
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x01,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                          /* bCountryCode: Hardware target country */
-    0x01,                          /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                          /* bDescriptorType */
-    HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -112,117 +79,6 @@ const struct usb_descriptor hid_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-static const uint8_t hid_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x01,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                          /* bCountryCode: Hardware target country */
-    0x01,                          /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                          /* bDescriptorType */
-    HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'H', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'D', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 /* USB HID device Configuration Descriptor */
 static uint8_t hid_desc[9] __ALIGN_END = {
@@ -319,11 +175,8 @@ struct usbd_interface intf0;
 
 void hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &hid_descriptor);
-#else
-    usbd_desc_register(busid, hid_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
     usbd_add_endpoint(busid, &hid_in_ep);
 

+ 4 - 152
components/drivers/usb/cherryusb/demo/hid_mouse_template.c

@@ -17,50 +17,17 @@
 #define USBD_LANGID_STRING 1033
 
 /*!< config descriptor size */
-#define USB_HID_CONFIG_DESC_SIZ 34
+#define USB_CONFIG_SIZE 34
 /*!< report descriptor size */
 #define HID_MOUSE_REPORT_DESC_SIZE 74
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -115,118 +82,6 @@ const struct usb_descriptor hid_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-const uint8_t hid_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'H', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'D', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 /*!< hid mouse report descriptor */
 static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -337,11 +192,8 @@ struct usbd_interface intf0;
 
 void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &hid_descriptor);
-#else
-    usbd_desc_register(busid, hid_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
     usbd_add_endpoint(busid, &hid_in_ep);
 

+ 4 - 152
components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c

@@ -17,50 +17,17 @@
 #define USBD_LANGID_STRING 1033
 
 /*!< config descriptor size */
-#define USB_HID_CONFIG_DESC_SIZ 34
+#define USB_CONFIG_SIZE 34
 /*!< report descriptor size */
 #define HID_MOUSE_REPORT_DESC_SIZE 74
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
+    HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -115,118 +82,6 @@ const struct usb_descriptor hid_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-/*!< global descriptor */
-const uint8_t hid_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'H', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'D', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 /*!< hid mouse report descriptor */
 static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -337,11 +192,8 @@ static struct usbd_interface intf0;
 
 void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &hid_descriptor);
-#else
-    usbd_desc_register(busid, hid_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
     usbd_add_endpoint(busid, &hid_in_ep);
 

+ 11 - 178
components/drivers/usb/cherryusb/demo/midi_template.c

@@ -14,7 +14,13 @@
 #define USBD_MAX_POWER     100
 #define USBD_LANGID_STRING 1033
 
-#define USB_CONFIG_SIZE (9 + 9 + 9 + 9 + 7 + MIDI_SIZEOF_JACK_DESC + 9 + 5 + 9 + 5)
+#define AUDIO_AC_SIZ AUDIO_SIZEOF_AC_HEADER_DESC(1)
+#define AUDIO_MS_SIZ (7 + MIDI_SIZEOF_JACK_DESC + 9 + 5 + 9 + 5)
+
+#define USB_CONFIG_SIZE (unsigned long)(9 +                            \
+                                        AUDIO_AC_DESCRIPTOR_LEN(1) +   \
+                                        MIDI_STANDARD_DESCRIPTOR_LEN + \
+                                        AUDIO_MS_SIZ)
 
 #ifdef CONFIG_USB_HS
 #define MIDI_EP_MPS 512
@@ -22,55 +28,15 @@
 #define MIDI_EP_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
     USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    // Standard AC Interface Descriptor
-    0x09,
-    0x04,
-    0x00,
-    0x00,
-    0x00,
-    0x01,
-    0x01,
-    0x00,
-    0x00,
-    // Class-specific AC Interface Descriptor
-    0x09,
-    0x24,
-    0x01,
-    0x00,
-    0x01,
-    0x09,
-    0x00,
-    0x01,
-    0x01,
-    // MIDIStreaming Interface Descriptors
-    0x09,
-    0x04,
-    0x01,
-    0x00,
-    0x02,
-    0x01,
-    0x03,
-    0x00,
-    0x00,
-    // Class-Specific MS Interface Header Descriptor
-    0x07,
-    0x24,
-    0x01,
-    0x00,
-    0x01,
-    WBVAL(65),
-
-    // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x01),
-    // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x02),
-    // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x03, 0x02),
-    // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x04, 0x01),
+    AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
+    MIDI_STANDARD_DESCRIPTOR_INIT(0x01, 0x02),
+    MIDI_CS_HEADER_DESCRIPTOR_INIT(AUDIO_MS_SIZ),
     MIDI_JACK_DESCRIPTOR_INIT(0x01),
     // OUT endpoint descriptor
     0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
@@ -133,136 +99,6 @@ const struct usb_descriptor midi_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t midi_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    // Standard AC Interface Descriptor
-    0x09,
-    0x04,
-    0x00,
-    0x00,
-    0x00,
-    0x01,
-    0x01,
-    0x00,
-    0x00,
-    // Class-specific AC Interface Descriptor
-    0x09,
-    0x24,
-    0x01,
-    0x00,
-    0x01,
-    0x09,
-    0x00,
-    0x01,
-    0x01,
-    // MIDIStreaming Interface Descriptors
-    0x09,
-    0x04,
-    0x01,
-    0x00,
-    0x02,
-    0x01,
-    0x03,
-    0x00,
-    0x00,
-    // Class-Specific MS Interface Header Descriptor
-    0x07,
-    0x24,
-    0x01,
-    0x00,
-    0x01,
-    WBVAL(65),
-
-    // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x01),
-    // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x02),
-    // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x03, 0x02),
-    // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x04, 0x01),
-    MIDI_JACK_DESCRIPTOR_INIT(0x01),
-    // OUT endpoint descriptor
-    0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
-    0x05, 0x25, 0x01, 0x01, 0x01,
-
-    // IN endpoint descriptor
-    0x09, 0x05, MIDI_IN_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
-    0x05, 0x25, 0x01, 0x01, 0x03,
-
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x28,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'M', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'D', 0x00,                  /* wcChar12 */
-    'I', 0x00,                  /* wcChar13 */
-    ' ', 0x00,                  /* wcChar14 */
-    'D', 0x00,                  /* wcChar15 */
-    'E', 0x00,                  /* wcChar16 */
-    'M', 0x00,                  /* wcChar17 */
-    'O', 0x00,                  /* wcChar18 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-    '0', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[MIDI_EP_MPS];
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[MIDI_EP_MPS];
@@ -317,11 +153,8 @@ struct usbd_endpoint midi_in_ep = {
 
 void midi_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &midi_descriptor);
-#else
-    usbd_desc_register(busid, midi_descriptor);
-#endif
+
     usbd_add_interface(busid, &intf0);
     usbd_add_interface(busid, &intf1);
     usbd_add_endpoint(busid, &midi_out_ep);

+ 1 - 84
components/drivers/usb/cherryusb/demo/msc_ram_template.c

@@ -22,7 +22,6 @@
 #define MSC_MAX_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
 };
@@ -84,85 +83,6 @@ const struct usb_descriptor msc_ram_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t msc_ram_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'M', 0x00,                  /* wcChar10 */
-    'S', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static void usbd_event_handler(uint8_t busid, uint8_t event)
 {
@@ -267,11 +187,8 @@ void msc_ram_init(uint8_t busid, uintptr_t reg_base)
     res = rt_device_open(blk_dev, RT_DEVICE_OFLAG_RDWR);
     RT_ASSERT(res == RT_EOK);
 #endif
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &msc_ram_descriptor);
-#else
-    usbd_desc_register(busid, msc_ram_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
 
     usbd_initialize(busid, reg_base, usbd_event_handler);

+ 124 - 92
components/drivers/usb/cherryusb/demo/usb_host.c

@@ -4,79 +4,73 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 #include "usbh_core.h"
-#include "usbh_cdc_acm.h"
+#include "usbh_serial.h"
 #include "usbh_hid.h"
 #include "usbh_msc.h"
-#include "usbh_video.h"
-#include "usbh_audio.h"
 
-#ifndef CONFIG_TEST_USBH_CDC_ACM
-#define CONFIG_TEST_USBH_CDC_ACM 1
-#endif
-#ifndef TEST_USBH_CDC_SPEED
-#define TEST_USBH_CDC_SPEED 0
-#endif
-#ifndef CONFIG_TEST_USBH_HID
-#define CONFIG_TEST_USBH_HID 1
-#endif
-#ifndef CONFIG_TEST_USBH_MSC
-#define CONFIG_TEST_USBH_MSC 1
-#endif
-#ifndef TEST_USBH_MSC_FATFS
-#define TEST_USBH_MSC_FATFS 0
-#endif
-#ifndef TEST_USBH_MSC_FATFS_SPEED
-#define TEST_USBH_MSC_FATFS_SPEED 0
-#endif
-#ifndef CONFIG_TEST_USBH_AUDIO
-#define CONFIG_TEST_USBH_AUDIO 0
-#endif
-#ifndef CONFIG_TEST_USBH_VIDEO
-#define CONFIG_TEST_USBH_VIDEO 0
-#endif
+// net class demos use socket api
 
-#if defined(TEST_USBH_CDC_ECM) || defined(TEST_USBH_CDC_RNDIS) || defined(TEST_USBH_ASIX) || defined(TEST_USBH_RTL8152)
-#error we have move those class implements into platform/none/usbh_lwip.c, and you should call tcpip_init(NULL, NULL) in your app
+#ifdef CONFIG_TEST_USBH_SERIAL
+#define SERIAL_TEST_LEN (1 * 1024)
+
+#if SERIAL_TEST_LEN >= CONFIG_USBHOST_SERIAL_RX_SIZE
+#error SERIAL_TEST_LEN is larger than CONFIG_USBHOST_SERIAL_RX_SIZE, please reduce SERIAL_TEST_LEN or increase CONFIG_USBHOST_SERIAL_RX_SIZE
 #endif
 
-#if CONFIG_TEST_USBH_CDC_ACM
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[4096];
+volatile uint32_t serial_tx_bytes = 0;
+volatile uint32_t serial_rx_bytes = 0;
+volatile bool serial_is_opened = false;
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t serial_tx_buffer[SERIAL_TEST_LEN];
+uint8_t serial_rx_data[SERIAL_TEST_LEN];
 
-#if TEST_USBH_CDC_SPEED
+#ifdef CONFIG_TEST_USBH_CDC_SPEED
 #define TEST_LEN   (16 * 1024)
 #define TEST_COUNT (10240)
 
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_speed_buffer[TEST_LEN];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t serial_speed_buffer[TEST_LEN];
 #endif
 
-void usbh_cdc_acm_callback(void *arg, int nbytes)
+static void usbh_serial_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
 {
-    //struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg;
-
-    if (nbytes > 0) {
-        for (size_t i = 0; i < nbytes; i++) {
-            USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
+    int ret;
+    struct usbh_serial *serial;
+    bool serial_test_success = false;
+
+    serial = usbh_serial_open("/dev/ttyACM0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
+    if (serial == NULL) {
+        serial = usbh_serial_open("/dev/ttyUSB0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
+        if (serial == NULL) {
+            USB_LOG_RAW("no serial device found\r\n");
+            goto delete;
         }
-        USB_LOG_RAW("nbytes:%d\r\n", (unsigned int)nbytes);
     }
-}
 
-static void usbh_cdc_acm_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
-{
-    int ret;
-    struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
+    struct usbh_serial_termios termios;
+
+    memset(&termios, 0, sizeof(termios));
+    termios.baudrate = 115200;
+    termios.stopbits = 0;
+    termios.parity = 0;
+    termios.databits = 8;
+    termios.rtscts = false;
+    termios.rx_timeout = 0;
+    ret = usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios);
+    if (ret < 0) {
+        USB_LOG_RAW("set serial attr error, ret:%d\r\n", ret);
+        goto delete_with_close;
+    }
 
     /* test with only one buffer, if you have more cdc acm class, modify by yourself */
-#if TEST_USBH_CDC_SPEED
+#ifdef CONFIG_TEST_USBH_CDC_SPEED
     const uint32_t test_len[] = { 512, 1 * 1024, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024 };
 
-    memset(cdc_speed_buffer, 0xAA, TEST_LEN);
+    memset(serial_speed_buffer, 0xAA, TEST_LEN);
 
     for (uint8_t j = 0; j < 6; j++) {
         uint32_t start_time = (uint32_t)xTaskGetTickCount();
         for (uint32_t i = 0; i < TEST_COUNT; i++) {
-            usbh_bulk_urb_fill(&cdc_acm_class->bulkout_urb, cdc_acm_class->hport, cdc_acm_class->bulkout, cdc_speed_buffer, test_len[j], 0XFFFFFFF, NULL, NULL);
-            ret = usbh_submit_urb(&cdc_acm_class->bulkout_urb);
+            usbh_serial_write(serial, serial_speed_buffer, test_len[j]);
             if (ret < 0) {
                 USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
                 while (1) {
@@ -87,35 +81,75 @@ static void usbh_cdc_acm_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
         uint32_t time_ms = xTaskGetTickCount() - start_time;
         USB_LOG_RAW("per packet len:%d, out speed:%f MB/S\r\n", (unsigned int)test_len[j], (test_len[j] * TEST_COUNT / 1024 / 1024) * 1000 / ((float)time_ms));
     }
+    usbh_serial_close(serial);
+    goto delete;
 #endif
-    memset(cdc_buffer, 0x55, 4096);
+    memset(serial_tx_buffer, 0xA5, sizeof(serial_tx_buffer));
+    USB_LOG_RAW("start serial loopback test, len: %d\r\n", SERIAL_TEST_LEN);
+
+    serial_tx_bytes = 0;
+    while (1) {
+        ret = usbh_serial_write(serial, serial_tx_buffer, sizeof(serial_tx_buffer));
+        if (ret < 0) {
+            USB_LOG_RAW("serial write error, ret:%d\r\n", ret);
+            goto delete_with_close;
+        } else {
+            serial_tx_bytes += ret;
 
-    /* for common, we use timeout with 0xffffffff, this is just a test */
-    usbh_bulk_urb_fill(&cdc_acm_class->bulkout_urb, cdc_acm_class->hport, cdc_acm_class->bulkout, cdc_buffer, sizeof(cdc_buffer), 3000, NULL, NULL);
-    ret = usbh_submit_urb(&cdc_acm_class->bulkout_urb);
-    if (ret < 0) {
-        USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
-        goto delete;
-    } else {
-        USB_LOG_RAW("send over:%d\r\n", (unsigned int)cdc_acm_class->bulkout_urb.actual_length);
+            if (serial_tx_bytes == SERIAL_TEST_LEN) {
+                USB_LOG_RAW("send over\r\n");
+                break;
+            }
+        }
     }
 
-    /* we can change cdc_acm_class->bulkin->wMaxPacketSize with 4096 for testing zlp, default is ep mps  */
-    usbh_bulk_urb_fill(&cdc_acm_class->bulkin_urb, cdc_acm_class->hport, cdc_acm_class->bulkin, cdc_buffer, cdc_acm_class->bulkin->wMaxPacketSize, 0xffffffff, usbh_cdc_acm_callback, cdc_acm_class);
-    ret = usbh_submit_urb(&cdc_acm_class->bulkin_urb);
-    if (ret < 0) {
-        USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
-        goto delete;
-    } else {
+    volatile uint32_t wait_timeout = 0;
+    serial_rx_bytes = 0;
+    while (1) {
+        ret = usbh_serial_read(serial, &serial_rx_data[serial_rx_bytes], SERIAL_TEST_LEN - serial_rx_bytes);
+        if (ret < 0) {
+            USB_LOG_RAW("serial read error, ret:%d\r\n", ret);
+            goto delete_with_close;
+        } else {
+            serial_rx_bytes += ret;
+
+            if (serial_rx_bytes == SERIAL_TEST_LEN) {
+                USB_LOG_RAW("receive over\r\n");
+                for (uint32_t i = 0; i < SERIAL_TEST_LEN; i++) {
+                    if (serial_rx_data[i] != 0xa5) {
+                        USB_LOG_RAW("serial loopback data error at index %d, data: 0x%02x\r\n", (unsigned int)i, serial_rx_data[i]);
+                        goto delete_with_close;
+                    }
+                }
+                serial_test_success = true;
+                break;
+            }
+        }
+        wait_timeout++;
+
+        if (wait_timeout > 500) { // 5s
+            USB_LOG_RAW("serial read timeout\r\n");
+            goto delete_with_close;
+        }
+
+        usb_osal_msleep(10);
     }
+
     // clang-format off
+delete_with_close:
+    if (serial_test_success) {
+        USB_LOG_RAW("serial loopback test success\r\n");
+    } else {
+        USB_LOG_RAW("serial loopback test failed\r\n");
+    }
+    usbh_serial_close(serial);
 delete:
     usb_osal_thread_delete(NULL);
     // clang-format on
 }
 #endif
 
-#if CONFIG_TEST_USBH_HID
+#ifdef CONFIG_TEST_USBH_HID
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128];
 
 void usbh_hid_callback(void *arg, int nbytes)
@@ -140,7 +174,6 @@ static void usbh_hid_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
 {
     int ret;
     struct usbh_hid *hid_class = (struct usbh_hid *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
-    ;
 
     /* test with only one buffer, if you have more hid class, modify by yourself */
 
@@ -157,15 +190,15 @@ delete:
 }
 #endif
 
-#if CONFIG_TEST_USBH_MSC
+#ifdef CONFIG_TEST_USBH_MSC
 
-#if TEST_USBH_MSC_FATFS
+#ifdef CONFIG_TEST_USBH_MSC_FATFS
 #include "ff.h"
 
-#if TEST_USBH_MSC_FATFS_SPEED
+#ifdef CONFIG_TEST_USBH_MSC_FATFS_SPEED
 #define WRITE_SIZE_MB (128UL)
-#define WRITE_SIZE (1024UL * 1024UL * WRITE_SIZE_MB)
-#define BUF_SIZE (1024UL * 128UL)
+#define WRITE_SIZE    (1024UL * 1024UL * WRITE_SIZE_MB)
+#define BUF_SIZE      (1024UL * 128UL)
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_write_buffer[BUF_SIZE];
 #else
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_write_buffer[25 * 100];
@@ -223,7 +256,7 @@ int usb_msc_fatfs_test()
         goto unmount;
     }
 
-#if TEST_USBH_MSC_FATFS_SPEED
+#ifdef CONFIG_TEST_USBH_MSC_FATFS_SPEED
     for (uint32_t i = 0; i < BUF_SIZE; i++) {
         read_write_buffer[i] = i % 256;
     }
@@ -234,9 +267,9 @@ int usb_msc_fatfs_test()
         uint32_t write_size = WRITE_SIZE;
         uint32_t start_time = (uint32_t)xTaskGetTickCount();
         while (write_size > 0) {
-            res_sd = f_write(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum);
+            res_sd = f_write(&fnew, read_write_buffer, BUF_SIZE, (UINT *)&fnum);
             if (res_sd != FR_OK) {
-                printf("Write file failed, cause: %s\n", res_sd);
+                USB_LOG_RAW("Write file failed, cause: %s\n", res_sd);
                 goto unmount;
             }
             write_size -= BUF_SIZE;
@@ -260,9 +293,9 @@ int usb_msc_fatfs_test()
         uint32_t write_size = WRITE_SIZE;
         uint32_t start_time = (uint32_t)xTaskGetTickCount();
         while (write_size > 0) {
-            res_sd = f_read(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum);
+            res_sd = f_read(&fnew, read_write_buffer, BUF_SIZE, (UINT *)&fnum);
             if (res_sd != FR_OK) {
-                printf("Read file failed, cause: %s\n", res_sd);
+                USB_LOG_RAW("Read file failed, cause: %s\n", res_sd);
                 goto unmount;
             }
             write_size -= BUF_SIZE;
@@ -295,8 +328,10 @@ static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
     int ret;
     struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
 
+    (void)msc_class;
+
     /* test with only one buffer, if you have more msc class, modify by yourself */
-#if TEST_USBH_MSC_FATFS == 0
+#ifndef TEST_USBH_MSC_FATFS
     ret = usbh_msc_scsi_init(msc_class);
     if (ret < 0) {
         USB_LOG_RAW("scsi_init error,ret:%d\r\n", ret);
@@ -326,18 +361,23 @@ delete:
 }
 #endif
 
-#if CONFIG_TEST_USBH_CDC_ACM
-void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
+#ifdef CONFIG_TEST_USBH_SERIAL
+void usbh_serial_run(struct usbh_serial *serial)
 {
-    usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class);
+    if (serial_is_opened) {
+        return;
+    }
+    serial_is_opened = true;
+    usb_osal_thread_create("usbh_serial", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_serial_thread, serial);
 }
 
-void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
+void usbh_serial_stop(struct usbh_serial *serial)
 {
+    serial_is_opened = false;
 }
 #endif
 
-#if CONFIG_TEST_USBH_HID
+#ifdef CONFIG_TEST_USBH_HID
 void usbh_hid_run(struct usbh_hid *hid_class)
 {
     usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
@@ -348,7 +388,7 @@ void usbh_hid_stop(struct usbh_hid *hid_class)
 }
 #endif
 
-#if CONFIG_TEST_USBH_MSC
+#ifdef CONFIG_TEST_USBH_MSC
 void usbh_msc_run(struct usbh_msc *msc_class)
 {
     usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
@@ -359,14 +399,6 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
 }
 #endif
 
-#if CONFIG_TEST_USBH_AUDIO
-#error "commercial charge"
-#endif
-
-#if CONFIG_TEST_USBH_VIDEO
-#error "commercial charge"
-#endif
-
 #if 0
 #include "usbh_aoa.h"
 

+ 182 - 0
components/drivers/usb/cherryusb/demo/usbh_bl616_wifi_cli.c

@@ -0,0 +1,182 @@
+#include "usbh_core.h"
+#include "usbh_cdc_acm.h"
+#include "shell.h"
+
+static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[8 * 1024];
+
+int wifi_scan(int argc, char **argv)
+{
+    struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
+    uint32_t len;
+    int ret;
+
+    if (cdc_acm_class == NULL) {
+        printf("cdc acm class not found\r\n");
+        return -1;
+    }
+
+    len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_scan\r\n");
+    ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
+    if (ret < 0) {
+        printf("wifi scan failed1, ret:%d\r\n", ret);
+        return -1;
+    }
+
+    ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
+    if (ret < 0) {
+        printf("wifi scan failed2, ret:%d\r\n", ret);
+        return -1;
+    }
+    cdc_buffer[ret] = '\0';
+    printf("%s\r\n", cdc_buffer);
+    return 0;
+}
+CSH_CMD_EXPORT(wifi_scan, wifi_scan);
+
+int wifi_scan_result(int argc, char **argv)
+{
+    struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
+    uint32_t len;
+    int ret;
+
+    if (cdc_acm_class == NULL) {
+        printf("cdc acm class not found\r\n");
+        return -1;
+    }
+
+    len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_scan_result {\"offset\":0, \"count\":0}\r\n");
+    ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
+    if (ret < 0) {
+        printf("wifi scan failed1, ret:%d\r\n", ret);
+        return -1;
+    }
+
+    ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
+    if (ret < 0) {
+        printf("wifi scan failed2, ret:%d\r\n", ret);
+        return -1;
+    }
+    cdc_buffer[ret] = '\0';
+    printf("%s\r\n", cdc_buffer);
+    return 0;
+}
+CSH_CMD_EXPORT(wifi_scan_result, wifi_scan_result);
+
+int wifi_connect(int argc, char **argv)
+{
+    struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
+    uint32_t len;
+    int ret;
+
+    if (cdc_acm_class == NULL) {
+        printf("cdc acm class not found\r\n");
+        return -1;
+    }
+
+    if (argc < 3) {
+        printf("please input correct command: wifi_connect ssid password\r\n");
+        return -1;
+    }
+
+    len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_connect {\"ssid\":\"%s\", \"password\":\"%s\"}\r\n", argv[1], argv[2]);
+    ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
+    if (ret < 0) {
+        printf("wifi connect failed1, ret:%d\r\n", ret);
+        return -1;
+    }
+    ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
+    if (ret < 0) {
+        printf("wifi connect failed2, ret:%d\r\n", ret);
+        return -1;
+    }
+    cdc_buffer[ret] = '\0';
+    printf("%s\r\n", cdc_buffer);
+    return 0;
+}
+CSH_CMD_EXPORT(wifi_connect, wifi_connect);
+
+int wifi_disconnect(int argc, char **argv)
+{
+    struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
+    uint32_t len;
+    int ret;
+
+    if (cdc_acm_class == NULL) {
+        printf("cdc acm class not found\r\n");
+        return -1;
+    }
+
+    len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_disconnect\r\n");
+    ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
+    if (ret < 0) {
+        printf("wifi disconnect failed1, ret:%d\r\n", ret);
+        return -1;
+    }
+    ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
+    if (ret < 0) {
+        printf("wifi disconnect failed2, ret:%d\r\n", ret);
+        return -1;
+    }
+    cdc_buffer[ret] = '\0';
+    printf("%s\r\n", cdc_buffer);
+    return 0;
+}
+CSH_CMD_EXPORT(wifi_disconnect, wifi_disconnect);
+
+int wifi_status(int argc, char **argv)
+{
+    struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
+    uint32_t len;
+    int ret;
+
+    if (cdc_acm_class == NULL) {
+        printf("cdc acm class not found\r\n");
+        return -1;
+    }
+
+    len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_status\r\n");
+    ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
+    if (ret < 0) {
+        printf("wifi status failed1, ret:%d\r\n", ret);
+        return -1;
+    }
+
+    ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
+    if (ret < 0) {
+        printf("wifi status failed2, ret:%d\r\n", ret);
+        return -1;
+    }
+    cdc_buffer[ret] = '\0';
+    printf("%s\r\n", cdc_buffer);
+    return 0;
+}
+CSH_CMD_EXPORT(wifi_status, wifi_status);
+
+int wifi_version(int argc, char **argv)
+{
+    struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
+    uint32_t len;
+    int ret;
+
+    if (cdc_acm_class == NULL) {
+        printf("cdc acm class not found\r\n");
+        return -1;
+    }
+
+    len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "sys_version\r\n");
+    ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
+    if (ret < 0) {
+        printf("wifi status failed1, ret:%d\r\n", ret);
+        return -1;
+    }
+
+    ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
+    if (ret < 0) {
+        printf("wifi status failed2, ret:%d\r\n", ret);
+        return -1;
+    }
+    cdc_buffer[ret] = '\0';
+    printf("%s\r\n", cdc_buffer);
+    return 0;
+}
+CSH_CMD_EXPORT(wifi_version, wifi_version);

+ 9 - 174
components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c

@@ -46,15 +46,15 @@
                                            VS_HEADER_SIZ +                           \
                                            9 +                                       \
                                            7 +                                       \
-                                           AUDIO_AC_DESCRIPTOR_INIT_LEN(2) +         \
+                                           AUDIO_AC_DESCRIPTOR_LEN(2) +         \
                                            AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
                                            AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
                                            AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +    \
                                            AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC +     \
                                            AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
                                            AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC +    \
-                                           AUDIO_AS_DESCRIPTOR_INIT_LEN(1) +         \
-                                           AUDIO_AS_DESCRIPTOR_INIT_LEN(1) +         \
+                                           AUDIO_AS_DESCRIPTOR_LEN(1) +         \
+                                           AUDIO_AS_DESCRIPTOR_LEN(1) +         \
                                            25)
 
 #define USBD_VID           0xffff
@@ -103,7 +103,6 @@
 
 #define HID_KEYBOARD_REPORT_DESC_SIZE 63
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
@@ -130,38 +129,7 @@ static const uint8_t config_descriptor[] = {
                              EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
     AUDIO_AS_DESCRIPTOR_INIT(0x04, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
                              EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x05,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x01,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                          /* bCountryCode: Hardware target country */
-    0x01,                          /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                          /* bDescriptorType */
-    HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
+    HID_KEYBOARD_DESCRIPTOR_INIT(0x05, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -216,136 +184,6 @@ const struct usb_descriptor video_audio_hid_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t video_audio_hid_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x06, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
-    VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
-    VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01),
-    VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
-    /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
-    USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
-    AUDIO_AC_DESCRIPTOR_INIT(0x02, 0x03, AUDIO_AC_SIZ, 0x00, 0x03, 0x04),
-    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003),
-    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00),
-    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
-    AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
-    AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
-    AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
-    AUDIO_AS_DESCRIPTOR_INIT(0x03, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
-                             EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
-    AUDIO_AS_DESCRIPTOR_INIT(0x04, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
-                             EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x05,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x01,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                          /* bCountryCode: Hardware target country */
-    0x01,                          /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                          /* bDescriptorType */
-    HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'A', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '4', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-    '0', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
     0x05, 0x01, // USAGE_PAGE (Generic Desktop)
@@ -469,11 +307,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
         audio_rx_flag = 1;
         /* setup first out ep read transfer */
         usbd_ep_start_read(busid, AUDIO_OUT_EP, audio_read_buffer, AUDIO_OUT_PACKET);
-        printf("OPEN1\r\n");
+        USB_LOG_RAW("OPEN1\r\n");
     } else if (intf == 4) {
         audio_tx_flag = 1;
         audio_iso_tx_busy = false;
-        printf("OPEN2\r\n");
+        USB_LOG_RAW("OPEN2\r\n");
     }
 }
 
@@ -481,11 +319,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
 {
     if (intf == 3) {
         audio_rx_flag = 0;
-        printf("CLOSE1\r\n");
+        USB_LOG_RAW("CLOSE1\r\n");
     } else if (intf == 4) {
         audio_tx_flag = 0;
         audio_iso_tx_busy = false;
-        printf("CLOSE2\r\n");
+        USB_LOG_RAW("CLOSE2\r\n");
     }
 }
 
@@ -541,11 +379,8 @@ struct audio_entity_info audio_entity_table[] = {
 
 void composite_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &video_audio_hid_descriptor);
-#else
-    usbd_desc_register(busid, video_audio_hid_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_endpoint(busid, &video_in_ep);

+ 1 - 93
components/drivers/usb/cherryusb/demo/video_static_h264_template.c

@@ -48,7 +48,6 @@
 #define USBD_MAX_POWER     100
 #define USBD_LANGID_STRING 1033
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
@@ -118,94 +117,6 @@ const struct usb_descriptor video_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t video_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
-    VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
-    VIDEO_VS_FORMAT_H264_DESCRIPTOR_INIT(0x01, 0x01),
-    VIDEO_VS_FRAME_H264_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
-    /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
-    USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
-
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'V', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-    '0', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 volatile bool tx_flag = 0;
 volatile bool iso_tx_busy = false;
@@ -272,11 +183,8 @@ struct usbd_interface intf1;
 
 void video_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &video_descriptor);
-#else
-    usbd_desc_register(busid, video_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_endpoint(busid, &video_in_ep);

+ 1 - 93
components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c

@@ -48,7 +48,6 @@
 #define USBD_MAX_POWER     100
 #define USBD_LANGID_STRING 1033
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
@@ -118,94 +117,6 @@ const struct usb_descriptor video_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t video_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
-    VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
-    VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01),
-    VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
-    /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
-    USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
-
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'V', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-    '0', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 volatile bool tx_flag = 0;
 volatile bool iso_tx_busy = false;
@@ -272,11 +183,8 @@ struct usbd_interface intf1;
 
 void video_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &video_descriptor);
-#else
-    usbd_desc_register(busid, video_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_endpoint(busid, &video_in_ep);

+ 1 - 94
components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c

@@ -49,7 +49,6 @@
 #define USBD_MAX_POWER     100
 #define USBD_LANGID_STRING 1033
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
@@ -121,95 +120,6 @@ const struct usb_descriptor video_descriptor = {
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback
 };
-#else
-const uint8_t video_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
-    VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
-    VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, 0x01, VIDEO_GUID_YUY2),
-    VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
-    VIDEO_VS_COLOR_MATCHING_DESCRIPTOR_INIT(),
-    VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
-    /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
-    USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
-
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x26,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'U', 0x00,                  /* wcChar10 */
-    'V', 0x00,                  /* wcChar11 */
-    'C', 0x00,                  /* wcChar12 */
-    ' ', 0x00,                  /* wcChar13 */
-    'D', 0x00,                  /* wcChar14 */
-    'E', 0x00,                  /* wcChar15 */
-    'M', 0x00,                  /* wcChar16 */
-    'O', 0x00,                  /* wcChar17 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '0', 0x00,                  /* wcChar4 */
-    '3', 0x00,                  /* wcChar5 */
-    '1', 0x00,                  /* wcChar6 */
-    '0', 0x00,                  /* wcChar7 */
-    '0', 0x00,                  /* wcChar8 */
-    '0', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 volatile bool tx_flag = 0;
 volatile bool iso_tx_busy = false;
@@ -276,11 +186,8 @@ struct usbd_interface intf1;
 
 void video_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &video_descriptor);
-#else
-    usbd_desc_register(busid, video_descriptor);
-#endif
+
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
     usbd_add_endpoint(busid, &video_in_ep);

+ 34 - 275
components/drivers/usb/cherryusb/demo/webusb_hid_template.c

@@ -6,76 +6,17 @@
 #include "usbd_core.h"
 #include "usbd_hid.h"
 
-#define USBD_VID           0xffff
-#define USBD_PID           0xffff
-#define USBD_MAX_POWER     100
-#define USBD_LANGID_STRING 1033
-
-#define HID_INT_EP          0x81
-#define HID_INT_EP_SIZE     8
-#define HID_INT_EP_INTERVAL 10
-
-#define USB_HID_CONFIG_DESC_SIZ       (34 + 9)
-#define HID_KEYBOARD_REPORT_DESC_SIZE 63
-
-#define USBD_WEBUSB_VENDOR_CODE  (0x22)
-#define USBD_WINUSB_VENDOR_CODE  (0x21)
+#define WEBUSB_VENDOR_CODE (0x22)
+#define WINUSB_VENDOR_CODE (0x21)
 
-#define USBD_WINUSB_DESC_SET_LEN (0xB2)
 #define URL_DESCRIPTOR_LENGTH    (3 + 36)
 
-#define USBD_WEBUSB_INTF_NUM     0x01
+#define WEBUSB_INTF_NUM 0x01
 
 #define WEBUSB_URL_STRINGS                                 \
     'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', \
         'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '/', 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B',
 
-const uint8_t USBD_WinUSBDescriptorSetDescriptor[USBD_WINUSB_DESC_SET_LEN] = {
-    // Microsoft OS 2.0 描述符集标头
-    0x0A, 0x00,                     // Descriptor size (10 bytes)
-    0x00, 0x00,                     // MS OS 2.0 descriptor set header
-    0x00, 0x00, 0x03, 0x06,         // Windows version (8.1) (0x06030000)
-    USBD_WINUSB_DESC_SET_LEN, 0x00, // Size, MS OS 2.0 descriptor set
-
-    // Microsoft OS 2.0 配置子集标头
-    0x08, 0x00, // wLength
-    0x01, 0x00, // wDescriptorType
-    0x00,       // 适用于配置 1
-    0x00,       // bReserved
-    0XA8, 0X00, // Size, MS OS 2.0 configuration subset
-
-    // Microsoft OS 2.0 功能子集头
-    0x08, 0x00,           // Descriptor size (8 bytes)
-    0x02, 0x00,           // MS OS 2.0 function subset header
-    USBD_WEBUSB_INTF_NUM, // bFirstInterface
-    0x00,                 // 必须设置为 0
-    0xA0, 0x00,
-
-    // Microsoft OS 2.0 兼容 ID 描述符
-    // 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容
-    0x14, 0x00, // wLength  20
-    0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID
-    'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-    // Microsoft OS 2.0 注册表属性描述符
-    // 注册表属性分配设备接口 GUID
-    0x84, 0x00, //wLength: 132
-    0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9)
-    0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15)
-    0x2a, 0x00, //wPropertyNameLength:
-    //bPropertyName: “DeviceInterfaceGUID”
-    'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
-    'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00,
-    0x00, 0x00,
-    0x50, 0x00, // wPropertyDataLength
-    //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
-    '{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00,
-    'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00,
-    '9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00,
-    '8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
 const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
     URL_DESCRIPTOR_LENGTH,
     WEBUSB_URL_TYPE,
@@ -83,113 +24,54 @@ const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
     WEBUSB_URL_STRINGS
 };
 
-#define USBD_BOS_WTOTALLENGTH 0x39
-
-#define LANDING_PAGE          0x01
-uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = {
-    // BOS描述符
-    0x05,                        // bLength          固长为5
-    0x0F,                        // bDescriptorType  固定为15
-    USBD_BOS_WTOTALLENGTH, 0x00, // wTotalLength     BOS描述符的总大小
-    0x02,                        // bNumDeviceCaps   BOS描述符中独立设备功能特性描述符的数量
-
-    // WebUSB 平台功能描述符
-    0x18, // Descriptor size (24 bytes)
-    0x10, // Descriptor type (Device Capability) 设备功能描述符
-    0x05, // Capability type (Platform) 平台描述符
-    0x00, // Reserved
-
-    // WebUSB Platform Capability ID (3408b638-09a9-47a0-8bfd-a0768815b665)
-    // 平台功能 UUID 将此标识为WebUSB 平台功能描述符,它提供有关设备的基本信息
-    0x38, 0xB6, 0x08, 0x34,
-    0xA9, 0x09,
-    0xA0, 0x47,
-    0x8B, 0xFD,
-    0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
-
-    0x00, 0x01,              // WebUSB version 1.0
-    USBD_WEBUSB_VENDOR_CODE, // Vendor-assigned WebUSB request code
-    LANDING_PAGE,            // Landing page
-
-    // Microsoft 平台功能描述符
-    // 标头
-    0x1C, // Descriptor size (28 bytes)
-    0x10, // Descriptor type (Device Capability)
-    0x05, // Capability type (Platform)
-    0x00, // Reserved
-
-    0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
-    0x89, 0x45, 0xC7, 0x4C,
-    0x9C, 0xD2, 0x65, 0x9D,
-    0x9E, 0x64, 0x8A, 0x9F,
-
-    // 描述符集信息结构
-    0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 * dwWindowsVersion    最低兼容 Windows 版本 */
-
-    USBD_WINUSB_DESC_SET_LEN, 0X00, /* wDescriptorSetTotalLength */
-
-    USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
-    0X00                     /* bAltEnumCode */
+const uint8_t WINUSB_WCIDDescriptor[] = {
+    USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN),
+    USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(WEBUSB_INTF_NUM),
+};
+
+__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
+    USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_LEN + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 2),
+    USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_INIT(WEBUSB_VENDOR_CODE, 0x01),
+    USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)),
 };
 
 struct usb_webusb_descriptor webusb_url_desc = {
-    .vendor_code = USBD_WEBUSB_VENDOR_CODE,
+    .vendor_code = WEBUSB_VENDOR_CODE,
     .string = USBD_WebUSBURLDescriptor,
     .string_len = URL_DESCRIPTOR_LENGTH
 };
 
 struct usb_msosv2_descriptor msosv2_desc = {
-    .vendor_code = USBD_WINUSB_VENDOR_CODE,
-    .compat_id = USBD_WinUSBDescriptorSetDescriptor,
-    .compat_id_len = USBD_WINUSB_DESC_SET_LEN,
+    .vendor_code = WINUSB_VENDOR_CODE,
+    .compat_id = WINUSB_WCIDDescriptor,
+    .compat_id_len = sizeof(WINUSB_WCIDDescriptor),
 };
 
 struct usb_bos_descriptor bos_desc = {
     .string = USBD_BinaryObjectStoreDescriptor,
-    .string_len = USBD_BOS_WTOTALLENGTH
+    .string_len = sizeof(USBD_BinaryObjectStoreDescriptor)
 };
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
+#define USBD_VID           0xffff
+#define USBD_PID           0xffff
+#define USBD_MAX_POWER     100
+#define USBD_LANGID_STRING 1033
+
+#define HID_INT_EP          0x81
+#define HID_INT_EP_SIZE     8
+#define HID_INT_EP_INTERVAL 10
+
+#define USB_CONFIG_SIZE       (34 + 9)
+#define HID_KEYBOARD_REPORT_DESC_SIZE 63
+
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
 };
 
 static const uint8_t config_descriptor[] = {
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x01,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                          /* bCountryCode: Hardware target country */
-    0x01,                          /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                          /* bDescriptorType */
-    HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
-    USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00)
+    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+    HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
+    USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00)
 };
 
 static const uint8_t device_quality_descriptor[] = {
@@ -247,121 +129,6 @@ const struct usb_descriptor webusb_hid_descriptor = {
     .webusb_url_descriptor = &webusb_url_desc,
     .bos_descriptor = &bos_desc
 };
-#else
-static const uint8_t webusb_hid_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x00,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x01,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                          /* bCountryCode: Hardware target country */
-    0x01,                          /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                          /* bDescriptorType */
-    HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* 34 */
-    USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00),
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x2C,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'W', 0x00,                  /* wcChar10 */
-    'E', 0x00,                  /* wcChar11 */
-    'B', 0x00,                  /* wcChar12 */
-    'U', 0x00,                  /* wcChar13 */
-    'S', 0x00,                  /* wcChar14 */
-    'B', 0x00,                  /* wcChar15 */
-    ' ', 0x00,                  /* wcChar16 */
-    'D', 0x00,                  /* wcChar17 */
-    'E', 0x00,                  /* wcChar18 */
-    'M', 0x00,                  /* wcChar19 */
-    'O', 0x00,                  /* wcChar20 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 /* USB HID device Configuration Descriptor */
 static uint8_t hid_desc[9] __ALIGN_END = {
@@ -458,16 +225,8 @@ static struct usbd_interface intf0;
 
 void webusb_hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
     usbd_desc_register(busid, &webusb_hid_descriptor);
-#else
-    usbd_desc_register(busid, webusb_hid_descriptor);
-#endif
-#ifndef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_bos_desc_register(busid, &bos_desc);
-    usbd_msosv2_desc_register(busid, &msosv2_desc);
-    usbd_webusb_desc_register(busid, &webusb_url_desc);
-#endif
+
     usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
     usbd_add_endpoint(busid, &hid_in_ep);
 
@@ -480,7 +239,7 @@ void hid_keyboard_test(uint8_t busid)
 {
     const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
-    if(usb_device_is_configured(busid) == false) {
+    if (usb_device_is_configured(busid) == false) {
         return;
     }
 

+ 84 - 291
components/drivers/usb/cherryusb/demo/winusb1.0_template.c

@@ -4,161 +4,106 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 #include "usbd_core.h"
-#include "usbd_cdc_acm.h"
 
-#define WCID_VENDOR_CODE 0x17
+#define WINUSB_VENDOR_CODE 0x17
 
-#define DOUBLE_WINUSB 0
+#define WINUSB_NUM 1
 
-__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
-    ///////////////////////////////////////
-    /// MS OS string descriptor
-    ///////////////////////////////////////
-    0x12,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    /* MSFT100 */
-    'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
-    '1', 0x00, '0', 0x00, '0', 0x00,            /* wcChar_7 */
-    WCID_VENDOR_CODE,                           /* bVendorCode */
-    0x00,                                       /* bReserved */
+const uint8_t WCID_StringDescriptor_MSOS[18] = {
+    USB_MSOSV1_STRING_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE)
 };
 
-#if DOUBLE_WINUSB == 0
-__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
+const uint8_t WINUSB_WCIDDescriptor[] = {
+    USB_MSOSV1_COMP_ID_HEADER_DESCRIPTOR_INIT(WINUSB_NUM),
+    USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(0),
+#if WINUSB_NUM == 2
+    USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(1),
+#endif
+};
+
+const uint8_t WINUSB_IF0_WCIDProperties[142] = {
     ///////////////////////////////////////
-    /// WCID descriptor
+    /// WCID property descriptor
     ///////////////////////////////////////
-    0x28, 0x00, 0x00, 0x00,                   /* dwLength */
-    0x00, 0x01,                               /* bcdVersion */
-    0x04, 0x00,                               /* wIndex */
-    0x01,                                     /* bCount */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
+    0x8e, 0x00, 0x00, 0x00, /* dwLength */
+    0x00, 0x01,             /* bcdVersion */
+    0x05, 0x00,             /* wIndex */
+    0x01, 0x00,             /* wCount */
 
     ///////////////////////////////////////
-    /// WCID function descriptor
+    /// registry propter descriptor
     ///////////////////////////////////////
-    0x00, /* bFirstInterfaceNumber */
-    0x01, /* bReserved */
-    /* WINUSB */
-    'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
-    /*  */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             /* bReserved_6 */
+    0x84, 0x00, 0x00, 0x00, /* dwSize */
+    0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
+    0x28, 0x00,             /* wPropertyNameLength */
+    /* DeviceInterfaceGUID */
+    'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00,  /* wcName_20 */
+    'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00,  /* wcName_20 */
+    't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00,  /* wcName_20 */
+    'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00,  /* wcName_20 */
+    'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
+    0x4e, 0x00, 0x00, 0x00,                      /* dwPropertyDataLength */
+    /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
+    '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
+    'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
+    '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
+    '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
+    '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
+    'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
+    '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
+    'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
+    'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
+    '6', 0x00, '}', 0x00, 0x00, 0x00,           /* wcData_39 */
 };
-#else
-__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[64] __ALIGN_END = {
-    ///////////////////////////////////////
-    /// WCID descriptor
-    ///////////////////////////////////////
-    0x40, 0x00, 0x00, 0x00,                   /* dwLength */
-    0x00, 0x01,                               /* bcdVersion */
-    0x04, 0x00,                               /* wIndex */
-    0x02,                                     /* bCount */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
 
+#if WINUSB_NUM == 2
+#define WINUSB_IF1_WCID_PROPERTIES_SIZE (142)
+const uint8_t WINUSB_IF1_WCIDProperties[142] = {
     ///////////////////////////////////////
-    /// WCID function descriptor
+    /// WCID property descriptor
     ///////////////////////////////////////
-    0x00, /* bFirstInterfaceNumber */
-    0x01, /* bReserved */
-    /* WINUSB */
-    'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
-    /*  */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             /* bReserved_6 */
+    0x8e, 0x00, 0x00, 0x00, /* dwLength */
+    0x00, 0x01,             /* bcdVersion */
+    0x05, 0x00,             /* wIndex */
+    0x01, 0x00,             /* wCount */
 
     ///////////////////////////////////////
-    /// WCID function descriptor
+    /// registry propter descriptor
     ///////////////////////////////////////
-    0x01, /* bFirstInterfaceNumber */
-    0x01, /* bReserved */
-    /* WINUSB */
-    'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
-    /*  */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             /* bReserved_6 */
+    0x84, 0x00, 0x00, 0x00, /* dwSize */
+    0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
+    0x28, 0x00,             /* wPropertyNameLength */
+    /* DeviceInterfaceGUID */
+    'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00,  /* wcName_20 */
+    'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00,  /* wcName_20 */
+    't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00,  /* wcName_20 */
+    'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00,  /* wcName_20 */
+    'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
+    0x4e, 0x00, 0x00, 0x00,                      /* dwPropertyDataLength */
+    /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
+    '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
+    'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
+    '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
+    '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
+    '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
+    'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
+    '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
+    'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
+    'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
+    '6', 0x00, '}', 0x00, 0x00, 0x00,           /* wcData_39 */
 };
 #endif
-__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties [142] __ALIGN_END = {
-  ///////////////////////////////////////
-  /// WCID property descriptor
-  ///////////////////////////////////////
-  0x8e, 0x00, 0x00, 0x00,                           /* dwLength */
-  0x00, 0x01,                                       /* bcdVersion */
-  0x05, 0x00,                                       /* wIndex */
-  0x01, 0x00,                                       /* wCount */
-
-  ///////////////////////////////////////
-  /// registry propter descriptor
-  ///////////////////////////////////////
-  0x84, 0x00, 0x00, 0x00,                           /* dwSize */
-  0x01, 0x00, 0x00, 0x00,                           /* dwPropertyDataType */
-  0x28, 0x00,                                       /* wPropertyNameLength */
-  /* DeviceInterfaceGUID */
-  'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00,       /* wcName_20 */
-  'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00,       /* wcName_20 */
-  't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00,       /* wcName_20 */
-  'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00,       /* wcName_20 */
-  'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00,      /* wcName_20 */
-  0x4e, 0x00, 0x00, 0x00,                           /* dwPropertyDataLength */
-  /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
-  '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00,       /* wcData_39 */
-  'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00,       /* wcData_39 */
-  '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00,       /* wcData_39 */
-  '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00,       /* wcData_39 */
-  '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00,       /* wcData_39 */
-  'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00,       /* wcData_39 */
-  '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00,       /* wcData_39 */
-  'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00,       /* wcData_39 */
-  'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00,       /* wcData_39 */
-  '6', 0x00, '}', 0x00, 0x00, 0x00,                 /* wcData_39 */
-};
-#define  WINUSB_IF1_WCID_PROPERTIES_SIZE  (142)
-__ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = {
-  ///////////////////////////////////////
-  /// WCID property descriptor
-  ///////////////////////////////////////
-  0x8e, 0x00, 0x00, 0x00,                           /* dwLength */
-  0x00, 0x01,                                       /* bcdVersion */
-  0x05, 0x00,                                       /* wIndex */
-  0x01, 0x00,                                       /* wCount */
-
-  ///////////////////////////////////////
-  /// registry propter descriptor
-  ///////////////////////////////////////
-  0x84, 0x00, 0x00, 0x00,                           /* dwSize */
-  0x01, 0x00, 0x00, 0x00,                           /* dwPropertyDataType */
-  0x28, 0x00,                                       /* wPropertyNameLength */
-  /* DeviceInterfaceGUID */
-  'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00,       /* wcName_20 */
-  'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00,       /* wcName_20 */
-  't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00,       /* wcName_20 */
-  'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00,       /* wcName_20 */
-  'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00,      /* wcName_20 */
-  0x4e, 0x00, 0x00, 0x00,                           /* dwPropertyDataLength */
-  /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
-  '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00,       /* wcData_39 */
-  'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00,       /* wcData_39 */
-  '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00,       /* wcData_39 */
-  '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00,       /* wcData_39 */
-  '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00,       /* wcData_39 */
-  'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00,       /* wcData_39 */
-  '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00,       /* wcData_39 */
-  'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00,       /* wcData_39 */
-  'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00,       /* wcData_39 */
-  '6', 0x00, '}', 0x00, 0x00, 0x00,                 /* wcData_39 */
-};
 
 const uint8_t *WINUSB_IFx_WCIDProperties[] = {
     WINUSB_IF0_WCIDProperties,
-#if DOUBLE_WINUSB == 1
+#if WINUSB_NUM == 2
     WINUSB_IF1_WCIDProperties,
 #endif
 };
 
 struct usb_msosv1_descriptor msosv1_desc = {
     .string = WCID_StringDescriptor_MSOS,
-    .vendor_code = WCID_VENDOR_CODE,
+    .vendor_code = WINUSB_VENDOR_CODE,
     .compat_id = WINUSB_WCIDDescriptor,
     .comp_id_property = WINUSB_IFx_WCIDProperties,
 };
@@ -166,20 +111,20 @@ struct usb_msosv1_descriptor msosv1_desc = {
 #define WINUSB_IN_EP  0x81
 #define WINUSB_OUT_EP 0x02
 
-#define USBD_VID           0xefff
+#define USBD_VID           0xFFFE
 #define USBD_PID           0xffff
 #define USBD_MAX_POWER     100
 #define USBD_LANGID_STRING 1033
 
-#if DOUBLE_WINUSB == 0
+#if WINUSB_NUM == 1
 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
-#define INTF_NUM 1
+#define INTF_NUM        1
 #else
 #define WINUSB_IN_EP2  0x83
 #define WINUSB_OUT_EP2 0x04
 
 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 7 + 7)
-#define INTF_NUM 2
+#define INTF_NUM        2
 #endif
 
 #ifdef CONFIG_USB_HS
@@ -188,7 +133,6 @@ struct usb_msosv1_descriptor msosv1_desc = {
 #define WINUSB_EP_MPS 64
 #endif
 
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
 };
@@ -198,7 +142,7 @@ static const uint8_t config_descriptor[] = {
     USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04),
     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00),
     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00),
-#if DOUBLE_WINUSB == 1
+#if WINUSB_NUM == 2
     USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05),
     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00),
     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00),
@@ -253,158 +197,13 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
     return string_descriptors[index];
 }
 
-const struct usb_descriptor winusb_descriptor = {
+const struct usb_descriptor winusbv1_descriptor = {
     .device_descriptor_callback = device_descriptor_callback,
     .config_descriptor_callback = config_descriptor_callback,
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
     .string_descriptor_callback = string_descriptor_callback,
     .msosv1_descriptor = &msosv1_desc
 };
-#else
-const uint8_t winusb_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04),
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00),
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00),
-#if DOUBLE_WINUSB == 1
-    USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05),
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00),
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00),
-#endif
-    ///////////////////////////////////////
-    /// string0 descriptor
-    ///////////////////////////////////////
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    ///////////////////////////////////////
-    /// string1 descriptor
-    ///////////////////////////////////////
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x2C,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'W', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'N', 0x00,                  /* wcChar12 */
-    'U', 0x00,                  /* wcChar13 */
-    'S', 0x00,                  /* wcChar14 */
-    'B', 0x00,                  /* wcChar15 */
-    ' ', 0x00,                  /* wcChar16 */
-    'D', 0x00,                  /* wcChar17 */
-    'E', 0x00,                  /* wcChar18 */
-    'M', 0x00,                  /* wcChar19 */
-    'O', 0x00,                  /* wcChar20 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '1', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-    ///////////////////////////////////////
-    /// string4 descriptor
-    ///////////////////////////////////////
-    0x30,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'W', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'N', 0x00,                  /* wcChar12 */
-    'U', 0x00,                  /* wcChar13 */
-    'S', 0x00,                  /* wcChar14 */
-    'B', 0x00,                  /* wcChar15 */
-    ' ', 0x00,                  /* wcChar16 */
-    'D', 0x00,                  /* wcChar17 */
-    'E', 0x00,                  /* wcChar18 */
-    'M', 0x00,                  /* wcChar19 */
-    'O', 0x00,                  /* wcChar20 */
-    ' ', 0x00,                  /* wcChar16 */
-    '1', 0x00,                  /* wcChar21 */
-    ///////////////////////////////////////
-    /// string5 descriptor
-    ///////////////////////////////////////
-    0x30,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'W', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'N', 0x00,                  /* wcChar12 */
-    'U', 0x00,                  /* wcChar13 */
-    'S', 0x00,                  /* wcChar14 */
-    'B', 0x00,                  /* wcChar15 */
-    ' ', 0x00,                  /* wcChar16 */
-    'D', 0x00,                  /* wcChar17 */
-    'E', 0x00,                  /* wcChar18 */
-    'M', 0x00,                  /* wcChar19 */
-    'O', 0x00,                  /* wcChar20 */
-    ' ', 0x00,                  /* wcChar16 */
-    '2', 0x00,                  /* wcChar21 */
-#ifdef CONFIG_USB_HS
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x00,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    0x00
-};
-#endif
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -428,7 +227,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
             ep_tx_busy_flag = false;
             /* setup first out ep read transfer */
             usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
-#if DOUBLE_WINUSB == 1
+#if WINUSB_NUM == 2
             usbd_ep_start_read(busid, WINUSB_OUT_EP2, read_buffer, 2048);
 #endif
             break;
@@ -478,7 +277,7 @@ struct usbd_endpoint winusb_in_ep1 = {
 
 struct usbd_interface intf0;
 
-#if DOUBLE_WINUSB == 1
+#if WINUSB_NUM == 2
 
 void usbd_winusb_out2(uint8_t busid, uint8_t ep, uint32_t nbytes)
 {
@@ -518,20 +317,14 @@ struct usbd_interface intf1;
 
 #endif
 
-void winusb_init(uint8_t busid, uintptr_t reg_base)
+void winusbv1_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_desc_register(busid, &winusb_descriptor);
-#else
-    usbd_desc_register(busid, winusb_descriptor);
-#endif
-#ifndef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_msosv1_desc_register(busid, &msosv1_desc);
-#endif
+    usbd_desc_register(busid, &winusbv1_descriptor);
+
     usbd_add_interface(busid, &intf0);
     usbd_add_endpoint(busid, &winusb_out_ep1);
     usbd_add_endpoint(busid, &winusb_in_ep1);
-#if DOUBLE_WINUSB == 1
+#if WINUSB_NUM == 2
     usbd_add_interface(busid, &intf1);
     usbd_add_endpoint(busid, &winusb_out_ep2);
     usbd_add_endpoint(busid, &winusb_in_ep2);

+ 27 - 225
components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c

@@ -6,6 +6,29 @@
 #include "usbd_core.h"
 #include "usbd_cdc_acm.h"
 
+#define WINUSB_VENDOR_CODE 0x17
+
+const uint8_t WINUSB_WCIDDescriptor[] = {
+    USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN),
+    USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(0x00),
+};
+
+__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
+    USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 1),
+    USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)),
+};
+
+const struct usb_msosv2_descriptor msosv2_desc = {
+    .vendor_code = WINUSB_VENDOR_CODE,
+    .compat_id = WINUSB_WCIDDescriptor,
+    .compat_id_len = sizeof(WINUSB_WCIDDescriptor),
+};
+
+const struct usb_bos_descriptor bos_desc = {
+    .string = USBD_BinaryObjectStoreDescriptor,
+    .string_len = sizeof(USBD_BinaryObjectStoreDescriptor),
+};
+
 #define WINUSB_IN_EP  0x81
 #define WINUSB_OUT_EP 0x02
 
@@ -27,136 +50,6 @@
 #define WINUSB_EP_MPS 64
 #endif
 
-#define USBD_WINUSB_VENDOR_CODE 0x20
-
-#define USBD_WEBUSB_ENABLE 0
-#define USBD_BULK_ENABLE   1
-#define USBD_WINUSB_ENABLE 1
-
-/* WinUSB Microsoft OS 2.0 descriptor sizes */
-#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE  10
-#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
-#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE  20
-
-#define FUNCTION_SUBSET_LEN                160
-#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
-
-#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
-
-__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
-    WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
-    WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
-    0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */  /* dwWindowsVersion*/
-    WBVAL(USBD_WINUSB_DESC_SET_LEN),          /* wDescriptorSetTotalLength */
-#if (USBD_WEBUSB_ENABLE)
-    WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
-    WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
-    0,                                         // bFirstInterface USBD_WINUSB_IF_NUM
-    0,                                         // bReserved
-    WBVAL(FUNCTION_SUBSET_LEN),                // wSubsetLength
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  // wLength
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  // wDescriptorType
-    'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        // CompatibleId
-    0, 0, 0, 0, 0, 0, 0, 0,                    // SubCompatibleId
-    WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
-    WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   // wDescriptorType
-    WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
-    WBVAL(42),                                 // wPropertyNameLength
-    'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
-    'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
-    'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
-    WBVAL(80), // wPropertyDataLength
-    '{', 0,
-    '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
-    '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
-    '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
-    '9', 0, '3', 0, '3', 0, 'B', 0, '-',
-    0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
-    '}', 0, 0, 0, 0, 0
-#endif
-#if USBD_BULK_ENABLE
-    WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
-    WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
-    0,                                         /* bFirstInterface USBD_BULK_IF_NUM*/
-    0,                                         /* bReserved */
-    WBVAL(FUNCTION_SUBSET_LEN),                /* wSubsetLength */
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  /* wLength */
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  /* wDescriptorType */
-    'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        /* CompatibleId*/
-    0, 0, 0, 0, 0, 0, 0, 0,                    /* SubCompatibleId*/
-    WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
-    WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   /* wDescriptorType */
-    WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
-    WBVAL(42),                                 /* wPropertyNameLength */
-    'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
-    'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
-    'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
-    WBVAL(80), /* wPropertyDataLength */
-    '{', 0,
-    'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
-    '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
-    '4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
-    'A', 0, 'A', 0, '3', 0, '6', 0, '-',
-    0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
-    '}', 0, 0, 0, 0, 0
-#endif
-};
-
-#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
-
-#define USBD_WEBUSB_DESC_LEN 24
-#define USBD_WINUSB_DESC_LEN 28
-
-#define USBD_BOS_WTOTALLENGTH (0x05 +                                      \
-                               USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
-                               USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
-
-__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
-    0x05,                         /* bLength */
-    0x0f,                         /* bDescriptorType */
-    WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
-    USBD_NUM_DEV_CAPABILITIES,    /* bNumDeviceCaps */
-#if (USBD_WEBUSB_ENABLE)
-    USBD_WEBUSB_DESC_LEN,           /* bLength */
-    0x10,                           /* bDescriptorType */
-    USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
-    0x00,                           /* bReserved */
-    0x38, 0xB6, 0x08, 0x34,         /* PlatformCapabilityUUID */
-    0xA9, 0x09, 0xA0, 0x47,
-    0x8B, 0xFD, 0xA0, 0x76,
-    0x88, 0x15, 0xB6, 0x65,
-    WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
-    USBD_WINUSB_VENDOR_CODE,  /* bVendorCode */
-    0,                        /* iLandingPage */
-#endif
-#if (USBD_WINUSB_ENABLE)
-    USBD_WINUSB_DESC_LEN,           /* bLength */
-    0x10,                           /* bDescriptorType */
-    USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
-    0x00,                           /* bReserved */
-    0xDF, 0x60, 0xDD, 0xD8,         /* PlatformCapabilityUUID */
-    0x89, 0x45, 0xC7, 0x4C,
-    0x9C, 0xD2, 0x65, 0x9D,
-    0x9E, 0x64, 0x8A, 0x9F,
-    0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
-    WBVAL(USBD_WINUSB_DESC_SET_LEN),         /* wDescriptorSetTotalLength */
-    USBD_WINUSB_VENDOR_CODE,                 /* bVendorCode */
-    0,                                       /* bAltEnumCode */
-#endif
-};
-
-struct usb_msosv2_descriptor msosv2_desc = {
-    .vendor_code = USBD_WINUSB_VENDOR_CODE,
-    .compat_id = USBD_WinUSBDescriptorSetDescriptor,
-    .compat_id_len = USBD_WINUSB_DESC_SET_LEN,
-};
-
-struct usb_bos_descriptor bos_desc = {
-    .string = USBD_BinaryObjectStoreDescriptor,
-    .string_len = USBD_BOS_WTOTALLENGTH
-};
-
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
 static const uint8_t device_descriptor[] = {
     USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
 };
@@ -219,7 +112,7 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
     return string_descriptors[index];
 }
 
-const struct usb_descriptor winusbv2_descriptor = {
+const struct usb_descriptor winusbv2_cdc_descriptor = {
     .device_descriptor_callback = device_descriptor_callback,
     .config_descriptor_callback = config_descriptor_callback,
     .device_quality_descriptor_callback = device_quality_descriptor_callback,
@@ -227,90 +120,6 @@ const struct usb_descriptor winusbv2_descriptor = {
     .msosv2_descriptor = &msosv2_desc,
     .bos_descriptor = &bos_desc
 };
-#else
-const uint8_t winusbv2_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    /* Configuration 0 */
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    /* Interface 0 */
-    USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
-    /* Endpoint OUT 2 */
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
-    /* Endpoint IN 1 */
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
-    CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, WINUSB_EP_MPS, 0x00),
-    /* String 0 (LANGID) */
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    /* String 1 (Manufacturer) */
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x2C,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'W', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'N', 0x00,                  /* wcChar12 */
-    'U', 0x00,                  /* wcChar13 */
-    'S', 0x00,                  /* wcChar14 */
-    'B', 0x00,                  /* wcChar15 */
-    ' ', 0x00,                  /* wcChar16 */
-    'D', 0x00,                  /* wcChar17 */
-    'E', 0x00,                  /* wcChar18 */
-    'M', 0x00,                  /* wcChar19 */
-    'O', 0x00,                  /* wcChar20 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    /* Device Qualifier */
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x10,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    /* End */
-    0x00
-};
-#endif
 
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -418,17 +227,10 @@ struct usbd_interface winusb_intf;
 struct usbd_interface intf1;
 struct usbd_interface intf2;
 
-void winusbv2_init(uint8_t busid, uintptr_t reg_base)
+void winusbv2_cdc_init(uint8_t busid, uintptr_t reg_base)
 {
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_desc_register(busid, &winusbv2_descriptor);
-#else
-    usbd_desc_register(busid, winusbv2_descriptor);
-#endif
-#ifndef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_bos_desc_register(busid, &bos_desc);
-    usbd_msosv2_desc_register(busid, &msosv2_desc);
-#endif
+    usbd_desc_register(busid, &winusbv2_cdc_descriptor);
+
     /*!< winusb */
     usbd_add_interface(busid, &winusb_intf);
     usbd_add_endpoint(busid, &winusb_out_ep1);

+ 0 - 550
components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c

@@ -1,550 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbd_core.h"
-#include "usbd_hid.h"
-
-#define WINUSB_IN_EP  0x81
-#define WINUSB_OUT_EP 0x02
-
-/*!< endpoint address */
-#define HID_INT_EP          0x83
-#define HID_INT_EP_SIZE     4
-#define HID_INT_EP_INTERVAL 10
-
-#define USBD_VID           0xFFFE
-#define USBD_PID           0xFFFF
-#define USBD_MAX_POWER     500
-#define USBD_LANGID_STRING 1033
-
-#define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 9 + 7)
-#define INTF_NUM        2
-
-/*!< config descriptor size */
-#define USB_HID_CONFIG_DESC_SIZ 34
-/*!< report descriptor size */
-#define HID_MOUSE_REPORT_DESC_SIZE 74
-
-#ifdef CONFIG_USB_HS
-#define WINUSB_EP_MPS 512
-#else
-#define WINUSB_EP_MPS 64
-#endif
-
-#define USBD_WINUSB_VENDOR_CODE 0x20
-
-#define USBD_WEBUSB_ENABLE 0
-#define USBD_BULK_ENABLE   1
-#define USBD_WINUSB_ENABLE 1
-
-/* WinUSB Microsoft OS 2.0 descriptor sizes */
-#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE  10
-#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
-#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE  20
-
-#define FUNCTION_SUBSET_LEN                160
-#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
-
-#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
-
-__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
-    WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
-    WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
-    0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */  /* dwWindowsVersion*/
-    WBVAL(USBD_WINUSB_DESC_SET_LEN),          /* wDescriptorSetTotalLength */
-#if (USBD_WEBUSB_ENABLE)
-    WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
-    WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
-    0,                                         // bFirstInterface USBD_WINUSB_IF_NUM
-    0,                                         // bReserved
-    WBVAL(FUNCTION_SUBSET_LEN),                // wSubsetLength
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  // wLength
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  // wDescriptorType
-    'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        // CompatibleId
-    0, 0, 0, 0, 0, 0, 0, 0,                    // SubCompatibleId
-    WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
-    WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   // wDescriptorType
-    WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
-    WBVAL(42),                                 // wPropertyNameLength
-    'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
-    'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
-    'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
-    WBVAL(80), // wPropertyDataLength
-    '{', 0,
-    '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
-    '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
-    '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
-    '9', 0, '3', 0, '3', 0, 'B', 0, '-',
-    0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
-    '}', 0, 0, 0, 0, 0
-#endif
-#if USBD_BULK_ENABLE
-    WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
-    WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
-    0,                                         /* bFirstInterface USBD_BULK_IF_NUM*/
-    0,                                         /* bReserved */
-    WBVAL(FUNCTION_SUBSET_LEN),                /* wSubsetLength */
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  /* wLength */
-    WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  /* wDescriptorType */
-    'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        /* CompatibleId*/
-    0, 0, 0, 0, 0, 0, 0, 0,                    /* SubCompatibleId*/
-    WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
-    WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   /* wDescriptorType */
-    WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
-    WBVAL(42),                                 /* wPropertyNameLength */
-    'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
-    'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
-    'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
-    WBVAL(80), /* wPropertyDataLength */
-    '{', 0,
-    'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
-    '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
-    '4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
-    'A', 0, 'A', 0, '3', 0, '6', 0, '-',
-    0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
-    '}', 0, 0, 0, 0, 0
-#endif
-};
-
-#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
-
-#define USBD_WEBUSB_DESC_LEN 24
-#define USBD_WINUSB_DESC_LEN 28
-
-#define USBD_BOS_WTOTALLENGTH (0x05 +                                      \
-                               USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
-                               USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
-
-__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
-    0x05,                         /* bLength */
-    0x0f,                         /* bDescriptorType */
-    WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
-    USBD_NUM_DEV_CAPABILITIES,    /* bNumDeviceCaps */
-#if (USBD_WEBUSB_ENABLE)
-    USBD_WEBUSB_DESC_LEN,           /* bLength */
-    0x10,                           /* bDescriptorType */
-    USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
-    0x00,                           /* bReserved */
-    0x38, 0xB6, 0x08, 0x34,         /* PlatformCapabilityUUID */
-    0xA9, 0x09, 0xA0, 0x47,
-    0x8B, 0xFD, 0xA0, 0x76,
-    0x88, 0x15, 0xB6, 0x65,
-    WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
-    USBD_WINUSB_VENDOR_CODE,  /* bVendorCode */
-    0,                        /* iLandingPage */
-#endif
-#if (USBD_WINUSB_ENABLE)
-    USBD_WINUSB_DESC_LEN,           /* bLength */
-    0x10,                           /* bDescriptorType */
-    USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
-    0x00,                           /* bReserved */
-    0xDF, 0x60, 0xDD, 0xD8,         /* PlatformCapabilityUUID */
-    0x89, 0x45, 0xC7, 0x4C,
-    0x9C, 0xD2, 0x65, 0x9D,
-    0x9E, 0x64, 0x8A, 0x9F,
-    0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
-    WBVAL(USBD_WINUSB_DESC_SET_LEN),         /* wDescriptorSetTotalLength */
-    USBD_WINUSB_VENDOR_CODE,                 /* bVendorCode */
-    0,                                       /* bAltEnumCode */
-#endif
-};
-
-struct usb_msosv2_descriptor msosv2_desc = {
-    .vendor_code = USBD_WINUSB_VENDOR_CODE,
-    .compat_id = USBD_WinUSBDescriptorSetDescriptor,
-    .compat_id_len = USBD_WINUSB_DESC_SET_LEN,
-};
-
-struct usb_bos_descriptor bos_desc = {
-    .string = USBD_BinaryObjectStoreDescriptor,
-    .string_len = USBD_BOS_WTOTALLENGTH
-};
-
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
-static const uint8_t device_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
-};
-
-static const uint8_t config_descriptor[] = {
-    /* Configuration 0 */
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    /* Interface 0 */
-    USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
-    /* Endpoint OUT 2 */
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
-    /* Endpoint IN 1 */
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x01,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-};
-
-static const uint8_t device_quality_descriptor[] = {
-    ///////////////////////////////////////
-    /// device qualifier descriptor
-    ///////////////////////////////////////
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x10,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-};
-
-static const char *string_descriptors[] = {
-    (const char[]){ 0x09, 0x04 }, /* Langid */
-    "CherryUSB",                  /* Manufacturer */
-    "CherryUSB WINUSB DEMO",      /* Product */
-    "2022123456",                 /* Serial Number */
-};
-
-static const uint8_t *device_descriptor_callback(uint8_t speed)
-{
-    return device_descriptor;
-}
-
-static const uint8_t *config_descriptor_callback(uint8_t speed)
-{
-    return config_descriptor;
-}
-
-static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
-{
-    return device_quality_descriptor;
-}
-
-static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
-{
-    if (index > 3) {
-        return NULL;
-    }
-    return string_descriptors[index];
-}
-
-const struct usb_descriptor winusbv2_descriptor = {
-    .device_descriptor_callback = device_descriptor_callback,
-    .config_descriptor_callback = config_descriptor_callback,
-    .device_quality_descriptor_callback = device_quality_descriptor_callback,
-    .string_descriptor_callback = string_descriptor_callback,
-    .msosv2_descriptor = &msosv2_desc,
-    .bos_descriptor = &bos_desc
-};
-#else
-const uint8_t winusbv2_descriptor[] = {
-    USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
-    /* Configuration 0 */
-    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
-    /* Interface 0 */
-    USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
-    /* Endpoint OUT 2 */
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
-    /* Endpoint IN 1 */
-    USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
-    /************** Descriptor of Joystick Mouse interface ****************/
-    /* 09 */
-    0x09,                          /* bLength: Interface Descriptor size */
-    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
-    0x01,                          /* bInterfaceNumber: Number of Interface */
-    0x00,                          /* bAlternateSetting: Alternate setting */
-    0x01,                          /* bNumEndpoints */
-    0x03,                          /* bInterfaceClass: HID */
-    0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-    0,                             /* iInterface: Index of string descriptor */
-    /******************** Descriptor of Joystick Mouse HID ********************/
-    /* 18 */
-    0x09,                    /* bLength: HID Descriptor size */
-    HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
-    0x11,                    /* bcdHID: HID Class Spec release number */
-    0x01,
-    0x00,                       /* bCountryCode: Hardware target country */
-    0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
-    0x22,                       /* bDescriptorType */
-    HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
-    0x00,
-    /******************** Descriptor of Mouse endpoint ********************/
-    /* 27 */
-    0x07,                         /* bLength: Endpoint Descriptor size */
-    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
-    HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
-    0x03,                         /* bmAttributes: Interrupt endpoint */
-    HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
-    0x00,
-    HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
-    /* String 0 (LANGID) */
-    USB_LANGID_INIT(USBD_LANGID_STRING),
-    /* String 1 (Manufacturer) */
-    0x14,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ///////////////////////////////////////
-    /// string2 descriptor
-    ///////////////////////////////////////
-    0x2C,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    'C', 0x00,                  /* wcChar0 */
-    'h', 0x00,                  /* wcChar1 */
-    'e', 0x00,                  /* wcChar2 */
-    'r', 0x00,                  /* wcChar3 */
-    'r', 0x00,                  /* wcChar4 */
-    'y', 0x00,                  /* wcChar5 */
-    'U', 0x00,                  /* wcChar6 */
-    'S', 0x00,                  /* wcChar7 */
-    'B', 0x00,                  /* wcChar8 */
-    ' ', 0x00,                  /* wcChar9 */
-    'W', 0x00,                  /* wcChar10 */
-    'I', 0x00,                  /* wcChar11 */
-    'N', 0x00,                  /* wcChar12 */
-    'U', 0x00,                  /* wcChar13 */
-    'S', 0x00,                  /* wcChar14 */
-    'B', 0x00,                  /* wcChar15 */
-    ' ', 0x00,                  /* wcChar16 */
-    'D', 0x00,                  /* wcChar17 */
-    'E', 0x00,                  /* wcChar18 */
-    'M', 0x00,                  /* wcChar19 */
-    'O', 0x00,                  /* wcChar20 */
-    ///////////////////////////////////////
-    /// string3 descriptor
-    ///////////////////////////////////////
-    0x16,                       /* bLength */
-    USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
-    '2', 0x00,                  /* wcChar0 */
-    '0', 0x00,                  /* wcChar1 */
-    '2', 0x00,                  /* wcChar2 */
-    '2', 0x00,                  /* wcChar3 */
-    '1', 0x00,                  /* wcChar4 */
-    '2', 0x00,                  /* wcChar5 */
-    '3', 0x00,                  /* wcChar6 */
-    '4', 0x00,                  /* wcChar7 */
-    '5', 0x00,                  /* wcChar8 */
-    '6', 0x00,                  /* wcChar9 */
-#ifdef CONFIG_USB_HS
-    /* Device Qualifier */
-    0x0a,
-    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
-    0x10,
-    0x02,
-    0x00,
-    0x00,
-    0x00,
-    0x40,
-    0x00,
-    0x00,
-#endif
-    /* End */
-    0x00
-};
-#endif
-
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
-
-volatile bool ep_tx_busy_flag = false;
-
-static void usbd_event_handler(uint8_t busid, uint8_t event)
-{
-    switch (event) {
-        case USBD_EVENT_RESET:
-            break;
-        case USBD_EVENT_CONNECTED:
-            break;
-        case USBD_EVENT_DISCONNECTED:
-            break;
-        case USBD_EVENT_RESUME:
-            break;
-        case USBD_EVENT_SUSPEND:
-            break;
-        case USBD_EVENT_CONFIGURED:
-            ep_tx_busy_flag = false;
-            /* setup first out ep read transfer */
-            usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
-            break;
-        case USBD_EVENT_SET_REMOTE_WAKEUP:
-            break;
-        case USBD_EVENT_CLR_REMOTE_WAKEUP:
-            break;
-
-        default:
-            break;
-    }
-}
-
-void usbd_winusb_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
-{
-    USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
-    // for (int i = 0; i < 100; i++) {
-    //     printf("%02x ", read_buffer[i]);
-    // }
-    // printf("\r\n");
-    usbd_ep_start_write(busid, WINUSB_IN_EP, read_buffer, nbytes);
-    /* setup next out ep read transfer */
-    usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
-}
-
-void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
-{
-    USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
-
-    if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
-        /* send zlp */
-        usbd_ep_start_write(busid, WINUSB_IN_EP, NULL, 0);
-    } else {
-        ep_tx_busy_flag = false;
-    }
-}
-
-struct usbd_endpoint winusb_out_ep1 = {
-    .ep_addr = WINUSB_OUT_EP,
-    .ep_cb = usbd_winusb_out
-};
-
-struct usbd_endpoint winusb_in_ep1 = {
-    .ep_addr = WINUSB_IN_EP,
-    .ep_cb = usbd_winusb_in
-};
-
-/*!< hid mouse report descriptor */
-static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
-    0x05, 0x01, // USAGE_PAGE (Generic Desktop)
-    0x09, 0x02, // USAGE (Mouse)
-    0xA1, 0x01, // COLLECTION (Application)
-    0x09, 0x01, //   USAGE (Pointer)
-
-    0xA1, 0x00, //   COLLECTION (Physical)
-    0x05, 0x09, //     USAGE_PAGE (Button)
-    0x19, 0x01, //     USAGE_MINIMUM (Button 1)
-    0x29, 0x03, //     USAGE_MAXIMUM (Button 3)
-
-    0x15, 0x00, //     LOGICAL_MINIMUM (0)
-    0x25, 0x01, //     LOGICAL_MAXIMUM (1)
-    0x95, 0x03, //     REPORT_COUNT (3)
-    0x75, 0x01, //     REPORT_SIZE (1)
-
-    0x81, 0x02, //     INPUT (Data,Var,Abs)
-    0x95, 0x01, //     REPORT_COUNT (1)
-    0x75, 0x05, //     REPORT_SIZE (5)
-    0x81, 0x01, //     INPUT (Cnst,Var,Abs)
-
-    0x05, 0x01, //     USAGE_PAGE (Generic Desktop)
-    0x09, 0x30, //     USAGE (X)
-    0x09, 0x31, //     USAGE (Y)
-    0x09, 0x38,
-
-    0x15, 0x81, //     LOGICAL_MINIMUM (-127)
-    0x25, 0x7F, //     LOGICAL_MAXIMUM (127)
-    0x75, 0x08, //     REPORT_SIZE (8)
-    0x95, 0x03, //     REPORT_COUNT (2)
-
-    0x81, 0x06, //     INPUT (Data,Var,Rel)
-    0xC0, 0x09,
-    0x3c, 0x05,
-    0xff, 0x09,
-
-    0x01, 0x15,
-    0x00, 0x25,
-    0x01, 0x75,
-    0x01, 0x95,
-
-    0x02, 0xb1,
-    0x22, 0x75,
-    0x06, 0x95,
-    0x01, 0xb1,
-
-    0x01, 0xc0 //   END_COLLECTION
-};
-
-/*!< mouse report struct */
-struct hid_mouse {
-    uint8_t buttons;
-    int8_t x;
-    int8_t y;
-    int8_t wheel;
-};
-
-/*!< mouse report */
-static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg;
-
-#define HID_STATE_IDLE 0
-#define HID_STATE_BUSY 1
-
-/*!< hid state ! Data can be sent only when state is idle  */
-static volatile uint8_t hid_state = HID_STATE_IDLE;
-
-/* function ------------------------------------------------------------------*/
-static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
-{
-    hid_state = HID_STATE_IDLE;
-}
-
-/*!< endpoint call back */
-static struct usbd_endpoint hid_in_ep = {
-    .ep_cb = usbd_hid_int_callback,
-    .ep_addr = HID_INT_EP
-};
-
-struct usbd_interface winusb_intf;
-struct usbd_interface intf1;
-
-void winusbv2_init(uint8_t busid, uintptr_t reg_base)
-{
-#ifdef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_desc_register(busid, &winusbv2_descriptor);
-#else
-    usbd_desc_register(busid, winusbv2_descriptor);
-#endif
-#ifndef CONFIG_USBDEV_ADVANCE_DESC
-    usbd_bos_desc_register(busid, &bos_desc);
-    usbd_msosv2_desc_register(busid, &msosv2_desc);
-#endif
-    /*!< winusb */
-    usbd_add_interface(busid, &winusb_intf);
-    usbd_add_endpoint(busid, &winusb_out_ep1);
-    usbd_add_endpoint(busid, &winusb_in_ep1);
-
-    usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf1, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
-    usbd_add_endpoint(busid, &hid_in_ep);
-
-    usbd_initialize(busid, reg_base, usbd_event_handler);
-}

Некоторые файлы не были показаны из-за большого количества измененных файлов