diff --git a/components/drivers/usb/cherryusb/Kconfig b/components/drivers/usb/cherryusb/Kconfig
index 2b7ce80679..9e0f8ce02a 100644
--- a/components/drivers/usb/cherryusb/Kconfig
+++ b/components/drivers/usb/cherryusb/Kconfig
@@ -125,7 +125,9 @@ if RT_USING_CHERRYUSB
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
bool "cdc_acm"
config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
- bool "msc"
+ bool "msc_ram"
+ config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
+ bool "msc_blkdev"
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
bool "hid_keyboard"
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
diff --git a/components/drivers/usb/cherryusb/README.md b/components/drivers/usb/cherryusb/README.md
index e56946a772..25e7f0b624 100644
--- a/components/drivers/usb/cherryusb/README.md
+++ b/components/drivers/usb/cherryusb/README.md
@@ -12,7 +12,7 @@
English
-CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP.
+CherryUSB is a tiny and beautiful, high performance and portable USB host and device stack for embedded system with USB IP.

@@ -103,7 +103,7 @@ CherryUSB Host Stack has the following functions:
- Automatic loading of supported Class drivers
- 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 and ehci now)
+- 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 Human Interface Device (HID)
- Support Mass Storage Class (MSC)
@@ -197,12 +197,12 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|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/canmv_k230)|v1.2.0 | Long-term |
+|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.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 | TBD |
-|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
## Package Support
diff --git a/components/drivers/usb/cherryusb/README_zh.md b/components/drivers/usb/cherryusb/README_zh.md
index 50d2b6f672..8a5bb45dd2 100644
--- a/components/drivers/usb/cherryusb/README_zh.md
+++ b/components/drivers/usb/cherryusb/README_zh.md
@@ -12,7 +12,7 @@
English
-CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的 USB 主从协议栈。
+CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的高性能 USB 主从协议栈。

@@ -103,7 +103,7 @@ CherryUSB Host 协议栈当前实现以下功能:
- 自动加载支持的Class 驱动
- 支持阻塞式传输和异步传输
- 支持复合设备
-- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,当前仅支持 dwc2 和 ehci)
+- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,仅支持 dwc2/ehci/xhci/rp2040)
- 支持 Communication Device Class (CDC_ACM, CDC_ECM)
- 支持 Human Interface Device (HID)
- 支持 Mass Storage Class (MSC)
@@ -198,12 +198,12 @@ CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和
|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/canmv_k230)|v1.2.0 | Long-term |
+|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.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 | TBD |
-|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
## 软件包支持
diff --git a/components/drivers/usb/cherryusb/SConscript b/components/drivers/usb/cherryusb/SConscript
index 29cbd4ae80..e4af1fc5f6 100644
--- a/components/drivers/usb/cherryusb/SConscript
+++ b/components/drivers/usb/cherryusb/SConscript
@@ -1,18 +1,23 @@
from building import *
cwd = GetCurrentDir()
-path = [cwd + '/common']
+path = [cwd]
+path += [cwd + '/common']
path += [cwd + '/core']
+path += [cwd + '/class/hub']
path += [cwd + '/class/cdc']
path += [cwd + '/class/msc']
path += [cwd + '/class/hid']
path += [cwd + '/class/audio']
path += [cwd + '/class/video']
path += [cwd + '/class/wireless']
+path += [cwd + '/class/midi']
+path += [cwd + '/class/adb']
path += [cwd + '/class/dfu']
path += [cwd + '/class/midi']
path += [cwd + '/class/vendor/net']
path += [cwd + '/class/vendor/serial']
+path += [cwd + '/class/vendor/wifi']
src = []
LIBS = []
@@ -109,13 +114,15 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
src += Glob('class/cdc/usbd_cdc_ecm.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_NCM']):
src += Glob('class/cdc/usbd_cdc_ncm.c')
- if GetDepend(['RT_CHERRYUSB_USING_DFU']):
+ if GetDepend(['RT_CHERRYUSB_DEVICE_DFU']):
src += Glob('class/dfu/usbd_dfu.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM']):
src += Glob('demo/cdc_acm_template.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_MSC']):
src += Glob('demo/msc_ram_template.c')
+ if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV']):
+ src += Glob('platform/rtthread/usbd_msc_blkdev.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE']):
src += Glob('demo/hid_mouse_template.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD']):
@@ -147,7 +154,6 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
# USB HOST
if GetDepend(['RT_CHERRYUSB_HOST']):
- path += [cwd + '/class/hub']
src += Glob('core/usbh_core.c')
src += Glob('class/hub/usbh_hub.c')
src += Glob('osal/usb_osal_rtthread.c')
diff --git a/components/drivers/usb/cherryusb/VERSION b/components/drivers/usb/cherryusb/VERSION
index 340d4aefcd..ce12c2dbf9 100644
--- a/components/drivers/usb/cherryusb/VERSION
+++ b/components/drivers/usb/cherryusb/VERSION
@@ -1,5 +1,5 @@
VERSION_MAJOR = 1
VERSION_MINOR = 4
-PATCHLEVEL = 2
+PATCHLEVEL = 3
VERSION_TWEAK = 0
EXTRAVERSION = 0
diff --git a/components/drivers/usb/cherryusb/cherryusb.cmake b/components/drivers/usb/cherryusb/cherryusb.cmake
index 271717008c..0fe2292239 100644
--- a/components/drivers/usb/cherryusb/cherryusb.cmake
+++ b/components/drivers/usb/cherryusb/cherryusb.cmake
@@ -26,6 +26,7 @@
# set(CONFIG_CHERRYUSB_HOST_HCD "ehci_xxx")
list(APPEND cherryusb_incs
+${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/common
${CMAKE_CURRENT_LIST_DIR}/core
${CMAKE_CURRENT_LIST_DIR}/class/hub
@@ -37,6 +38,7 @@ ${CMAKE_CURRENT_LIST_DIR}/class/video
${CMAKE_CURRENT_LIST_DIR}/class/wireless
${CMAKE_CURRENT_LIST_DIR}/class/midi
${CMAKE_CURRENT_LIST_DIR}/class/adb
+${CMAKE_CURRENT_LIST_DIR}/class/dfu
${CMAKE_CURRENT_LIST_DIR}/class/vendor/net
${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial
${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi
@@ -116,6 +118,8 @@ if(CONFIG_CHERRYUSB_DEVICE)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "aic")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic_ll.c)
+ elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "rp2040")
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_dc_rp2040.c)
endif()
endif()
@@ -270,6 +274,8 @@ if(CONFIG_CHERRYUSB_HOST)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "kinetis_mcx")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_hc_kinetis.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_glue_mcx.c)
+ elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "rp2040")
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c)
endif()
endif()
diff --git a/components/drivers/usb/cherryusb/cherryusb_config_template.h b/components/drivers/usb/cherryusb/cherryusb_config_template.h
index e7d5230f1c..41cc246eb1 100644
--- a/components/drivers/usb/cherryusb/cherryusb_config_template.h
+++ b/components/drivers/usb/cherryusb/cherryusb_config_template.h
@@ -17,11 +17,13 @@
/* Enable print with color */
#define CONFIG_USB_PRINTF_COLOR_ENABLE
-/* data align size when use dma */
+/* data align size when use dma or use dcache */
#ifndef CONFIG_USB_ALIGN_SIZE
#define CONFIG_USB_ALIGN_SIZE 4
#endif
+//#define CONFIG_USB_DCACHE_ENABLE
+
/* attribute data into no cache ram */
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
@@ -46,6 +48,20 @@
/* Enable test mode */
// #define CONFIG_USBDEV_TEST_MODE
+/* enable advance desc register api */
+// CONFIG_USBDEV_ADVANCE_DESC
+
+/* move ep0 setup handler from isr to thread */
+// #define CONFIG_USBDEV_EP0_THREAD
+
+#ifndef CONFIG_USBDEV_EP0_PRIO
+#define CONFIG_USBDEV_EP0_PRIO 4
+#endif
+
+#ifndef CONFIG_USBDEV_EP0_STACKSIZE
+#define CONFIG_USBDEV_EP0_STACKSIZE 2048
+#endif
+
#ifndef CONFIG_USBDEV_MSC_MAX_LUN
#define CONFIG_USBDEV_MSC_MAX_LUN 1
#endif
@@ -276,4 +292,26 @@
/* ---------------- MUSB Configuration ---------------- */
// #define CONFIG_USB_MUSB_SUNXI
+/* ================ USB Dcache Configuration ==================*/
+
+#ifdef CONFIG_USB_DCACHE_ENABLE
+/* style 1*/
+// void usb_dcache_clean(uintptr_t addr, uint32_t size);
+// void usb_dcache_invalidate(uintptr_t addr, uint32_t size);
+// void usb_dcache_flush(uintptr_t addr, uint32_t size);
+
+/* style 2*/
+// #define usb_dcache_clean(addr, size)
+// #define usb_dcache_invalidate(addr, size)
+// #define usb_dcache_flush(addr, size)
+#endif
+
+#ifndef usb_phyaddr2ramaddr
+#define usb_phyaddr2ramaddr(addr) (addr)
+#endif
+
+#ifndef usb_ramaddr2phyaddr
+#define usb_ramaddr2phyaddr(addr) (addr)
+#endif
+
#endif
diff --git a/components/drivers/usb/cherryusb/class/audio/usb_audio.h b/components/drivers/usb/cherryusb/class/audio/usb_audio.h
index ff7a9fe2a9..eb518b7bcb 100644
--- a/components/drivers/usb/cherryusb/class/audio/usb_audio.h
+++ b/components/drivers/usb/cherryusb/class/audio/usb_audio.h
@@ -822,7 +822,66 @@ struct audio_cs_ep_ep_general_descriptor {
0x00, /* wLockDelay */ \
0x00
+#define AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, bFeedbackEndpointAddress, ...) \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
+ bInterfaceNumber, /* bInterfaceNumber */ \
+ 0x00, /* bAlternateSetting */ \
+ 0x00, /* bNumEndpoints */ \
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
+ 0x00, /* iInterface */ \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
+ bInterfaceNumber, /* bInterfaceNumber */ \
+ 0x01, /* bAlternateSetting */ \
+ 0x02, /* bNumEndpoints */ \
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
+ 0x00, /* iInterface */ \
+ 0x07, /* bLength */ \
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
+ AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \
+ bTerminalLink, /* bTerminalLink : Unit ID of the Output Terminal*/ \
+ 0x01, /* bDelay */ \
+ WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag : AUDIO_FORMAT_PCM */ \
+ 0x08 + PP_NARG(__VA_ARGS__), /* bLength */ \
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
+ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \
+ AUDIO_FORMAT_TYPE_I, /* bFormatType */ \
+ bNrChannels, /* bNrChannels */ \
+ bSubFrameSize, /* bSubFrameSize : Bytes per audio subframe */ \
+ bBitResolution, /* bBitResolution : bits per sample */ \
+ (PP_NARG(__VA_ARGS__)/3), /* bSamFreqType : only one frequency supported */ \
+ __VA_ARGS__, /* tSamFreq : Audio sampling frequency coded on 3 bytes */ \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ bEndpointAddress, /* bEndpointAddress : IN endpoint 1 */ \
+ 0x05, /* bmAttributes */ \
+ WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
+ bInterval, /* bInterval : one packet per frame */ \
+ 0x00, /* bRefresh */ \
+ bFeedbackEndpointAddress, /* bSynchAddress */ \
+ 0x07, /* bLength */ \
+ AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
+ AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \
+ AUDIO_EP_CONTROL_SAMPLING_FEQ, /* bmAttributes AUDIO_SAMPLING_FREQ_CONTROL */ \
+ 0x00, /* bLockDelayUnits */ \
+ 0x00, /* wLockDelay */ \
+ 0x00, \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ bFeedbackEndpointAddress, /* bFeedbackEndpointAddress Revise Dir to bEndpointAddress */ \
+ 0x11, /* bmAttributes: TransferType=Isochronous SyncType=None EndpointType=Feedback */ \
+ WBVAL(4), /* XXXX wMaxPacketSize in Bytes */ \
+ bInterval, /* bInterval */ \
+ 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_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \
0x09, /* bLength */ \
@@ -1281,4 +1340,19 @@ struct audio_v2_control_range3_param_block {
#define AUDIO_SAMPLE_FREQ_4B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), \
(uint8_t)((frq >> 16)), (uint8_t)((frq >> 24))
+/* format 10.14 */
+#define AUDIO_FREQ_TO_FEEDBACK_FS(freq) ((freq << 10) / 1000)
+#define AUDIO_FEEDBACK_TO_BUF_FS(buf, feedback) \
+ buf[0] = ((feedback << 4) & 0xFFU); \
+ buf[1] = (((feedback << 4) >> 8U) & 0xFFU); \
+ buf[2] = (((feedback << 4) >> 16U) & 0xFFU)
+
+/* format 16.16 */
+#define AUDIO_FREQ_TO_FEEDBACK_HS(freq) ((freq << 13) / 1000)
+#define AUDIO_FEEDBACK_TO_BUF_HS(buf, feedback) \
+ buf[0] = (((feedback & 0x00001FFFu) << 3) & 0xFFu); \
+ buf[1] = ((((feedback & 0x00001FFFu) << 3) >> 8) & 0xFFu); \
+ buf[2] = (((feedback & 0x01FFE000u) >> 13) & 0xFFu); \
+ buf[3] = (((feedback & 0x01FFE000u) >> 21) & 0xFFu)
+
#endif /* USB_AUDIO_H */
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c
index c4743e56d3..5ca1ff33b4 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c
+++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c
@@ -231,12 +231,12 @@ static int usbh_cdc_ecm_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
-void usbh_cdc_ecm_rx_thread(void *argument)
+void usbh_cdc_ecm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_cdc_ecm_rx_length;
int ret;
- (void)argument;
+ (void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create cdc ecm rx thread\r\n");
// clang-format off
find_class:
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.h b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.h
index 6e8dbc7f95..a3ab84a5cd 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.h
+++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.h
@@ -41,7 +41,7 @@ void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class);
uint8_t *usbh_cdc_ecm_get_eth_txbuf(void);
int usbh_cdc_ecm_eth_output(uint32_t buflen);
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen);
-void usbh_cdc_ecm_rx_thread(void *argument);
+void usbh_cdc_ecm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c
index f9f3c53381..8bffea7ff8 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c
+++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c
@@ -62,12 +62,12 @@ static void print_ntb_parameters(struct cdc_ncm_ntb_parameters *param)
USB_LOG_RAW("wLength: 0x%02x \r\n", param->wLength);
USB_LOG_RAW("bmNtbFormatsSupported: %s \r\n", param->bmNtbFormatsSupported ? "NTB16" : "NTB32");
- USB_LOG_RAW("dwNtbInMaxSize: 0x%04x \r\n", param->dwNtbInMaxSize);
+ USB_LOG_RAW("dwNtbInMaxSize: 0x%08lx \r\n", param->dwNtbInMaxSize);
USB_LOG_RAW("wNdbInDivisor: 0x%02x \r\n", param->wNdbInDivisor);
USB_LOG_RAW("wNdbInPayloadRemainder: 0x%02x \r\n", param->wNdbInPayloadRemainder);
USB_LOG_RAW("wNdbInAlignment: 0x%02x \r\n", param->wNdbInAlignment);
- USB_LOG_RAW("dwNtbOutMaxSize: 0x%04x \r\n", param->dwNtbOutMaxSize);
+ USB_LOG_RAW("dwNtbOutMaxSize: 0x%08lx \r\n", param->dwNtbOutMaxSize);
USB_LOG_RAW("wNdbOutDivisor: 0x%02x \r\n", param->wNdbOutDivisor);
USB_LOG_RAW("wNdbOutPayloadRemainder: 0x%02x \r\n", param->wNdbOutPayloadRemainder);
USB_LOG_RAW("wNdbOutAlignment: 0x%02x \r\n", param->wNdbOutAlignment);
@@ -249,7 +249,7 @@ static int usbh_cdc_ncm_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
-void usbh_cdc_ncm_rx_thread(void *argument)
+void usbh_cdc_ncm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_cdc_ncm_rx_length;
int ret;
@@ -259,7 +259,7 @@ void usbh_cdc_ncm_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
- (void)argument;
+ (void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
// clang-format off
find_class:
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.h b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.h
index e9b3e8e055..b86122a232 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.h
+++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.h
@@ -45,7 +45,7 @@ void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class);
uint8_t *usbh_cdc_ncm_get_eth_txbuf(void);
int usbh_cdc_ncm_eth_output(uint32_t buflen);
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen);
-void usbh_cdc_ncm_rx_thread(void *argument);
+void usbh_cdc_ncm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}
diff --git a/components/drivers/usb/cherryusb/class/hid/usb_hid.h b/components/drivers/usb/cherryusb/class/hid/usb_hid.h
index b244d11972..62525a7444 100644
--- a/components/drivers/usb/cherryusb/class/hid/usb_hid.h
+++ b/components/drivers/usb/cherryusb/class/hid/usb_hid.h
@@ -191,11 +191,11 @@
#define HID_MOUSE_INPUT_REPORT_BUTTON3 (1 << 2)
#define HID_MOUSE_INPUT_REPORT_BUTTON_MASK (7)
-#define HID_MOUSE_INPUT_BUTTON_LEFT (1 << 0)
-#define HID_MOUSE_INPUT_BUTTON_RIGHT (1 << 1)
-#define HID_MOUSE_INPUT_BUTTON_MIDDLE (1 << 2)
-#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
-#define HID_MOUSE_INPUT_BUTTON_FORWARD (1 << 4)
+#define HID_MOUSE_INPUT_BUTTON_LEFT (1 << 0)
+#define HID_MOUSE_INPUT_BUTTON_RIGHT (1 << 1)
+#define HID_MOUSE_INPUT_BUTTON_MIDDLE (1 << 2)
+#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
+#define HID_MOUSE_INPUT_BUTTON_FORWARD (1 << 4)
/* Joystick input report (4 bytes) (HID D.1) */
#define HID_JS_INPUT_REPORT_HATSWITCH_SHIFT (0)
@@ -241,14 +241,14 @@
#define HID_DESKTOP_USAGE_UNDEFINED 0x00 /* Undefined */
#define HID_DESKTOP_USAGE_POINTER 0x01 /* Pointer */
#define HID_DESKTOP_USAGE_MOUSE 0x02 /* Mouse */
- /* 0x03 Reserved */
+ /* 0x03 Reserved */
#define HID_DESKTOP_USAGE_JOYSTICK 0x04 /* Joystick */
#define HID_DESKTOP_USAGE_GAMEPAD 0x05 /* Game Pad */
#define HID_DESKTOP_USAGE_KEYBOARD 0x06 /* Keyboard */
#define HID_DESKTOP_USAGE_KEYPAD 0x07 /* Keypad */
#define HID_DESKTOP_USAGE_MULTIAXIS 0x08 /* Multi-axis Controller */
#define HID_DESKTOP_USAGE_TABLET 0x09 /* Tablet PC System Controls */
- /* 0x0a-2f Reserved */
+ /* 0x0a-2f Reserved */
#define HID_DESKTOP_USAGE_X 0x30 /* X */
#define HID_DESKTOP_USAGE_Y 0x31 /* Y */
#define HID_DESKTOP_USAGE_Z 0x32 /* Z */
@@ -264,7 +264,7 @@
#define HID_DESKTOP_USAGE_MOTION 0x3c /* Motion Wakeup */
#define HID_DESKTOP_USAGE_START 0x3d /* Start */
#define HID_DESKTOP_USAGE_SELECT 0x3e /* Select */
- /* 0x3f Reserved */
+ /* 0x3f Reserved */
#define HID_DESKTOP_USAGE_VX 0x40 /* Vx */
#define HID_DESKTOP_USAGE_VY 0x41 /* Vy */
#define HID_DESKTOP_USAGE_VZ 0x42 /* Vz */
@@ -274,7 +274,7 @@
#define HID_DESKTOP_USAGE_VNO 0x46 /* Vno */
#define HID_DESKTOP_USAGE_FEATURE 0x47 /* Feature Notification */
#define HID_DESKTOP_USAGE_RESOLUTION 0x48 /* Resolution Multiplier */
- /* 0x49-7f Reserved */
+ /* 0x49-7f Reserved */
#define HID_DESKTOP_USAGE_CONTROL 0x80 /* System Control */
#define HID_DESKTOP_USAGE_POWERDOWN 0x81 /* System Power Down */
#define HID_DESKTOP_USAGE_SLEEP 0x82 /* System Sleep */
@@ -295,7 +295,7 @@
#define HID_DESKTOP_USAGE_DPAD_DOWN 0x91 /* D-pad Down */
#define HID_DESKTOP_USAGE_DPAD_RIGHT 0x92 /* D-pad Right */
#define HID_DESKTOP_USAGE_DPAD_LEFT 0x93 /* D-pad Left */
- /* 0x94-9f Reserved */
+ /* 0x94-9f Reserved */
#define HID_DESKTOP_USAGE_DOCK 0xa0 /* System Dock */
#define HID_DESKTOP_USAGE_UNDOCK 0xa1 /* System Undock */
#define HID_DESKTOP_USAGE_SETUP 0xa2 /* System Setup */
@@ -305,7 +305,7 @@
#define HID_DESKTOP_USAGE_APP_DEBUG_BREAK 0xa6 /* Application Debugger Break */
#define HID_DESKTOP_USAGE_MUTE 0xa7 /* System Speaker Mute */
#define HID_DESKTOP_USAGE_HIBERNATE 0xa8 /* System Hibernate */
- /* 0xa9-af Reserved */
+ /* 0xa9-af Reserved */
#define HID_DESKTOP_USAGE_DISPLAY_INVERT 0xb0 /* System Display Invert */
#define HID_DESKTOP_USAGE_DISPALY_INTERNAL 0xb1 /* System Display Internal */
#define HID_DESKTOP_USAGE_DISPLAY_EXTERNAL 0xb2 /* System Display External */
@@ -314,7 +314,7 @@
#define HID_DESKTOP_USAGE_DISPLAY_TOGGLE 0xb5 /* System Display Toggle Int/Ext */
#define HID_DESKTOP_USAGE_DISPLAY_SWAP 0xb6 /* System Display Swap */
#define HID_DESKTOP_USAGE_ 0xb7 /* System Display LCD Autoscale */
- /* 0xb8-ffff Reserved */
+ /* 0xb8-ffff Reserved */
/* Keyboard usage IDs (HuT 10) */
#define HID_KBD_USAGE_NONE 0x00 /* Reserved (no event indicated) */
@@ -529,16 +529,16 @@
/* HID Report Definitions */
struct usb_hid_class_subdescriptor {
- uint8_t bDescriptorType;/* Class descriptor type (See 7.1) */
- uint16_t wDescriptorLength;/* Size of the report descriptor */
+ uint8_t bDescriptorType; /* Class descriptor type (See 7.1) */
+ uint16_t wDescriptorLength; /* Size of the report descriptor */
} __PACKED;
struct usb_hid_descriptor {
- uint8_t bLength; /* Size of the HID descriptor */
- uint8_t bDescriptorType;/* HID descriptor type */
- uint16_t bcdHID;/* HID class specification release */
- uint8_t bCountryCode;/* Country code */
- uint8_t bNumDescriptors;/* Number of descriptors (>=1) */
+ uint8_t bLength; /* Size of the HID descriptor */
+ uint8_t bDescriptorType; /* HID descriptor type */
+ uint16_t bcdHID; /* HID class specification release */
+ uint8_t bCountryCode; /* Country code */
+ uint8_t bNumDescriptors; /* Number of descriptors (>=1) */
/*
* Specification says at least one Class Descriptor needs to
@@ -550,11 +550,10 @@ struct usb_hid_descriptor {
/* Standard Reports *********************************************************/
/* Keyboard input report (8 bytes) (HID B.1) */
-struct usb_hid_kbd_report
-{
- uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
- uint8_t reserved;
- uint8_t key[6]; /* Keycode 1-6 */
+struct usb_hid_kbd_report {
+ uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
+ uint8_t reserved;
+ uint8_t key[6]; /* Keycode 1-6 */
};
/* Keyboard output report (1 byte) (HID B.1),
@@ -562,22 +561,109 @@ struct usb_hid_kbd_report
*/
/* Mouse input report (HID B.2) */
-struct usb_hid_mouse_report
-{
- uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
- int8_t xdisp; /* X displacement */
- int8_t ydisp; /* y displacement */
+struct usb_hid_mouse_report {
+ uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
+ int8_t xdisp; /* X displacement */
+ int8_t ydisp; /* y displacement */
/* Device specific additional bytes may follow */
- uint8_t wdisp; /* Wheel displacement */
+ uint8_t wdisp; /* Wheel displacement */
};
/* Joystick input report (1 bytes) (HID D.1) */
-struct usb_hid_js_report
-{
- int8_t xpos; /* X position */
- int8_t ypos; /* X position */
- uint8_t buttons; /* See USBHID_JSIN_* definitions */
- uint8_t throttle; /* Throttle */
+struct usb_hid_js_report {
+ int8_t xpos; /* X position */
+ int8_t ypos; /* X position */
+ uint8_t buttons; /* See USBHID_JSIN_* definitions */
+ uint8_t throttle; /* Throttle */
};
+// clang-format off
+#define HID_MOUSE_DESCRIPTOR_LEN (9 + 9 + 7)
+
+#define HID_MOUSE_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
+ 0x09, /* bLength: Interface Descriptor size */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
+ bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
+ 0x00, /* bAlternateSetting: Alternate setting */ \
+ 0x01, /* bNumEndpoints */ \
+ 0x03, /* bInterfaceClass: HID */ \
+ bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
+ 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
+ 0x00, /* iInterface: Index of string descriptor */ \
+ 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 */ \
+ WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
+ 0x07, /* bLength: Endpoint Descriptor size */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
+ int_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
+ 0x03, /* bmAttributes: Interrupt endpoint */ \
+ WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
+ bInterval /* bInterval: Polling Interval */
+
+#define HID_KEYBOARD_DESCRIPTOR_LEN (9 + 9 + 7)
+
+#define HID_KEYBOARD_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
+ 0x09, /* bLength: Interface Descriptor size */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
+ bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
+ 0x00, /* bAlternateSetting: Alternate setting */ \
+ 0x01, /* bNumEndpoints */ \
+ 0x03, /* bInterfaceClass: HID */ \
+ bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
+ 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
+ 0x00, /* iInterface: Index of string descriptor */ \
+ 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 */ \
+ WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
+ 0x07, /* bLength: Endpoint Descriptor size */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
+ int_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
+ 0x03, /* bmAttributes: Interrupt endpoint */ \
+ WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
+ bInterval /* bInterval: Polling Interval */
+
+#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) \
+ 0x09, /* bLength: Interface Descriptor size */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
+ bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
+ 0x00, /* bAlternateSetting: Alternate setting */ \
+ 0x02, /* bNumEndpoints */ \
+ 0x03, /* bInterfaceClass: HID */ \
+ bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
+ 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
+ 0x00, /* iInterface: Index of string descriptor */ \
+ 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 */ \
+ WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
+ 0x07, /* bLength: Endpoint Descriptor size */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
+ in_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
+ 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) */ \
+ 0x03, /* bmAttributes: Interrupt endpoint */ \
+ WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
+ bInterval /* bInterval: Polling Interval */
+// clang-format on
+
#endif /* USB_HID_H */
diff --git a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c
index 9dae396607..54377a74be 100644
--- a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c
+++ b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c
@@ -648,12 +648,12 @@ static void usbh_hub_events(struct usbh_hub *hub)
}
}
-static void usbh_hub_thread(void *argument)
+static void usbh_hub_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
struct usbh_hub *hub;
int ret = 0;
- struct usbh_bus *bus = (struct usbh_bus *)argument;
+ struct usbh_bus *bus = (struct usbh_bus *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
usb_hc_init(bus);
while (1) {
diff --git a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
index 1f84d02c9b..993617abe1 100644
--- a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
+++ b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
@@ -60,7 +60,7 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_priv {
} g_usbd_msc[CONFIG_USBDEV_MAX_BUS];
#ifdef CONFIG_USBDEV_MSC_THREAD
-static void usbdev_msc_thread(void *argument);
+static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#endif
static void usdb_msc_set_max_lun(uint8_t busid)
@@ -911,11 +911,11 @@ void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
}
#if defined(CONFIG_USBDEV_MSC_THREAD)
-static void usbdev_msc_thread(void *argument)
+static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uintptr_t event;
int ret;
- uint8_t busid = (uint8_t)(uint32_t)argument;
+ uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
while (1) {
ret = usb_osal_mq_recv(g_usbd_msc[busid].usbd_msc_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
diff --git a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c
index 96cb53d263..88c90b0b1a 100644
--- a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c
+++ b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c
@@ -13,8 +13,11 @@
#define DEV_FORMAT "/dev/sd%c"
-#define MSC_INQUIRY_TIMEOUT 500
+#ifndef CONFIG_USBHOST_MSC_READY_CHECK_TIMES
+#define CONFIG_USBHOST_MSC_READY_CHECK_TIMES 10
+#endif
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_cbw_csw[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
static struct usbh_msc g_msc_class[CONFIG_USBHOST_MAX_MSC_CLASS];
@@ -131,7 +134,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
/* Send the CBW */
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, timeout);
if (nbytes < 0) {
- USB_LOG_ERR("cbw transfer error\r\n");
+ USB_LOG_ERR("cbw transfer error: %d\r\n", nbytes);
goto __err_exit;
}
@@ -150,7 +153,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
}
if (nbytes < 0) {
- USB_LOG_ERR("msc data transfer error\r\n");
+ USB_LOG_ERR("msc data transfer error: %d\r\n", nbytes);
goto __err_exit;
}
}
@@ -159,7 +162,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
memset(csw, 0, USB_SIZEOF_MSC_CSW);
nbytes = usbh_msc_bulk_in_transfer(msc_class, (uint8_t *)csw, USB_SIZEOF_MSC_CSW, timeout);
if (nbytes < 0) {
- USB_LOG_ERR("csw transfer error\r\n");
+ USB_LOG_ERR("csw transfer error: %d\r\n", nbytes);
goto __err_exit;
}
@@ -184,14 +187,14 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
+ cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
cbw->bCBLength = SCSICMD_TESTUNITREADY_SIZEOF;
cbw->CB[0] = SCSI_CMD_TESTUNITREADY;
- return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
+ return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], NULL, CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
@@ -199,7 +202,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
+ cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -209,7 +212,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
cbw->CB[0] = SCSI_CMD_REQUESTSENSE;
cbw->CB[4] = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
- return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
+ return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
@@ -217,7 +220,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
+ cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -227,7 +230,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
cbw->CB[0] = SCSI_CMD_INQUIRY;
cbw->CB[4] = SCSIRESP_INQUIRY_SIZEOF;
- return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
+ return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
@@ -235,7 +238,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
+ cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -244,7 +247,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
cbw->bCBLength = SCSICMD_READCAPACITY10_SIZEOF;
cbw->CB[0] = SCSI_CMD_READCAPACITY10;
- return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
+ return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message)
@@ -252,18 +255,18 @@ static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
+ cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
- memcpy(g_msc_buf[msc_class->sdchar - 'a'], message, 31);
+ memcpy(g_msc_cbw_csw[msc_class->sdchar - 'a'], message, 31);
- usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
+ usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], NULL, CONFIG_USBHOST_MSC_TIMEOUT);
}
static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;
- int ret;
struct usbh_msc_modeswitch_config *config;
+ int ret;
struct usbh_msc *msc_class = usbh_msc_class_alloc();
if (msc_class == NULL) {
@@ -315,34 +318,6 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
}
}
- ret = usbh_msc_scsi_testunitready(msc_class);
- if (ret < 0) {
- ret = usbh_msc_scsi_requestsense(msc_class);
- if (ret < 0) {
- USB_LOG_ERR("Fail to scsi_testunitready\r\n");
- return ret;
- }
- }
-
- ret = usbh_msc_scsi_inquiry(msc_class);
- if (ret < 0) {
- USB_LOG_ERR("Fail to scsi_inquiry\r\n");
- return ret;
- }
- ret = usbh_msc_scsi_readcapacity10(msc_class);
- if (ret < 0) {
- USB_LOG_ERR("Fail to scsi_readcapacity10\r\n");
- return ret;
- }
-
- if (msc_class->blocksize > 0) {
- USB_LOG_INFO("Capacity info:\r\n");
- USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize);
- } else {
- USB_LOG_ERR("Invalid block size\r\n");
- return -USB_ERR_RANGE;
- }
-
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
USB_LOG_INFO("Register MSC Class:%s\r\n", hport->config.intf[intf].devname);
@@ -377,12 +352,52 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
+int usbh_msc_scsi_init(struct usbh_msc *msc_class)
+{
+ int ret;
+ uint16_t cnt;
+
+ cnt = 0;
+ while (usbh_msc_scsi_testunitready(msc_class) < 0) {
+ USB_LOG_WRN("Device not ready, try again...\r\n");
+ ret = usbh_msc_scsi_requestsense(msc_class);
+ if (ret < 0) {
+ USB_LOG_ERR("Fail to scsi_testunitready\r\n");
+ }
+ cnt++;
+ if (cnt > CONFIG_USBHOST_MSC_READY_CHECK_TIMES) {
+ return -USB_ERR_NODEV;
+ }
+ }
+ ret = usbh_msc_scsi_inquiry(msc_class);
+ if (ret < 0) {
+ USB_LOG_ERR("Fail to scsi_inquiry\r\n");
+ return ret;
+ }
+
+ ret = usbh_msc_scsi_readcapacity10(msc_class);
+ if (ret < 0) {
+ USB_LOG_ERR("Fail to scsi_readcapacity10\r\n");
+ return ret;
+ }
+
+ if (msc_class->blocksize > 0) {
+ USB_LOG_INFO("Capacity info:\r\n");
+ USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize);
+ } else {
+ USB_LOG_ERR("Invalid block size\r\n");
+ return -USB_ERR_RANGE;
+ }
+
+ return 0;
+}
+
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
{
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
+ cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -393,7 +408,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
SET_BE32(&cbw->CB[2], start_sector);
SET_BE16(&cbw->CB[7], nsectors);
- return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
+ return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
}
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
@@ -401,7 +416,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
+ cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -413,7 +428,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
SET_BE32(&cbw->CB[2], start_sector);
SET_BE16(&cbw->CB[7], nsectors);
- return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
+ return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
}
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
diff --git a/components/drivers/usb/cherryusb/class/msc/usbh_msc.h b/components/drivers/usb/cherryusb/class/msc/usbh_msc.h
index 50a61a9c11..c4aee8a855 100644
--- a/components/drivers/usb/cherryusb/class/msc/usbh_msc.h
+++ b/components/drivers/usb/cherryusb/class/msc/usbh_msc.h
@@ -32,6 +32,7 @@ struct usbh_msc_modeswitch_config {
};
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config);
+int usbh_msc_scsi_init(struct usbh_msc *msc_class);
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);
diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c
index 66c1f07803..f497671829 100644
--- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c
+++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c
@@ -670,7 +670,7 @@ int usbh_asix_get_connect_status(struct usbh_asix *asix_class)
return 0;
}
-void usbh_asix_rx_thread(void *argument)
+void usbh_asix_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_asix_rx_length;
int ret;
@@ -683,7 +683,7 @@ void usbh_asix_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
- (void)argument;
+ (void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create asix rx thread\r\n");
// clang-format off
find_class:
diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.h b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.h
index 8b0b5d98fd..bdeb0e3107 100644
--- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.h
+++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.h
@@ -168,7 +168,7 @@ void usbh_asix_stop(struct usbh_asix *asix_class);
uint8_t *usbh_asix_get_eth_txbuf(void);
int usbh_asix_eth_output(uint32_t buflen);
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen);
-void usbh_asix_rx_thread(void *argument);
+void usbh_asix_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}
diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c
index 10fc048398..4913389a22 100644
--- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c
+++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c
@@ -2130,7 +2130,7 @@ static int usbh_rtl8152_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
-void usbh_rtl8152_rx_thread(void *argument)
+void usbh_rtl8152_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_rtl8152_rx_length;
int ret;
@@ -2142,7 +2142,7 @@ void usbh_rtl8152_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
- (void)argument;
+ (void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
// clang-format off
find_class:
diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.h b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.h
index 9d593b9126..171fa0bf6b 100644
--- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.h
+++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.h
@@ -59,7 +59,7 @@ void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class);
uint8_t *usbh_rtl8152_get_eth_txbuf(void);
int usbh_rtl8152_eth_output(uint32_t buflen);
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen);
-void usbh_rtl8152_rx_thread(void *argument);
+void usbh_rtl8152_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}
diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c
index 9275faacc6..059086bebf 100644
--- a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c
+++ b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c
@@ -347,7 +347,7 @@ static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
-void usbh_bl616_rx_thread(void *argument)
+void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
usb_data_t *usb_hdr;
@@ -356,7 +356,7 @@ void usbh_bl616_rx_thread(void *argument)
rnm_scan_ind_msg_t *scanmsg;
uint8_t *data;
- (void)argument;
+ (void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create bl616 wifi rx thread\r\n");
while (1) {
diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h
index 6ec5a7a8ab..2d247ae2ea 100644
--- a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h
+++ b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h
@@ -205,7 +205,7 @@ void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t
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(void *argument);
+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);
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c
index 43849706ea..3f778c2f31 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c
+++ b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c
@@ -37,14 +37,17 @@ struct usbd_rndis_priv {
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
#endif
+#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
+#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8];
volatile uint8_t *g_rndis_rx_data_buffer;
volatile uint32_t g_rndis_rx_data_length;
+volatile uint32_t g_rndis_rx_total_length;
volatile uint32_t g_rndis_tx_data_length;
/* RNDIS options list */
@@ -447,12 +450,14 @@ static void rndis_notify_handler(uint8_t busid, uint8_t event, void *arg)
switch (event) {
case USBD_EVENT_RESET:
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
- break;
- case USBD_EVENT_CONFIGURED:
g_rndis_rx_data_length = 0;
g_rndis_tx_data_length = 0;
+ break;
+ case USBD_EVENT_CONFIGURED:
+#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_CONNECTED;
- usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
+ usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
+#endif
break;
default:
@@ -467,10 +472,9 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
(void)busid;
(void)ep;
- hdr = (rndis_data_packet_t *)g_rndis_rx_buffer;
- g_rndis_rx_data_buffer = g_rndis_rx_buffer;
+ hdr = (rndis_data_packet_t *)g_rndis_rx_data_buffer;
if ((hdr->MessageType != REMOTE_NDIS_PACKET_MSG) || (nbytes < hdr->MessageLength)) {
- usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
+ usbd_rndis_start_read((uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_total_length);
return;
}
@@ -503,6 +507,34 @@ void rndis_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
//USB_LOG_DBG("len:%d\r\n", nbytes);
}
+int usbd_rndis_start_write(uint8_t *buf, uint32_t len)
+{
+ if (!usb_device_is_configured(0)) {
+ return -USB_ERR_NODEV;
+ }
+
+ if (g_rndis_tx_data_length > 0) {
+ return -USB_ERR_BUSY;
+ }
+
+ g_rndis_tx_data_length = len;
+
+ USB_LOG_DBG("txlen:%d\r\n", g_rndis_tx_data_length);
+ return usbd_ep_start_write(0, rndis_ep_data[RNDIS_IN_EP_IDX].ep_addr, buf, len);
+}
+
+int usbd_rndis_start_read(uint8_t *buf, uint32_t len)
+{
+ if (!usb_device_is_configured(0)) {
+ return -USB_ERR_NODEV;
+ }
+
+ g_rndis_rx_data_buffer = buf;
+ g_rndis_rx_total_length = len;
+ g_rndis_rx_data_length = 0;
+ return usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, buf, len);
+}
+
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
#include
@@ -515,15 +547,14 @@ struct pbuf *usbd_rndis_eth_rx(void)
}
p = pbuf_alloc(PBUF_RAW, g_rndis_rx_data_length, PBUF_POOL);
if (p == NULL) {
+ usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
return NULL;
}
usb_memcpy(p->payload, (uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
p->len = g_rndis_rx_data_length;
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_data_length);
- g_rndis_rx_data_length = 0;
- usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
-
+ usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
return p;
}
@@ -594,6 +625,11 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
return intf;
}
+void usbd_rndis_set_connect(bool connect)
+{
+ g_usbd_rndis.link_status = connect ? NDIS_MEDIA_STATE_CONNECTED : NDIS_MEDIA_STATE_DISCONNECTED;
+}
+
__WEAK void usbd_rndis_data_recv_done(uint32_t len)
{
(void)len;
@@ -602,4 +638,4 @@ __WEAK void usbd_rndis_data_recv_done(uint32_t len)
__WEAK void usbd_rndis_data_send_done(uint32_t len)
{
(void)len;
-}
\ No newline at end of file
+}
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h
index 72b89eab89..f0fc3ee233 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h
+++ b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h
@@ -18,8 +18,12 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
const uint8_t in_ep,
const uint8_t int_ep, uint8_t mac[6]);
+void usbd_rndis_set_connect(bool connect);
+
void usbd_rndis_data_recv_done(uint32_t len);
void usbd_rndis_data_send_done(uint32_t len);
+int usbd_rndis_start_write(uint8_t *buf, uint32_t len);
+int usbd_rndis_start_read(uint8_t *buf, uint32_t len);
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
struct pbuf *usbd_rndis_eth_rx(void);
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c
index 991f09579b..e507c7e658 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c
+++ b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c
@@ -189,7 +189,7 @@ int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen)
return ret;
}
-void usbh_bluetooth_hci_rx_thread(void *argument)
+void usbh_bluetooth_hci_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
uint32_t ep_mps;
@@ -271,7 +271,7 @@ int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen)
return ret;
}
-void usbh_bluetooth_hci_evt_rx_thread(void *argument)
+void usbh_bluetooth_hci_evt_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
uint32_t ep_mps;
@@ -320,7 +320,7 @@ delete :
// clang-format on
}
-void usbh_bluetooth_hci_acl_rx_thread(void *argument)
+void usbh_bluetooth_hci_acl_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
uint32_t ep_mps;
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.h b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.h
index 868ff2c2cc..87eb02acb3 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.h
+++ b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.h
@@ -40,10 +40,10 @@ extern "C" {
int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen);
void usbh_bluetooth_hci_read_callback(uint8_t *data, uint32_t len);
#ifdef CONFIG_USBHOST_BLUETOOTH_HCI_H4
-void usbh_bluetooth_hci_rx_thread(void *argument);
+void usbh_bluetooth_hci_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#else
-void usbh_bluetooth_hci_evt_rx_thread(void *argument);
-void usbh_bluetooth_hci_acl_rx_thread(void *argument);
+void usbh_bluetooth_hci_evt_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
+void usbh_bluetooth_hci_acl_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#endif
void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class);
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c
index e9eaff0114..17260acda2 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c
+++ b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c
@@ -90,8 +90,8 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
rndis_class->max_transfer_pkts = resp->MaxPacketsPerTransfer;
rndis_class->max_transfer_size = resp->MaxTransferSize;
- USB_LOG_INFO("MaxPacketsPerTransfer:%d\r\n", resp->MaxPacketsPerTransfer);
- USB_LOG_INFO("MaxTransferSize:%d\r\n", resp->MaxTransferSize);
+ USB_LOG_INFO("MaxPacketsPerTransfer:%ld\r\n", resp->MaxPacketsPerTransfer);
+ USB_LOG_INFO("MaxTransferSize:%ld\r\n", resp->MaxTransferSize);
return ret;
}
@@ -278,8 +278,8 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
struct usb_endpoint_descriptor *ep_desc;
int ret;
uint32_t *oid_support_list;
- unsigned int oid = 0;
- unsigned int oid_num = 0;
+ uint32_t oid = 0;
+ uint32_t oid_num = 0;
uint32_t data_len;
uint8_t tmp_buffer[512];
uint8_t data[32];
@@ -319,7 +319,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
oid_num = (data_len / 4);
- USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%d\r\n", oid_num);
+ USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%ld\r\n", oid_num);
oid_support_list = (uint32_t *)tmp_buffer;
@@ -380,10 +380,10 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
}
break;
default:
- USB_LOG_WRN("Ignore rndis query iod:%08x\r\n", oid);
+ USB_LOG_WRN("Ignore rndis query iod:%08lx\r\n", oid);
continue;
}
- USB_LOG_INFO("rndis query iod:%08x success\r\n", oid);
+ USB_LOG_INFO("rndis query iod:%08lx success\r\n", oid);
}
uint32_t packet_filter = 0x0f;
@@ -414,7 +414,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
usbh_rndis_run(rndis_class);
return ret;
query_errorout:
- USB_LOG_ERR("rndis query iod:%08x error\r\n", oid);
+ USB_LOG_ERR("rndis query iod:%08lx error\r\n", oid);
return ret;
}
@@ -448,7 +448,7 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
-void usbh_rndis_rx_thread(void *argument)
+void usbh_rndis_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_rndis_rx_length;
int ret;
@@ -461,7 +461,7 @@ void usbh_rndis_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
- (void)argument;
+ (void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create rndis rx thread\r\n");
// clang-format off
@@ -501,7 +501,7 @@ find_class:
uint32_t total_len = g_rndis_rx_length;
while (g_rndis_rx_length > 0) {
- USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_length);
+ USB_LOG_DBG("rxlen:%ld\r\n", g_rndis_rx_length);
pmsg = (rndis_data_packet_t *)(g_rndis_rx_buffer + pmg_offset);
@@ -523,7 +523,7 @@ find_class:
g_rndis_rx_length = 0;
}
} else {
- USB_LOG_ERR("offset:%d,remain:%d,total:%d\r\n", pmg_offset, g_rndis_rx_length, total_len);
+ USB_LOG_ERR("offset:%ld,remain:%ld,total:%ld\r\n", pmg_offset, g_rndis_rx_length, total_len);
g_rndis_rx_length = 0;
USB_LOG_ERR("Error rndis packet message\r\n");
}
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.h b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.h
index 17a400067f..505a07aeb5 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.h
+++ b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.h
@@ -46,7 +46,7 @@ void usbh_rndis_stop(struct usbh_rndis *rndis_class);
uint8_t *usbh_rndis_get_eth_txbuf(void);
int usbh_rndis_eth_output(uint32_t buflen);
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen);
-void usbh_rndis_rx_thread(void *argument);
+void usbh_rndis_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}
diff --git a/components/drivers/usb/cherryusb/common/usb_dc.h b/components/drivers/usb/cherryusb/common/usb_dc.h
index 1f2fdddddc..dd85d7cb98 100644
--- a/components/drivers/usb/cherryusb/common/usb_dc.h
+++ b/components/drivers/usb/cherryusb/common/usb_dc.h
@@ -136,7 +136,7 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
*/
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len);
-/* usb dcd irq callback */
+/* usb dcd irq callback, called by user */
/**
* @brief Usb connect irq callback.
@@ -194,6 +194,9 @@ void usbd_event_ep_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode);
#endif
+/* called by user */
+void USBD_IRQHandler(uint8_t busid);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/drivers/usb/cherryusb/common/usb_dcache.h b/components/drivers/usb/cherryusb/common/usb_dcache.h
new file mode 100644
index 0000000000..60fbb7e90d
--- /dev/null
+++ b/components/drivers/usb/cherryusb/common/usb_dcache.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USB_DCACHE_H
+#define USB_DCACHE_H
+
+#ifdef CONFIG_USB_DCACHE_ENABLE
+#if CONFIG_USB_ALIGN_SIZE % 32
+#error "CONFIG_USB_ALIGN_SIZE must be multiple of 32"
+#endif
+#else
+#define usb_dcache_clean(addr, size)
+#define usb_dcache_invalidate(addr, size)
+#define usb_dcache_flush(addr, size)
+#endif
+
+#endif /* USB_DCACHE_H */
diff --git a/components/drivers/usb/cherryusb/common/usb_hc.h b/components/drivers/usb/cherryusb/common/usb_hc.h
index c4e2a16dc9..3335af2fd3 100644
--- a/components/drivers/usb/cherryusb/common/usb_hc.h
+++ b/components/drivers/usb/cherryusb/common/usb_hc.h
@@ -108,6 +108,9 @@ int usbh_submit_urb(struct usbh_urb *urb);
*/
int usbh_kill_urb(struct usbh_urb *urb);
+/* called by user */
+void USBH_IRQHandler(uint8_t busid);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/drivers/usb/cherryusb/common/usb_log.h b/components/drivers/usb/cherryusb/common/usb_log.h
index 8c798c7cb4..94eedfb63e 100644
--- a/components/drivers/usb/cherryusb/common/usb_log.h
+++ b/components/drivers/usb/cherryusb/common/usb_log.h
@@ -86,12 +86,12 @@ void usb_assert(const char *filename, int linenum);
static inline void usb_hexdump(const void *ptr, uint32_t buflen)
{
unsigned char *buf = (unsigned char *)ptr;
- uint32_t i, j;
+ unsigned int i, j;
(void)buf;
for (i = 0; i < buflen; i += 16) {
- CONFIG_USB_PRINTF("%08X:", i);
+ CONFIG_USB_PRINTF("%08x:", i);
for (j = 0; j < 16; j++)
if (i + j < buflen) {
diff --git a/components/drivers/usb/cherryusb/common/usb_osal.h b/components/drivers/usb/cherryusb/common/usb_osal.h
index a3380d1339..aa2f133689 100644
--- a/components/drivers/usb/cherryusb/common/usb_osal.h
+++ b/components/drivers/usb/cherryusb/common/usb_osal.h
@@ -10,13 +10,21 @@
#include
#include
+#ifdef __INCLUDE_NUTTX_CONFIG_H
+#define CONFIG_USB_OSAL_THREAD_SET_ARGV int argc, char **argv
+#define CONFIG_USB_OSAL_THREAD_GET_ARGV ((uintptr_t)strtoul(argv[1], NULL, 16))
+#else
+#define CONFIG_USB_OSAL_THREAD_SET_ARGV void *argument
+#define CONFIG_USB_OSAL_THREAD_GET_ARGV ((uintptr_t)argument)
+#endif
+
#define USB_OSAL_WAITING_FOREVER (0xFFFFFFFFU)
typedef void *usb_osal_thread_t;
typedef void *usb_osal_sem_t;
typedef void *usb_osal_mutex_t;
typedef void *usb_osal_mq_t;
-typedef void (*usb_thread_entry_t)(void *argument);
+typedef void (*usb_thread_entry_t)(CONFIG_USB_OSAL_THREAD_SET_ARGV);
typedef void (*usb_timer_handler_t)(void *argument);
struct usb_osal_timer {
usb_timer_handler_t handler;
diff --git a/components/drivers/usb/cherryusb/common/usb_util.h b/components/drivers/usb/cherryusb/common/usb_util.h
index 624cd9fcb3..b2223b2b94 100644
--- a/components/drivers/usb/cherryusb/common/usb_util.h
+++ b/components/drivers/usb/cherryusb/common/usb_util.h
@@ -207,4 +207,12 @@
#define USB_ALIGN_UP(size, align) (((size) + (align)-1) & ~((align)-1))
+#ifndef usb_phyaddr2ramaddr
+#define usb_phyaddr2ramaddr(addr) (addr)
+#endif
+
+#ifndef usb_ramaddr2phyaddr
+#define usb_ramaddr2phyaddr(addr) (addr)
+#endif
+
#endif /* USB_UTIL_H */
diff --git a/components/drivers/usb/cherryusb/core/usbd_core.c b/components/drivers/usb/cherryusb/core/usbd_core.c
index d7fb351775..2a2fda460d 100644
--- a/components/drivers/usb/cherryusb/core/usbd_core.c
+++ b/components/drivers/usb/cherryusb/core/usbd_core.c
@@ -4,6 +4,17 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
+#ifdef CONFIG_USBDEV_EP0_THREAD
+#include "usb_osal.h"
+
+#define USB_EP0_STATE_SETUP 0
+#define USB_EP0_STATE_IN 1
+#define USB_EP0_STATE_OUT 2
+#endif
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbd_core"
+#include "usb_log.h"
/* general descriptor field offsets */
#define DESC_bLength 0 /** Length offset */
@@ -62,6 +73,10 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
#endif
#ifdef CONFIG_USBDEV_TEST_MODE
bool test_req;
+#endif
+#ifdef CONFIG_USBDEV_EP0_THREAD
+ usb_osal_mq_t usbd_ep0_mq;
+ usb_osal_thread_t usbd_ep0_thread;
#endif
struct usbd_interface *intf[16];
uint8_t intf_altsetting[16];
@@ -431,8 +446,8 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t
}
/* skip to next descriptor */
- p += p[DESC_bLength];
current_desc_len += p[DESC_bLength];
+ p += p[DESC_bLength];
if (current_desc_len >= desc_len && desc_len) {
break;
}
@@ -497,7 +512,6 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
if (alt_setting == 0) {
ret = usbd_reset_endpoint(busid, ep_desc);
- goto find_end;
} else if (cur_alt_setting == alt_setting) {
ret = usbd_set_endpoint(busid, ep_desc);
} else {
@@ -511,14 +525,13 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
}
/* skip to next descriptor */
- p += p[DESC_bLength];
current_desc_len += p[DESC_bLength];
+ p += p[DESC_bLength];
if (current_desc_len >= desc_len && desc_len) {
break;
}
}
-find_end:
usbd_class_event_notify_handler(busid, USBD_EVENT_SET_INTERFACE, (void *)if_desc);
return ret;
@@ -685,8 +698,8 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
}
/* skip to next descriptor */
- p += p[DESC_bLength];
current_desc_len += p[DESC_bLength];
+ p += p[DESC_bLength];
if (current_desc_len >= desc_len && desc_len) {
break;
}
@@ -1125,12 +1138,10 @@ void usbd_event_reset_handler(uint8_t busid)
g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESET);
}
-void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
+static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_setup_packet *setup)
{
- struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
uint8_t *buf;
- memcpy(setup, psetup, 8);
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
usbd_print_setup(setup);
#endif
@@ -1195,7 +1206,20 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
}
}
-void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
+void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
+{
+ struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
+
+ memcpy(setup, psetup, 8);
+
+#ifdef CONFIG_USBDEV_EP0_THREAD
+ usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_SETUP);
+#else
+ __usbd_event_ep0_setup_complete_handler(busid, setup);
+#endif
+}
+
+static void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
@@ -1236,11 +1260,12 @@ void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
}
}
-void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
+static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
(void)ep;
+ (void)setup;
if (nbytes > 0) {
g_usbd_core[busid].ep0_data_buf += nbytes;
@@ -1249,6 +1274,9 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, g_usbd_core[busid].ep0_data_buf_residue);
if (g_usbd_core[busid].ep0_data_buf_residue == 0) {
+#ifdef CONFIG_USBDEV_EP0_THREAD
+ usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_OUT);
+#else
/* Received all, send data to handler */
g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
@@ -1258,6 +1286,7 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
/*Send status to host*/
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
+#endif
} else {
/* Start reading the remain data */
usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
@@ -1396,6 +1425,47 @@ int usbd_send_remote_wakeup(uint8_t busid)
}
}
+#ifdef CONFIG_USBDEV_EP0_THREAD
+static void usbdev_ep0_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
+{
+ uintptr_t event;
+ int ret;
+ uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
+ struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
+
+ while (1) {
+ ret = usb_osal_mq_recv(g_usbd_core[busid].usbd_ep0_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
+ if (ret < 0) {
+ continue;
+ }
+ USB_LOG_DBG("event:%d\r\n", event);
+
+ switch (event) {
+ case USB_EP0_STATE_SETUP:
+ __usbd_event_ep0_setup_complete_handler(busid, setup);
+ break;
+ case USB_EP0_STATE_IN:
+ // do nothing
+ break;
+ case USB_EP0_STATE_OUT:
+ /* Received all, send data to handler */
+ g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
+ if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
+ usbd_ep_set_stall(busid, USB_CONTROL_IN_EP0);
+ continue;
+ }
+
+ /*Send status to host*/
+ usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+#endif
+
int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
{
int ret;
@@ -1410,6 +1480,21 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
bus = &g_usbdev_bus[busid];
bus->reg_base = reg_base;
+#ifdef CONFIG_USBDEV_EP0_THREAD
+ g_usbd_core[busid].usbd_ep0_mq = usb_osal_mq_create(1);
+ if (g_usbd_core[busid].usbd_ep0_mq == NULL) {
+ USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_mq\r\n");
+ while (1) {
+ }
+ }
+ g_usbd_core[busid].usbd_ep0_thread = usb_osal_thread_create("usbd_ep0", CONFIG_USBDEV_EP0_STACKSIZE, CONFIG_USBDEV_EP0_PRIO, usbdev_ep0_thread, (void *)(uint32_t)busid);
+ if (g_usbd_core[busid].usbd_ep0_thread == NULL) {
+ USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_thread\r\n");
+ while (1) {
+ }
+ }
+#endif
+
g_usbd_core[busid].event_handler = event_handler;
ret = usb_dc_init(busid);
usbd_class_event_notify_handler(busid, USBD_EVENT_INIT, NULL);
@@ -1429,5 +1514,14 @@ int usbd_deinitialize(uint8_t busid)
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);
+ }
+#endif
+
return 0;
}
diff --git a/components/drivers/usb/cherryusb/core/usbh_core.c b/components/drivers/usb/cherryusb/core/usbh_core.c
index cb36f97eea..38b5439fee 100644
--- a/components/drivers/usb/cherryusb/core/usbh_core.c
+++ b/components/drivers/usb/cherryusb/core/usbh_core.c
@@ -324,6 +324,17 @@ static void usbh_print_hubport_info(struct usbh_hubport *hport)
}
}
+static void usbh_print_setup(struct usb_setup_packet *setup)
+{
+ USB_LOG_DBG("Setup: "
+ "bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
+ setup->bmRequestType,
+ setup->bRequest,
+ setup->wValue,
+ setup->wIndex,
+ setup->wLength);
+}
+
static int usbh_get_default_mps(int speed)
{
switch (speed) {
@@ -674,10 +685,16 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
struct usbh_urb *urb;
int ret;
+ if (!hport || !setup) {
+ return -USB_ERR_INVAL;
+ }
+
urb = &hport->ep0_urb;
usb_osal_mutex_take(hport->mutex);
+ usbh_print_setup(setup);
+
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) {
@@ -841,7 +858,11 @@ static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t
if (hub->index == hub_index) {
hport = &hub->child[hub_port - 1];
- return hport;
+ if (hport->connected) {
+ return hport;
+ } else {
+ return NULL;
+ }
} else {
for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
@@ -865,6 +886,7 @@ static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t
}
return NULL;
}
+
void *usbh_find_class_instance(const char *devname)
{
usb_slist_t *bus_list;
diff --git a/components/drivers/usb/cherryusb/core/usbh_core.h b/components/drivers/usb/cherryusb/core/usbh_core.h
index eaddb30432..1bed410d09 100644
--- a/components/drivers/usb/cherryusb/core/usbh_core.h
+++ b/components/drivers/usb/cherryusb/core/usbh_core.h
@@ -21,6 +21,7 @@
#include "usb_osal.h"
#include "usbh_hub.h"
#include "usb_memcpy.h"
+#include "usb_dcache.h"
#include "usb_version.h"
#ifdef __cplusplus
diff --git a/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c b/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c
index 2090dae25c..c5a2d9ef9b 100644
--- a/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c
+++ b/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c
@@ -108,6 +108,70 @@ 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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryADB", /* Product */
+ "CherryADB2024", /* 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 msc_bootuf2_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
/*!< global descriptor */
static const uint8_t adb_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
@@ -171,15 +235,16 @@ static const uint8_t adb_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
0x40,
0x00,
0x00,
#endif
0x00
};
+#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -222,7 +287,14 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base)
}
}
+#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);
}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c
index 56684e4607..b1622656e6 100644
--- a/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c
+++ b/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c
@@ -68,6 +68,73 @@
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),
+ 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))
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UAC 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 audio_v1_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
+};
+#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),
@@ -125,12 +192,12 @@ const uint8_t audio_v1_descriptor[] = {
'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 */
+ '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
///////////////////////////////////////
@@ -149,6 +216,7 @@ const uint8_t audio_v1_descriptor[] = {
#endif
0x00
};
+#endif
volatile bool tx_flag = 0;
volatile bool ep_tx_busy_flag = false;
@@ -214,7 +282,11 @@ struct audio_entity_info audio_entity_table[] = {
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);
diff --git a/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c
index 4beccc6baf..add1d8db7c 100644
--- a/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c
+++ b/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c
@@ -6,19 +6,24 @@
#include "usbd_core.h"
#include "usbd_audio.h"
+#define USING_FEEDBACK 0
+
#define USBD_VID 0xffff
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#ifdef CONFIG_USB_HS
-#define EP_INTERVAL 0x04
+#define EP_INTERVAL 0x04
+#define FEEDBACK_ENDP_PACKET_SIZE 0x04
#else
-#define EP_INTERVAL 0x01
+#define EP_INTERVAL 0x01
+#define FEEDBACK_ENDP_PACKET_SIZE 0x03
#endif
#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
@@ -38,6 +43,7 @@
/* 16bit(2 Bytes) 双声道(Mono:2) */
#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 + \
@@ -48,6 +54,18 @@
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \
AUDIO_AS_DESCRIPTOR_INIT_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))
+#endif
#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
@@ -57,6 +75,84 @@
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 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),
+ 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))
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UAC 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 audio_v1_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
+};
+#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),
@@ -67,8 +163,13 @@ const uint8_t audio_v1_descriptor[] = {
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)),
///////////////////////////////////////
@@ -120,13 +221,17 @@ const uint8_t audio_v1_descriptor[] = {
'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 */
+ '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
@@ -144,9 +249,11 @@ const uint8_t audio_v1_descriptor[] = {
#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];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
volatile bool tx_flag = 0;
volatile bool rx_flag = 0;
@@ -183,6 +290,9 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
rx_flag = 1;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
+ uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
+ 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);
printf("OPEN1\r\n");
} else {
tx_flag = 1;
@@ -215,6 +325,16 @@ void usbd_audio_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
ep_tx_busy_flag = false;
}
+#if USING_FEEDBACK == 1
+void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
+ uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
+ AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
+ usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
+}
+#endif
+
static struct usbd_endpoint audio_in_ep = {
.ep_cb = usbd_audio_in_callback,
.ep_addr = AUDIO_IN_EP
@@ -225,6 +345,13 @@ static struct usbd_endpoint audio_out_ep = {
.ep_addr = AUDIO_OUT_EP
};
+#if USING_FEEDBACK == 1
+static struct usbd_endpoint audio_out_feedback_ep = {
+ .ep_cb = usbd_audio_iso_out_feedback_callback,
+ .ep_addr = AUDIO_OUT_FEEDBACK_EP
+};
+#endif
+
struct usbd_interface intf0;
struct usbd_interface intf1;
struct usbd_interface intf2;
@@ -240,13 +367,19 @@ struct audio_entity_info audio_entity_table[] = {
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));
usbd_add_endpoint(busid, &audio_in_ep);
usbd_add_endpoint(busid, &audio_out_ep);
-
+#if USING_FEEDBACK == 1
+ usbd_add_endpoint(busid, &audio_out_feedback_ep);
+#endif
usbd_initialize(busid, reg_base, usbd_event_handler);
}
diff --git a/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c
index c00fffa9fd..81b8e23094 100644
--- a/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c
+++ b/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c
@@ -72,6 +72,74 @@
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),
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UAC 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 audio_v2_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
+};
+#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),
@@ -154,6 +222,7 @@ const uint8_t audio_v2_descriptor[] = {
#endif
0x00
};
+#endif
static const uint8_t mic_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(1),
@@ -162,7 +231,10 @@ static const uint8_t mic_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_4B(0x00)
};
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
+
volatile bool tx_flag = 0;
+volatile bool ep_tx_busy_flag = false;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -210,6 +282,7 @@ void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sam
void usbd_audio_iso_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
+ ep_tx_busy_flag = false;
}
static struct usbd_endpoint audio_in_ep = {
@@ -231,7 +304,11 @@ struct audio_entity_info audio_entity_table[] = {
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);
@@ -242,5 +319,13 @@ void audio_v2_init(uint8_t busid, uintptr_t reg_base)
void audio_v2_test(uint8_t busid)
{
if (tx_flag) {
+ memset(write_buffer, 'a', AUDIO_IN_PACKET);
+ ep_tx_busy_flag = true;
+ usbd_ep_start_write(busid, AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
+ while (ep_tx_busy_flag) {
+ if (tx_flag == false) {
+ break;
+ }
+ }
}
}
diff --git a/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c
index 0aebe57517..93630dea9b 100644
--- a/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c
+++ b/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c
@@ -114,6 +114,79 @@
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),
+ 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_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(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UAC 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 audio_v2_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
+};
+#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),
@@ -201,6 +274,7 @@ uint8_t audio_v2_descriptor[] = {
#endif
0x00
};
+#endif
static const uint8_t speaker_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(5),
@@ -233,6 +307,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
volatile bool tx_flag = 0;
volatile bool rx_flag = 0;
+volatile bool ep_tx_busy_flag = false;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -293,20 +368,6 @@ void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sam
}
}
-void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
-{
- uint16_t packet_size = 0;
- if (ep == AUDIO_OUT_EP) {
- packet_size = ((sampling_freq * 2 * OUT_CHANNEL_NUM) / 1000);
- audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 11] = packet_size;
- audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 10] = packet_size >> 8;
- } else if (ep == AUDIO_IN_EP) {
- packet_size = ((sampling_freq * 2 * IN_CHANNEL_NUM) / 1000);
- audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 11] = packet_size;
- audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 10] = packet_size >> 8;
- }
-}
-
void usbd_audio_iso_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
@@ -348,7 +409,11 @@ struct audio_entity_info audio_entity_table[] = {
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));
@@ -361,6 +426,14 @@ void audio_v2_init(uint8_t busid, uintptr_t reg_base)
void audio_v2_test(uint8_t busid)
{
if (tx_flag) {
+ memset(write_buffer, 'a', AUDIO_IN_PACKET);
+ ep_tx_busy_flag = true;
+ usbd_ep_start_write(busid, AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
+ while (ep_tx_busy_flag) {
+ if (tx_flag == false) {
+ break;
+ }
+ }
}
if (rx_flag) {
}
diff --git a/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c
index 0abb677a09..b34e03fcd5 100644
--- a/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c
+++ b/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c
@@ -6,18 +6,23 @@
#include "usbd_core.h"
#include "usbd_audio.h"
+#define USING_FEEDBACK 0
+
#define USBD_VID 0xffff
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#ifdef CONFIG_USB_HS
-#define EP_INTERVAL 0x04
+#define EP_INTERVAL 0x04
+#define FEEDBACK_ENDP_PACKET_SIZE 0x04
#else
-#define EP_INTERVAL 0x01
+#define EP_INTERVAL 0x01
+#define FEEDBACK_ENDP_PACKET_SIZE 0x03
#endif
-#define AUDIO_OUT_EP 0x01
+#define AUDIO_OUT_EP 0x01
+#define AUDIO_OUT_FEEDBACK_EP 0x82
#define AUDIO_OUT_CLOCK_ID 0x01
#define AUDIO_OUT_FU_ID 0x03
@@ -58,6 +63,7 @@
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_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 + \
@@ -65,6 +71,15 @@
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_DESCRIPTOR_INIT_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)
+#endif
#define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
@@ -72,6 +87,78 @@
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),
+ 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
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UAC 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 audio_v2_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
+};
+#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),
@@ -80,7 +167,11 @@ const uint8_t audio_v2_descriptor[] = {
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
///////////////////////////////////////
@@ -136,7 +227,11 @@ const uint8_t audio_v2_descriptor[] = {
'1', 0x00, /* wcChar6 */
'0', 0x00, /* wcChar7 */
'0', 0x00, /* wcChar8 */
- '3', 0x00, /* wcChar9 */
+#if USING_FEEDBACK == 0
+ '3', 0x00, /* wcChar9 */
+#else
+ '4', 0x00, /* wcChar9 */
+#endif
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
@@ -154,6 +249,7 @@ const uint8_t audio_v2_descriptor[] = {
#endif
0x00
};
+#endif
static const uint8_t default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(5),
@@ -175,6 +271,7 @@ static const uint8_t default_sampling_freq_table[] = {
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
volatile bool rx_flag = 0;
@@ -208,6 +305,14 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
rx_flag = 1;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
+#ifdef CONFIG_USB_HS
+ uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
+ AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
+#else
+ uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
+ AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
+#endif
+ usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
USB_LOG_RAW("OPEN\r\n");
}
@@ -230,11 +335,33 @@ void usbd_audio_iso_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
}
+#if USING_FEEDBACK == 1
+void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
+#ifdef CONFIG_USB_HS
+ uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
+ AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
+#else
+ uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
+ AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
+#endif
+ usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
+}
+#endif
+
static struct usbd_endpoint audio_out_ep = {
.ep_cb = usbd_audio_iso_out_callback,
.ep_addr = AUDIO_OUT_EP
};
+#if USING_FEEDBACK == 1
+static struct usbd_endpoint audio_out_feedback_ep = {
+ .ep_cb = usbd_audio_iso_out_feedback_callback,
+ .ep_addr = AUDIO_OUT_FEEDBACK_EP
+};
+#endif
+
struct usbd_interface intf0;
struct usbd_interface intf1;
@@ -249,11 +376,17 @@ struct audio_entity_info audio_entity_table[] = {
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);
-
+#if USING_FEEDBACK == 1
+ usbd_add_endpoint(busid, &audio_out_feedback_ep);
+#endif
usbd_initialize(busid, reg_base, usbd_event_handler);
}
diff --git a/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c b/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c
index fbada2dbe7..7c805699e8 100644
--- a/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c
+++ b/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c
@@ -23,6 +23,69 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UF2 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 msc_bootuf2_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
+};
+#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),
@@ -100,6 +163,7 @@ const uint8_t msc_bootuf2_descriptor[] = {
#endif
0x00
};
+#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -151,7 +215,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c
index 148f324c37..40cae68f14 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c
@@ -43,6 +43,101 @@
#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)
+};
+
+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 */
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB CDC MSC HID 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 cdc_acm_hid_msc_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
+};
+#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),
@@ -152,6 +247,7 @@ const uint8_t cdc_acm_hid_msc_descriptor[] = {
#endif
0x00
};
+#endif
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -303,8 +399,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c
index a5ad404866..b35cc34ec6 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c
@@ -54,9 +54,9 @@ static const uint8_t device_quality_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
0x40,
0x00,
0x00,
@@ -169,9 +169,9 @@ static const uint8_t cdc_msc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
0x40,
0x00,
0x00,
diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c
index 13f67f4b5f..966a817b1e 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c
@@ -37,8 +37,74 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB CDC MULTI 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 cdc_multi_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
+};
+#else
/*!< global descriptor */
-static const uint8_t cdc_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),
@@ -109,15 +175,16 @@ static const uint8_t cdc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 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];
@@ -225,8 +292,11 @@ struct usbd_interface intf7;
void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base)
{
- usbd_desc_register(busid, cdc_descriptor);
-
+#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);
diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c
index a13d96a4b9..f8d5c4b941 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c
@@ -25,6 +25,69 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB CDC 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 cdc_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
+};
+#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),
@@ -94,15 +157,16 @@ static const uint8_t cdc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 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];
@@ -181,7 +245,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c
index 9147c92320..70a16af65b 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c
@@ -34,6 +34,69 @@
/* str idx = 4 is for mac address: aa:bb:cc:dd:ee:ff*/
#define CDC_ECM_MAC_STRING_INDEX 4
+#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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB CDC ECM 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 cdc_ecm_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
+};
+#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),
@@ -124,15 +187,16 @@ static const uint8_t cdc_ecm_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
0x40,
0x00,
0x00,
#endif
0x00
};
+#endif
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
@@ -277,7 +341,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c
index a83a75551a..1d43f34ad0 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c
@@ -29,8 +29,71 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB RNDIS 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 cdc_rndis_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
+};
+#else
/*!< global descriptor */
-static const uint8_t cdc_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),
@@ -100,15 +163,16 @@ static const uint8_t cdc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
0x40,
0x00,
0x00,
#endif
0x00
};
+#endif
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
@@ -315,7 +379,11 @@ void cdc_rndis_init(uint8_t busid, uintptr_t reg_base)
#else
rndis_lwip_init();
#endif
- usbd_desc_register(busid, cdc_descriptor);
+#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, mac));
usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
usbd_initialize(busid, reg_base, usbd_event_handler);
diff --git a/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c b/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c
index cd3ed53dfb..9c36433a08 100644
--- a/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c
+++ b/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c
@@ -15,6 +15,69 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+ DFU_DESCRIPTOR_INIT()
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB DFU 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 dfu_flash_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
+};
+#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),
@@ -141,6 +204,7 @@ const uint8_t dfu_flash_descriptor[] = {
#endif
0x00
};
+#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -171,7 +235,11 @@ 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);
}
diff --git a/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c b/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c
index e5874c7677..47438d41b6 100644
--- a/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c
+++ b/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c
@@ -39,6 +39,103 @@
/*!< custom hid report descriptor size */
#define HID_CUSTOM_REPORT_DESC_SIZE 38
+#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 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 */
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB HID 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 hid_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
+};
+#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),
@@ -151,6 +248,7 @@ static const uint8_t hid_descriptor[] = {
#endif
0x00
};
+#endif
/*!< custom hid report descriptor */
static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
@@ -274,7 +372,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c
index 4d1afc3056..9fabba60dd 100644
--- a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c
+++ b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c
@@ -18,6 +18,101 @@
#define USB_HID_CONFIG_DESC_SIZ 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 */
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB HID 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 hid_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
+};
+#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),
@@ -127,6 +222,7 @@ static const uint8_t hid_descriptor[] = {
#endif
0x00
};
+#endif
/* USB HID device Configuration Descriptor */
static uint8_t hid_desc[9] __ALIGN_END = {
@@ -223,7 +319,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c
index 564d1718bb..bcd03e1d17 100644
--- a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c
+++ b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c
@@ -21,6 +21,101 @@
/*!< 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 */
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB HID 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 hid_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
+};
+#else
/*!< global descriptor */
const uint8_t hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
@@ -131,6 +226,7 @@ const uint8_t hid_descriptor[] = {
#endif
0x00
};
+#endif
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -241,7 +337,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c
index 786c324039..fa4381191d 100644
--- a/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c
+++ b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c
@@ -21,6 +21,101 @@
/*!< 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 */
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB HID 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 hid_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
+};
+#else
/*!< global descriptor */
const uint8_t hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
@@ -131,6 +226,7 @@ const uint8_t hid_descriptor[] = {
#endif
0x00
};
+#endif
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -241,7 +337,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/midi_template.c b/components/drivers/usb/cherryusb/demo/midi_template.c
index aa3b2ad78b..0203c74445 100644
--- a/components/drivers/usb/cherryusb/demo/midi_template.c
+++ b/components/drivers/usb/cherryusb/demo/midi_template.c
@@ -22,6 +22,118 @@
#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),
+ 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
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB MIDI 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 midi_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
+};
+#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),
@@ -141,15 +253,16 @@ const uint8_t midi_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 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];
@@ -204,7 +317,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/msc_ram_template.c b/components/drivers/usb/cherryusb/demo/msc_ram_template.c
index 90214834c0..1b19a571b5 100644
--- a/components/drivers/usb/cherryusb/demo/msc_ram_template.c
+++ b/components/drivers/usb/cherryusb/demo/msc_ram_template.c
@@ -22,6 +22,69 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB MSC 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 msc_ram_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
+};
+#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),
@@ -99,6 +162,7 @@ const uint8_t msc_ram_descriptor[] = {
#endif
0x00
};
+#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -158,7 +222,11 @@ static struct usbd_interface intf0;
void msc_ram_init(uint8_t busid, uintptr_t reg_base)
{
+#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);
diff --git a/components/drivers/usb/cherryusb/demo/msc_storage_template.c b/components/drivers/usb/cherryusb/demo/msc_storage_template.c
deleted file mode 100644
index 047bad8e2f..0000000000
--- a/components/drivers/usb/cherryusb/demo/msc_storage_template.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbd_core.h"
-#include "usbd_msc.h"
-
-#ifdef __RT_THREAD_H__
-
-#define MSC_IN_EP 0x81
-#define MSC_OUT_EP 0x02
-
-#define USBD_VID 0xFFFF
-#define USBD_PID 0xFFFF
-#define USBD_MAX_POWER 100
-#define USBD_LANGID_STRING 1033
-
-#define USB_CONFIG_SIZE (9 + MSC_DESCRIPTOR_LEN)
-
-#ifdef CONFIG_USB_HS
-#define MSC_MAX_MPS 512
-#else
-#define MSC_MAX_MPS 64
-#endif
-
-
-const uint8_t msc_storage_descriptor[] = {
- USB_DEVICE_DESCRIPTOR_INIT(USB_1_1, 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
-};
-
-struct usbd_interface intf0;
-
-/* assume the block device is 512M */
-#define BLOCK_DEV_NAME "sd0"
-#define BLOCK_SIZE 512U
-#define BLOCK_COUNT 0x1024U * 0x1024U
-static rt_device_t blk_dev = RT_NULL;
-
-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:
- break;
- case USBD_EVENT_SET_REMOTE_WAKEUP:
- break;
- case USBD_EVENT_CLR_REMOTE_WAKEUP:
- break;
-
- default:
- break;
- }
-}
-
-void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
-{
- *block_num = BLOCK_COUNT;
- *block_size = BLOCK_SIZE;
-}
-
-int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
-{
- rt_device_read(blk_dev, sector, buffer, length / BLOCK_SIZE);
- return 0;
-}
-
-int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
-{
- rt_device_write(blk_dev, sector, buffer, length / BLOCK_SIZE);
- return 0;
-}
-
-void msc_storage_init(uint8_t busid, uintptr_t reg_base)
-{
- rt_err_t res;
-
- blk_dev = rt_device_find(BLOCK_DEV_NAME);
- RT_ASSERT(blk_dev);
-
- res = rt_device_open(blk_dev, RT_DEVICE_OFLAG_RDWR);
- RT_ASSERT(res == RT_EOK);
-
- usbd_desc_register(busid, msc_storage_descriptor);
- usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
-
- usbd_initialize(busid, reg_base, usbd_event_handler);
-}
-#endif
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/demo/usb_host.c b/components/drivers/usb/cherryusb/demo/usb_host.c
index 817103d5c0..c891d67a40 100644
--- a/components/drivers/usb/cherryusb/demo/usb_host.c
+++ b/components/drivers/usb/cherryusb/demo/usb_host.c
@@ -58,10 +58,10 @@ void usbh_cdc_acm_callback(void *arg, int nbytes)
}
}
-static void usbh_cdc_acm_thread(void *argument)
+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 *)argument;
+ struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
/* test with only one buffer, if you have more cdc acm class, modify by yourself */
#if TEST_USBH_CDC_SPEED
@@ -133,10 +133,10 @@ void usbh_hid_callback(void *arg, int nbytes)
}
}
-static void usbh_hid_thread(void *argument)
+static void usbh_hid_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
- struct usbh_hid *hid_class = (struct usbh_hid *)argument;
+ 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 */
@@ -222,13 +222,18 @@ unmount:
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t partition_table[512];
-static void usbh_msc_thread(void *argument)
+static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
- struct usbh_msc *msc_class = (struct usbh_msc *)argument;
+ struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
/* test with only one buffer, if you have more msc class, modify by yourself */
-#if 1
+#if TEST_USBH_MSC_FATFS == 0
+ ret = usbh_msc_scsi_init(msc_class);
+ if (ret < 0) {
+ USB_LOG_RAW("scsi_init error,ret:%d\r\n", ret);
+ goto delete;
+ }
/* get the partition table */
ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
if (ret < 0) {
@@ -242,11 +247,10 @@ static void usbh_msc_thread(void *argument)
USB_LOG_RAW("%02x ", partition_table[i]);
}
USB_LOG_RAW("\r\n");
-#endif
-
-#if TEST_USBH_MSC_FATFS
+#else
usb_msc_fatfs_test();
#endif
+
// clang-format off
delete:
usb_osal_thread_delete(NULL);
diff --git a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c
index 6a4116222a..0241b5d7a3 100644
--- a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c
@@ -103,6 +103,120 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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 */
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UVC UAC HID 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 video_audio_hid_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
+};
+#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),
@@ -231,6 +345,7 @@ const uint8_t video_audio_hid_descriptor[] = {
#endif
0x00
};
+#endif
static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
@@ -422,7 +537,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/video_static_h264_template.c b/components/drivers/usb/cherryusb/demo/video_static_h264_template.c
index e325964a2f..607376720d 100644
--- a/components/drivers/usb/cherryusb/demo/video_static_h264_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_static_h264_template.c
@@ -50,6 +50,77 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UVC 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 video_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
+};
+#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),
@@ -136,6 +207,7 @@ const uint8_t video_descriptor[] = {
#endif
0x00
};
+#endif
volatile bool tx_flag = 0;
volatile bool iso_tx_busy = false;
@@ -198,7 +270,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c b/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c
index 1d2ae01ba4..0e77b38dc4 100644
--- a/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c
@@ -50,6 +50,77 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UVC 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 video_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
+};
+#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),
@@ -136,6 +207,7 @@ const uint8_t video_descriptor[] = {
#endif
0x00
};
+#endif
volatile bool tx_flag = 0;
volatile bool iso_tx_busy = false;
@@ -198,7 +270,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c b/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c
index 4ba71701c4..1aca76d025 100644
--- a/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c
@@ -51,6 +51,79 @@
#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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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),
+
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB UVC 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 video_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
+};
+#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),
@@ -138,6 +211,7 @@ const uint8_t video_descriptor[] = {
#endif
0x00
};
+#endif
volatile bool tx_flag = 0;
volatile bool iso_tx_busy = false;
@@ -200,7 +274,11 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c
index 5257087997..f446391f18 100644
--- a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c
+++ b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c
@@ -149,6 +149,105 @@ struct usb_bos_descriptor bos_desc = {
.string_len = USBD_BOS_WTOTALLENGTH
};
+#ifdef CONFIG_USBDEV_ADVANCE_DESC
+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)
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00,
+ 0x00,
+};
+
+static const char *string_descriptors[] = {
+ (const char[]){ 0x09, 0x04 }, /* Langid */
+ "CherryUSB", /* Manufacturer */
+ "CherryUSB WEBUSB HID 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 webusb_hid_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,
+ .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),
@@ -207,7 +306,7 @@ static const uint8_t webusb_hid_descriptor[] = {
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
- 0x26, /* bLength */
+ 0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
@@ -219,14 +318,17 @@ static const uint8_t webusb_hid_descriptor[] = {
'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 */
+ '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
///////////////////////////////////////
@@ -259,6 +361,7 @@ static const uint8_t webusb_hid_descriptor[] = {
#endif
0x00
};
+#endif
/* USB HID device Configuration Descriptor */
static uint8_t hid_desc[9] __ALIGN_END = {
@@ -355,10 +458,16 @@ 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);
diff --git a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c
index 1eb390b92f..6568939cc4 100644
--- a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c
+++ b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c
@@ -188,6 +188,79 @@ 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)
+};
+
+static const uint8_t config_descriptor[] = {
+ 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
+};
+
+static const uint8_t device_quality_descriptor[] = {
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 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 */
+ "CherryUSB WINUSB DEMO 1", /* STRING4 */
+ "CherryUSB WINUSB DEMO 2", /* STRING5 */
+};
+
+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 > 5) {
+ return NULL;
+ }
+ return string_descriptors[index];
+}
+
+const struct usb_descriptor winusb_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),
@@ -252,12 +325,12 @@ const uint8_t winusb_descriptor[] = {
'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 */
+ '1', 0x00, /* wcChar4 */
+ '2', 0x00, /* wcChar5 */
+ '3', 0x00, /* wcChar6 */
+ '4', 0x00, /* wcChar7 */
+ '5', 0x00, /* wcChar8 */
+ '6', 0x00, /* wcChar9 */
///////////////////////////////////////
/// string4 descriptor
///////////////////////////////////////
@@ -322,15 +395,16 @@ const uint8_t winusb_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
- 0x02,
- 0x02,
- 0x01,
+ 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];
@@ -446,8 +520,14 @@ struct usbd_interface intf1;
void winusb_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_add_interface(busid, &intf0);
usbd_add_endpoint(busid, &winusb_out_ep1);
usbd_add_endpoint(busid, &winusb_in_ep1);
diff --git a/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c b/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c
index 493668e55b..34e646efa6 100644
--- a/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c
+++ b/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c
@@ -145,6 +145,89 @@ __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
#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),
+ CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, WINUSB_EP_MPS, 0x00)
+};
+
+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 */
@@ -170,7 +253,9 @@ const uint8_t winusbv2_descriptor[] = {
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
- /* String 2 (Product) */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
@@ -194,21 +279,21 @@ const uint8_t winusbv2_descriptor[] = {
'E', 0x00, /* wcChar18 */
'M', 0x00, /* wcChar19 */
'O', 0x00, /* wcChar20 */
- /* String 3 (Serial Number) */
- 0x1A, // bLength
- USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
- '0', 0, // wcChar0
- '1', 0, // wcChar1
- '2', 0, // wcChar2
- '3', 0, // wcChar3
- '4', 0, // wcChar4
- '5', 0, // wcChar5
- 'A', 0, // wcChar6
- 'B', 0, // wcChar7
- 'C', 0, // wcChar8
- 'D', 0, // wcChar9
- 'E', 0, // wcChar10
- 'F', 0, // wcChar11
+ ///////////////////////////////////////
+ /// 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,
@@ -225,6 +310,7 @@ const uint8_t winusbv2_descriptor[] = {
/* 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];
@@ -248,6 +334,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);
+ usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
@@ -283,6 +370,30 @@ void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
}
}
+void usbd_cdc_acm_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ USB_LOG_RAW("actual out len:%d\r\n", nbytes);
+ // for (int i = 0; i < 100; i++) {
+ // printf("%02x ", read_buffer[i]);
+ // }
+ // printf("\r\n");
+ usbd_ep_start_write(busid, CDC_IN_EP, read_buffer, nbytes);
+ /* setup next out ep read transfer */
+ usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
+}
+
+void usbd_cdc_acm_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ USB_LOG_RAW("actual in len:%d\r\n", nbytes);
+
+ if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
+ /* send zlp */
+ usbd_ep_start_write(busid, CDC_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
@@ -295,35 +406,29 @@ struct usbd_endpoint winusb_in_ep1 = {
static struct usbd_endpoint cdc_out_ep = {
.ep_addr = CDC_OUT_EP,
- .ep_cb = NULL
+ .ep_cb = usbd_cdc_acm_out
};
static struct usbd_endpoint cdc_in_ep = {
.ep_addr = CDC_IN_EP,
- .ep_cb = NULL
+ .ep_cb = usbd_cdc_acm_in
};
struct usbd_interface winusb_intf;
struct usbd_interface intf1;
struct usbd_interface intf2;
-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
-};
-
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);
@@ -336,4 +441,26 @@ void winusbv2_init(uint8_t busid, uintptr_t reg_base)
usbd_add_endpoint(busid, &cdc_in_ep);
usbd_initialize(busid, reg_base, usbd_event_handler);
+}
+
+volatile uint8_t dtr_enable = 0;
+
+void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
+{
+ if (dtr) {
+ dtr_enable = 1;
+ } else {
+ dtr_enable = 0;
+ }
+}
+
+void cdc_acm_data_send_with_dtr_test(uint8_t busid)
+{
+ if (dtr_enable) {
+ memset(&write_buffer[10], 'a', 2038);
+ ep_tx_busy_flag = true;
+ usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048);
+ while (ep_tx_busy_flag) {
+ }
+ }
}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c b/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c
index a209dbd59a..1fc6de3565 100644
--- a/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c
+++ b/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c
@@ -151,6 +151,119 @@ __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
#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 */
@@ -206,7 +319,9 @@ const uint8_t winusbv2_descriptor[] = {
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
- /* String 2 (Product) */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
@@ -230,21 +345,21 @@ const uint8_t winusbv2_descriptor[] = {
'E', 0x00, /* wcChar18 */
'M', 0x00, /* wcChar19 */
'O', 0x00, /* wcChar20 */
- /* String 3 (Serial Number) */
- 0x1A, // bLength
- USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
- '0', 0, // wcChar0
- '1', 0, // wcChar1
- '2', 0, // wcChar2
- '3', 0, // wcChar3
- '4', 0, // wcChar4
- '5', 0, // wcChar5
- 'A', 0, // wcChar6
- 'B', 0, // wcChar7
- 'C', 0, // wcChar8
- 'D', 0, // wcChar9
- 'E', 0, // wcChar10
- 'F', 0, // wcChar11
+ ///////////////////////////////////////
+ /// 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,
@@ -261,6 +376,7 @@ const uint8_t winusbv2_descriptor[] = {
/* 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];
@@ -411,23 +527,17 @@ static struct usbd_endpoint hid_in_ep = {
struct usbd_interface winusb_intf;
struct usbd_interface intf1;
-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
-};
-
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);
diff --git a/components/drivers/usb/cherryusb/idf_component.yml b/components/drivers/usb/cherryusb/idf_component.yml
index a500a24047..b34f4759bf 100644
--- a/components/drivers/usb/cherryusb/idf_component.yml
+++ b/components/drivers/usb/cherryusb/idf_component.yml
@@ -1,4 +1,4 @@
-version: "1.4.2"
+version: "1.4.3"
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
tags:
- usb
diff --git a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
index d355699c06..dd1075a5fa 100644
--- a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
+++ b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
@@ -26,6 +26,8 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size,
void usb_osal_thread_delete(usb_osal_thread_t thread)
{
if (thread == NULL) {
+ rt_thread_t self = rt_thread_self();
+ rt_thread_control(self, RT_THREAD_CTRL_CLOSE, RT_NULL);
return;
}
diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c b/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c
index 073d52ea4e..eee64a0bfb 100644
--- a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c
+++ b/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c
@@ -42,6 +42,12 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t msc_sector[512];
static rt_err_t rt_udisk_init(rt_device_t dev)
{
+ struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
+
+ if (usbh_msc_scsi_init(msc_class) < 0) {
+ return -RT_ERROR;
+ }
+
return RT_EOK;
}
@@ -157,39 +163,35 @@ const static struct rt_device_ops udisk_device_ops = {
};
#endif
-int udisk_init(struct usbh_msc *msc_class)
+static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
- rt_err_t ret = 0;
- rt_uint8_t i;
- struct dfs_partition part0;
- struct rt_device *dev;
+ struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
char name[CONFIG_USBHOST_DEV_NAMELEN];
char mount_point[CONFIG_USBHOST_DEV_NAMELEN];
+ int ret;
+
+ snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
+ snprintf(mount_point, CONFIG_USBHOST_DEV_NAMELEN, CONFIG_USB_DFS_MOUNT_POINT, msc_class->sdchar);
+
+ ret = dfs_mount(name, mount_point, "elm", 0, 0);
+ if (ret == 0) {
+ rt_kprintf("udisk: %s mount successfully\n", name);
+ } else {
+ rt_kprintf("udisk: %s mount failed, ret = %d\n", name, ret);
+ }
+
+ usb_osal_thread_delete(NULL);
+}
+
+void usbh_msc_run(struct usbh_msc *msc_class)
+{
+ struct rt_device *dev;
+ char name[CONFIG_USBHOST_DEV_NAMELEN];
dev = rt_malloc(sizeof(struct rt_device));
memset(dev, 0, sizeof(struct rt_device));
snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
- snprintf(mount_point, CONFIG_USBHOST_DEV_NAMELEN, CONFIG_USB_DFS_MOUNT_POINT, msc_class->sdchar);
-
- ret = usbh_msc_scsi_read10(msc_class, 0, msc_sector, 1);
- if (ret != RT_EOK) {
- rt_kprintf("usb mass_storage read failed\n");
- rt_free(dev);
- return ret;
- }
-
- for (i = 0; i < 4; i++) {
- /* Get the first partition */
- ret = dfs_filesystem_get_partition(&part0, msc_sector, i);
- if (ret == RT_EOK) {
- rt_kprintf("Found partition %d: type = %d, offet=0x%x, size=0x%x\n",
- i, part0.type, part0.offset, part0.size);
- break;
- } else {
- break;
- }
- }
dev->type = RT_Device_Class_Block;
#ifdef RT_USING_DEVICE_OPS
@@ -204,19 +206,7 @@ int udisk_init(struct usbh_msc *msc_class)
rt_device_register(dev, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
- ret = dfs_mount(name, mount_point, "elm", 0, 0);
- if (ret == 0) {
- rt_kprintf("udisk: %s mount successfully\n", name);
- } else {
- rt_kprintf("udisk: %s mount failed, ret = %d\n", name, ret);
- }
-
- return ret;
-}
-
-void usbh_msc_run(struct usbh_msc *msc_class)
-{
- udisk_init(msc_class);
+ usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
}
void usbh_msc_stop(struct usbh_msc *msc_class)
diff --git a/components/drivers/usb/cherryusb/port/aic/usb_dc_aic.c b/components/drivers/usb/cherryusb/port/aic/usb_dc_aic.c
new file mode 100644
index 0000000000..46cbfea858
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/aic/usb_dc_aic.c
@@ -0,0 +1,1304 @@
+/*
+ * Copyright (c) 2023, Artinchip Technology Co., Ltd
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include
+#include "usbd_core.h"
+#include "usb_dc_aic_reg.h"
+
+// clang-format off
+#ifndef __UNALIGNED_UINT32_WRITE
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpacked"
+ #pragma GCC diagnostic ignored "-Wattributes"
+ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+ #pragma GCC diagnostic pop
+ #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+#endif
+#ifndef __UNALIGNED_UINT32_READ
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpacked"
+ #pragma GCC diagnostic ignored "-Wattributes"
+ __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+ #pragma GCC diagnostic pop
+ #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+#endif
+// clang-format on
+
+#define FS_PORT 0
+#define HS_PORT 1
+
+#ifndef CONFIG_USB_AIC_DC_PORT
+#error "please select CONFIG_USB_AIC_DC_PORT with FS_PORT or HS_PORT"
+#endif
+
+#ifndef USB_BASE
+#define USB_BASE CONFIG_USB_AIC_DC_BASE
+#endif
+
+#ifdef LPKG_CHERRYUSB_DEVICE_HID_IO_TEMPLATE
+#define USB_RAM_SIZE 1024 /* define with maximum value*/
+#else
+#define USB_RAM_SIZE 512 /* define with maximum value*/
+#endif
+
+#ifndef USB_NUM_BIDIR_ENDPOINTS
+#define USB_NUM_BIDIR_ENDPOINTS 5 /* define with minimum value*/
+#endif
+
+#define AIC_UDC_REG ((AIC_UDC_RegDef *)(USB_BASE))
+#define AIC_EP_FIFO(i) *(__IO uint32_t *)(USB_BASE + AIC_EP_FIFO_BASE + ((i)*AIC_EP_FIFO_SIZE))
+
+static uint8_t g_aic_udc_ibuf[USB_RAM_SIZE] __ALIGNED(CACHE_LINE_SIZE);
+static uint8_t g_aic_udc_obuf[USB_RAM_SIZE] __ALIGNED(CACHE_LINE_SIZE);
+
+/* Endpoint state */
+struct aic_ep_state {
+ uint16_t ep_mps; /* Endpoint max packet size */
+ uint8_t ep_type; /* Endpoint type */
+ uint8_t ep_stalled; /* Endpoint stall flag */
+ uint8_t *xfer_buf;
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ uint8_t *xfer_align_buf;
+ uint32_t xfer_align_len;
+#endif
+ uint32_t xfer_len;
+ uint32_t actual_xfer_len;
+};
+
+extern uint32_t usbd_clk;
+
+/* Driver state */
+/*USB_NOCACHE_RAM_SECTION*/ struct aic_udc {
+ USB_MEM_ALIGNX struct usb_setup_packet setup;
+ USB_MEM_ALIGNX struct aic_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
+ struct aic_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
+ uint32_t tx_fifo_map;
+} g_aic_udc;
+
+uint8_t rst_allow = 0;
+uint8_t ep0_ctrl_stage = 0; /* 1 = setup stage, 2 = data stage, 3 = status stage */
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+void aic_udc_dcache_clean(uintptr_t addr, uint32_t len)
+{
+ aicos_dcache_clean_range((size_t *)addr, len);
+}
+
+void aic_udc_dcache_invalidate(uintptr_t addr, uint32_t len)
+{
+ aicos_dcache_invalid_range((size_t *)addr, len);
+}
+
+void aic_udc_dcache_clean_invalidate(uintptr_t addr, uint32_t len)
+{
+ aicos_dcache_clean_invalid_range((size_t *)addr, len);
+}
+
+static int aic_udc_ep_buf_alloc(struct aic_ep_state *ep, uint32_t len,
+ uint8_t *sbuf)
+{
+ ep->xfer_len = len;
+ if (len % CACHE_LINE_SIZE)
+ ep->xfer_align_len = ALIGN_UP(len, CACHE_LINE_SIZE);
+ else
+ ep->xfer_align_len = len;
+
+ if (ep->xfer_align_len > USB_RAM_SIZE) {
+ ep->xfer_align_buf = aicos_malloc_align(0, ep->xfer_align_len,
+ CACHE_LINE_SIZE);
+ if (!ep->xfer_align_buf) {
+ USB_LOG_ERR("alloc error.\r\n");
+ return -5;
+ }
+ } else {
+ ep->xfer_align_buf = sbuf;
+ }
+
+ return 0;
+}
+
+static void aic_udc_ep_buf_free(struct aic_ep_state *ep, uint8_t *sbuf)
+{
+ if (!ep->xfer_align_buf)
+ return;
+
+ /* Whether the buf is allocated dynamically */
+ if (ep->xfer_align_buf != sbuf)
+ aicos_free_align(0, ep->xfer_align_buf);
+
+ ep->xfer_align_buf = NULL;
+ ep->xfer_align_len = 0;
+}
+
+static int aic_udc_ibuf_alloc(struct aic_ep_state *ep, uint32_t len)
+{
+ return aic_udc_ep_buf_alloc(ep, len, g_aic_udc_ibuf);
+}
+
+static int aic_udc_obuf_alloc(struct aic_ep_state *ep, uint32_t len)
+{
+ return aic_udc_ep_buf_alloc(ep, len, g_aic_udc_obuf);
+}
+
+static void aic_udc_ibuf_free(struct aic_ep_state *ep)
+{
+ aic_udc_ep_buf_free(ep, g_aic_udc_ibuf);
+}
+
+static void aic_udc_obuf_free(struct aic_ep_state *ep)
+{
+ aic_udc_ep_buf_free(ep, g_aic_udc_obuf);
+}
+#else
+#define aic_udc_dcache_clean(addr, len)
+#define aic_udc_dcache_invalidate(addr, len)
+#define aic_udc_dcache_clean_invalidate(addr, len)
+#endif
+
+static void aic_set_dma_nextep(void)
+{
+ uint32_t i;
+
+ /* dma to set the next-endpoint pointer. */
+ for (i = 0; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
+ uint32_t next = ((i + 1) % USB_NUM_BIDIR_ENDPOINTS) << DEPCTL_NEXT_EP_BIT;
+
+ AIC_UDC_REG->inepcfg[i] &= ~DEPCTL_NEXT_EP_MASK;
+ AIC_UDC_REG->inepcfg[i] |= next;
+ }
+}
+
+static inline int aic_reset(void)
+{
+ uint32_t count = 0U;
+
+ /* Wait for AHB master IDLE state. */
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((AIC_UDC_REG->ahbbasic & AHBBASIC_AHBIDLE) == 0U);
+
+ /* Core Soft Reset */
+ count = 0U;
+ AIC_UDC_REG->usbdevinit |= USBDEVINIT_CSFTRST;
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((AIC_UDC_REG->usbdevinit & USBDEVINIT_CSFTRST) == USBDEVINIT_CSFTRST);
+
+ return 0;
+}
+
+static inline int aic_core_init(void)
+{
+ int ret;
+ uint32_t usb_gusbcfg =
+ 0 << 19 /* ULPI Clock SuspendM */
+ | 0 << 18 /* ULPI Phy Auto Resume */
+ | 0 << 15 /* PHY Low Power Clock sel */
+ | 0x5 << 10 /* USB Turnaround time (0x5 for HS phy) */
+ | 0 << 7 /* ULPI DDR sel 0:single 8bit, 1:double 4bit */
+ /*| 0 << 6 0: high speed utmi+, 1: full speed serial*/
+#ifdef FPGA_BOARD_ARTINCHIP
+ | 1 << 4 /* 0: utmi+, 1:ulpi*/
+#else
+ | 0 << 4 /* 0: utmi+, 1:ulpi*/
+#endif
+ | 0 << 3 /* UTMI+ PHY 0:8bit, 1:16bit (ULPI PHY set 8bit) */
+ | 0x7 << 0; /* HS/FS timeout calibration**/
+
+ /* Reset after a PHY select */
+ ret = aic_reset();
+
+ /* Activate the USB Transceiver */
+ AIC_UDC_REG->usbphyif = usb_gusbcfg;
+
+ aic_set_dma_nextep();
+
+ return ret;
+}
+
+static inline int aic_flush_rxfifo(void)
+{
+ uint32_t count = 0;
+
+ AIC_UDC_REG->usbdevinit |= USBDEVINIT_RXFFLSH;
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((AIC_UDC_REG->usbdevinit & USBDEVINIT_RXFFLSH) == USBDEVINIT_RXFFLSH);
+
+ return 0;
+}
+
+static inline int aic_flush_txfifo(uint32_t num)
+{
+ uint32_t count = 0U;
+
+ AIC_UDC_REG->usbdevinit |= USBDEVINIT_TXFNUM(num & USBDEVINIT_TXFNUM_LIMIT);
+
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((AIC_UDC_REG->usbdevinit & USBDEVINIT_TXFFLSH) == USBDEVINIT_TXFFLSH);
+
+ return 0;
+}
+
+static void aic_set_turnaroundtime(uint32_t hclk, uint8_t speed)
+{
+ uint32_t UsbTrd;
+
+ /* The USBTRD is configured according to the tables below, depending on AHB frequency
+ used by application. In the low AHB frequency range it is used to stretch enough the USB response
+ time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
+ latency to the Data FIFO */
+ if (speed == USB_ENUM_SPEED_FULL) {
+ if ((hclk >= 14200000U) && (hclk < 15000000U)) {
+ /* hclk Clock Range between 14.2-15 MHz */
+ UsbTrd = 0xFU;
+ } else if ((hclk >= 15000000U) && (hclk < 16000000U)) {
+ /* hclk Clock Range between 15-16 MHz */
+ UsbTrd = 0xEU;
+ } else if ((hclk >= 16000000U) && (hclk < 17200000U)) {
+ /* hclk Clock Range between 16-17.2 MHz */
+ UsbTrd = 0xDU;
+ } else if ((hclk >= 17200000U) && (hclk < 18500000U)) {
+ /* hclk Clock Range between 17.2-18.5 MHz */
+ UsbTrd = 0xCU;
+ } else if ((hclk >= 18500000U) && (hclk < 20000000U)) {
+ /* hclk Clock Range between 18.5-20 MHz */
+ UsbTrd = 0xBU;
+ } else if ((hclk >= 20000000U) && (hclk < 21800000U)) {
+ /* hclk Clock Range between 20-21.8 MHz */
+ UsbTrd = 0xAU;
+ } else if ((hclk >= 21800000U) && (hclk < 24000000U)) {
+ /* hclk Clock Range between 21.8-24 MHz */
+ UsbTrd = 0x9U;
+ } else if ((hclk >= 24000000U) && (hclk < 27700000U)) {
+ /* hclk Clock Range between 24-27.7 MHz */
+ UsbTrd = 0x8U;
+ } else if ((hclk >= 27700000U) && (hclk < 32000000U)) {
+ /* hclk Clock Range between 27.7-32 MHz */
+ UsbTrd = 0x7U;
+ } else {/* if(hclk >= 32000000) */
+ /* hclk Clock Range between 32-200 MHz */
+ UsbTrd = 0x6U;
+ }
+ } else if (speed == USB_ENUM_SPEED_HIGH) {
+ UsbTrd = USBPHYIF_HS_TRDT_VALUE;
+ } else {
+ UsbTrd = USBPHYIF_DEFAULT_TRDT_VALUE;
+ }
+
+ AIC_UDC_REG->usbphyif |= USBPHYIF_TOUTCAL_LIMIT;
+
+ AIC_UDC_REG->usbphyif &= ~USBPHYIF_USBTRDTIM_MASK;
+ AIC_UDC_REG->usbphyif |= (uint32_t)((UsbTrd << USBPHYIF_USBTRDTIM_SHIFT)
+ & USBPHYIF_USBTRDTIM_MASK);
+}
+
+#if 0
+static void aic_set_txfifo(uint8_t fifo, uint16_t size)
+{
+ uint8_t i;
+ uint32_t Tx_Offset;
+
+ /* TXn min size = 16 words. (n : Transmit FIFO index)
+ When a TxFIFO is not used, the Configuration should be as follows:
+ case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txm can use the space allocated for Txn.
+ case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txn should be configured with the minimum space of 16 words
+ The FIFO is used optimally when used TxFIFOs are allocated in the top
+ of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+ When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
+
+ Tx_Offset = AIC_UDC_REG->rxfifosiz;
+
+ if (fifo == 0U) {
+ AIC_UDC_REG->nptxfifosiz = ((uint32_t)size << 16) | Tx_Offset;
+ } else {
+ Tx_Offset += (AIC_UDC_REG->nptxfifosiz) >> 16;
+ for (i = 0U; i < (fifo - 1U); i++) {
+ Tx_Offset += (AIC_UDC_REG->txfifosiz[i] >> 16);
+ }
+
+ /* Multiply Tx_Size by 2 to get higher performance */
+ AIC_UDC_REG->txfifosiz[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
+ }
+}
+#endif
+
+static uint8_t aic_get_devspeed(void)
+{
+ uint8_t speed;
+ uint32_t DevEnumSpeed = AIC_UDC_REG->usblinests & USB_ENUM_SPEED_MASK;
+
+ if (DevEnumSpeed == USB_HIGH_30_60MHZ) {
+ speed = USB_ENUM_SPEED_HIGH;
+ } else if (DevEnumSpeed == USB_FULL_30_60MHZ) {
+ speed = USB_ENUM_SPEED_FULL;
+ } else {
+ speed = 0xFU;
+ }
+
+ return speed;
+}
+
+static void aic_ep0_start_read_setup(uint8_t *psetup)
+{
+ g_aic_udc.out_ep[0].xfer_buf = psetup;
+ g_aic_udc.out_ep[0].xfer_len = 8;
+ ep0_ctrl_stage = 1;
+
+ aic_udc_dcache_invalidate((uintptr_t)psetup, CACHE_LINE_SIZE);
+
+ AIC_UDC_REG->outeptsfsiz[0] = 0U;
+ AIC_UDC_REG->outeptsfsiz[0] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
+ AIC_UDC_REG->outeptsfsiz[0] |= (3U * 8U);
+ AIC_UDC_REG->outeptsfsiz[0] |= DXEPTSIZ_MULCNT_MASK;
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ AIC_UDC_REG->outepdmaaddr[0] = (uint32_t)(uintptr_t)psetup;
+#endif
+
+ /* EP enable */
+ AIC_UDC_REG->outepcfg[0] |= DEPCTL_CNAK | DEPCTL_EPENA | DEPCTL_USBACTEP;
+}
+
+void aic_ep_write(uint8_t ep_idx, uint8_t *src, uint16_t len)
+{
+ uint32_t *pSrc = (uint32_t *)src;
+ uint32_t count32b, i;
+
+ count32b = ((uint32_t)len + 3U) / 4U;
+ for (i = 0U; i < count32b; i++) {
+ AIC_EP_FIFO(ep_idx) = __UNALIGNED_UINT32_READ(pSrc);
+ pSrc++;
+ }
+}
+
+void aic_ep_read(uint8_t *dest, uint16_t len)
+{
+ uint32_t *pDest = (uint32_t *)dest;
+ uint32_t i;
+ uint32_t count32b = ((uint32_t)len + 3U) / 4U;
+
+ for (i = 0U; i < count32b; i++) {
+ __UNALIGNED_UINT32_WRITE(pDest, AIC_EP_FIFO(0U));
+ pDest++;
+ }
+}
+
+#ifndef CONFIG_USB_AIC_DMA_ENABLE
+static void aic_tx_fifo_empty_procecss(uint8_t ep_idx)
+{
+ uint32_t len;
+ //uint32_t len32b;
+
+ len = g_aic_udc.in_ep[ep_idx].xfer_len - g_aic_udc.in_ep[ep_idx].actual_xfer_len;
+ if (len > g_aic_udc.in_ep[ep_idx].ep_mps) {
+ len = g_aic_udc.in_ep[ep_idx].ep_mps;
+ }
+
+ //len32b = (len + 3U) / 4U;
+
+ while (/*((AIC_UDC_REG->ineptxsts[ep_idx] & INEPTXSTS_IN_EP_TXFIFO_STS) >= len32b) &&*/
+ (g_aic_udc.in_ep[ep_idx].actual_xfer_len < g_aic_udc.in_ep[ep_idx].xfer_len) && (g_aic_udc.in_ep[ep_idx].xfer_len != 0U)) {
+ /* Write the FIFO */
+ len = g_aic_udc.in_ep[ep_idx].xfer_len - g_aic_udc.in_ep[ep_idx].actual_xfer_len;
+ if (len > g_aic_udc.in_ep[ep_idx].ep_mps) {
+ len = g_aic_udc.in_ep[ep_idx].ep_mps;
+ }
+
+ aic_ep_write(ep_idx, g_aic_udc.in_ep[ep_idx].xfer_buf, len);
+ g_aic_udc.in_ep[ep_idx].xfer_buf += len;
+ g_aic_udc.in_ep[ep_idx].actual_xfer_len += len;
+ }
+}
+#endif
+
+/**
+ * @brief aic_get_glb_intstatus: return the global USB interrupt status
+ * @retval status
+ */
+static inline uint32_t aic_get_glb_intstatus(void)
+{
+ uint32_t tmpreg;
+
+ tmpreg = AIC_UDC_REG->usbintsts;
+ tmpreg &= AIC_UDC_REG->usbintmsk;
+
+ return tmpreg;
+}
+
+/**
+ * @brief aic_get_outeps_intstatus: return the USB device OUT endpoints interrupt status
+ * @retval status
+ */
+static inline uint32_t aic_get_outeps_intstatus(void)
+{
+ uint32_t tmpreg;
+
+ tmpreg = AIC_UDC_REG->usbepint;
+ tmpreg &= AIC_UDC_REG->usbepintmsk;
+
+ return ((tmpreg & 0xffff0000U) >> 16);
+}
+
+/**
+ * @brief aic_get_ineps_intstatus: return the USB device IN endpoints interrupt status
+ * @retval status
+ */
+static inline uint32_t aic_get_ineps_intstatus(void)
+{
+ uint32_t tmpreg;
+
+ tmpreg = AIC_UDC_REG->usbepint;
+ tmpreg &= AIC_UDC_REG->usbepintmsk;
+
+ return ((tmpreg & 0xFFFFU));
+}
+
+/**
+ * @brief Returns Device OUT EP Interrupt register
+ * @param epnum endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device OUT EP Interrupt register
+ */
+static inline uint32_t aic_get_outep_intstatus(uint8_t epnum)
+{
+ uint32_t tmpreg;
+
+ tmpreg = AIC_UDC_REG->outepint[epnum];
+ tmpreg &= AIC_UDC_REG->outepintmsk;
+
+ return tmpreg;
+}
+
+/**
+ * @brief Returns Device IN EP Interrupt register
+ * @param epnum endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device IN EP Interrupt register
+ */
+static inline uint32_t aic_get_inep_intstatus(uint8_t epnum)
+{
+ uint32_t tmpreg;
+
+ tmpreg = AIC_UDC_REG->inepint[epnum];
+ tmpreg &= AIC_UDC_REG->inepintmsk;
+
+ return tmpreg;
+}
+
+__WEAK void usb_dc_low_level_init(void)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(void)
+{
+}
+
+int usb_dc_rst(void)
+{
+ for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
+ if (i == 0U) {
+ AIC_UDC_REG->inepcfg[i] = DEPCTL_SNAK;
+ AIC_UDC_REG->outepcfg[i] = DEPCTL_SNAK;
+ } else {
+ usbd_ep_close(i);
+ usbd_ep_close(i | 0x80);
+ }
+ AIC_UDC_REG->ineptsfsiz[i] = 0U;
+ AIC_UDC_REG->inepint[i] = 0xFBFFU;
+ AIC_UDC_REG->outeptsfsiz[i] = 0U;
+ AIC_UDC_REG->outepint[i] = 0xFBFFU;
+ }
+
+ AIC_UDC_REG->usbepintmsk |= 0x10001U;
+ AIC_UDC_REG->outepintmsk = CTRL_OUT_EP_SETUP_PHASE_DONE | TRANSFER_DONE;
+ AIC_UDC_REG->inepintmsk = TRANSFER_DONE;
+#ifndef CONFIG_USB_AIC_DMA_ENABLE
+ AIC_UDC_REG->inepintmsk |= INTKN_TXFEMP;
+#endif
+
+ aic_flush_txfifo(0x10U);
+ aic_flush_rxfifo();
+
+ aic_set_dma_nextep();
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
+ aic_udc_obuf_free(&g_aic_udc.out_ep[i]);
+ aic_udc_ibuf_free(&g_aic_udc.in_ep[i]);
+ }
+#endif
+
+ memset(&g_aic_udc, 0, sizeof(struct aic_udc));
+ usbd_event_reset_handler(0);
+ /* Start reading setup */
+ aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
+
+ return 0;
+}
+
+int usb_dc_init(uint8_t busid)
+{
+ int ret;
+ uint32_t base = 0;
+
+ memset(&g_aic_udc, 0, sizeof(struct aic_udc));
+
+ usb_dc_low_level_init();
+
+ /* Disconnect */
+ AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SFTDISCON;
+ /* Disable Interrupt */
+ AIC_UDC_REG->usbdevinit &= ~USBDEVINIT_GLBL_INTR_EN;
+
+ ret = aic_core_init();
+
+ for (uint8_t i = 0U; i < 2U; i++) {
+ AIC_UDC_REG->txfifosiz[i] = 0U;
+ }
+
+ /* Device mode configuration */
+ AIC_UDC_REG->usbdevconf |= PERIOD_FRAME_INTERVAL_80;
+
+#if defined(CONFIG_USB_HS)
+ /* Set Core speed to High speed mode */
+ AIC_UDC_REG->usbdevconf |= DEV_SPEED_HIGH_SPEED_20;
+#else
+
+ AIC_UDC_REG->usbdevconf |= DEV_SPEED_FULL_SPEED_20;
+#endif
+
+ ret = aic_flush_txfifo(0x10U);
+ ret = aic_flush_rxfifo();
+
+ /* Clear all pending Device Interrupts */
+ AIC_UDC_REG->inepintmsk = 0U;
+ AIC_UDC_REG->outepintmsk = 0U;
+ AIC_UDC_REG->usbepintmsk = 0U;
+
+ /* Disable all interrupts. */
+ AIC_UDC_REG->usbintmsk = 0U;
+ /* Clear any pending interrupts */
+ AIC_UDC_REG->usbintsts = 0xBFFFFFFFU;
+
+ /* Enable interrupts matching to the Device mode ONLY */
+ AIC_UDC_REG->usbintmsk = INT_RESET | INT_ENUMDONE |
+ INT_OUT_EP | INT_IN_EP |
+ INT_INCOMP_ISO_IN_INT | INT_INCOMP_ISO_OUT_INT;
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ AIC_UDC_REG->usbdevinit |= (USBDEVINIT_HBSTLEN_INCR4 << USBDEVINIT_HBSTLEN_SHIFT);
+ AIC_UDC_REG->usbdevinit |= USBDEVINIT_DMA_EN;
+#else
+ AIC_UDC_REG->usbintmsk |= INT_RX_FIFO_NOT_EMPTY;
+#endif
+
+ /* Assign FIFO */
+ base = 0;
+ AIC_UDC_REG->rxfifosiz = AIC_RX_FIFO_SIZE;
+ base += AIC_RX_FIFO_SIZE;
+ AIC_UDC_REG->nptxfifosiz = (AIC_NP_TX_FIFO_SIZE << 16) | base;
+ base += AIC_NP_TX_FIFO_SIZE;
+ AIC_UDC_REG->txfifosiz[0] = (AIC_PERIOD_TX_FIFO1_SIZE << 16) | base;
+ base += AIC_PERIOD_TX_FIFO1_SIZE;
+ AIC_UDC_REG->txfifosiz[1] = (AIC_PERIOD_TX_FIFO2_SIZE << 16) | base;
+
+ usb_dc_rst();
+
+ /* Enable Interrupt */
+ AIC_UDC_REG->usbdevinit |= USBDEVINIT_GLBL_INTR_EN;
+ /* Connect */
+ AIC_UDC_REG->usbdevfunc &= ~USBDEVFUNC_SFTDISCON;
+
+ return ret;
+}
+
+int usb_dc_deinit(uint8_t busid)
+{
+ /* Clear Pending interrupt */
+ for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
+ AIC_UDC_REG->outepint[i] = 0xFB7FU;
+ AIC_UDC_REG->inepint[i] = 0xFB7FU;
+ }
+
+ /* Clear interrupt masks */
+ AIC_UDC_REG->inepintmsk = 0U;
+ AIC_UDC_REG->outepintmsk = 0U;
+ AIC_UDC_REG->usbepintmsk = 0U;
+
+ /* Flush the FIFO */
+ aic_flush_txfifo(0x10U);
+ aic_flush_rxfifo();
+
+ AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SFTDISCON;
+
+ usb_dc_low_level_deinit();
+ return 0;
+}
+
+int usbd_set_address(uint8_t busid, const uint8_t addr)
+{
+ AIC_UDC_REG->usbdevconf &= ~(DEVICE_ADDRESS_MASK);
+ AIC_UDC_REG->usbdevconf |= ((uint32_t)addr << 4) & DEVICE_ADDRESS_MASK;
+
+ rst_allow = 1;
+ return 0;
+}
+
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ return -1;
+}
+
+uint8_t usbd_get_port_speed(uint8_t busid)
+{
+ uint8_t speed;
+ uint32_t DevEnumSpeed = AIC_UDC_REG->usblinests & USB_ENUM_SPEED_MASK;
+
+ if (DevEnumSpeed == USB_HIGH_30_60MHZ) {
+ speed = USB_SPEED_HIGH;
+ } else if (DevEnumSpeed == USB_FULL_30_60MHZ) {
+ speed = USB_SPEED_FULL;
+ } else {
+ speed = USB_SPEED_FULL;
+ }
+
+ return speed;
+}
+
+int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
+ uint16_t ep_mps;
+ uint8_t tx_fifo_num = 0;
+ uint32_t i;
+
+ if (ep_idx > (USB_NUM_BIDIR_ENDPOINTS - 1)) {
+ USB_LOG_ERR("Ep addr %d overflow\r\n", ep->bEndpointAddress);
+ return -1;
+ }
+
+ if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
+ g_aic_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_aic_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+
+ AIC_UDC_REG->usbepintmsk |= DAINT_OUT_MASK & (uint32_t)(1UL << (16 + ep_idx));
+
+ ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ if (ep_idx == 0) {
+ switch (ep_mps) {
+ case 8:
+ ep_mps = DEPCTL0_MPS_8;
+ break;
+ case 16:
+ ep_mps = DEPCTL0_MPS_16;
+ break;
+ case 32:
+ ep_mps = DEPCTL0_MPS_32;
+ break;
+ case 64:
+ ep_mps = DEPCTL0_MPS_64;
+ break;
+ }
+ }
+
+ AIC_UDC_REG->outepcfg[ep_idx] |= (ep_mps & DEPCTL_MPS_MASK) |
+ ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) |
+ DEPCTL_SETD0PID |
+ DEPCTL_USBACTEP;
+ } else {
+ g_aic_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_aic_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+
+ AIC_UDC_REG->usbepintmsk |= DAINT_IN_MASK & (uint32_t)(1UL << ep_idx);
+
+ /* Period IN EP alloc fifo num */
+ if (( USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) ||
+ ( USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS)) {
+ for (i=1; i<=2; i++) {
+ if (g_aic_udc.tx_fifo_map & (1<inepcfg[ep_idx] |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & DEPCTL_MPS_MASK) |
+ ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) |
+ (tx_fifo_num << 22) |
+ DEPCTL_SETD0PID |
+ DEPCTL_USBACTEP;
+ }
+ return 0;
+}
+
+int usbd_ep_close(uint8_t busid, const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint8_t tx_fifo_num = 0;
+ int i = 0;
+ #define DIS_EP_TIMOUT 100
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ if (AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_EPENA) {
+ /* (1) Wait for global nak to take effect */
+ if (!(AIC_UDC_REG->usbintsts & INT_GOUTNAKEFF))
+ AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SGOUTNAK;
+
+ for (i = 0; i < DIS_EP_TIMOUT; i++) {
+ if (AIC_UDC_REG->usbintsts & INT_GOUTNAKEFF)
+ break;
+ aic_udelay(1);
+ }
+
+ if (i == DIS_EP_TIMOUT)
+ USB_LOG_ERR("%s: timeout USBINTSTS.GOUTNAKEFF\n", __func__);
+
+ /* (2) Disable ep */
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SNAK;
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_EPDIS;
+
+ for (i = 0; i < DIS_EP_TIMOUT; i++) {
+ if (AIC_UDC_REG->outepint[ep_idx] & EPDISBLD)
+ break;
+ aic_udelay(1);
+ }
+
+ if (i == DIS_EP_TIMOUT)
+ USB_LOG_ERR("%s: timeout OUTEPCFG.EPDisable\n", __func__);
+
+ /* Clear EPDISBLD interrupt */
+ AIC_UDC_REG->outepint[ep_idx] |= EPDISBLD;
+
+ /* (3) Remove global NAKs */
+ AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_CGOUTNAK;
+ }
+
+ AIC_UDC_REG->usbepintmsk &= ~(DAINT_OUT_MASK & (uint32_t)(1UL << (16 + ep_idx)));
+ AIC_UDC_REG->outepcfg[ep_idx] = 0;
+ } else {
+ tx_fifo_num = (AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_TXFIFONUM_MASK) >> DEPCTL_TXFIFONUM_SHIFT;
+
+ if (AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_EPENA) {
+ if (tx_fifo_num) {
+ /* (1) Wait for Nak effect */
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SNAK;
+
+ for (i = 0; i < DIS_EP_TIMOUT; i++) {
+ if (AIC_UDC_REG->inepint[ep_idx] & INEP_NAKEFF)
+ break;
+ aic_udelay(1);
+ }
+
+ if (i == DIS_EP_TIMOUT)
+ USB_LOG_ERR("%s: timeout INEPINT.NAKEFF\n", __func__);
+ } else {
+ /* (1) Wait for Nak effect */
+ AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SGNPINNAK;
+
+ for (i = 0; i < DIS_EP_TIMOUT; i++) {
+ if (AIC_UDC_REG->usbintsts & INT_GINNAKEFF)
+ break;
+ aic_udelay(1);
+ }
+
+ if (i == DIS_EP_TIMOUT)
+ USB_LOG_ERR("%s: timeout USBINTSTS.GOUTNAKEFF\n", __func__);
+ }
+
+ /* (2) Disable ep */
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SNAK;
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_EPDIS;
+
+ for (i = 0; i < DIS_EP_TIMOUT; i++) {
+ if (AIC_UDC_REG->inepint[ep_idx] & EPDISBLD)
+ break;
+ aic_udelay(1);
+ }
+
+ if (i == DIS_EP_TIMOUT)
+ USB_LOG_ERR("%s: timeout OUTEPCFG.EPDisable\n", __func__);
+
+ /* Clear EPDISBLD interrupt */
+ AIC_UDC_REG->inepint[ep_idx] |= EPDISBLD;
+
+ /* (3) Clear Global In NP NAK in Shared FIFO for non periodic ep */
+ if (!tx_fifo_num)
+ AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_CGNPINNAK;
+ }
+
+ AIC_UDC_REG->usbepintmsk &= ~(DAINT_OUT_MASK & (uint32_t)(1UL << ep_idx));
+ AIC_UDC_REG->inepcfg[ep_idx] = 0;
+
+ /* Flush TX FIFO */
+ aic_flush_txfifo(tx_fifo_num);
+
+ /* Period IN EP free fifo num */
+ if (tx_fifo_num > 0)
+ g_aic_udc.tx_fifo_map &= ~(1<outepcfg[ep_idx] & DEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
+ AIC_UDC_REG->outepcfg[ep_idx] &= ~(DEPCTL_EPDIS);
+ }
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_STALL;
+ } else {
+ if (((AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
+ AIC_UDC_REG->inepcfg[ep_idx] &= ~(DEPCTL_EPDIS);
+ }
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_STALL;
+ }
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ if (ep_idx == 0) {
+ aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
+ }
+#endif
+ return 0;
+}
+
+int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_STALL;
+ if ((g_aic_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
+ (g_aic_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD0PID; /* DATA0 */
+ }
+ } else {
+ AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_STALL;
+ if ((g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
+ (g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD0PID; /* DATA0 */
+ }
+ }
+
+ return 0;
+}
+
+int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
+{
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ } else {
+ }
+ return 0;
+}
+
+int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint32_t pktcnt = 0;
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_EPENA) {
+ return -2;
+ }
+ if (ep_idx && !(AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_MPS_MASK)) {
+ return -3;
+ }
+ if ((uint32_t)(uintptr_t)data & 0x03) {
+ return -4;
+ }
+
+ g_aic_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_aic_udc.in_ep[ep_idx].xfer_len = data_len;
+ g_aic_udc.in_ep[ep_idx].actual_xfer_len = 0;
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ if ((ep_idx != 0) && (data_len > 0) &&
+ ((((uint32_t)(uintptr_t)data % CACHE_LINE_SIZE) != 0) ||
+ (((uint32_t)(uintptr_t)(data + data_len) % CACHE_LINE_SIZE) != 0))) {
+
+ if (g_aic_udc.in_ep[ep_idx].xfer_align_len != data_len) {
+ int ret = 0;
+
+ aic_udc_ibuf_free(&g_aic_udc.in_ep[ep_idx]);
+ ret = aic_udc_ibuf_alloc(&g_aic_udc.in_ep[ep_idx], data_len);
+ if (ret)
+ return ret;
+ }
+ memcpy(g_aic_udc.in_ep[ep_idx].xfer_align_buf, data, data_len);
+ data = g_aic_udc.in_ep[ep_idx].xfer_align_buf;
+ } else {
+ aic_udc_ibuf_free(&g_aic_udc.in_ep[ep_idx]);
+ }
+
+ if (data_len>0)
+ aic_udc_dcache_clean((uintptr_t)data, ALIGN_UP(data_len, CACHE_LINE_SIZE));
+#endif
+
+ AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_PKT_CNT_MASK);
+ AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_XFER_SIZE_MASK);
+ AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_MULCNT_MASK);
+
+ if (data_len == 0) {
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
+ AIC_UDC_REG->inepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
+ return 0;
+ }
+
+ if (ep_idx == 0) {
+ if (data_len > g_aic_udc.in_ep[ep_idx].ep_mps) {
+ data_len = g_aic_udc.in_ep[ep_idx].ep_mps;
+ }
+ g_aic_udc.in_ep[ep_idx].xfer_len = data_len;
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
+ } else {
+ pktcnt = (uint16_t)((data_len + g_aic_udc.in_ep[ep_idx].ep_mps - 1U) / g_aic_udc.in_ep[ep_idx].ep_mps);
+
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (pktcnt << 19));
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
+ }
+
+ if ((g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) ||
+ (g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT)) {
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (1<usblinests & (1U << 8)) == 0U) {
+ AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD1PID;
+ } else {
+ AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD0PID;
+ }
+ AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_MULCNT_MASK);
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (1U << DXEPTSIZ_MULCNT_SHIFT);
+ } else if (g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
+ AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_MULCNT_MASK);
+ AIC_UDC_REG->ineptsfsiz[ep_idx] |= (1U << DXEPTSIZ_MULCNT_SHIFT);
+ }
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ AIC_UDC_REG->inepdmaaddr[ep_idx] = (uint32_t)(uintptr_t)data;
+#endif
+
+ AIC_UDC_REG->inepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
+
+ return 0;
+}
+
+int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint32_t pktcnt = 0;
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_EPENA) {
+ return -2;
+ }
+ if (ep_idx && !(AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_MPS_MASK)) {
+ return -3;
+ }
+ if (((uint32_t)(uintptr_t)data) & 0x03) {
+ return -4;
+ }
+
+ g_aic_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_aic_udc.out_ep[ep_idx].xfer_len = data_len;
+ g_aic_udc.out_ep[ep_idx].actual_xfer_len = 0;
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ if ((ep_idx != 0) && (data_len > 0) &&
+ ((((uint32_t)(uintptr_t)data % CACHE_LINE_SIZE) != 0) ||
+ (((uint32_t)(uintptr_t)(data + data_len) % CACHE_LINE_SIZE) != 0))) {
+
+ if (g_aic_udc.out_ep[ep_idx].xfer_align_len != data_len) {
+ int ret = 0;
+
+ aic_udc_obuf_free(&g_aic_udc.out_ep[ep_idx]);
+ ret = aic_udc_obuf_alloc(&g_aic_udc.out_ep[ep_idx], data_len);
+ if (ret)
+ return ret;
+ }
+ data = g_aic_udc.out_ep[ep_idx].xfer_align_buf;
+ } else {
+ aic_udc_obuf_free(&g_aic_udc.out_ep[ep_idx]);
+ }
+
+ if (data_len > 0)
+ aic_udc_dcache_invalidate((uintptr_t)data, ALIGN_UP(data_len, CACHE_LINE_SIZE));
+#endif
+
+ AIC_UDC_REG->outeptsfsiz[ep_idx] &= ~(DXEPTSIZ_PKT_CNT_MASK);
+ AIC_UDC_REG->outeptsfsiz[ep_idx] &= ~(DXEPTSIZ_XFER_SIZE_MASK);
+ if (data_len == 0) {
+ AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1 << 19));
+ AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & g_aic_udc.out_ep[ep_idx].ep_mps);
+ AIC_UDC_REG->outepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
+ return 0;
+ }
+
+ if (ep_idx == 0) {
+ if (data_len > g_aic_udc.out_ep[ep_idx].ep_mps) {
+ data_len = g_aic_udc.out_ep[ep_idx].ep_mps;
+ }
+ g_aic_udc.out_ep[ep_idx].xfer_len = data_len;
+ AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
+ AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
+ } else {
+ pktcnt = (uint16_t)((data_len + g_aic_udc.out_ep[ep_idx].ep_mps - 1U) / g_aic_udc.out_ep[ep_idx].ep_mps);
+
+ AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (pktcnt << 19));
+ AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
+ }
+
+#ifdef CONFIG_USB_AIC_DMA_ENABLE
+ AIC_UDC_REG->outepdmaaddr[ep_idx] = (uint32_t)(uintptr_t)data;
+#endif
+ if (g_aic_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ if ((AIC_UDC_REG->usblinests & (1U << 8)) == 0U) {
+ AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD1PID;
+ } else {
+ AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD0PID;
+ }
+ }
+ AIC_UDC_REG->outepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
+ return 0;
+}
+
+void USBD_IRQHandler(void)
+{
+ uint32_t gint_status, ep_idx, ep_intr, epint, daintmask;
+ gint_status = aic_get_glb_intstatus();
+
+ /* Avoid spurious interrupt */
+ if (gint_status == 0) {
+ return;
+ }
+
+#ifndef CONFIG_USB_AIC_DMA_ENABLE
+ uint32_t temp;
+ uint32_t read_count;
+
+ /* Handle RxQLevel Interrupt */
+ if (gint_status & INT_RX_FIFO_NOT_EMPTY) {
+ AIC_UDC_REG->usbintmsk &= ~(INT_RX_FIFO_NOT_EMPTY);
+
+ temp = AIC_UDC_REG->rxfifosts_pop;
+ ep_idx = temp & RXFIFOSTS_EPNUM_MASK;
+
+ if ((temp & RXFIFOSTS_PKTSTS_MASK) == PKTSTS_OUT_DATA_PKT_REC) {
+ read_count = (temp & RXFIFOSTS_BCNT_MASK) >> 4;
+ if (read_count != 0) {
+ aic_ep_read(g_aic_udc.out_ep[ep_idx].xfer_buf, read_count);
+ g_aic_udc.out_ep[ep_idx].xfer_buf += read_count;
+ }
+ } else if ((temp & RXFIFOSTS_PKTSTS_MASK) == PKTSTS_SETUP_DATA_PKT_REC) {
+ read_count = (temp & RXFIFOSTS_BCNT_MASK) >> 4;
+ aic_ep_read((uint8_t *)&g_aic_udc.setup, read_count);
+ } else {
+ /* ... */
+ }
+ AIC_UDC_REG->usbintmsk |= INT_RX_FIFO_NOT_EMPTY;
+ }
+#endif
+ if (gint_status & INT_OUT_EP) {
+ ep_idx = 0;
+ ep_intr = aic_get_outeps_intstatus();
+ while (ep_intr != 0U) {
+ if ((ep_intr & 0x1U) != 0U) {
+ epint = aic_get_outep_intstatus(ep_idx);
+ uint32_t DoepintReg = AIC_UDC_REG->outepint[ep_idx];
+ AIC_UDC_REG->outepint[ep_idx] = DoepintReg;
+
+ struct aic_ep_state *ep = &g_aic_udc.out_ep[ep_idx];
+ if ((epint & TRANSFER_DONE) == TRANSFER_DONE) {
+ #ifdef CONFIG_USB_AIC_DMA_ENABLE
+ if (ep->xfer_align_buf)
+ memcpy(ep->xfer_buf, ep->xfer_align_buf, ep->xfer_len);
+ #endif
+ if ((ep_idx == 0)) {
+ if (ep0_ctrl_stage == 1) {
+ ep0_ctrl_stage = 2;
+ usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_aic_udc.setup);
+ } else {
+ if (ep->xfer_len == 0) {
+ /* Out status, start reading setup */
+ aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
+ } else {
+ ep->actual_xfer_len = ep->xfer_len - ((AIC_UDC_REG->outeptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
+ ep->xfer_len = 0;
+ usbd_event_ep_out_complete_handler(0, 0x00, ep->actual_xfer_len);
+ }
+ }
+ } else {
+ ep->actual_xfer_len = ep->xfer_len - ((AIC_UDC_REG->outeptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
+ ep->xfer_len = 0;
+ usbd_event_ep_out_complete_handler(0, ep_idx, ep->actual_xfer_len);
+ }
+ }
+
+ if ((epint & CTRL_OUT_EP_SETUP_PHASE_DONE) == CTRL_OUT_EP_SETUP_PHASE_DONE) {
+ if (ep0_ctrl_stage == 1) {
+ ep0_ctrl_stage = 2;
+ usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_aic_udc.setup);
+ }
+ }
+ }
+ ep_intr >>= 1U;
+ ep_idx++;
+ }
+ }
+
+#ifndef CONFIG_USB_AIC_DMA_ENABLE
+ if (gint_status & INT_NP_TX_FIFO_EMPTY) {
+ AIC_UDC_REG->usbintmsk &= ~(INT_NP_TX_FIFO_EMPTY);
+ aic_tx_fifo_empty_procecss(0);
+ }
+#endif
+
+ if (gint_status & INT_IN_EP) {
+ ep_idx = 0U;
+ ep_intr = aic_get_ineps_intstatus();
+ while (ep_intr != 0U) {
+ if ((ep_intr & 0x1U) != 0U) {
+ epint = aic_get_inep_intstatus(ep_idx);
+ uint32_t DiepintReg = AIC_UDC_REG->inepint[ep_idx];
+ AIC_UDC_REG->inepint[ep_idx] = DiepintReg;
+
+ if ((epint & TRANSFER_DONE) == TRANSFER_DONE) {
+ if (ep_idx == 0) {
+ g_aic_udc.in_ep[ep_idx].actual_xfer_len = g_aic_udc.in_ep[ep_idx].xfer_len - ((AIC_UDC_REG->ineptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
+ g_aic_udc.in_ep[ep_idx].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(0, 0x80, g_aic_udc.in_ep[ep_idx].actual_xfer_len);
+
+ if (g_aic_udc.setup.wLength && ((g_aic_udc.setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
+ /* In status, start reading setup */
+ aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
+ } else if (g_aic_udc.setup.wLength == 0) {
+ /* In status, start reading setup */
+ aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
+ }
+ } else {
+ g_aic_udc.in_ep[ep_idx].actual_xfer_len = g_aic_udc.in_ep[ep_idx].xfer_len - ((AIC_UDC_REG->ineptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
+ g_aic_udc.in_ep[ep_idx].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_aic_udc.in_ep[ep_idx].actual_xfer_len);
+ }
+ }
+
+ #ifndef CONFIG_USB_AIC_DMA_ENABLE
+ if ((epint & INTKN_TXFEMP) == INTKN_TXFEMP) {
+ aic_tx_fifo_empty_procecss(ep_idx);
+ }
+ #endif
+ }
+ ep_intr >>= 1U;
+ ep_idx++;
+ }
+ }
+ if (gint_status & INT_RESET) {
+ AIC_UDC_REG->usbintsts |= INT_RESET;
+ AIC_UDC_REG->usbdevfunc &= ~USBDEVFUNC_RMTWKUPSIG;
+
+ usb_dc_rst();
+ }
+
+ if (gint_status & INT_ENUMDONE) {
+ AIC_UDC_REG->usbintsts |= INT_ENUMDONE;
+ aic_set_turnaroundtime(usbd_clk, aic_get_devspeed());
+
+ AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_CGNPINNAK;
+ }
+ if (gint_status & INT_INCOMP_ISO_OUT_INT) {
+ daintmask = AIC_UDC_REG->usbepintmsk;
+ daintmask >>= 16;
+
+ for (ep_idx = 1; ep_idx < USB_NUM_BIDIR_ENDPOINTS; ep_idx++) {
+ if ((BIT(ep_idx) & ~daintmask) || (g_aic_udc.out_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
+ continue;
+ if (!(AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_USBACTEP))
+ continue;
+
+ if ((AIC_UDC_REG->usblinests & (1U << 8)) != 0U) {
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD0PID;
+ AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
+ } else {
+ AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
+ AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD1PID;
+ }
+ }
+
+ AIC_UDC_REG->usbintsts |= INT_INCOMP_ISO_OUT_INT;
+ }
+
+ if (gint_status & INT_INCOMP_ISO_IN_INT) {
+ daintmask = AIC_UDC_REG->usbepintmsk;
+ daintmask >>= 16;
+
+ for (ep_idx = 1; ep_idx < USB_NUM_BIDIR_ENDPOINTS; ep_idx++) {
+ if (((BIT(ep_idx) & ~daintmask)) || (g_aic_udc.in_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
+ continue;
+
+ if (!(AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_USBACTEP))
+ continue;
+
+ if ((AIC_UDC_REG->usblinests & (1U << 8)) != 0U) {
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD0PID;
+ AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
+ } else {
+ AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
+ AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD1PID;
+ }
+ }
+ AIC_UDC_REG->usbintsts |= INT_INCOMP_ISO_IN_INT;
+ }
+
+ if (gint_status & INT_SOF) {
+ AIC_UDC_REG->usbintsts |= INT_SOF;
+ }
+ if (gint_status & INT_SUSPEND) {
+ AIC_UDC_REG->usbintsts |= INT_SUSPEND;
+ }
+ if (gint_status & INT_RESUME) {
+ AIC_UDC_REG->usbintsts |= INT_RESUME;
+ }
+}
diff --git a/components/drivers/usb/cherryusb/port/aic/usb_dc_aic_ll.c b/components/drivers/usb/cherryusb/port/aic/usb_dc_aic_ll.c
new file mode 100644
index 0000000000..d2db1b5d66
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/aic/usb_dc_aic_ll.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, Artinchip Technology Co., Ltd
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include
+#include
+#include
+#include "usbd_core.h"
+#include "usb_dc_aic_reg.h"
+
+extern irqreturn_t USBD_IRQHandler(int irq, void * data);
+
+uint32_t usbd_clk;
+
+void usb_dc_low_level_init(void)
+{
+ /* set usb0 phy switch: Host/Device */
+#ifdef AIC_USING_USB0_DEVICE
+ syscfg_usb_phy0_sw_host(0);
+#endif
+ /* set pin-mux */
+
+ /* enable clock */
+ hal_clk_enable(CONFIG_USB_AIC_DC_PHY_CLK);
+ hal_clk_enable(CONFIG_USB_AIC_DC_CLK);
+ aicos_udelay(300);
+ hal_reset_assert(CONFIG_USB_AIC_DC_PHY_RESET);
+ hal_reset_assert(CONFIG_USB_AIC_DC_RESET);
+ aicos_udelay(300);
+ hal_reset_deassert(CONFIG_USB_AIC_DC_PHY_RESET);
+ hal_reset_deassert(CONFIG_USB_AIC_DC_RESET);
+ aicos_udelay(300);
+
+ usbd_clk = hal_clk_get_freq(CONFIG_USB_AIC_DC_CLK);
+
+ /* register interrupt callback */
+ aicos_request_irq(CONFIG_USB_AIC_DC_IRQ_NUM, USBD_IRQHandler,
+ 0, "usb_device", NULL);
+ aicos_irq_enable(CONFIG_USB_AIC_DC_IRQ_NUM);
+}
+
diff --git a/components/drivers/usb/cherryusb/port/aic/usb_dc_aic_reg.h b/components/drivers/usb/cherryusb/port/aic/usb_dc_aic_reg.h
new file mode 100644
index 0000000000..80e6997ac9
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/aic/usb_dc_aic_reg.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2022, Artinchip Technology Co., Ltd
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __USB_DC_AIC_REG_H__
+#define __USB_DC_AIC_REG_H__
+
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+typedef struct {
+ __IO uint32_t ahbbasic; /* 0x0000: AHBBASIC */
+ __IO uint32_t usbdevinit; /* 0x0004: USBDEVINIT */
+ __IO uint32_t usbphyif; /* 0x0008: USBPHYIF */
+ __IO uint32_t usbulpiphy; /* 0x000C: USBULPIPHY */
+ __IO uint32_t usbintsts; /* 0x0010: USBINTSTS */
+ __IO uint32_t usbintmsk; /* 0x0014: USBINTMSK */
+ __IO uint32_t rxfifosiz; /* 0x0018: RXFIFOSIZ */
+ __IO uint32_t rxfifosts_pop; /* 0x001C: RXFIFOSTS pop */
+ __IO uint32_t nptxfifosiz; /* 0x0020: NPTXFIFOSIZ */
+ __IO uint32_t nptxfifosts; /* 0x0024: NPTXFIFOSTS */
+ __IO uint32_t txfifosiz[2]; /* 0x0028 - 0x002C: TXFIFOSIZ() */
+ __IO uint32_t rxfifosts_dbg; /* 0x0030: RXFIFOSTS_DBG */
+ uint8_t res0[0x1cc];
+ __IO uint32_t usbdevconf; /* 0x0200: USBDEVCONF */
+ __IO uint32_t usbdevfunc; /* 0x0204: USBDEVFUNC */
+ __IO uint32_t usblinests; /* 0x0208: USBLINESTS */
+ __IO uint32_t inepintmsk; /* 0x020C: INEPINTMSK */
+ __IO uint32_t outepintmsk; /* 0x0210: OUTEPINTMSK */
+ __IO uint32_t usbepint; /* 0x0214: USBEPINT */
+ __IO uint32_t usbepintmsk; /* 0x0218: USBEPINTMSK */
+ uint8_t res1[4];
+ __IO uint32_t inepcfg[5]; /* 0x0220 - 0x0230: INEPCFG() */
+ uint8_t res2[0xc];
+ __IO uint32_t outepcfg[5]; /* 0x0240 - 0x0250: OUTEPCFG() */
+ uint8_t res3[0xc];
+ __IO uint32_t inepint[5]; /* 0x0260 - 0x0270: INEPINT() */
+ uint8_t res4[0xc];
+ __IO uint32_t outepint[5]; /* 0x0280 - 0x0290: OUTEPINT() */
+ uint8_t res5[0xc];
+ __IO uint32_t ineptsfsiz[5]; /* 0x02A0 - 0x02B0: INEPTSFSIZ() */
+ uint8_t res6[0xc];
+ __IO uint32_t outeptsfsiz[5]; /* 0x02C0 - 0x02D0: OUTEPTSFSIZ() */
+ uint8_t res7[0x2c];
+ __IO uint32_t inepdmaaddr[5]; /* 0x0300 - 0x0310: INEPDMAADDR() */
+ uint8_t res8[0xc];
+ __IO uint32_t outepdmaaddr[5]; /* 0x0320 - 0x0330: OUTEPDMAADDR() */
+ uint8_t res9[0xc];
+ __IO uint32_t ineptxsts[5]; /* 0x0340 - 0x0350: INEPTXSTS() */
+ uint8_t res10[0xc];
+ __IO uint32_t dtknqr1; /* 0x0360: DTKNQR1 */
+ __IO uint32_t dtknqr2; /* 0x0364: DTKNQR2 */
+ __IO uint32_t dtknqr3; /* 0x0368: DTKNQR3 */
+ __IO uint32_t dtknqr4; /* 0x036C: DTKNQR4 */
+}AIC_UDC_RegDef;
+
+/*===================================================================== */
+/*definitions related to CSR setting */
+
+/* AHBBASIC */
+#define AHBBASIC_NOTI_ALL_DMA_WRIT (1 << 8)
+#define AHBBASIC_REM_MEM_SUPP (1 << 7)
+#define AHBBASIC_INV_DESC_ENDIANNESS (1 << 6)
+#define AHBBASIC_AHB_SINGLE (1 << 5)
+#define AHBBASIC_TXENDDELAY (1 << 3)
+#define AHBBASIC_AHBIDLE (1 << 2)
+#define AHBBASIC_DMAREQ (1 << 1)
+
+/* USBDEVINIT */
+#define USBDEVINIT_HBSTLEN_MASK (0xf << 12)
+#define USBDEVINIT_HBSTLEN_SHIFT 12
+#define USBDEVINIT_HBSTLEN_SINGLE 0
+#define USBDEVINIT_HBSTLEN_INCR 1
+#define USBDEVINIT_HBSTLEN_INCR4 3
+#define USBDEVINIT_HBSTLEN_INCR8 5
+#define USBDEVINIT_HBSTLEN_INCR16 7
+#define USBDEVINIT_DMA_EN (1 << 11)
+#define USBDEVINIT_NP_TXF_EMP_LVL (1 << 10)
+#define USBDEVINIT_GLBL_INTR_EN (1 << 9)
+#define USBDEVINIT_CTRL_MASK (USBDEVINIT_NP_TXF_EMP_LVL | \
+ USBDEVINIT_DMA_EN | \
+ USBDEVINIT_GLBL_INTR_EN)
+#define USBDEVINIT_IN_TKNQ_FLSH (1 << 8)
+#define USBDEVINIT_TXFNUM_MASK (0x1f << 3)
+#define USBDEVINIT_TXFNUM_SHIFT 3
+#define USBDEVINIT_TXFNUM_LIMIT 0x1f
+#define USBDEVINIT_TXFNUM(_x) ((_x) << 3)
+#define USBDEVINIT_TXFFLSH (1 << 2)
+#define USBDEVINIT_RXFFLSH (1 << 1)
+#define USBDEVINIT_CSFTRST (1 << 0)
+
+/* USBPHYIF */
+#define USBPHYIF_ULPI_CLK_SUSP_M (1 << 19)
+#define USBPHYIF_ULPI_AUTO_RES (1 << 18)
+#define USBPHYIF_PHY_LP_CLK_SEL (1 << 15)
+#define USBPHYIF_USBTRDTIM_MASK (0xf << 10)
+#define USBPHYIF_USBTRDTIM_SHIFT 10
+#ifndef USBPHYIF_HS_TRDT_VALUE
+#define USBPHYIF_HS_TRDT_VALUE 9U
+#endif /* USBD_HS_TRDT_VALUE */
+#ifndef USBPHYIF_FS_TRDT_VALUE
+#define USBPHYIF_FS_TRDT_VALUE 5U
+#define USBPHYIF_DEFAULT_TRDT_VALUE 9U
+#endif /* USBD_HS_TRDT_VALUE */
+#define USBPHYIF_DDRSEL (1 << 7)
+#define USBPHYIF_ULPI_UTMI_SEL (1 << 4)
+#define USBPHYIF_PHYIF16 (1 << 3)
+#define USBPHYIF_PHYIF8 (0 << 3)
+#define USBPHYIF_TOUTCAL_MASK (0x7 << 0)
+#define USBPHYIF_TOUTCAL_SHIFT 0
+#define USBPHYIF_TOUTCAL_LIMIT 0x7
+#define USBPHYIF_TOUTCAL(_x) ((_x) << 0)
+
+/* USBINTSTS/USBINTMSK interrupt register */
+#define INT_RESUME (1u << 31)
+#define INT_INCOMP_ISO_OUT_INT (0x1 << 21)
+#define INT_INCOMP_ISO_IN_INT (0x1 << 20)
+#define INT_OUT_EP (0x1 << 19)
+#define INT_IN_EP (0x1 << 18)
+#define INT_ENUMDONE (0x1 << 13)
+#define INT_RESET (0x1 << 12)
+#define INT_SUSPEND (0x1 << 11)
+#define INT_EARLY_SUSPEND (0x1 << 10)
+#define INT_GOUTNAKEFF (0x1 << 7)
+#define INT_GINNAKEFF (0x1 << 6)
+#define INT_NP_TX_FIFO_EMPTY (0x1 << 5)
+#define INT_RX_FIFO_NOT_EMPTY (0x1 << 4)
+#define INT_SOF (0x1 << 3)
+
+#define FULL_SPEED_CONTROL_PKT_SIZE 8
+#define FULL_SPEED_BULK_PKT_SIZE 64
+
+#define HIGH_SPEED_CONTROL_PKT_SIZE 64
+#define HIGH_SPEED_BULK_PKT_SIZE 512
+
+#define RX_FIFO_SIZE (1024)
+#define NPTX_FIFO_SIZE (1024)
+#define PTX_FIFO_SIZE (384)
+
+/* fifo size configure */
+#define EPS_NUM 5
+#define PERIOD_IN_EP_NUM 2
+#define TOTAL_FIFO_SIZE 0x3f6
+#define AIC_RX_FIFO_SIZE 0x119
+#define AIC_NP_TX_FIFO_SIZE 0x100
+#define AIC_PERIOD_TX_FIFO1_SIZE 0x100
+#define AIC_PERIOD_TX_FIFO2_SIZE 0xDD
+
+#define DEPCTL_TXFNUM_0 (0x0 << 22)
+#define DEPCTL_TXFNUM_1 (0x1 << 22)
+#define DEPCTL_TXFNUM_2 (0x2 << 22)
+#define DEPCTL_TXFNUM_3 (0x3 << 22)
+#define DEPCTL_TXFNUM_4 (0x4 << 22)
+
+/* RXFIFOSTS */
+#define RXFIFOSTS_EPNUM_MASK (0xFU << 0)
+#define RXFIFOSTS_BCNT_MASK (0x7FFU << 4)
+#define RXFIFOSTS_DPID_MASK (0x3U << 15)
+#define RXFIFOSTS_PKTSTS_SHIFT (17)
+#define RXFIFOSTS_PKTSTS_MASK (0xFU << RXFIFOSTS_PKTSTS_SHIFT)
+#define PKTSTS_GLOBAL_OUT_NAK (0x1 << RXFIFOSTS_PKTSTS_SHIFT)
+#define PKTSTS_OUT_DATA_PKT_REC (0x2 << RXFIFOSTS_PKTSTS_SHIFT)
+#define PKTSTS_OUT_TRANSFER_COMP (0x3 << RXFIFOSTS_PKTSTS_SHIFT)
+#define PKTSTS_SETUP_TRANSACTION_COMP (0x4 << RXFIFOSTS_PKTSTS_SHIFT)
+#define PKTSTS_SETUP_DATA_PKT_REC (0x6 << RXFIFOSTS_PKTSTS_SHIFT)
+#define RXFIFOSTS_FN_MASK (0xFU << 21)
+
+/* USBDEVCONF */
+#define DEV_SPEED_HIGH_SPEED_20 (0x0 << 0)
+#define DEV_SPEED_FULL_SPEED_20 (0x1 << 0)
+#define DEV_SPEED_LOW_SPEED_11 (0x2 << 0)
+#define DEV_SPEED_FULL_SPEED_11 (0x3 << 0)
+#define EP_MISS_CNT(x) (x << 18)
+#define DEVICE_ADDRESS_MASK (0x7F << 4)
+#define DEVICE_ADDRESS(x) (x << 4)
+#define PERIOD_FRAME_INTERVAL_80 (0 << 11)
+#define PERIOD_FRAME_INTERVAL_85 (1 << 11)
+#define PERIOD_FRAME_INTERVAL_90 (2 << 11)
+#define PERIOD_FRAME_INTERVAL_95 (3 << 11)
+
+/* USBDEVFUNC */
+#define NORMAL_OPERATION (0x1 << 0)
+#define SOFT_DISCONNECT (0x1 << 1)
+#define USBDEVFUNC_SERVICE_INTERVAL_SUPPORTED (1 << 19)
+#define USBDEVFUNC_PWRONPRGDONE (1 << 11)
+#define USBDEVFUNC_CGOUTNAK (1 << 10)
+#define USBDEVFUNC_SGOUTNAK (1 << 9)
+#define USBDEVFUNC_CGNPINNAK (1 << 8)
+#define USBDEVFUNC_SGNPINNAK (1 << 7)
+#define USBDEVFUNC_TSTCTL_MASK (0x7 << 4)
+#define USBDEVFUNC_TSTCTL_SHIFT (4)
+#define USBDEVFUNC_GOUTNAKSTS (1 << 3)
+#define USBDEVFUNC_GNPINNAKSTS (1 << 2)
+#define USBDEVFUNC_SFTDISCON (1 << 1)
+#define USBDEVFUNC_RMTWKUPSIG (1 << 0)
+
+/* USBLINESTS: Enumeration speed */
+#define USB_ENUM_SPEED_SHIFT 1
+#define USB_ENUM_SPEED_MASK (0x3 << USB_ENUM_SPEED_SHIFT)
+#define USB_ENUM_SPEED_HIGH 0
+#define USB_ENUM_SPEED_FULL 1
+#define USB_HIGH_30_60MHZ (0x0 << USB_ENUM_SPEED_SHIFT)
+#define USB_FULL_30_60MHZ (0x1 << USB_ENUM_SPEED_SHIFT)
+#define USB_LOW_6MHZ (0x2 << USB_ENUM_SPEED_SHIFT)
+#define USB_FULL_48MHZ (0x3 << USB_ENUM_SPEED_SHIFT)
+
+/* USBEPINT endpoint interrupt register */
+#define DAINT_OUT_BIT (16)
+#define DAINT_IN_MASK (0xFFFF)
+#define DAINT_OUT_MASK (0xFFFFU << DAINT_OUT_BIT)
+
+/* INEPCFG()/OUTEPCFG()
+ * devicecontrol IN/OUT endpoint 0 control register
+ */
+#define DEPCTL_EPENA (1u << 31)
+#define DEPCTL_EPDIS (0x1 << 30)
+#define DEPCTL_SETD1PID (0x1 << 29)
+#define DEPCTL_SETD0PID (0x1 << 28)
+#define DEPCTL_SNAK (0x1 << 27)
+#define DEPCTL_CNAK (0x1 << 26)
+#define DEPCTL_TXFIFONUM_SHIFT 22
+#define DEPCTL_TXFIFONUM_MASK (0xF << 22)
+#define DEPCTL_STALL (0x1 << 21)
+#define DEPCTL_TYPE_BIT (18)
+#define DEPCTL_TYPE_MASK (0x3 << 18)
+#define DEPCTL_CTRL_TYPE (0x0 << 18)
+#define DEPCTL_ISO_TYPE (0x1 << 18)
+#define DEPCTL_BULK_TYPE (0x2 << 18)
+#define DEPCTL_INTR_TYPE (0x3 << 18)
+#define DEPCTL_USBACTEP (0x1 << 15)
+#define DEPCTL_NEXT_EP_BIT (11)
+#define DEPCTL_NEXT_EP_MASK (0xFU << DEPCTL_NEXT_EP_BIT)
+#define DEPCTL_MPS_BIT (0)
+#define DEPCTL_MPS_MASK (0x7FF)
+
+#define DEPCTL0_MPS_64 (0x0 << 0)
+#define DEPCTL0_MPS_32 (0x1 << 0)
+#define DEPCTL0_MPS_16 (0x2 << 0)
+#define DEPCTL0_MPS_8 (0x3 << 0)
+#define DEPCTL_MPS_BULK_512 (512 << 0)
+#define DEPCTL_MPS_INT_MPS_16 (16 << 0)
+
+#define DIEPCTL0_NEXT_EP_BIT (11)
+
+/* INEPINT/OUTEPINT device IN/OUT endpoint interrupt register */
+#define TXFIFO_EMP_INT (0x1 << 7)
+#define INEP_NAKEFF (0x1 << 6)
+#define BACK2BACK_SETUP_RECEIVED (0x1 << 6)
+#define INTKNEPMIS (0x1 << 5)
+#define INTKN_TXFEMP (0x1 << 4)
+#define NON_ISO_IN_EP_TIMEOUT (0x1 << 3)
+#define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1 << 3)
+#define AHB_ERROR (0x1 << 2)
+#define EPDISBLD (0x1 << 1)
+#define TRANSFER_DONE (0x1 << 0)
+
+/* Masks definitions */
+#define GINTMSK_INIT (INT_OUT_EP | INT_IN_EP | INT_RESUME | INT_ENUMDONE\
+ | INT_RESET | INT_SUSPEND)
+#define DOEPMSK_INIT (CTRL_OUT_EP_SETUP_PHASE_DONE |\
+ AHB_ERROR | TRANSFER_DONE)
+#define DIEPMSK_INIT (NON_ISO_IN_EP_TIMEOUT | AHB_ERROR | TRANSFER_DONE)
+#define GAHBCFG_INIT (USBDEVINIT_DMA_EN | USBDEVINIT_GLBL_INTR_EN\
+ | (USBDEVINIT_HBSTLEN_INCR4 <<\
+ USBDEVINIT_HBSTLEN_SHIFT))
+
+/* INEPTSFSIZ/OUTEPTSFSIZ */
+#define DXEPTSIZ_MULCNT_SHIFT 29
+#define DXEPTSIZ_MULCNT_MASK (0x3U << DXEPTSIZ_MULCNT_SHIFT)
+#define DXEPTSIZ_PKT_CNT_SHIFT 19
+#define DXEPTSIZ_PKT_CNT_MASK (0x3FFU << DXEPTSIZ_PKT_CNT_SHIFT)
+#define DXEPTSIZ_XFER_SIZE_SHIFT 0
+#define DXEPTSIZ_XFER_SIZE_MASK (0x7FFFFU << DXEPTSIZ_XFER_SIZE_SHIFT)
+
+/* Device Endpoint X Transfer Size Register INEPTSFSIZ() */
+#define DIEPT_SIZ_PKT_CNT(x) (x << 19)
+#define DIEPT_SIZ_XFER_SIZE(x) (x << 0)
+
+/* Device OUT Endpoint X Transfer Size Register OUTEPTSFSIZ() */
+#define DOEPT_SIZ_PKT_CNT(x) (x << 19)
+#define DOEPT_SIZ_XFER_SIZE(x) (x << 0)
+#define DOEPT_SIZ_XFER_SIZE_MAX_EP0 (0x7F << 0)
+#define DOEPT_SIZ_XFER_SIZE_MAX_EP (0x7FFF << 0)
+
+/* Device Endpoint-N Control Register INEPCFG()/OUTEPCFG() */
+#define DIEPCTL_TX_FIFO_NUM(x) (x << 22)
+#define DIEPCTL_TX_FIFO_NUM_MASK (~DIEPCTL_TX_FIFO_NUM(0xF))
+
+/* Device ALL Endpoints Interrupt Register (USBEPINT) */
+#define DAINT_IN_EP_INT(x) (x << 0)
+#define DAINT_OUT_EP_INT(x) (x << 16)
+
+#define AIC_EP_FIFO_BASE 0x1000UL
+#define AIC_EP_FIFO_SIZE 0x1000UL
+
+/* In EPn Txfifo Status (INEPTXSTS) */
+#define INEPTXSTS_IN_EP_TXFIFO_STS (0xFFFFU << 0)
+
+
+#endif
diff --git a/components/drivers/usb/cherryusb/port/ch32/ch585_usbhs_dc.c b/components/drivers/usb/cherryusb/port/ch32/ch585_usbhs_dc.c
new file mode 100644
index 0000000000..1ccdfe3ea3
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ch32/ch585_usbhs_dc.c
@@ -0,0 +1,525 @@
+#include "usbd_core.h"
+#include "ch585_usbhs_reg.h"
+
+/**
+ * @brief Related register macro
+ */
+#define USB_BASE 0x40009000u
+#define CH585_USBHS_DEV ((USBHSD_TypeDef *)USB_BASE)
+
+#ifndef USBD_IRQHandler
+#define USBD_IRQHandler USB2_DEVICE_IRQHandler //use actual usb irq name instead
+#endif
+
+#define R16_PIN_CONFIG (*((PUINT16V)0x4000101A))
+#define R32_PIN_CONFIG (*((PUINT32V)0x40001018)) // RW, I/O pin configuration
+#define RB_PIN_USB2_EN 0x20
+
+#define USB_SET_RX_DMA(ep_idx, addr) (*(volatile uint32_t *)((uint32_t)(&CH585_USBHS_DEV->UEP1_RX_DMA) + 4 * (ep_idx - 1)) = addr)
+#define USB_SET_TX_DMA(ep_idx, addr) (*(volatile uint32_t *)((uint32_t)(&CH585_USBHS_DEV->UEP1_TX_DMA) + 4 * (ep_idx - 1)) = addr)
+
+#define USB_SET_MAX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_MAX_LEN) + 4 * ep_idx) = len)
+#define USB_SET_TX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx) = len)
+#define USB_GET_TX_LEN(ep_idx) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx))
+#define USB_SET_TX_CTRL(ep_idx, val) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_CTRL) + 4 * ep_idx) = val)
+#define USB_GET_TX_CTRL(ep_idx) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_CTRL) + 4 * ep_idx))
+#define USB_SET_RX_CTRL(ep_idx, val) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_RX_CTRL) + 4 * ep_idx) = val)
+#define USB_GET_RX_CTRL(ep_idx) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_RX_CTRL) + 4 * ep_idx))
+#define EPn_SET_TX_NAK(ep_idx) USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_NAK)
+#define EPn_SET_TX_VALID(ep_idx) USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_ACK)
+#define EPn_SET_RX_NAK(ep_idx) USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_NAK)
+#define EPn_SET_RX_VALID(ep_idx) USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_ACK)
+#define EPn_GET_RX_LEN(ep_idx) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->USB_EP0_RX_LEN) + 4 * ep_idx))
+#define EPn_SET_TX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx) = len)
+#define EPn_CLEAR_TX_DONE(ep_idx) USB_SET_TX_CTRL(ep_idx, USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_DONE)
+#define EPn_CLEAR_RX_DONE(ep_idx) USB_SET_RX_CTRL(ep_idx, USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_DONE)
+#define EPn_SET_TX_ISO_VALID(ep_idx)
+#define EPn_SET_RX_ISO_VALID(ep_idx)
+
+/* ep nums */
+#ifndef CONFIG_USBDEV_EP_NUM
+#define CONFIG_USBDEV_EP_NUM 8
+#endif
+
+/**
+ * @brief Endpoint information structure
+ */
+typedef struct _usbd_ep_info {
+ uint8_t mps; /* Maximum packet length of endpoint */
+ uint8_t eptype; /* Endpoint Type */
+ uint8_t ep_enable; /* Endpoint enable */
+ uint8_t *xfer_buf;
+ uint32_t xfer_len;
+ uint32_t actual_xfer_len;
+} usbd_ep_info;
+
+/* ch58x usb */
+static struct _ch58x_core_prvi {
+ uint8_t address; /* Address */
+ usbd_ep_info ep_in[CONFIG_USBDEV_EP_NUM];
+ usbd_ep_info ep_out[CONFIG_USBDEV_EP_NUM];
+ struct usb_setup_packet setup;
+} usb_dc_cfg;
+
+__WEAK void usb_dc_low_level_init(void)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(void)
+{
+}
+
+/**
+ * @brief USB initialization
+ * @pre None
+ * @param[in] None
+ * @retval >=0 success otherwise failure
+ */
+int usb_dc_init(uint8_t busid)
+{
+ R8_USBHS_PLL_CTRL = USBHS_PLL_EN;
+ R16_PIN_CONFIG |= RB_PIN_USB2_EN;
+ CH585_USBHS_DEV->CONTROL = USBHS_UD_RST_LINK | USBHS_UD_PHY_SUSPENDM;
+ CH585_USBHS_DEV->INT_EN = USBHS_UDIE_BUS_RST | USBHS_UDIE_SUSPEND | USBHS_UDIE_BUS_SLEEP | USBHS_UDIE_LPM_ACT | USBHS_UDIE_TRANSFER | USBHS_UDIE_LINK_RDY;
+ /* Enable all end points */
+ CH585_USBHS_DEV->UEP_TX_EN = 0xffff;
+ CH585_USBHS_DEV->UEP_RX_EN = 0xffff;
+
+ CH585_USBHS_DEV->BASE_MODE = USBHS_UD_SPEED_HIGH;
+ CH585_USBHS_DEV->CONTROL = USBHS_UD_DEV_EN | USBHS_UD_DMA_EN | USBHS_UD_LPM_EN | USBHS_UD_PHY_SUSPENDM;
+
+ CH585_USBHS_DEV->UEP_T_TOG_AUTO = 0xfe;
+ CH585_USBHS_DEV->UEP_R_TOG_AUTO = 0xfe;
+ usb_dc_low_level_init();
+ return 0;
+}
+
+int usb_dc_deinit(uint8_t busid)
+{
+ R8_USBHS_PLL_CTRL &= ~USBHS_PLL_EN;
+ R32_PIN_CONFIG &= ~RB_PIN_USB2_EN;
+
+ CH585_USBHS_DEV->CONTROL |= USBHS_UD_RST_SIE;
+ CH585_USBHS_DEV->CONTROL &= ~USBHS_UD_RST_SIE;
+ usb_dc_low_level_deinit();
+ return 0;
+}
+
+/**
+ * @brief Set address
+ * @pre None
+ * @param[in] address :8-bit valid address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_set_address(uint8_t busid, const uint8_t address)
+{
+ if (address == 0) {
+ CH585_USBHS_DEV->DEV_AD = (CH585_USBHS_DEV->DEV_AD & 0x80) | address;
+ }
+ usb_dc_cfg.address = address;
+ return 0;
+}
+
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ return -1;
+}
+
+uint8_t usbd_get_port_speed(uint8_t busid)
+{
+ return USB_SPEED_HIGH;
+}
+
+/**
+ * @brief Open endpoint
+ * @pre None
+ * @param[in] ep_cfg : Endpoint configuration structure pointer
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
+{
+ uint8_t epid = USB_EP_GET_IDX(ep->bEndpointAddress);
+ if (epid > (CONFIG_USBDEV_EP_NUM - 1)) {
+ /**
+ * If you use ch58x, you can change the CONFIG_USBDEV_EP_NUM set to 8
+ */
+ USB_LOG_ERR("Ep addr %02x overflow\r\n", ep->bEndpointAddress);
+ return -1;
+ }
+
+ uint8_t mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ USB_SET_MAX_LEN(epid, mps);
+
+ if (USB_EP_DIR_IS_IN(ep->bEndpointAddress)) {
+ usb_dc_cfg.ep_in[epid].ep_enable = true;
+ usb_dc_cfg.ep_in[epid].mps = mps;
+ usb_dc_cfg.ep_in[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ USB_SET_TX_CTRL(epid, USBHS_UEP_T_RES_NAK);
+ EPn_CLEAR_TX_DONE(epid);
+ } else if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
+ usb_dc_cfg.ep_out[epid].ep_enable = true;
+ usb_dc_cfg.ep_out[epid].mps = mps;
+ usb_dc_cfg.ep_out[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ USB_SET_RX_CTRL(epid, USBHS_UEP_R_RES_NAK);
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Close endpoint
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_close(uint8_t busid, const uint8_t ep)
+{
+ uint8_t epid = USB_EP_GET_IDX(ep);
+ if (USB_EP_DIR_IS_IN(ep)) {
+ usb_dc_cfg.ep_in[epid].ep_enable = false;
+ } else if (USB_EP_DIR_IS_OUT(ep)) {
+ usb_dc_cfg.ep_out[epid].ep_enable = false;
+ }
+ return 0;
+}
+
+/**
+ * @brief Endpoint setting stall
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ if (ep_idx == 0) {
+ CH585_USBHS_DEV->UEP0_RX_CTRL = USBHS_UEP_R_RES_STALL;
+ } else {
+ USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_STALL);
+ }
+ } else {
+ if (ep_idx == 0) {
+ CH585_USBHS_DEV->UEP0_TX_CTRL = USBHS_UEP_T_RES_STALL;
+ } else {
+ USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_STALL);
+ }
+ }
+ return 0;
+}
+
+/**
+ * @brief Endpoint clear stall
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ USB_SET_RX_CTRL(ep_idx, USBHS_UEP_R_RES_ACK | USBHS_UEP_R_TOG_DATA0);
+ } else {
+ USB_SET_TX_CTRL(ep_idx, USBHS_UEP_T_RES_NAK | USBHS_UEP_T_TOG_DATA0);
+ }
+ return 0;
+}
+
+/**
+ * @brief Check endpoint status
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @param[out] stalled : Outgoing endpoint status
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
+{
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ } else {
+ }
+ return 0;
+}
+
+/**
+ * @brief Setup in ep transfer setting and start transfer.
+ *
+ * This function is asynchronous.
+ * This function is similar to uart with tx dma.
+ *
+ * This function is called to write data to the specified endpoint. The
+ * supplied usbd_endpoint_callback function will be called when data is transmitted
+ * out.
+ *
+ * @param[in] ep Endpoint address corresponding to the one
+ * listed in the device configuration table
+ * @param[in] data Pointer to data to write
+ * @param[in] data_len Length of the data requested to write. This may
+ * be zero for a zero length status packet.
+ * @return 0 on success, negative errno code on fail.
+ */
+int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (!usb_dc_cfg.ep_in[ep_idx].ep_enable) {
+ return -2;
+ }
+ if ((uint32_t)data & 0x03) {
+ return -3;
+ }
+
+ usb_dc_cfg.ep_in[ep_idx].xfer_buf = (uint8_t *)data;
+ usb_dc_cfg.ep_in[ep_idx].xfer_len = data_len;
+ usb_dc_cfg.ep_in[ep_idx].actual_xfer_len = 0;
+
+ if (ep_idx == 0) {
+ if (data_len == 0) {
+ USB_SET_TX_LEN(ep_idx, 0);
+ } else {
+ data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
+ USB_SET_TX_LEN(ep_idx, data_len);
+ CH585_USBHS_DEV->UEP0_DMA = (uint32_t)data;
+ }
+ } else {
+ if (data_len == 0) {
+ USB_SET_TX_LEN(ep_idx, 0);
+ } else {
+ data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
+ USB_SET_TX_LEN(ep_idx, data_len);
+ USB_SET_TX_DMA(ep_idx, (uint32_t)data);
+ }
+ }
+
+ EPn_SET_TX_VALID(ep_idx);
+ return 0;
+}
+
+/**
+ * @brief Setup out ep transfer setting and start transfer.
+ *
+ * This function is asynchronous.
+ * This function is similar to uart with rx dma.
+ *
+ * This function is called to read data to the specified endpoint. The
+ * supplied usbd_endpoint_callback function will be called when data is received
+ * in.
+ *
+ * @param[in] ep Endpoint address corresponding to the one
+ * listed in the device configuration table
+ * @param[in] data Pointer to data to read
+ * @param[in] data_len Max length of the data requested to read.
+ *
+ * @return 0 on success, negative errno code on fail.
+ */
+int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (!usb_dc_cfg.ep_out[ep_idx].ep_enable) {
+ return -2;
+ }
+ if ((uint32_t)data & 0x03) {
+ return -3;
+ }
+
+ usb_dc_cfg.ep_out[ep_idx].xfer_buf = (uint8_t *)data;
+ usb_dc_cfg.ep_out[ep_idx].xfer_len = data_len;
+ usb_dc_cfg.ep_out[ep_idx].actual_xfer_len = 0;
+
+ if (ep_idx == 0) {
+ if (data_len == 0) {
+ } else {
+ CH585_USBHS_DEV->UEP0_DMA = (uint32_t)data;
+ }
+ } else {
+ USB_SET_RX_DMA(ep_idx, (uint32_t)data);
+ }
+
+ EPn_SET_RX_VALID(ep_idx);
+ return 0;
+}
+
+static inline void handle_ep0_in(void)
+{
+ switch (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
+ case 1:
+ CH585_USBHS_DEV->UEP0_TX_CTRL ^= USBHS_UEP_T_TOG_DATA1;
+ EPn_SET_TX_NAK(0);
+ if (usb_dc_cfg.ep_in[0].xfer_len > usb_dc_cfg.ep_in[0].mps) {
+ usb_dc_cfg.ep_in[0].xfer_len -= usb_dc_cfg.ep_in[0].mps;
+ usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].mps;
+ usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
+ } else {
+ usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].xfer_len;
+ usb_dc_cfg.ep_in[0].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
+ }
+ break;
+ case 0:
+ /* Set */
+ switch (usb_dc_cfg.setup.bRequest) {
+ case USB_REQUEST_SET_ADDRESS:
+ /* Fill in the equipment address */
+ CH585_USBHS_DEV->DEV_AD = usb_dc_cfg.address;
+ CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
+ EPn_SET_TX_NAK(0);
+ EPn_SET_RX_VALID(0);
+ break;
+ default:
+ /* Normal out state phase */
+ CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
+ EPn_SET_TX_NAK(0);
+ EPn_SET_RX_VALID(0);
+ break;
+ }
+ break;
+ }
+}
+
+static inline void handle_non_ep0_in(uint8_t epid)
+{
+ EPn_SET_TX_NAK(epid);
+ if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
+ /* Need start in again */
+ usb_dc_cfg.ep_in[epid].xfer_buf += usb_dc_cfg.ep_in[epid].mps;
+ usb_dc_cfg.ep_in[epid].xfer_len -= usb_dc_cfg.ep_in[epid].mps;
+ usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].mps;
+
+ uint32_t write_count = MIN(usb_dc_cfg.ep_in[epid].xfer_len, usb_dc_cfg.ep_in[epid].mps);
+ USB_SET_TX_LEN(epid, write_count);
+ USB_SET_TX_DMA(epid, (uint32_t)usb_dc_cfg.ep_in[epid].xfer_buf);
+
+ if (usb_dc_cfg.ep_in[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ EPn_SET_TX_VALID(epid);
+ } else {
+ EPn_SET_TX_ISO_VALID(epid);
+ }
+ } else {
+ usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].xfer_len;
+ usb_dc_cfg.ep_in[epid].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(0, epid | 0x80, usb_dc_cfg.ep_in[epid].actual_xfer_len);
+ }
+}
+
+static inline void usb_process_ep_in(uint8_t epid)
+{
+ if (epid == 0) {
+ handle_ep0_in();
+ } else {
+ handle_non_ep0_in(epid);
+ }
+
+ EPn_CLEAR_TX_DONE(epid);
+}
+
+static inline void usb_process_ep_out(uint8_t epid)
+{
+ EPn_SET_RX_NAK(epid);
+ if (epid == 0) {
+ if (CH585_USBHS_DEV->UEP0_RX_CTRL & USBHS_UEP_R_SETUP_IS) {
+ CH585_USBHS_DEV->UEP0_RX_CTRL |= USBHS_UEP_R_TOG_DATA1;
+ CH585_USBHS_DEV->UEP0_TX_CTRL |= USBHS_UEP_T_TOG_DATA1;
+ if (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT == 0) {
+ /**
+ * Ep0 The next in must be the status stage.
+ * The device must reply to the host data 0 length packet.
+ * Here, set the transmission length to 0 and the transmission status to ACK,
+ * and wait for the host to send the in token to retrieve
+ */
+ EPn_SET_TX_LEN(0, 0);
+ EPn_SET_TX_VALID(0);
+ }
+ usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&usb_dc_cfg.setup);
+ } else {
+ CH585_USBHS_DEV->UEP0_RX_CTRL ^= USBHS_UEP_R_TOG_DATA1;
+ uint32_t read_count = EPn_GET_RX_LEN(0);
+ usb_dc_cfg.ep_out[0].actual_xfer_len += read_count;
+ usb_dc_cfg.ep_out[0].xfer_len -= read_count;
+ usbd_event_ep_out_complete_handler(0, 0x00, usb_dc_cfg.ep_out[0].actual_xfer_len);
+ if (read_count == 0) {
+ /* Out status, start reading setup */
+ CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
+ EPn_SET_RX_VALID(0);
+ }
+ }
+ } else {
+ if (USB_GET_RX_CTRL(epid) & USBHS_UEP_R_TOG_MATCH) {
+ uint32_t read_count = EPn_GET_RX_LEN(epid);
+ usb_dc_cfg.ep_out[epid].xfer_buf += read_count;
+ usb_dc_cfg.ep_out[epid].actual_xfer_len += read_count;
+ usb_dc_cfg.ep_out[epid].xfer_len -= read_count;
+
+ if ((read_count < usb_dc_cfg.ep_out[epid].mps) || (usb_dc_cfg.ep_out[epid].xfer_len == 0)) {
+ usbd_event_ep_out_complete_handler(0, ((epid) & 0x7f), usb_dc_cfg.ep_out[epid].actual_xfer_len);
+ } else {
+ USB_SET_RX_DMA(epid, (uint32_t)usb_dc_cfg.ep_out[epid].xfer_buf);
+ if (usb_dc_cfg.ep_out[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ EPn_SET_RX_VALID(epid);
+ } else {
+ EPn_SET_RX_ISO_VALID(epid);
+ }
+ }
+ }
+ }
+
+ EPn_CLEAR_RX_DONE(epid);
+}
+
+static inline void usb_trans_end_process(void)
+{
+ uint8_t epid = (CH585_USBHS_DEV->INT_ST & USBHS_UDIS_EP_ID_MASK);
+ switch (CH585_USBHS_DEV->INT_ST & USBHS_UDIS_EP_DIR) {
+ case USBHS_UDIS_EP_DIR: /* in */
+ usb_process_ep_in(epid);
+ break;
+ case 0: /* setup or out */
+ usb_process_ep_out(epid);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief USB interrupt processing function
+ * @pre None
+ * @param[in] None
+ * @retval None
+ */
+__attribute__((interrupt("WCH-Interrupt-fast")))
+__attribute__((section(".highcode"))) void
+USBD_IRQHandler(void)
+{
+ volatile uint8_t intflag = 0;
+ intflag = CH585_USBHS_DEV->INT_FG;
+
+ if (intflag & USBHS_UDIF_TRANSFER) {
+ usb_trans_end_process();
+ } else if (intflag & USBHS_UDIF_BUS_RST) {
+ /* Reset */
+ CH585_USBHS_DEV->DEV_AD = 0;
+ usbd_event_reset_handler(0);
+ /* Set ep0 rx vaild to start receive setup packet */
+ CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
+ // EPn_SET_RX_VALID(0);
+ R8_U2EP0_TX_CTRL = USBHS_UEP_T_RES_NAK;
+ R8_U2EP0_RX_CTRL = USBHS_UEP_R_RES_ACK;
+ CH585_USBHS_DEV->INT_FG = USBHS_UDIF_BUS_RST;
+ } else if (intflag & USBHS_UDIF_SUSPEND) {
+ if (CH585_USBHS_DEV->MIS_ST & 0x04) {
+ /* Suspend */
+ } else {
+ /* Wake up */
+ }
+ CH585_USBHS_DEV->INT_FG = USBHS_UDIF_SUSPEND;
+ } else {
+ CH585_USBHS_DEV->INT_FG = intflag;
+ }
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/ch32/ch585_usbhs_reg.h b/components/drivers/usb/cherryusb/port/ch32/ch585_usbhs_reg.h
new file mode 100644
index 0000000000..29ed6db0e5
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ch32/ch585_usbhs_reg.h
@@ -0,0 +1,450 @@
+#pragma once
+
+/**********************************/
+/*********USB high speed**********/
+/**********************************/
+typedef volatile unsigned short *PUINT16V;
+typedef volatile unsigned long *PUINT32V;
+typedef volatile unsigned char *PUINT8V;
+
+/* USB high speed device register */
+#define R8_USB2_CTRL (*((PUINT8V)0x40009000)) // RW, USB_high_speed control register
+#define USBHS_UD_LPM_EN 0x80 // RW, enable LPM
+#define USBHS_UD_DEV_EN 0x20 // RW, enable USB equipment
+#define USBHS_UD_DMA_EN 0x10 // RW, enable DMA transmit
+#define USBHS_UD_PHY_SUSPENDM 0x08 // RW, suspeng USB PHY
+#define USBHS_UD_CLR_ALL 0x04 // RW, clear all interupt flag
+#define USBHS_UD_RST_SIE 0x02 // RW, reset USB protocol processor,including end point register
+#define USBHS_UD_RST_LINK 0x01 // RW, enable LNK layer reset
+#define R8_USB2_BASE_MODE (*((PUINT8V)0x40009001)) // RW, USB_high_speed mode control register
+#define USBHS_UD_SPEED_FULL 0x00
+#define USBHS_UD_SPEED_HIGH 0x01
+#define USBHS_UD_SPEED_LOW 0x02
+#define USBHS_UD_SPEED_TYPE 0x03 // RW, speed mode excpeted by the equipment,00:full speed, 01:high speed, 10:low speed
+#define R8_USB2_INT_EN (*((PUINT8V)0x40009002)) // RW, USB_high_speed intreurpt enable register
+#define USBHS_UDIE_FIFO_OVER 0x80 // RW, enable fifo overflow interupt
+#define USBHS_UDIE_LINK_RDY 0x40 // RW, enable USB conect interupt
+#define USBHS_UDIE_SOF_ACT 0x20 // RW, enable SOF package received interupt
+#define USBHS_UDIE_TRANSFER 0x10 // RW, enable USB transmit end interupt
+#define USBHS_UDIE_LPM_ACT 0x08 // RW, enable lpm transmit end interupt
+#define USBHS_UDIE_BUS_SLEEP 0x04 // RW, enable usb bus sleep interupt
+#define USBHS_UDIE_SUSPEND 0x02 // RW, enable usb bus suspend interupt
+#define USBHS_UDIE_BUS_RST 0x01 // RW, enable usb bus reset interupt
+#define R8_USB2_DEV_AD (*((PUINT8V)0x40009003)) // RW, USB_high_speed device adress register
+#define USBHS_UD_DEV_ADDR 0x7F // RW, adress of usb equipment
+#define R8_USB2_WAKE_CTRL (*((PUINT8V)0x40009004)) // RW, USB_high_speed wake up remotely register
+#define USBHS_UD_UD_REMOTE_WKUP 0x01 // RW1, wake up remotely and auto reset hardware
+#define R8_USB2_TEST_MODE (*((PUINT8V)0x40009005)) // RW, USB_high_speed test mode register
+#define USBHS_UD_TEST_EN 0x80 // RW, enable test mode
+#define USBHS_UD_TEST_SE0NAK 0x08 // RW, output SE0 when in test mode
+#define USBHS_UD_TEST_PKT 0x04 // RW, output one package(including DATA0,data and length of end pont4) when in test mode,not work on virtual equipment
+#define USBHS_UD_TEST_K 0x02 // RW, output K when in test mode
+#define USBHS_UD_TEST_J 0x01 // RW, output J when in test mode
+#define R16_USB2_LPM_DATA (*((PUINT16V)0x40009006)) // RW, USB_high_speed power control register
+#define USBHS_UD_LPM_BUSY 0x8000 // RW, power control busy
+#define USBHS_UD_LPM_DATA 0x07FF // RO, power control data
+#define R8_USB2_INT_FG (*((PUINT8V)0x40009008)) // RW, USB_high_speed interupt flag register
+#define USBHS_UDIF_FIFO_OV 0x80 // RW1, clear fifo overflow interupt flag
+#define USBHS_UDIF_LINK_RDY 0x40 // RW1, clear USB conect interupt flag
+#define USBHS_UDIF_RX_SOF 0x20 // RW1, clear SOF package received interupt flag
+#define USBHS_UDIF_TRANSFER 0x10 // RO, USB transmit end interupt flag,cleared by USBHS_UDMS_HS_MOD
+#define USBHS_UDIF_LPM_ACT 0x08 // RW1, clear lpm transmit end interupt flag
+#define USBHS_UDIF_BUS_SLEEP 0x04 // RW1, clear usb bus sleep interupt flag
+#define USBHS_UDIF_SUSPEND 0x02 // RW1, clear usb bus suspend interupt flag
+#define USBHS_UDIF_BUS_RST 0x01 // RW1, clear usb bus reset interupt flag
+#define R8_USB2_INT_ST (*((PUINT8V)0x40009009)) // RW, USB_high_speed interupt status register
+#define USBHS_UDIS_EP_DIR 0x10 // RO, end point tranfer diector of data
+#define USBHS_UDIS_EP_ID_MASK 0x07 // RO, number of end point which data transmission occured
+#define R8_USB2_MIS_ST (*((PUINT8V)0x4000900A)) // RW, USB_high_speed miscellaneous register
+#define USBHS_UDMS_HS_MOD 0x80 // RO, host with high speed
+#define USBHS_UDMS_SUSP_REQ 0x10 // RO, requirment of suspending USB
+#define USBHS_UDMS_SIE_FREE 0x08 // RO, USB free state
+#define USBHS_UDMS_SLEEP 0x04 // RO, USB sleep state
+#define USBHS_UDMS_SUSPEND 0x02 // RO, USB in suspend state
+#define USBHS_UDMS_READY 0x01 // RO, USB in connected state
+#define R16_USB2_FRAME_NO (*((PUINT16V)0x4000900C)) // RW, USB_high_speed frame number register
+#define USBHS_UD_MFRAME_NO 0xE000
+#define USBHS_UD_FRAME_NO 0x07FF
+#define R16_USB2_BUS (*((PUINT16V)0x4000900E)) // RW, USB_high_speed bus status register
+#define USBHS_USB_DM_ST 0x08
+#define USBHS_USB_DP_ST 0x04
+#define USB_WAKEUP 0x01
+#define R16_U2EP_TX_EN (*((PUINT16V)0x40009010)) // RW, USB_high_speed end point transmit enable register
+/* Bit definition for R16_U2EP_TX_EN & R16_U2EP_RX_EN register */
+#define RB_EP0_EN 0x0001
+#define RB_EP1_EN 0x0002
+#define RB_EP2_EN 0x0004
+#define RB_EP3_EN 0x0008
+#define RB_EP4_EN 0x0010
+#define RB_EP5_EN 0x0020
+#define RB_EP6_EN 0x0040
+#define RB_EP7_EN 0x0080
+#define RB_EP8_EN 0x0100
+#define RB_EP9_EN 0x0200
+#define RB_EP10_EN 0x0400
+#define RB_EP11_EN 0x0800
+#define RB_EP12_EN 0x1000
+#define RB_EP13_EN 0x2000
+#define RB_EP14_EN 0x4000
+#define RB_EP15_EN 0x8000
+
+#define R16_U2EP_RX_EN (*((PUINT16V)0x40009012)) // RW, USB_high_speed end point receive enableregister
+#define USBHS_UEP_RX_EN 0xFFFF
+#define R16_U2EP_T_TOG_AUTO (*((PUINT16V)0x40009014)) // RW, USB_high_speed end point transmit auto toggle enable register
+#define USBHS_UEP_T_TOG_AUTO 0xFF
+#define R16_U2EP_R_TOG_AUTO (*((PUINT16V)0x40009016)) // RW, USB_high_speed end point receive auto toggle enable register
+#define USBHS_UEP_R_TOG_AUTO 0xFF
+#define R8_U2EP_T_BURST (*((PUINT8V)0x40009018)) // RW, USB_high_speed end point transmit burst register
+#define USBHS_UEP_T_BURST_EN 0xFF
+#define R8_U2EP_T_BURST_MODE (*((PUINT8V)0x40009019)) // RW, USB_high_speed end point transmit burst mode register
+#define USBHS_UEP_T_BURST_MODE 0xFF
+#define R8_U2EP_R_BURST (*((PUINT8V)0x4000901A)) // RW, USB_high_speed end point receive burst register
+#define USBHS_UEP_R_BURST_EN 0xFF
+#define R8_U2EP_R_RES_MODE (*((PUINT8V)0x4000901B)) // RW, USB_high_speed end point transmit reply mode register
+#define USBHS_UEP_R_RES_MODE 0xFF
+#define R32_U2EP_AF_MODE (*((PUINT32V)0x4000901C)) // RW, USB_high_speed end point multiplexing register
+#define USBHS_UEP_T_AF 0xFE
+#define R32_U2EP0_DMA (*((PUINT32V)0x40009020)) // RW, USB_high_speed end point0 begin adress of DMA buffer register
+#define UEPn_DMA 0x01FFFF
+#define R32_U2EP1_RX_DMA (*((PUINT32V)0x40009024)) // RW, USB_high_speed end point1 begin adress of DMA receive buffer register
+#define R32_U2EP2_RX_DMA (*((PUINT32V)0x40009028)) // RW, USB_high_speed end point2 begin adress of DMA receive buffer register
+#define R32_U2EP3_RX_DMA (*((PUINT32V)0x4000902C)) // RW, USB_high_speed end point3 begin adress of DMA receive buffer register
+#define R32_U2EP4_RX_DMA (*((PUINT32V)0x40009030)) // RW, USB_high_speed end point4 begin adress of DMA receive buffer register
+#define R32_U2EP5_RX_DMA (*((PUINT32V)0x40009034)) // RW, USB_high_speed end point5 begin adress of DMA receive buffer register
+#define R32_U2EP6_RX_DMA (*((PUINT32V)0x40009038)) // RW, USB_high_speed end point6 begin adress of DMA receive buffer register
+#define R32_U2EP7_RX_DMA (*((PUINT32V)0x4000903C)) // RW, USB_high_speed end point7 begin adress of DMA receive buffer register
+#define UEPn_RX_DMA 0x01FFFF
+#define R32_U2EP1_TX_DMA (*((PUINT32V)0x40009040)) // RW, USB_high_speed end point1 begin adress of DMA transmit buffer register
+#define R32_U2EP2_TX_DMA (*((PUINT32V)0x40009044)) // RW, USB_high_speed end point2 begin adress of DMA transmit buffer register
+#define R32_U2EP3_TX_DMA (*((PUINT32V)0x40009048)) // RW, USB_high_speed end point3 begin adress of DMA transmit buffer register
+#define R32_U2EP4_TX_DMA (*((PUINT32V)0x4000904C)) // RW, USB_high_speed end point4 begin adress of DMA transmit buffer register
+#define R32_U2EP5_TX_DMA (*((PUINT32V)0x40009050)) // RW, USB_high_speed end point5 begin adress of DMA transmit buffer register
+#define R32_U2EP6_TX_DMA (*((PUINT32V)0x40009054)) // RW, USB_high_speed end point6 begin adress of DMA transmit buffer register
+#define R32_U2EP7_TX_DMA (*((PUINT32V)0x40009058)) // RW, USB_high_speed end point7 begin adress of DMA transmit buffer register
+#define UEPn_TX_DMA 0x01FFFF
+#define R32_U2EP0_MAX_LEN (*((PUINT32V)0x4000905C)) // RW, USB_high_speed end point0 max length package register
+#define R32_U2EP1_MAX_LEN (*((PUINT32V)0x40009060)) // RW, USB_high_speed end point1 max length package register
+#define R32_U2EP2_MAX_LEN (*((PUINT32V)0x40009064)) // RW, USB_high_speed end point2 max length package register
+#define R32_U2EP3_MAX_LEN (*((PUINT32V)0x40009068)) // RW, USB_high_speed end point3 max length package register
+#define R32_U2EP4_MAX_LEN (*((PUINT32V)0x4000906C)) // RW, USB_high_speed end point4 max length package register
+#define R32_U2EP5_MAX_LEN (*((PUINT32V)0x40009070)) // RW, USB_high_speed end point5 max length package register
+#define R32_U2EP6_MAX_LEN (*((PUINT32V)0x40009074)) // RW, USB_high_speed end point6 max length package register
+#define R32_U2EP7_MAX_LEN (*((PUINT32V)0x40009078)) // RW, USB_high_speed end point7 max length package register
+#define UEPn_MAX_LEN 0x007F
+#define R16_U2EP0_RX_LEN (*((PUINT16V)0x4000907C)) // RW, USB_high_speed end point0 length of receive register
+#define UEP0_RX_LEN 0x007F
+#define R16_U2EP1_RX_LEN (*((PUINT16V)0x40009080)) // RW, USB_high_speed end point1 single received length register
+#define R16_U2EP1_R_SIZE (*((PUINT16V)0x40009082)) // RW, USB_high_speed end point1 total received length register
+#define R16_U2EP2_RX_LEN (*((PUINT16V)0x40009084)) // RW, USB_high_speed end point2 single received length register
+#define R16_U2EP2_R_SIZE (*((PUINT16V)0x40009086)) // RW, USB_high_speed end point2 total received length register
+#define R16_U2EP3_RX_LEN (*((PUINT16V)0x40009088)) // RW, USB_high_speed end point3 single received length register
+#define R16_U2EP3_R_SIZE (*((PUINT16V)0x4000908A)) // RW, USB_high_speed end point3 total received length register
+#define R16_U2EP4_RX_LEN (*((PUINT16V)0x4000908C)) // RW, USB_high_speed end point4 single received length register
+#define R16_U2EP4_R_SIZE (*((PUINT16V)0x4000908E)) // RW, USB_high_speed end point4 total received length register
+#define R16_U2EP5_RX_LEN (*((PUINT16V)0x40009090)) // RW, USB_high_speed end point5 single received length register
+#define R16_U2EP5_R_SIZE (*((PUINT16V)0x40009092)) // RW, USB_high_speed end point5 total received length register
+#define R16_U2EP6_RX_LEN (*((PUINT16V)0x40009094)) // RW, USB_high_speed end point6 single received length register
+#define R16_U2EP6_R_SIZE (*((PUINT16V)0x40009096)) // RW, USB_high_speed end point6 total received length register
+#define R16_U2EP7_RX_LEN (*((PUINT16V)0x40009098)) // RW, USB_high_speed end point7 single received length register
+#define R16_U2EP7_R_SIZE (*((PUINT16V)0x4000909A)) // RW, USB_high_speed end point7 total received length register
+#define UEPn_RX_LEN 0xFFFF
+#define UEPn_R_SIZE 0xFFFF
+#define R16_U2EP0_T_LEN (*((PUINT16V)0x4000909C)) // RW, USB_high_speed end point0 length of transmission register
+#define UEP0_T_LEN 0x7F
+#define R8_U2EP0_TX_CTRL (*((PUINT8V)0x4000909E)) // RW, USB_high_speed end point0 transmit control register
+#define R8_U2EP0_RX_CTRL (*((PUINT8V)0x4000909F)) // RW, USB_high_speed end point0 receive control register
+#define R16_U2EP1_T_LEN (*((PUINT16V)0x400090A0)) // RW, USB_high_speed end point1 length of transmission register
+#define R8_U2EP1_TX_CTRL (*((PUINT8V)0x400090A2)) // RW, USB_high_speed end point1 transmit control register
+#define R8_U2EP1_RX_CTRL (*((PUINT8V)0x400090A3)) // RW, USB_high_speed end point1 receive control register
+#define R16_U2EP2_T_LEN (*((PUINT16V)0x400090A4)) // RW, USB_high_speed end point2 length of transmission register
+#define R8_U2EP2_TX_CTRL (*((PUINT8V)0x400090A6)) // RW, USB_high_speed end point2 transmit control register
+#define R8_U2EP2_RX_CTRL (*((PUINT8V)0x400090A7)) // RW, USB_high_speed end point2 receive control register
+#define R16_U2EP3_T_LEN (*((PUINT16V)0x400090A8)) // RW, USB_high_speed end point3 length of transmission register
+#define R8_U2EP3_TX_CTRL (*((PUINT8V)0x400090AA)) // RW, USB_high_speed end point3 transmit control register
+#define R8_U2EP3_RX_CTRL (*((PUINT8V)0x400090AB)) // RW, USB_high_speed end point3 receive control register
+#define R16_U2EP4_T_LEN (*((PUINT16V)0x400090AC)) // RW, USB_high_speed end point4 length of transmission register
+#define R8_U2EP4_TX_CTRL (*((PUINT8V)0x400090AE)) // RW, USB_high_speed end point4 transmit control register
+#define R8_U2EP4_RX_CTRL (*((PUINT8V)0x400090AF)) // RW, USB_high_speed end point4 receive control register
+#define R16_U2EP5_T_LEN (*((PUINT16V)0x400090B0)) // RW, USB_high_speed end point5 length of transmission register
+#define R8_U2EP5_TX_CTRL (*((PUINT8V)0x400090B2)) // RW, USB_high_speed end point5 transmit control register
+#define R8_U2EP5_RX_CTRL (*((PUINT8V)0x400090B3)) // RW, USB_high_speed end point5 receive control register
+#define R16_U2EP6_T_LEN (*((PUINT16V)0x400090B4)) // RW, USB_high_speed end point6 length of transmission register
+#define R8_U2EP6_TX_CTRL (*((PUINT8V)0x400090B6)) // RW, USB_high_speed end point6 transmit control register
+#define R8_U2EP6_RX_CTRL (*((PUINT8V)0x400090B7)) // RW, USB_high_speed end point6 receive control register
+#define R16_U2EP7_T_LEN (*((PUINT16V)0x400090B8)) // RW, USB_high_speed end point7 length of transmission register
+#define R8_U2EP7_TX_CTRL (*((PUINT8V)0x400090BA)) // RW, USB_high_speed end point7 transmit control register
+#define R8_U2EP7_RX_CTRL (*((PUINT8V)0x400090BB)) // RW, USB_high_speed end point7 receive control register
+/**R16_UEPn_T_LEN**/
+#define UEPn_T_LEN 0xFFFF
+/**R8_UEPn_TX_CTRL**/
+#define USBHS_UEP_T_DONE 0x80
+#define USBHS_UEP_T_NAK_ACT 0x40
+#define USBHS_UEP_T_TOG_MASK 0x0C
+#define USBHS_UEP_T_TOG_MDATA 0x0C
+#define USBHS_UEP_T_TOG_DATA2 0x08
+#define USBHS_UEP_T_TOG_DATA1 0x04
+#define USBHS_UEP_T_TOG_DATA0 0x00
+#define USBHS_UEP_T_RES_MASK 0x03
+#define USBHS_UEP_T_RES_ACK 0x02
+#define USBHS_UEP_T_RES_STALL 0x01
+#define USBHS_UEP_T_RES_NAK 0x00
+
+/**R8_UEPn_RX_CTRL**/
+#define USBHS_UEP_R_DONE 0x80
+#define USBHS_UEP_R_NAK_ACT 0x40
+#define USBHS_UEP_R_NAK_TOG 0x20
+#define USBHS_UEP_R_TOG_MATCH 0x10
+#define USBHS_UEP_R_SETUP_IS 0x08
+#define USBHS_UEP_R_TOG_MASK 0x0C
+#define USBHS_UEP_R_TOG_MDATA 0x0C
+#define USBHS_UEP_R_TOG_DATA2 0x08
+#define USBHS_UEP_R_TOG_DATA1 0x04
+#define USBHS_UEP_R_TOG_DATA0 0x00
+#define USBHS_UEP_R_RES_MASK 0x03
+#define USBHS_UEP_R_RES_ACK 0x02
+#define USBHS_UEP_R_RES_STALL 0x01
+#define USBHS_UEP_R_RES_NAK 0x00
+
+#define R16_U2EP_T_ISO (*((PUINT16V)0x400090BC)) // RW, USB_high_speed end point transmit sync mode register
+#define USBHS_UEP1_T_ISO_EN 0x02
+#define USBHS_UEP2_T_ISO_EN 0x04
+#define USBHS_UEP3_T_ISO_EN 0x08
+#define USBHS_UEP4_T_ISO_EN 0x10
+#define USBHS_UEP5_T_ISO_EN 0x20
+#define USBHS_UEP6_T_ISO_EN 0x40
+#define USBHS_UEP7_T_ISO_EN 0x80
+#define R16_U2EP_R_ISO (*((PUINT16V)0x400090BE)) // RW, USB_high_speed end point receive sync mode register
+#define USBHS_UEP1_R_ISO_EN 0x02
+#define USBHS_UEP2_R_ISO_EN 0x04
+#define USBHS_UEP3_R_ISO_EN 0x08
+#define USBHS_UEP4_R_ISO_EN 0x10
+#define USBHS_UEP5_R_ISO_EN 0x20
+#define USBHS_UEP6_R_ISO_EN 0x40
+#define USBHS_UEP7_R_ISO_EN 0x80
+
+/* USB high speed host register */
+#define R8_U2H_CFG (*((PUINT8V)0x40009100)) // RW, USB_high_speed register
+#define USBHS_UH_LPM_EN 0x80
+#define USBHS_UH_FORCE_FS 0x40
+#define USBHS_UH_SOF_EN 0x20
+#define USBHS_UH_DMA_EN 0x10
+#define USBHS_UH_PHY_SUSPENDM 0x08
+#define USBHS_UH_CLR_ALL 0x04
+#define USBHS_RST_SIE 0x02
+#define USBHS_RST_LINK 0x01
+#define R8_U2H_INT_EN (*((PUINT8V)0x40009102)) // RW, USB_high_speed register
+#define USBHS_UHIE_FIFO_OVER 0x80
+#define USBHS_UHIE_TX_HALT 0x40
+#define USBHS_UHIE_SOF_ACT 0x20
+#define USBHS_UHIE_TRANSFER 0x10
+#define USBHS_UHIE_RESUME_ACT 0x08
+#define USBHS_UHIE_WKUP_ACT 0x04
+#define R8_U2H_DEV_AD (*((PUINT8V)0x40009103)) // RW, USB_high_speed register
+#define USBHS_UH_DEV_ADDR 0xFF
+#define R32_U2H_CONTROL (*((PUINT32V)0x40009104)) // RW, USB_high_speed register
+#define USBHS_UH_RX_NO_RES 0x800000
+#define USBHS_UH_TX_NO_RES 0x400000
+#define USBHS_UH_RX_NO_DATA 0x200000
+#define USBHS_UH_TX_NO_DATA 0x100000
+#define USBHS_UH_PRE_PID_EN 0x080000
+#define USBHS_UH_SPLIT_VALID 0x040000
+#define USBHS_UH_LPM_VALID 0x020000
+#define USBHS_UH_HOST_ACTION 0x010000
+#define USBHS_UH_BUF_MODE 0x0400
+#define USBHS_UH_T_TOG_MASK 0x0300
+#define USBHS_UH_T_TOG_MDATA 0x0300
+#define USBHS_UH_T_TOG_DATA2 0x0200
+#define USBHS_UH_T_TOG_DATA1 0x0100
+#define USBHS_UH_T_TOG_DATA0 0x0000
+#define USBHS_UH_T_ENDP_MASK 0xF0
+#define USBHS_UH_T_TOKEN_MASK 0x0F
+
+#define R8_U2H_INT_FLAG (*((PUINT8V)0x40009108)) // RW, USB_high_speed register
+#define USBHS_UHIF_FIFO_OVER 0x80
+#define USBHS_UHIF_TX_HALT 0x40
+#define USBHS_UHIF_SOF_ACT 0x20
+#define USBHS_UHIF_TRANSFER 0x10
+#define USBHS_UHIF_RESUME_ACT 0x08
+#define USBHS_UHIF_WKUP_ACT 0x04
+#define R8_U2H_INT_ST (*((PUINT8V)0x40009109)) // RW, USB_high_speed register
+#define USBHS_UHIF_PORT_RX_RESUME 0x10
+#define USBHS_UH_R_TOKEN_MASK 0x0F
+#define R8_U2H_MIS_ST (*((PUINT8V)0x4000910A)) // RW, USB_high_speed register
+#define USBHS_UHMS_BUS_SE0 0x80
+#define USBHS_UHMS_BUS_J 0x40
+#define USBHS_UHMS_LINESTATE 0x30
+#define USBHS_UHMS_USB_WAKEUP 0x08
+#define USBHS_UHMS_SOF_ACT 0x04
+#define USBHS_UHMS_SOF_PRE 0x02
+#define USBHS_UHMS_SOF_FREE 0x01
+#define R32_U2H_LPM_DATA (*((PUINT32V)0x4000910C)) // RW, USB_high_speed register
+#define USBHS_UH_LPM_DATA 0x07FF
+#define R32_U2H_SPLIT_DATA (*((PUINT32V)0x40009110)) // RW, USB_high_speed register
+#define USBHS_UH_SPLIT_DATA 0x07FFFF
+#define R32_U2H_FRAME (*((PUINT32V)0x40009114)) // RW, USB_high_speed register
+#define USBHS_UH_SOF_CNT_CLR 0x02000000
+#define USBHS_UH_SOF_CNT_EN 0x01000000
+#define USBHS_UH_MFRAME_NO 0x070000
+#define USBHS_UH_FRAME_NO 0x07FF
+#define R32_U2H_TX_LEN (*((PUINT32V)0x40009118)) // RW, USB_high_speed register
+#define USBHS_UH_TX_LEN 0x07FF
+#define R32_U2H_RX_LEN (*((PUINT32V)0x4000911C)) // RW, USB_high_speed register
+#define USBHS_UH_RX_LEN 0x07FF
+#define R32_U2H_RX_MAX_LEN (*((PUINT32V)0x40009120)) // RW, USB_high_speed register
+#define USBHS_UH_RX_MAX_LEN 0x07FF
+#define R32_U2H_RX_DMA (*((PUINT32V)0x40009124)) // RW, USB_high_speed register
+#define USBHS_R32_UH_RX_DMA 0x01FFFF
+#define R32_U2H_TX_DMA (*((PUINT32V)0x40009128)) // RW, USB_high_speed register
+#define USBHS_R32_UH_TX_DMA 0x01FFFF
+#define R32_U2H_PORT_CTRL (*((PUINT32V)0x4000912C)) // RW, USB_high_speed register
+#define USBHS_UH_BUS_RST_LONG 0x010000
+#define USBHS_UH_PORT_SLEEP_BESL 0xF000
+#define USBHS_UH_CLR_PORT_SLEEP 0x0100
+#define USBHS_UH_CLR_PORT_CONNECT 0x20
+#define USBHS_UH_CLR_PORT_EN 0x10
+#define USBHS_UH_SET_PORT_SLEEP 0x08
+#define USBHS_UH_CLR_PORT_SUSP 0x04
+#define USBHS_UH_SET_PORT_SUSP 0x02
+#define USBHS_UH_SET_PORT_RESET 0x01
+#define R8_U2H_PORT_CFG (*((PUINT8V)0x40009130)) // RW, USB_high_speed register
+#define USBHS_UH_PD_EN 0x80
+#define USBHS_UH_HOST_EN 0x01
+#define R8_U2H_PORT_INT_EN (*((PUINT8V)0x40009132)) // RW, USB_high_speed register
+#define USBHS_UHIE_PORT_SLP 0x20
+#define USBHS_UHIE_PORT_RESET 0x10
+#define USBHS_UHIE_PORT_SUSP 0x04
+#define USBHS_UHIE_PORT_EN 0x02
+#define USBHS_UHIE_PORT_CONNECT 0x01
+#define R8_U2H_PORT_TEST_CT (*((PUINT8V)0x40009133)) // RW, USB_high_speed register
+#define USBHS_UH_TEST_FORCE_EN 0x04
+#define USBHS_UH_TEST_K 0x02
+#define USBHS_UH_TEST_J 0x01
+#define R16_U2H_PORT_ST (*((PUINT16V)0x40009134)) // RW, USB_high_speed register
+#define USBHS_UHIS_PORT_TEST 0x0800
+#define USBHS_UHIS_PORT_SPEED_MASK 0x0600
+#define USBHS_UHIS_PORT_HS 0x0400
+#define USBHS_UHIS_PORT_LS 0x0200
+#define USBHS_UHIS_PORT_FS 0x0000
+#define USBHS_UHIS_PORT_SLP 0x20
+#define USBHS_UHIS_PORT_RST 0x10
+#define USBHS_UHIS_PORT_SUSP 0x04
+#define USBHS_UHIS_PORT_EN 0x02
+#define USBHS_UHIS_PORT_CONNECT 0x01
+#define R8_U2H_PORT_CHG (*((PUINT8V)0x40009136))
+#define USBHS_UHIF_PORT_SLP 0x20
+#define USBHS_UHIF_PORT_RESET 0x10
+#define USBHS_UHIF_PORT_SUSP 0x04
+#define USBHS_UHIF_PORT_EN 0x02
+#define USBHS_UHIF_PORT_CONNECT 0x01
+#define R32_U2H_BC_CTRL (*((PUINT32V)0x4000913C))
+#define UDM_VSRC_ACT 0x0400
+#define UDM_BC_VSRC 0x0200
+#define UDP_BC_VSRC 0x0100
+#define BC_AUTO_MODE 0x40
+#define UDM_BC_CMPE 0x20
+#define UDP_BC_CMPE 0x10
+#define UDM_BC_CMPO 0x02
+#define UDP_BC_CMPO 0x01
+#define R8_USBHS_PLL_CTRL (*((PUINT8V)0x40009200))
+#define USBHS_PLL_EN 0x04
+#define USBHS_PLL_LOWPOW 0x02
+#define USBHS_PLL_CKSEL 0x01
+
+#define __IO volatile /* defines 'read / write' permissions */
+
+typedef struct
+{
+ __IO uint8_t CONTROL; /* 0x40009000 */
+ __IO uint8_t BASE_MODE; /* 0x40009001 */
+ __IO uint8_t INT_EN; /* 0x40009002 */
+ __IO uint8_t DEV_AD; /* 0x40009003 */
+ __IO uint8_t WAKE_CTRL; /* 0x40009004 远程唤醒寄存器 */
+ __IO uint8_t TEST_MODE; /* 0x40009005 测试模式寄存器 */
+ __IO uint16_t LPM_DATA; /* 0x40009006 */
+ __IO uint8_t INT_FG; /* 0x40009008 */
+ __IO uint8_t INT_ST; /* 0x40009009 */
+ __IO uint8_t MIS_ST; /* 0x4000900a */
+ __IO uint8_t RESERVE0; /* 0x4000900b */
+ __IO uint16_t FRAME_NO; /* 0x4000900c */
+ __IO uint16_t USB_BUS; /* 0x4000900e */
+ __IO uint16_t UEP_TX_EN; /* 0x40009010 */
+ __IO uint16_t UEP_RX_EN; /* 0x40009012 */
+
+ __IO uint16_t UEP_T_TOG_AUTO; /* 0x40009014 */
+ __IO uint16_t UEP_R_TOG_AUTO; /* 0x40009016 */
+ __IO uint8_t UEP_T_BURST; /* 0x40009018 */
+ __IO uint8_t UEP_T_BURST_MODE; /* 0x40009019 */
+ __IO uint8_t UEP_R_BURST; /* 0x4000901a */
+ __IO uint8_t UEP_R_RES_MODE; /* 0x4000901b */
+ __IO uint32_t UEP_AF_MODE; /* 0x4000901c */
+
+ __IO uint32_t UEP0_DMA; /* 0x40009020 */
+ __IO uint32_t UEP1_RX_DMA; /* 0x40009024 */
+ __IO uint32_t UEP2_RX_DMA; /* 0x40009028 */
+ __IO uint32_t UEP3_RX_DMA; /* 0x4000902c */
+ __IO uint32_t UEP4_RX_DMA; /* 0x40009030 */
+ __IO uint32_t UEP5_RX_DMA; /* 0x40009034 */
+ __IO uint32_t UEP6_RX_DMA; /* 0x40009038 */
+ __IO uint32_t UEP7_RX_DMA; /* 0x4000903c */
+
+ __IO uint32_t UEP1_TX_DMA; /* 0x40009040 */
+ __IO uint32_t UEP2_TX_DMA; /* 0x40009044 */
+ __IO uint32_t UEP3_TX_DMA; /* 0x40009048 */
+ __IO uint32_t UEP4_TX_DMA; /* 0x4000904c */
+ __IO uint32_t UEP5_TX_DMA; /* 0x40009050 */
+ __IO uint32_t UEP6_TX_DMA; /* 0x40009054 */
+ __IO uint32_t UEP7_TX_DMA; /* 0x40009058 */
+
+ __IO uint32_t UEP0_MAX_LEN; /* 0x4000905c */
+ __IO uint32_t UEP1_MAX_LEN; /* 0x40009060 */
+ __IO uint32_t UEP2_MAX_LEN; /* 0x40009064 */
+ __IO uint32_t UEP3_MAX_LEN; /* 0x40009068 */
+ __IO uint32_t UEP4_MAX_LEN; /* 0x4000906c */
+ __IO uint32_t UEP5_MAX_LEN; /* 0x40009070 */
+ __IO uint32_t UEP6_MAX_LEN; /* 0x40009074 */
+ __IO uint32_t UEP7_MAX_LEN; /* 0x40009078 */
+
+ __IO uint16_t USB_EP0_RX_LEN; /* 0x4000907c */
+ __IO uint16_t RESERVE1; /* 0x4000907e */
+ __IO uint16_t UEP1_RX_LEN; /* 0x40009080 */
+ __IO uint16_t UEP1_R_SIZE; /* 0x40009082 */
+ __IO uint16_t UEP2_RX_LEN; /* 0x40009084 */
+ __IO uint16_t UEP2_R_SIZE; /* 0x40009086 */
+ __IO uint16_t UEP3_RX_LEN; /* 0x40009088 */
+ __IO uint16_t UEP3_R_SIZE; /* 0x4000908a */
+ __IO uint16_t UEP4_RX_LEN; /* 0x4000908c */
+ __IO uint16_t UEP4_R_SIZE; /* 0x4000908e */
+ __IO uint16_t UEP5_RX_LEN; /* 0x40009090 */
+ __IO uint16_t UEP5_R_SIZE; /* 0x40009092 */
+ __IO uint16_t UEP6_RX_LEN; /* 0x40009094 */
+ __IO uint16_t UEP6_R_SIZE; /* 0x40009096 */
+ __IO uint16_t UEP7_RX_LEN; /* 0x40009098 */
+ __IO uint16_t UEP7_R_SIZE; /* 0x4000909a */
+
+ __IO uint16_t UEP0_TX_LEN; /* 0x4000909c */
+ __IO uint8_t UEP0_TX_CTRL; /* 0x4000909e */
+ __IO uint8_t UEP0_RX_CTRL; /* 0x4000909f */
+ __IO uint16_t UEP1_TX_LEN; /* 0x400090a0 */
+ __IO uint8_t UEP1_TX_CTRL; /* 0x400090a2 */
+ __IO uint8_t UEP1_RX_CTRL; /* 0x400090a3 */
+ __IO uint16_t UEP2_TX_LEN; /* 0x400090a4 */
+ __IO uint8_t UEP2_TX_CTRL; /* 0x400090a6 */
+ __IO uint8_t UEP2_RX_CTRL; /* 0x400090a7 */
+ __IO uint16_t UEP3_TX_LEN; /* 0x400090a8 */
+ __IO uint8_t UEP3_TX_CTRL; /* 0x400090aa */
+ __IO uint8_t UEP3_RX_CTRL; /* 0x400090ab */
+ __IO uint16_t UEP4_TX_LEN; /* 0x400090ac */
+ __IO uint8_t UEP4_TX_CTRL; /* 0x400090ae */
+ __IO uint8_t UEP4_RX_CTRL; /* 0x400090af */
+ __IO uint16_t UEP5_TX_LEN; /* 0x400090b0 */
+ __IO uint8_t UEP5_TX_CTRL; /* 0x400090b2 */
+ __IO uint8_t UEP5_RX_CTRL; /* 0x400090b3 */
+ __IO uint16_t UEP6_TX_LEN; /* 0x400090b4 */
+ __IO uint8_t UEP6_TX_CTRL; /* 0x400090b6 */
+ __IO uint8_t UEP6_RX_CTRL; /* 0x400090b7 */
+ __IO uint16_t UEP7_TX_LEN; /* 0x400090b8 */
+ __IO uint8_t UEP7_TX_CTRL; /* 0x400090ba */
+ __IO uint8_t UEP7_RX_CTRL; /* 0x400090bb */
+ __IO uint16_t UEP_TX_ISO; /* 0x400090bc */
+ __IO uint16_t UEP_RX_ISO; /* 0x400090be */
+} USBHSD_TypeDef;
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/ch32/usb_ch58x_dc_usbfs.c b/components/drivers/usb/cherryusb/port/ch32/usb_ch58x_dc_usbfs.c
new file mode 100644
index 0000000000..5771efb637
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ch32/usb_ch58x_dc_usbfs.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usb_ch58x_usbfs_reg.h"
+
+/**
+ * @brief Related register macro
+ */
+#define USB0_BASE 0x40008000u
+#define USB1_BASE 0x40008400u
+
+#ifndef USBD
+#define USBD USB0_BASE
+#endif
+#define CH58x_USBFS_DEV ((USB_FS_TypeDef *)USBD)
+
+#ifndef USBD_IRQHandler
+#define USBD_IRQHandler USB_IRQHandler //use actual usb irq name instead
+#endif
+
+/*!< 8-bit value of endpoint control register */
+#define EPn_CTRL(epid) \
+ *(volatile uint8_t *)(&(CH58x_USBFS_DEV->UEP0_CTRL) + epid * 4 + (epid / 5) * 48)
+
+/*!< The length register value of the endpoint send buffer */
+#define EPn_TX_LEN(epid) \
+ *(volatile uint8_t *)(&(CH58x_USBFS_DEV->UEP0_T_LEN) + epid * 4 + (epid / 5) * 48)
+
+/*!< Read setup packet to use in ep0 in */
+#define GET_SETUP_PACKET(data_add) \
+ *(struct usb_setup_packet *)data_add
+
+/*!< Set epid ep tx valid // Not an isochronous endpoint */
+#define EPn_SET_TX_VALID(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_ACK;
+/*!< Set epid ep rx valid // Not an isochronous endpoint */
+#define EPn_SET_RX_VALID(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_ACK;
+/*!< Set epid ep tx valid // Isochronous endpoint */
+#define EPn_SET_TX_ISO_VALID(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_TOUT;
+/*!< Set epid ep rx valid // Isochronous endpoint */
+#define EPn_SET_RX_ISO_VALID(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_TOUT;
+/*!< Set epid ep tx nak */
+#define EPn_SET_TX_NAK(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
+/*!< Set epid ep rx nak */
+#define EPn_SET_RX_NAK(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_NAK;
+/*!< Set epid ep tx stall */
+#define EPn_SET_TX_STALL(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_STALL
+/*!< Set epid ep rx stall */
+#define EPn_SET_RX_STALL(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_STALL
+/*!< Clear epid ep tx stall */
+#define EPn_CLR_TX_STALL(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK
+/*!< Clear epid ep rx stall */
+#define EPn_CLR_RX_STALL(epid) \
+ EPn_CTRL(epid) = (EPn_CTRL(epid) & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK
+/*!< Set epid ep tx len */
+#define EPn_SET_TX_LEN(epid, len) \
+ EPn_TX_LEN(epid) = len
+/*!< Get epid ep rx len */
+#define EPn_GET_RX_LEN(epid) \
+ CH58x_USBFS_DEV->USB_RX_LEN
+
+/*!< ep nums */
+#ifndef CONFIG_USBDEV_EP_NUM
+#define CONFIG_USBDEV_EP_NUM 5
+#endif
+/*!< ep mps */
+#define EP_MPS 64
+/*!< set ep4 in mps 64 */
+#define EP4_IN_MPS EP_MPS
+/*!< set ep4 out mps 64 */
+#define EP4_OUT_MPS EP_MPS
+
+/*!< User defined assignment endpoint RAM */
+__attribute__((aligned(4))) uint8_t ep0_data_buff[64 + EP4_OUT_MPS + EP4_IN_MPS]; /*!< ep0(64)+ep4_out(64)+ep4_in(64) */
+__attribute__((aligned(4))) uint8_t ep1_data_buff[64 + 64]; /*!< ep1_out(64)+ep1_in(64) */
+__attribute__((aligned(4))) uint8_t ep2_data_buff[64 + 64]; /*!< ep2_out(64)+ep2_in(64) */
+__attribute__((aligned(4))) uint8_t ep3_data_buff[64 + 64]; /*!< ep3_out(64)+ep3_in(64) */
+#if (CONFIG_USBDEV_EP_NUM == 8)
+/**
+ * This dcd porting can be used on ch581, ch582, ch583,
+ * and also on ch571, ch572, and ch573. Note that only five endpoints are available for ch571, ch572, and ch573.
+ */
+__attribute__((aligned(4))) uint8_t ep5_data_buff[64 + 64]; /*!< ep5_out(64)+ep5_in(64) */
+__attribute__((aligned(4))) uint8_t ep6_data_buff[64 + 64]; /*!< ep6_out(64)+ep6_in(64) */
+__attribute__((aligned(4))) uint8_t ep7_data_buff[64 + 64]; /*!< ep7_out(64)+ep7_in(64) */
+#endif
+/**
+ * @brief Endpoint information structure
+ */
+typedef struct _usbd_ep_info {
+ uint8_t mps; /*!< Maximum packet length of endpoint */
+ uint8_t eptype; /*!< Endpoint Type */
+ uint8_t *ep_ram_addr; /*!< Endpoint buffer address */
+
+ uint8_t ep_enable; /* Endpoint enable */
+ uint8_t *xfer_buf;
+ uint32_t xfer_len;
+ uint32_t actual_xfer_len;
+} usbd_ep_info;
+
+/*!< ch58x usb */
+static struct _ch58x_core_prvi {
+ uint8_t address; /*!< Address */
+ usbd_ep_info ep_in[CONFIG_USBDEV_EP_NUM];
+ usbd_ep_info ep_out[CONFIG_USBDEV_EP_NUM];
+ struct usb_setup_packet setup;
+} usb_dc_cfg;
+
+__WEAK void usb_dc_low_level_init(void)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(void)
+{
+}
+
+/**
+ * @brief USB initialization
+ * @pre None
+ * @param[in] None
+ * @retval >=0 success otherwise failure
+ */
+int usb_dc_init(uint8_t busid)
+{
+ usb_dc_cfg.ep_in[0].ep_ram_addr = ep0_data_buff;
+ usb_dc_cfg.ep_out[0].ep_ram_addr = ep0_data_buff;
+
+ usb_dc_cfg.ep_in[1].ep_ram_addr = ep1_data_buff + 64;
+ usb_dc_cfg.ep_out[1].ep_ram_addr = ep1_data_buff;
+
+ usb_dc_cfg.ep_in[2].ep_ram_addr = ep2_data_buff + 64;
+ usb_dc_cfg.ep_out[2].ep_ram_addr = ep2_data_buff;
+
+ usb_dc_cfg.ep_in[3].ep_ram_addr = ep3_data_buff + 64;
+ usb_dc_cfg.ep_out[3].ep_ram_addr = ep3_data_buff;
+
+ usb_dc_cfg.ep_in[4].ep_ram_addr = ep0_data_buff + 64 + EP4_OUT_MPS;
+ usb_dc_cfg.ep_out[4].ep_ram_addr = ep0_data_buff + 64;
+#if (CONFIG_USBDEV_EP_NUM == 8)
+ usb_dc_cfg.ep_in[5].ep_ram_addr = ep5_data_buff + 64;
+ usb_dc_cfg.ep_out[5].ep_ram_addr = ep5_data_buff;
+
+ usb_dc_cfg.ep_in[6].ep_ram_addr = ep6_data_buff + 64;
+ usb_dc_cfg.ep_out[6].ep_ram_addr = ep6_data_buff;
+
+ usb_dc_cfg.ep_in[7].ep_ram_addr = ep7_data_buff + 64;
+ usb_dc_cfg.ep_out[7].ep_ram_addr = ep7_data_buff;
+#endif
+ /*!< Set the mode first and cancel RB_UC_CLR_ALL */
+ CH58x_USBFS_DEV->USB_CTRL = 0x00;
+ CH58x_USBFS_DEV->UEP4_1_MOD = RB_UEP4_RX_EN | RB_UEP4_TX_EN | RB_UEP1_RX_EN | RB_UEP1_TX_EN; /*!< EP4 OUT+IN EP1 OUT+IN */
+ CH58x_USBFS_DEV->UEP2_3_MOD = RB_UEP2_RX_EN | RB_UEP2_TX_EN | RB_UEP3_RX_EN | RB_UEP3_TX_EN; /*!< EP2 OUT+IN EP3 OUT+IN */
+#if (CONFIG_USBDEV_EP_NUM == 8)
+ CH58x_USBFS_DEV->UEP567_MOD = RB_UEP5_RX_EN | RB_UEP5_TX_EN | RB_UEP6_RX_EN | RB_UEP6_TX_EN | RB_UEP7_RX_EN | RB_UEP7_TX_EN; /*!< EP5 EP6 EP7 OUT+IN */
+#endif
+ CH58x_USBFS_DEV->UEP0_DMA = (uint16_t)(uint32_t)ep0_data_buff;
+ CH58x_USBFS_DEV->UEP1_DMA = (uint16_t)(uint32_t)ep1_data_buff;
+ CH58x_USBFS_DEV->UEP2_DMA = (uint16_t)(uint32_t)ep2_data_buff;
+ CH58x_USBFS_DEV->UEP3_DMA = (uint16_t)(uint32_t)ep3_data_buff;
+#if (CONFIG_USBDEV_EP_NUM == 8)
+ CH58x_USBFS_DEV->UEP5_DMA = (uint16_t)(uint32_t)ep5_data_buff;
+ CH58x_USBFS_DEV->UEP6_DMA = (uint16_t)(uint32_t)ep6_data_buff;
+ CH58x_USBFS_DEV->UEP7_DMA = (uint16_t)(uint32_t)ep7_data_buff;
+#endif
+ CH58x_USBFS_DEV->UEP0_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK;
+ CH58x_USBFS_DEV->UEP1_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
+ CH58x_USBFS_DEV->UEP2_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
+ CH58x_USBFS_DEV->UEP3_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
+ CH58x_USBFS_DEV->UEP4_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK;
+#if (CONFIG_USBDEV_EP_NUM == 8)
+ CH58x_USBFS_DEV->UEP5_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
+ CH58x_USBFS_DEV->UEP6_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
+ CH58x_USBFS_DEV->UEP7_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
+#endif
+ CH58x_USBFS_DEV->USB_DEV_AD = 0x00;
+
+ /*!< Start the USB device and DMA, and automatically return to NAK before the interrupt flag is cleared during the interrupt */
+ CH58x_USBFS_DEV->USB_CTRL = RB_UC_DEV_PU_EN | RB_UC_INT_BUSY | RB_UC_DMA_EN;
+ if ((uint32_t) & (CH58x_USBFS_DEV->USB_CTRL) == (uint32_t)USB0_BASE) {
+ /*!< USB0 */
+ R16_PIN_ANALOG_IE |= RB_PIN_USB_IE | RB_PIN_USB_DP_PU;
+ } else if ((uint32_t) & (CH58x_USBFS_DEV->USB_CTRL) == (uint32_t)USB1_BASE) {
+ /*!< USB1 */
+ R16_PIN_ANALOG_IE |= RB_PIN_USB2_IE | RB_PIN_USB2_DP_PU;
+ }
+
+ CH58x_USBFS_DEV->USB_INT_FG = 0xff; /*!< Clear interrupt flag */
+ CH58x_USBFS_DEV->UDEV_CTRL = RB_UD_PD_DIS | RB_UD_PORT_EN; /*!< Allow USB port */
+ CH58x_USBFS_DEV->USB_INT_EN = RB_UIE_SUSPEND | RB_UIE_BUS_RST | RB_UIE_TRANSFER;
+
+ usb_dc_low_level_init();
+ return 0;
+}
+
+int usb_dc_deinit(uint8_t busid)
+{
+ return 0;
+}
+
+/**
+ * @brief Set address
+ * @pre None
+ * @param[in] address :8-bit valid address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_set_address(uint8_t busid, const uint8_t address)
+{
+ if (address == 0) {
+ CH58x_USBFS_DEV->USB_DEV_AD = (CH58x_USBFS_DEV->USB_DEV_AD & 0x80) | address;
+ }
+ usb_dc_cfg.address = address;
+ return 0;
+}
+
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ return -1;
+}
+
+uint8_t usbd_get_port_speed(uint8_t busid)
+{
+ return USB_SPEED_FULL;
+}
+
+/**
+ * @brief Open endpoint
+ * @pre None
+ * @param[in] ep_cfg : Endpoint configuration structure pointer
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
+{
+ /*!< ep id */
+ uint8_t epid = USB_EP_GET_IDX(ep->bEndpointAddress);
+ if (epid > (CONFIG_USBDEV_EP_NUM - 1)) {
+ /**
+ * If you use ch58x, you can change the CONFIG_USBDEV_EP_NUM set to 8
+ */
+ USB_LOG_ERR("Ep addr %02x overflow\r\n", ep->bEndpointAddress);
+ return -1;
+ }
+
+ /*!< ep max packet length */
+ uint8_t mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ /*!< update ep max packet length */
+ if (USB_EP_DIR_IS_IN(ep->bEndpointAddress)) {
+ /*!< in */
+ usb_dc_cfg.ep_in[epid].ep_enable = true;
+ usb_dc_cfg.ep_in[epid].mps = mps;
+ usb_dc_cfg.ep_in[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ } else if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
+ /*!< out */
+ usb_dc_cfg.ep_out[epid].ep_enable = true;
+ usb_dc_cfg.ep_out[epid].mps = mps;
+ usb_dc_cfg.ep_out[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ }
+ return 0;
+}
+
+/**
+ * @brief Close endpoint
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_close(uint8_t busid, const uint8_t ep)
+{
+ /*!< ep id */
+ uint8_t epid = USB_EP_GET_IDX(ep);
+ if (USB_EP_DIR_IS_IN(ep)) {
+ /*!< in */
+ usb_dc_cfg.ep_in[epid].ep_enable = false;
+ } else if (USB_EP_DIR_IS_OUT(ep)) {
+ /*!< out */
+ usb_dc_cfg.ep_out[epid].ep_enable = false;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Endpoint setting stall
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
+{
+ /*!< ep id */
+ uint8_t epid = USB_EP_GET_IDX(ep);
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ EPn_SET_RX_STALL(epid);
+ } else {
+ EPn_SET_TX_STALL(epid);
+ }
+ return 0;
+}
+
+/**
+ * @brief Endpoint clear stall
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
+{
+ uint8_t epid = USB_EP_GET_IDX(ep);
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ EPn_CLR_RX_STALL(epid);
+ } else {
+ EPn_CLR_TX_STALL(epid);
+ }
+ return 0;
+}
+
+/**
+ * @brief Check endpoint status
+ * @pre None
+ * @param[in] ep : Endpoint address
+ * @param[out] stalled : Outgoing endpoint status
+ * @retval >=0 success otherwise failure
+ */
+int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
+{
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ } else {
+ }
+ return 0;
+}
+
+/**
+ * @brief Setup in ep transfer setting and start transfer.
+ *
+ * This function is asynchronous.
+ * This function is similar to uart with tx dma.
+ *
+ * This function is called to write data to the specified endpoint. The
+ * supplied usbd_endpoint_callback function will be called when data is transmitted
+ * out.
+ *
+ * @param[in] ep Endpoint address corresponding to the one
+ * listed in the device configuration table
+ * @param[in] data Pointer to data to write
+ * @param[in] data_len Length of the data requested to write. This may
+ * be zero for a zero length status packet.
+ * @return 0 on success, negative errno code on fail.
+ */
+int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (!usb_dc_cfg.ep_in[ep_idx].ep_enable) {
+ return -2;
+ }
+ if ((uint32_t)data & 0x03) {
+ return -3;
+ }
+
+ usb_dc_cfg.ep_in[ep_idx].xfer_buf = (uint8_t *)data;
+ usb_dc_cfg.ep_in[ep_idx].xfer_len = data_len;
+ usb_dc_cfg.ep_in[ep_idx].actual_xfer_len = 0;
+
+ if (data_len == 0) {
+ /*!< write 0 len data */
+ EPn_SET_TX_LEN(ep_idx, 0);
+ /*!< enable tx */
+ if (usb_dc_cfg.ep_in[ep_idx].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ EPn_SET_TX_VALID(ep_idx);
+ } else {
+ EPn_SET_TX_ISO_VALID(ep_idx);
+ }
+ /*!< return */
+ return 0;
+ } else {
+ /*!< Not zlp */
+ data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
+ /*!< write buff */
+ memcpy(usb_dc_cfg.ep_in[ep_idx].ep_ram_addr, data, data_len);
+ /*!< write real_wt_nums len data */
+ EPn_SET_TX_LEN(ep_idx, data_len);
+ /*!< enable tx */
+ if (usb_dc_cfg.ep_in[ep_idx].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ EPn_SET_TX_VALID(ep_idx);
+ } else {
+ EPn_SET_TX_ISO_VALID(ep_idx);
+ }
+ }
+ return 0;
+}
+
+/**
+ * @brief Setup out ep transfer setting and start transfer.
+ *
+ * This function is asynchronous.
+ * This function is similar to uart with rx dma.
+ *
+ * This function is called to read data to the specified endpoint. The
+ * supplied usbd_endpoint_callback function will be called when data is received
+ * in.
+ *
+ * @param[in] ep Endpoint address corresponding to the one
+ * listed in the device configuration table
+ * @param[in] data Pointer to data to read
+ * @param[in] data_len Max length of the data requested to read.
+ *
+ * @return 0 on success, negative errno code on fail.
+ */
+int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (!usb_dc_cfg.ep_out[ep_idx].ep_enable) {
+ return -2;
+ }
+ if ((uint32_t)data & 0x03) {
+ return -3;
+ }
+
+ usb_dc_cfg.ep_out[ep_idx].xfer_buf = (uint8_t *)data;
+ usb_dc_cfg.ep_out[ep_idx].xfer_len = data_len;
+ usb_dc_cfg.ep_out[ep_idx].actual_xfer_len = 0;
+
+ if (data_len == 0) {
+ } else {
+ data_len = MIN(data_len, usb_dc_cfg.ep_out[ep_idx].mps);
+ }
+
+ if (usb_dc_cfg.ep_out[ep_idx].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ EPn_SET_RX_VALID(ep_idx);
+ } else {
+ EPn_SET_RX_ISO_VALID(ep_idx);
+ }
+ return 0;
+}
+
+/**
+ * @brief USB interrupt processing function
+ * @pre None
+ * @param[in] None
+ * @retval None
+ */
+__attribute__((interrupt("WCH-Interrupt-fast")))
+__attribute__((section(".highcode"))) void
+USBD_IRQHandler(void)
+{
+ volatile uint8_t intflag = 0;
+ intflag = CH58x_USBFS_DEV->USB_INT_FG;
+
+ if (intflag & RB_UIF_TRANSFER) {
+ if ((CH58x_USBFS_DEV->USB_INT_ST & MASK_UIS_TOKEN) != MASK_UIS_TOKEN) {
+ uint8_t epid = ((CH58x_USBFS_DEV->USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) & 0x0f);
+ switch ((CH58x_USBFS_DEV->USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) & 0xf0) {
+ case UIS_TOKEN_IN:
+ if (epid == 0) {
+ /**
+ * IN The host takes away the data that has been stored in FIFO
+ */
+ switch (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
+ case 1:
+ /*!< Get */
+ CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_T_TOG;
+ /**
+ * Here is to take away the last data, and the IN interrupt will be triggered only after it is successfully taken away.
+ * Therefore, the status of the in endpoint is set to NAK here. If there is data transmission,
+ * the endpoint status will be set to ack again in the in handler of EP0.
+ */
+ EPn_SET_TX_NAK(0);
+
+ /*!< IN */
+ if (usb_dc_cfg.ep_in[0].xfer_len > usb_dc_cfg.ep_in[0].mps) {
+ usb_dc_cfg.ep_in[0].xfer_len -= usb_dc_cfg.ep_in[0].mps;
+ usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].mps;
+ usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
+ } else {
+ usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].xfer_len;
+ usb_dc_cfg.ep_in[0].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
+ }
+ break;
+ case 0:
+ /*!< Set */
+ switch (usb_dc_cfg.setup.bRequest) {
+ case USB_REQUEST_SET_ADDRESS:
+ /*!< Fill in the equipment address */
+ CH58x_USBFS_DEV->USB_DEV_AD = (CH58x_USBFS_DEV->USB_DEV_AD & RB_UDA_GP_BIT) | usb_dc_cfg.address;
+ /**
+ * In the state phase after setting the address, the host has sent an in token packet of data1 to take the packet of 0 length,
+ * Ch58x USB IP needs to manually set the status of the in endpoint to NAK
+ */
+ EPn_SET_TX_NAK(0);
+ EPn_SET_RX_VALID(0);
+ break;
+ default:
+ /*!< Normal out state phase */
+ /**
+ * The host has sent an in token packet of data1 and taken the packet of 0 length.
+ * Here, you only need to set the status of the in endpoint to NAK and out endpoint ACK
+ */
+ EPn_SET_TX_NAK(0);
+ EPn_SET_RX_VALID(0);
+ break;
+ }
+ break;
+ }
+ } else {
+ if (epid == 4) {
+ CH58x_USBFS_DEV->UEP4_CTRL ^= RB_UEP_T_TOG;
+ }
+ EPn_SET_TX_NAK(epid);
+ if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
+ /*!< Need start in again */
+ usb_dc_cfg.ep_in[epid].xfer_buf += usb_dc_cfg.ep_in[epid].mps;
+ usb_dc_cfg.ep_in[epid].xfer_len -= usb_dc_cfg.ep_in[epid].mps;
+ usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].mps;
+ if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
+ memcpy(usb_dc_cfg.ep_in[epid].ep_ram_addr, usb_dc_cfg.ep_in[epid].xfer_buf, usb_dc_cfg.ep_in[epid].mps);
+ EPn_SET_TX_LEN(epid, usb_dc_cfg.ep_in[epid].mps);
+ } else {
+ memcpy(usb_dc_cfg.ep_in[epid].ep_ram_addr, usb_dc_cfg.ep_in[epid].xfer_buf, usb_dc_cfg.ep_in[epid].xfer_len);
+ EPn_SET_TX_LEN(epid, usb_dc_cfg.ep_in[epid].xfer_len);
+ }
+ if (usb_dc_cfg.ep_in[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ EPn_SET_TX_VALID(epid);
+ } else {
+ EPn_SET_TX_ISO_VALID(epid);
+ }
+ } else {
+ usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].xfer_len;
+ usb_dc_cfg.ep_in[epid].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(0, epid | 0x80, usb_dc_cfg.ep_in[epid].actual_xfer_len);
+ }
+ }
+ break;
+ case UIS_TOKEN_OUT:
+ EPn_SET_RX_NAK(epid);
+
+ if (epid == 0) {
+ /*!< ep0 out */
+ CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_R_TOG;
+ uint32_t read_count = EPn_GET_RX_LEN(0);
+ memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
+
+ usb_dc_cfg.ep_out[0].actual_xfer_len += read_count;
+ usb_dc_cfg.ep_out[0].xfer_len -= read_count;
+ usbd_event_ep_out_complete_handler(0, 0x00, usb_dc_cfg.ep_out[0].actual_xfer_len);
+ if (read_count == 0) {
+ /*!< Out status, start reading setup */
+ EPn_SET_RX_VALID(0);
+ }
+ } else {
+ if ((CH58x_USBFS_DEV->USB_INT_ST) & RB_UIS_TOG_OK) {
+ if (epid == 4) {
+ CH58x_USBFS_DEV->UEP4_CTRL ^= RB_UEP_R_TOG;
+ }
+ uint32_t read_count = EPn_GET_RX_LEN(epid);
+ memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
+ usb_dc_cfg.ep_out[epid].xfer_buf += read_count;
+ usb_dc_cfg.ep_out[epid].actual_xfer_len += read_count;
+ usb_dc_cfg.ep_out[epid].xfer_len -= read_count;
+
+ if ((read_count < usb_dc_cfg.ep_out[epid].mps) || (usb_dc_cfg.ep_out[epid].xfer_len == 0)) {
+ usbd_event_ep_out_complete_handler(0, ((epid)&0x7f), usb_dc_cfg.ep_out[epid].actual_xfer_len);
+ } else {
+ if (usb_dc_cfg.ep_out[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ EPn_SET_RX_VALID(epid);
+ } else {
+ EPn_SET_RX_ISO_VALID(epid);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_TRANSFER;
+ }
+
+ if (CH58x_USBFS_DEV->USB_INT_ST & RB_UIS_SETUP_ACT) {
+ /*!< Setup */
+ /**
+ * Setup the device must respond with ACK, and the next data phase is DATA1
+ * If it is sent, the data1 packet will be sent.
+ * If it is received, the data1 packet is expected to be received.
+ * If it is in, the host will send the data1 out packet to complete the status phase after the in completes.
+ * If it is out, the host will send the data1 in packet to complete the status phase after the out completes.
+ */
+ CH58x_USBFS_DEV->UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_T_RES_NAK;
+ /*!< get setup packet */
+ usb_dc_cfg.setup = GET_SETUP_PACKET(usb_dc_cfg.ep_out[0].ep_ram_addr);
+ if (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT == 0) {
+ /**
+ * Ep0 The next in must be the status stage.
+ * The device must reply to the host data 0 length packet.
+ * Here, set the transmission length to 0 and the transmission status to ACK,
+ * and wait for the host to send the in token to retrieve
+ */
+ EPn_SET_TX_LEN(0, 0);
+ EPn_SET_TX_VALID(0);
+ }
+ EPn_SET_RX_NAK(0);
+ usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&(usb_dc_cfg.setup));
+ CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_TRANSFER;
+ }
+ } else if (intflag & RB_UIF_BUS_RST) {
+ /*!< Reset */
+ CH58x_USBFS_DEV->USB_DEV_AD = 0;
+ usbd_event_reset_handler(0);
+ /*!< Set ep0 rx vaild to start receive setup packet */
+ EPn_SET_RX_VALID(0);
+ CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_BUS_RST;
+ } else if (intflag & RB_UIF_SUSPEND) {
+ if (CH58x_USBFS_DEV->USB_MIS_ST & RB_UMS_SUSPEND) {
+ /*!< Suspend */
+ } else {
+ /*!< Wake up */
+ }
+ CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_SUSPEND;
+ } else {
+ CH58x_USBFS_DEV->USB_INT_FG = intflag;
+ }
+}
diff --git a/components/drivers/usb/cherryusb/port/ch32/usb_ch58x_usbfs_reg.h b/components/drivers/usb/cherryusb/port/ch32/usb_ch58x_usbfs_reg.h
new file mode 100644
index 0000000000..f7fda8c62f
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ch32/usb_ch58x_usbfs_reg.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#pragma once
+
+#define __IO volatile
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RB_UC_HOST_MODE 0x80 // enable USB host mode: 0=device mode, 1=host mode
+#define RB_UC_LOW_SPEED 0x40 // enable USB low speed: 0=12Mbps, 1=1.5Mbps
+#define RB_UC_DEV_PU_EN 0x20 // USB device enable and internal pullup resistance enable
+#define RB_UC_SYS_CTRL1 0x20 // USB system control high bit
+#define RB_UC_SYS_CTRL0 0x10 // USB system control low bit
+#define MASK_UC_SYS_CTRL 0x30 // bit mask of USB system control
+#define RB_UC_INT_BUSY 0x08 // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
+#define RB_UC_RESET_SIE 0x04 // force reset USB SIE, need software clear
+#define RB_UC_CLR_ALL 0x02 // force clear FIFO and count of USB
+#define RB_UC_DMA_EN 0x01 // DMA enable and DMA interrupt enable for USB
+
+#define RB_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
+#define RB_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
+#define RB_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
+#define RB_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
+#define RB_UD_GP_BIT 0x02 // general purpose bit
+#define RB_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
+
+#define RB_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
+#define RB_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
+#define RB_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
+#define RB_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
+#define RB_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
+#define RB_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
+
+#define RB_UIE_DEV_SOF 0x80 // enable interrupt for SOF received for USB device mode
+#define RB_UIE_DEV_NAK 0x40 // enable interrupt for NAK responded for USB device mode
+#define RB_UIE_FIFO_OV 0x10 // enable interrupt for FIFO overflow
+#define RB_UIE_HST_SOF 0x08 // enable interrupt for host SOF timer action for USB host mode
+#define RB_UIE_SUSPEND 0x04 // enable interrupt for USB suspend or resume event
+#define RB_UIE_TRANSFER 0x02 // enable interrupt for USB transfer completion
+#define RB_UIE_DETECT 0x01 // enable interrupt for USB device detected event for USB host mode
+#define RB_UIE_BUS_RST 0x01 // enable interrupt for USB bus reset event for USB device mode
+
+#define RB_UDA_GP_BIT 0x80 // general purpose bit
+#define MASK_USB_ADDR 0x7F // bit mask for USB device address
+
+#define RB_UMS_SOF_PRES 0x80 // RO, indicate host SOF timer presage status
+#define RB_UMS_SOF_ACT 0x40 // RO, indicate host SOF timer action status for USB host
+#define RB_UMS_SIE_FREE 0x20 // RO, indicate USB SIE free status
+#define RB_UMS_R_FIFO_RDY 0x10 // RO, indicate USB receiving FIFO ready status (not empty)
+#define RB_UMS_BUS_RESET 0x08 // RO, indicate USB bus reset status
+#define RB_UMS_SUSPEND 0x04 // RO, indicate USB suspend status
+#define RB_UMS_DM_LEVEL 0x02 // RO, indicate UDM level saved at device attached to USB host
+#define RB_UMS_DEV_ATTACH 0x01 // RO, indicate device attached status on USB host
+
+#define RB_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
+#define RB_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
+#define RB_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
+#define RB_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
+#define RB_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
+#define RB_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
+#define RB_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
+#define RB_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
+#define RB_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
+
+#define RB_UIS_SETUP_ACT 0x80 // RO, indicate SETUP token & 8 bytes setup request received for USB device mode
+#define RB_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
+#define RB_UIS_TOKEN1 0x20 // RO, current token PID code bit 1 received for USB device mode
+#define RB_UIS_TOKEN0 0x10 // RO, current token PID code bit 0 received for USB device mode
+#define MASK_UIS_TOKEN 0x30 // RO, bit mask of current token PID code received for USB device mode
+#define UIS_TOKEN_OUT 0x00
+#define UIS_TOKEN_SOF 0x10
+#define UIS_TOKEN_IN 0x20
+#define UIS_TOKEN_SETUP 0x30
+
+#define MASK_UIS_ENDP 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
+#define MASK_UIS_H_RES 0x0F // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
+
+#define R8_USB_RX_LEN (*((uint8_t *)0x40008008)) // USB receiving length
+#define RB_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
+#define RB_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
+#define RB_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
+
+#define RB_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
+#define RB_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
+
+#define RB_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
+#define RB_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
+#define RB_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
+#define RB_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
+#define RB_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
+#define RB_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
+
+#define RB_UEP7_RX_EN 0x20 // enable USB endpoint 7 receiving (OUT)
+#define RB_UEP7_TX_EN 0x10 // enable USB endpoint 7 transmittal (IN)
+#define RB_UEP6_RX_EN 0x08 // enable USB endpoint 6 receiving (OUT)
+#define RB_UEP6_TX_EN 0x04 // enable USB endpoint 6 transmittal (IN)
+#define RB_UEP5_RX_EN 0x02 // enable USB endpoint 5 receiving (OUT)
+#define RB_UEP5_TX_EN 0x01 // enable USB endpoint 5 transmittal (IN)
+
+#define RB_UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
+#define RB_UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint
+
+#define RB_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
+#define RB_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint
+
+#define RB_UEP_R_TOG 0x80 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
+#define RB_UEP_T_TOG 0x40 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
+#define RB_UEP_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
+#define RB_UEP_R_RES1 0x08 // handshake response type high bit for USB endpoint X receiving (OUT)
+#define RB_UEP_R_RES0 0x04 // handshake response type low bit for USB endpoint X receiving (OUT)
+#define MASK_UEP_R_RES 0x0C // bit mask of handshake response type for USB endpoint X receiving (OUT)
+#define UEP_R_RES_ACK 0x00
+#define UEP_R_RES_TOUT 0x04
+#define UEP_R_RES_NAK 0x08
+#define UEP_R_RES_STALL 0x0C
+
+#define RB_UEP_T_RES1 0x02 // handshake response type high bit for USB endpoint X transmittal (IN)
+#define RB_UEP_T_RES0 0x01 // handshake response type low bit for USB endpoint X transmittal (IN)
+#define MASK_UEP_T_RES 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
+#define UEP_T_RES_ACK 0x00
+#define UEP_T_RES_TOUT 0x01
+#define UEP_T_RES_NAK 0x02
+#define UEP_T_RES_STALL 0x03
+
+#define RB_UH_PRE_PID_EN 0x80 // USB host PRE PID enable for low speed device via hub
+#define RB_UH_SOF_EN 0x40 // USB host automatic SOF enable
+
+#define R8_UH_EP_PID R8_UEP2_T_LEN // host endpoint and PID
+#define MASK_UH_TOKEN 0xF0 // bit mask of token PID for USB host transfer
+#define MASK_UH_ENDP 0x0F // bit mask of endpoint number for USB host transfer
+
+#define R8_UH_RX_CTRL R8_UEP2_CTRL // host receiver endpoint control
+#define RB_UH_R_TOG 0x80 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
+#define RB_UH_R_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
+#define RB_UH_R_RES 0x04 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
+
+#define R8_UH_TX_LEN R8_UEP3_T_LEN // host transmittal endpoint transmittal length
+
+#define RB_UH_T_TOG 0x40 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
+#define RB_UH_T_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
+#define RB_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
+
+#define R16_PIN_ANALOG_IE (*((uint16_t *)0x4000101A)) // RW, analog pin enable and digital input disable
+#define RB_PIN_USB_IE 0x80 // RW, USB analog I/O enable: 0=analog I/O disable, 1=analog I/O enable
+#define RB_PIN_USB_DP_PU 0x40 // RW, USB UDP internal pullup resistance enable: 0=enable/disable by RB_UC_DEV_PU_EN, 1=enable pullup, replace RB_UC_DEV_PU_EN under sleep mode
+#define RB_PIN_USB2_IE 0x20 // RW, USB2 analog I/O enable: 0=analog I/O disable, 1=analog I/O enable
+#define RB_PIN_USB2_DP_PU 0x10 // RW, USB2 UDP internal pullup resistance enable: 0=enable/disable by RB_UC_DEV_PU_EN, 1=enable pullup, replace RB_UC_DEV_PU_EN under sleep mode
+/*!< USB Regs */
+typedef struct
+{
+ __IO uint8_t USB_CTRL; /*!< 0x40008000 */
+ union {
+ __IO uint8_t UDEV_CTRL; /*!< 0x40008001 */
+ __IO uint8_t UHOST_CTRL; /*!< 0x40008001 */
+ };
+ __IO uint8_t USB_INT_EN; /*!< 0x40008002 */
+ __IO uint8_t USB_DEV_AD; /*!< 0x40008003 */
+ __IO uint8_t USB_STATUS0; /*!< 0x40008004 */
+ __IO uint8_t USB_MIS_ST; /*!< 0x40008005 */
+ __IO uint8_t USB_INT_FG; /*!< 0x40008006 */
+ __IO uint8_t USB_INT_ST; /*!< 0x40008007 */
+ __IO uint8_t USB_RX_LEN; /*!< 0x40008008 */
+ __IO uint8_t Reserve1; /*!< 0x40008009 */
+ __IO uint8_t Reserve2; /*!< 0x4000800a */
+ __IO uint8_t Reserve3; /*!< 0x4000800b */
+ __IO uint8_t UEP4_1_MOD; /*!< 0x4000800c */
+ union {
+ __IO uint8_t UEP2_3_MOD; /*!< 0x4000800d */
+ __IO uint8_t UH_EP_MOD; /*!< 0x4000800d */
+ };
+ __IO uint8_t UEP567_MOD; /*!< 0x4000800e */
+ __IO uint8_t Reserve4; /*!< 0x4000800f */
+ __IO uint16_t UEP0_DMA; /*!< 0x40008010 */
+ __IO uint16_t Reserve5; /*!< 0x40008012 */
+ __IO uint16_t UEP1_DMA; /*!< 0x40008014 */
+ __IO uint16_t Reserve6; /*!< 0x40008016 */
+ union {
+ __IO uint16_t UEP2_DMA; /*!< 0x40008018 */
+ __IO uint16_t UH_RX_DMA; /*!< 0x40008018 */
+ };
+ __IO uint16_t Reserve7; /*!< 0x4000801a */
+ union {
+ __IO uint16_t UEP3_DMA; /*!< 0x4000801c */
+ __IO uint16_t UH_TX_DMA; /*!< 0x4000801c */
+ };
+ __IO uint16_t Reserve8; /*!< 0x4000801e */
+ __IO uint8_t UEP0_T_LEN; /*!< 0x40008020 */
+ __IO uint8_t Reserve9; /*!< 0x40008021 */
+ __IO uint8_t UEP0_CTRL; /*!< 0x40008022 */
+ __IO uint8_t Reserve10; /*!< 0x40008023 */
+ __IO uint8_t UEP1_T_LEN; /*!< 0x40008024 */
+ __IO uint8_t Reserve11; /*!< 0x40008025 */
+ union {
+ __IO uint8_t UEP1_CTRL; /*!< 0x40008026 */
+ __IO uint8_t UH_SETUP; /*!< 0x40008026 */
+ };
+ __IO uint8_t Reserve12; /*!< 0x40008027 */
+ union {
+ __IO uint8_t UEP2_T_LEN; /*!< 0x40008028 */
+ __IO uint8_t UH_EP_PID; /*!< 0x40008028 */
+ };
+ __IO uint8_t Reserve13; /*!< 0x40008029 */
+ union {
+ __IO uint8_t UEP2_CTRL; /*!< 0x4000802a */
+ __IO uint8_t UH_RX_CTRL; /*!< 0x4000802a */
+ };
+ __IO uint8_t Reserve14; /*!< 0x4000802b */
+ union {
+ __IO uint8_t UEP3_T_LEN; /*!< 0x4000802c */
+ __IO uint8_t UH_TX_LEN; /*!< 0x4000802c */
+ };
+ __IO uint8_t Reserve15; /*!< 0x4000802d */
+ union {
+ __IO uint8_t UEP3_CTRL; /*!< 0x4000802e */
+ __IO uint8_t UH_TX_CTRL; /*!< 0x4000802e */
+ };
+ __IO uint8_t Reserve16; /*!< 0x4000802f */
+ __IO uint8_t UEP4_T_LEN; /*!< 0x40008030 */
+ __IO uint8_t Reserve17; /*!< 0x40008031 */
+ __IO uint8_t UEP4_CTRL; /*!< 0x40008032 */
+ __IO uint8_t Reserve18[33]; /*!< 0x40008033 */
+ __IO uint16_t UEP5_DMA; /*!< 0x40008054 */
+ __IO uint16_t Reserve19; /*!< 0x40008056 */
+ __IO uint16_t UEP6_DMA; /*!< 0x40008058 */
+ __IO uint16_t Reserve20; /*!< 0x4000805a */
+ __IO uint16_t UEP7_DMA; /*!< 0x4000805c */
+ __IO uint8_t Reserve21[6]; /*!< 0x4000805e */
+ __IO uint8_t UEP5_T_LEN; /*!< 0x40008064 */
+ __IO uint8_t Reserve22; /*!< 0x40008065 */
+ __IO uint8_t UEP5_CTRL; /*!< 0x40008066 */
+ __IO uint8_t Reserve23; /*!< 0x40008067 */
+ __IO uint8_t UEP6_T_LEN; /*!< 0x40008068 */
+ __IO uint8_t Reserve24; /*!< 0x40008069 */
+ __IO uint8_t UEP6_CTRL; /*!< 0x4000806a */
+ __IO uint8_t Reserve25; /*!< 0x4000806b */
+ __IO uint8_t UEP7_T_LEN; /*!< 0x4000806c */
+ __IO uint8_t Reserve26; /*!< 0x4000806d */
+ __IO uint8_t UEP7_CTRL; /*!< 0x4000806e */
+} USB_FS_TypeDef;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/components/drivers/usb/cherryusb/port/dwc2/README.md b/components/drivers/usb/cherryusb/port/dwc2/README.md
index 3218b31cd5..b35a7a038e 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/README.md
+++ b/components/drivers/usb/cherryusb/port/dwc2/README.md
@@ -27,7 +27,7 @@ CONFIG_USBDEV_EP_NUM 必须为4 或者 6,并删除 usb_dc_dwc2.c 中 while(1){
- GD32F30X_CL
- GD32F405、GD32F407
-- GD32F450
+- GD32F350、GD32F450
## HC32
@@ -35,7 +35,7 @@ CONFIG_USBDEV_EP_NUM 必须为4 或者 6,并删除 usb_dc_dwc2.c 中 while(1){
## Espressif
-- ESP32S2、ESP32S3
+- ESP32S2、ESP32S3、ESP32P4
## Sophgo
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c
index 76abb19ea4..9b62db4e60 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c
@@ -9,6 +9,7 @@
#include "esp_private/usb_phy.h"
#include "soc/periph_defs.h"
#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
#include "usbd_core.h"
#include "usbh_core.h"
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
index 4dff31f83f..51838091e5 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
@@ -194,8 +194,6 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
USB_OTG_GLB->GCCFG = (1 << 23);
usb_hsphy_init(25000000U);
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
-#elif __has_include("stm32h7rsxx.h")
- return (1 << 21);
#else
return 0;
#endif
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c b/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c
index 09f55170a5..de053cd0cd 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c
@@ -41,6 +41,7 @@ struct dwc2_chan {
uint32_t xferlen;
uint8_t chidx;
bool inuse;
+ bool dir_in;
usb_osal_sem_t waitsem;
struct usbh_urb *urb;
uint32_t iso_frame_idx;
@@ -256,16 +257,26 @@ static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr
}
/* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of ep_mps size.*/
-static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
+static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint8_t ep_addr, uint8_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
{
__IO uint32_t tmpreg;
uint8_t is_oddframe;
+ struct dwc2_chan *chan;
+
+ chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[ch_num];
/* Initialize the HCTSIZn register */
USB_OTG_HC(ch_num)->HCTSIZ = (size & USB_OTG_HCTSIZ_XFRSIZ) |
(((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
(((uint32_t)pid << 29) & USB_OTG_HCTSIZ_DPID);
+ if (!(ep_addr & 0x80)) {
+ chan->dir_in = false;
+ usb_dcache_clean((uintptr_t)buf, USB_ALIGN_UP(size, CONFIG_USB_ALIGN_SIZE));
+ } else {
+ chan->dir_in = true;
+ }
+
/* xfer_buff MUST be 32-bits aligned */
USB_OTG_HC(ch_num)->HCDMA = (uint32_t)buf;
@@ -400,17 +411,17 @@ static void dwc2_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct us
{
chan->num_packets = dwc2_calculate_packet_num(8, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
- dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
+ dwc2_chan_transfer(bus, chidx, 0x00, (uint8_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
} else if (chan->ep0_state == DWC2_EP0_STATE_INDATA) /* fill in data */
{
chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
- dwc2_chan_transfer(bus, chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ dwc2_chan_transfer(bus, chidx, 0x80, buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) /* fill out data */
{
chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
- dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ dwc2_chan_transfer(bus, chidx, 0x00, buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
} else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) /* fill in status */
{
chan->num_packets = dwc2_calculate_packet_num(0, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
@@ -432,9 +443,10 @@ static void dwc2_bulk_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct
chan->num_packets = dwc2_calculate_packet_num(buflen, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
- dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)buffer, chan->xferlen, chan->num_packets, urb->data_toggle == 0 ? HC_PID_DATA0 : HC_PID_DATA1);
+ dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, buffer, chan->xferlen, chan->num_packets, urb->data_toggle == 0 ? HC_PID_DATA0 : HC_PID_DATA1);
}
+#if 0
static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usbh_iso_frame_packet *iso_packet)
{
struct dwc2_chan *chan;
@@ -443,8 +455,9 @@ static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_u
chan->num_packets = dwc2_calculate_packet_num(iso_packet->transfer_buffer_length, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_ENDPOINT_TYPE_ISOCHRONOUS, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
- dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
+ dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
}
+#endif
__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
{
@@ -754,6 +767,13 @@ int usbh_submit_urb(struct usbh_urb *urb)
return -USB_ERR_INVAL;
}
+#ifdef CONFIG_USB_DCACHE_ENABLE
+ if (((uintptr_t)urb->setup % CONFIG_USB_ALIGN_SIZE) || ((uintptr_t)urb->transfer_buffer % CONFIG_USB_ALIGN_SIZE)) {
+ USB_LOG_ERR("urb buffer is not align with %d\r\n", CONFIG_USB_ALIGN_SIZE);
+ while (1) {
+ }
+ }
+#endif
bus = urb->hport->bus;
if (!(USB_OTG_HPRT & USB_OTG_HPRT_PCSTS) || !urb->hport->connected) {
@@ -907,7 +927,7 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
urb->errorcode = 0;
uint32_t count = chan->xferlen - (USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* how many size has received */
- uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
+ //uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
urb->actual_length += count;
@@ -919,6 +939,10 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
urb->data_toggle = 1;
}
+ if (chan->dir_in) {
+ usb_dcache_invalidate((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(count, CONFIG_USB_ALIGN_SIZE));
+ }
+
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
if (chan->ep0_state == DWC2_EP0_STATE_INDATA) {
chan->ep0_state = DWC2_EP0_STATE_OUTSTATUS;
diff --git a/components/drivers/usb/cherryusb/port/ehci/README.md b/components/drivers/usb/cherryusb/port/ehci/README.md
index 8160c65d37..ede4cab812 100644
--- a/components/drivers/usb/cherryusb/port/ehci/README.md
+++ b/components/drivers/usb/cherryusb/port/ehci/README.md
@@ -12,7 +12,7 @@
### AllwinnerTech
-- F133
+- F133/T113
### Nuvoton
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_glue_t113.c b/components/drivers/usb/cherryusb/port/ehci/usb_glue_t113.c
new file mode 100644
index 0000000000..99927acbcc
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_glue_t113.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2025, YC113
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usb_hc_ehci.h"
+#include "usb_hc_ohci.h"
+
+#include "interrupt.h"
+#include "drv_reg_base.h"
+#include "drv_clock.h"
+
+#if !defined(CONFIG_USB_EHCI_WITH_OHCI)
+#error "t113 must define CONFIG_USB_EHCI_WITH_OHCI for ls/fs device"
+#endif
+
+#if CONFIG_USBHOST_MAX_BUS != 2
+#error "t113 has 2 usb host controller"
+#endif
+
+#if CONFIG_USB_OHCI_HCOR_OFFSET != 0x400
+#error "t113 CONFIG_USB_OHCI_HCOR_OFFSET must be 0x400"
+#endif
+
+#if defined(CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE)
+#error "t113 usb ehci register need reserved"
+#endif
+
+#if !defined(CONFIG_USB_EHCI_CONFIGFLAG)
+#error "t113 usb ehci has configflag register"
+#endif
+
+#if defined(CONFIG_USB_EHCI_ISO)
+#error "t113 usb ehci no iso register"
+#endif
+
+void usb_select_phyTohci(void)
+{
+ *(volatile rt_uint32_t *)(USB0_OTG_BASE_ADDR + 0x420) &= ~(1 << 0);
+}
+
+void usb_gate_open(rt_uint8_t busid)
+{
+ rt_uint32_t addr;
+
+ /* otg bus reset and gate open */
+ if (busid == 0)
+ usb_select_phyTohci();
+
+ /* reset phy */
+ addr = (rt_uint32_t)&CCU->usb0_clk + busid * 4;
+ *(volatile rt_uint32_t *)addr &= ~(1 << 30);
+ sdelay(10);
+ *(volatile rt_uint32_t *)addr |= 1 << 30;
+ sdelay(10);
+
+ /* ehci bus reset */
+ CCU->usb_bgr &= ~((1 << 20) << busid);
+ sdelay(10);
+ CCU->usb_bgr |= (1 << 20) << busid;
+ sdelay(10);
+
+ /* ehci gate open */
+ CCU->usb_bgr |= (1 << 4) << busid;
+
+ /* ohci bus reset */
+ CCU->usb_bgr &= ~((1 << 16) << busid);
+ sdelay(10);
+ CCU->usb_bgr |= (1 << 16) << busid;
+ sdelay(10);
+
+ /* ohci gate open */
+ CCU->usb_bgr |= 1 << busid;
+
+ sdelay(10);
+
+ /* clock enable */
+ *(volatile rt_uint32_t *)addr &= ~(3 << 24);
+ *(volatile rt_uint32_t *)addr |= (1 << 31) | (1 << 24);
+
+ USB_LOG_DBG("usb%d gate : %X, clock : %X\n", busid, CCU->usb_bgr, *(volatile rt_uint32_t *)addr);
+}
+
+void usb_clean_siddp(struct usbh_bus *bus)
+{
+ *(volatile rt_uint32_t *)(bus->hcd.reg_base + 0x810) &= ~(1 << 3);
+}
+
+static void usb_new_phyx_tp_write(struct usbh_bus *bus, int addr, int data, int len)
+{
+ rt_uint32_t base = bus->hcd.reg_base;
+
+ for (int i = 0; i < len; i++) {
+ *(volatile rt_uint8_t *)(base + 0x810) |= 1 << 1;
+
+ *(volatile rt_uint8_t *)(base + 0x810 + 1) = addr + i;
+
+ *(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 0);
+
+ *(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 7);
+ *(volatile rt_uint8_t *)(base + 0x810) |= (data & 0x1) << 7;
+
+ *(volatile rt_uint8_t *)(base + 0x810) |= 1 << 0;
+
+ *(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 0);
+
+ *(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 1);
+
+ data >>= 1;
+ }
+}
+
+void usb_new_phy_init(struct usbh_bus *bus)
+{
+ rt_int32_t value = 0;
+ rt_uint32_t efuse_val = 0x1E5080F;
+
+ usb_new_phyx_tp_write(bus, 0x1C, 0x0, 0x03);
+
+ /* vref mode */
+ usb_new_phyx_tp_write(bus, 0x60, 0x0, 0x01);
+
+ value = (efuse_val & 0x3C0000) >> 18;
+ usb_new_phyx_tp_write(bus, 0x44, value, 0x04);
+
+ value = (efuse_val & 0x1C00000) >> 22;
+ usb_new_phyx_tp_write(bus, 0x36, value, 0x03);
+}
+
+void usb_hci_set_passby(struct usbh_bus *bus)
+{
+ /* AHB Master interface INCR16 enable */
+ /* AHB Master interface INCR8 enable */
+ /* AHB Master interface burst type INCR4 enable */
+ /* AHB Master interface INCRX align enable */
+ /* ULPI bypass enable */
+ *(volatile rt_uint32_t *)(bus->hcd.reg_base + 0x800) |= (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 0);
+}
+
+void t113_ehci_isr(int vector, void *arg)
+{
+ struct usbh_bus *bus = (struct usbh_bus *)arg;
+
+ USB_LOG_DBG("t113_ehci_isr");
+
+ extern void USBH_IRQHandler(uint8_t busid);
+ USBH_IRQHandler(bus->hcd.hcd_id);
+}
+
+void t113_ohci_isr(int vector, void *arg)
+{
+ struct usbh_bus *bus = (struct usbh_bus *)arg;
+
+ USB_LOG_DBG("t113_ohci_isr");
+
+ extern void OHCI_IRQHandler(uint8_t busid);
+ OHCI_IRQHandler(bus->hcd.hcd_id);
+}
+
+void usb_hc_low_level_init(struct usbh_bus *bus)
+{
+ int vector;
+ RT_ASSERT(bus->busid <= 1);
+
+ usb_gate_open(bus->busid);
+ usb_clean_siddp(bus);
+ usb_hci_set_passby(bus);
+
+ /* register EHCI interrupt callback */
+ vector = T113_IRQ_USB0_EHCI + (bus->busid > 0 ? 3 : 0);
+ rt_hw_interrupt_install(vector, t113_ehci_isr, bus, RT_NULL);
+ rt_hw_interrupt_umask(vector);
+
+ /* register OHCI interrupt callback */
+ rt_hw_interrupt_install(vector + 1, t113_ohci_isr, bus, RT_NULL);
+ rt_hw_interrupt_umask(vector + 1);
+
+ USB_LOG_DBG("usb%d vector : %d, phy : %X\n", bus->busid, vector, *(volatile rt_uint32_t *)(bus->hcd.reg_base + 0x810));
+ USB_LOG_DBG("usb%d hc low level init success\n", bus->busid);
+}
+
+uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
+{
+ /* Defined by individual manufacturers */
+ uint32_t regval;
+
+ regval = EHCI_HCOR->portsc[port - 1];
+ if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE)
+ return USB_SPEED_LOW;
+
+ if (regval & EHCI_PORTSC_PE)
+ return USB_SPEED_HIGH;
+ else
+ return USB_SPEED_FULL;
+}
+
+int __usbh_init(void)
+{
+#ifdef T113_USING_USB0_HOST
+ /* USB0 MSC test OK */
+ usbh_initialize(0, USB0_BASE_ADDR);
+#endif
+
+#ifdef T113_USING_USB1_HOST
+ /* USB1 MSC test OK */
+ usbh_initialize(1, USB1_BASE_ADDR);
+#endif
+ return 0;
+}
+
+#ifdef PKG_CHERRYUSB_HOST
+
+#include
+#include
+
+INIT_ENV_EXPORT(__usbh_init);
+
+#endif
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c
index 4f61854a33..b40d60d553 100644
--- a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c
@@ -76,10 +76,36 @@ static void ehci_qh_free(struct usbh_bus *bus, struct ehci_qh_hw *qh)
}
}
+#ifdef CONFIG_USB_DCACHE_ENABLE
+static inline void usb_ehci_qh_qtd_flush(struct ehci_qh_hw *qh)
+{
+ struct ehci_qtd_hw *qtd;
+
+ qtd = EHCI_ADDR2QTD(qh->first_qtd);
+
+ while (qtd) {
+ usb_dcache_clean((uintptr_t)&qtd->hw, USB_ALIGN_UP(SIZEOF_EHCI_QTD, CONFIG_USB_EHCI_ALIGN_SIZE));
+
+ if (!qtd->dir_in) {
+ usb_dcache_clean(qtd->bufaddr, USB_ALIGN_UP(qtd->length, CONFIG_USB_ALIGN_SIZE));
+ }
+ qtd = EHCI_ADDR2QTD(qtd->hw.next_qtd);
+ }
+
+ usb_dcache_clean((uintptr_t)&qh->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
+}
+#else
+#define usb_ehci_qh_qtd_flush(qh)
+#endif
+
static inline void ehci_qh_add_head(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
{
n->hw.hlp = head->hw.hlp;
+ usb_ehci_qh_qtd_flush(n);
+
head->hw.hlp = QH_HLP_QH(n);
+
+ usb_dcache_clean((uintptr_t)&head->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
}
static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
@@ -92,6 +118,7 @@ static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
if (tmp) {
tmp->hw.hlp = n->hw.hlp;
+ usb_dcache_clean((uintptr_t)&tmp->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
}
}
@@ -254,7 +281,9 @@ static void ehci_qtd_fill(struct ehci_qtd_hw *qtd, uint32_t bufaddr, size_t bufl
qtd->hw.token = token;
- ehci_qtd_bpl_fill(qtd, bufaddr, buflen);
+ ehci_qtd_bpl_fill(qtd, usb_phyaddr2ramaddr(bufaddr), buflen);
+ qtd->dir_in = ((token & QTD_TOKEN_PID_MASK) == QTD_TOKEN_PID_IN) ? true : false;
+ qtd->bufaddr = bufaddr;
qtd->length = buflen;
}
@@ -591,6 +620,9 @@ static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, st
qtd = EHCI_ADDR2QTD(qh->first_qtd);
while (qtd) {
+ if (qtd->dir_in) {
+ usb_dcache_invalidate(qtd->bufaddr, USB_ALIGN_UP(qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT), CONFIG_USB_ALIGN_SIZE));
+ }
qtd->urb->actual_length += (qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT));
qh->first_qtd = qtd->hw.next_qtd;
@@ -611,6 +643,7 @@ static void ehci_check_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct
}
while (qtd) {
+ usb_dcache_invalidate((uintptr_t)&qtd->hw, USB_ALIGN_UP(SIZEOF_EHCI_QTD, CONFIG_USB_EHCI_ALIGN_SIZE));
token = qtd->hw.token;
if (token & QTD_TOKEN_STATUS_ERRORS) {
@@ -766,6 +799,10 @@ int usb_hc_init(struct usbh_bus *bus)
g_framelist[bus->hcd.hcd_id][i] = QH_HLP_QH(&g_periodic_qh_head[bus->hcd.hcd_id]);
}
+ usb_dcache_clean((uintptr_t)&g_async_qh_head[bus->hcd.hcd_id].hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
+ usb_dcache_clean((uintptr_t)&g_periodic_qh_head[bus->hcd.hcd_id].hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
+ usb_dcache_clean((uintptr_t)g_framelist[bus->hcd.hcd_id], sizeof(uint32_t) * CONFIG_USB_EHCI_FRAME_LIST_SIZE);
+
usb_hc_low_level_init(bus);
USB_LOG_INFO("EHCI HCIVERSION:0x%04x\r\n", (unsigned int)EHCI_HCCR->hciversion);
@@ -1138,6 +1175,13 @@ int usbh_submit_urb(struct usbh_urb *urb)
return -USB_ERR_INVAL;
}
+#ifdef CONFIG_USB_DCACHE_ENABLE
+ if (((uintptr_t)urb->setup % CONFIG_USB_ALIGN_SIZE) || ((uintptr_t)urb->transfer_buffer % CONFIG_USB_ALIGN_SIZE)) {
+ USB_LOG_ERR("urb buffer is not align with %d\r\n", CONFIG_USB_ALIGN_SIZE);
+ while (1) {
+ }
+ }
+#endif
bus = urb->hport->bus;
/* find active hubport in roothub */
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h
index 714128bc46..8d08cfa19a 100644
--- a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h
@@ -30,14 +30,19 @@
#ifndef CONFIG_USB_EHCI_ISO_NUM
#define CONFIG_USB_EHCI_ISO_NUM 4
#endif
+#ifndef CONFIG_USB_EHCI_ALIGN_SIZE
+#define CONFIG_USB_EHCI_ALIGN_SIZE 64
+#endif
extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port);
struct ehci_qtd_hw {
struct ehci_qtd hw;
struct usbh_urb *urb;
+ bool dir_in;
+ uintptr_t bufaddr;
uint32_t length;
-} __attribute__((aligned(32)));
+} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
struct ehci_qh_hw {
struct ehci_qh hw;
@@ -46,7 +51,7 @@ struct ehci_qh_hw {
struct usbh_urb *urb;
usb_osal_sem_t waitsem;
uint8_t remove_in_iaad;
-} __attribute__((aligned(32)));
+} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
struct ehci_itd_hw {
struct ehci_itd hw;
@@ -55,7 +60,8 @@ struct ehci_itd_hw {
uint8_t mf_unmask;
uint8_t mf_valid;
uint32_t pkt_idx[8];
-} __attribute__((aligned(32)));
+ bool dir_in;
+} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
struct ehci_iso_hw
{
diff --git a/components/drivers/usb/cherryusb/port/fsdev/README.md b/components/drivers/usb/cherryusb/port/fsdev/README.md
index ecb9c33c11..95e9ac2e1c 100644
--- a/components/drivers/usb/cherryusb/port/fsdev/README.md
+++ b/components/drivers/usb/cherryusb/port/fsdev/README.md
@@ -23,10 +23,7 @@
## GD32
-- GD32F10X_MD、GD32F10X_HD、GD32F10X_XD
-- GD32F30X_HD、GD32F30X_XD
-- GD32F350
-- GD32F407
+- GD32F10X
## CH32
diff --git a/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c b/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c
index 39c787f8ab..c32a3b1729 100644
--- a/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c
+++ b/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c
@@ -869,12 +869,7 @@ void handle_ep0(struct usbh_bus *bus)
break;
case USB_EP0_STATE_IN_DATA:
if (ep0_status & USB_CSRL0_RXRDY) {
- size = urb->transfer_buffer_length;
- if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
- size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
- }
-
- size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
+ size = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
musb_read_packet(bus, 0, urb->transfer_buffer, size);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_RXRDY;
urb->transfer_buffer += size;
@@ -933,6 +928,7 @@ void USBH_IRQHandler(uint8_t busid)
uint8_t ep_idx;
uint8_t old_ep_idx;
struct usbh_bus *bus;
+ uint32_t size;
bus = &g_usbhost_bus[busid];
@@ -1024,7 +1020,7 @@ void USBH_IRQHandler(uint8_t busid)
urb->errorcode = 0;
musb_urb_waitup(urb);
} else {
- musb_write_packet(bus, ep_idx, urb->transfer_buffer, size);
+ musb_write_packet(bus, ep_idx, urb->transfer_buffer, MIN(urb->transfer_buffer_length, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)));
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
}
}
@@ -1056,11 +1052,7 @@ void USBH_IRQHandler(uint8_t busid)
urb->errorcode = -USB_ERR_STALL;
musb_urb_waitup(urb);
} else if (ep_csrl_status & USB_RXCSRL1_RXRDY) {
- uint32_t size = urb->transfer_buffer_length;
- if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
- size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
- }
- size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
+ size = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
musb_read_packet(bus, ep_idx, urb->transfer_buffer, size);
diff --git a/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h b/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h
index 19d5190966..1b3220073a 100644
--- a/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h
+++ b/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h
@@ -22,14 +22,18 @@
#ifndef CONFIG_USB_OHCI_TD_NUM
#define CONFIG_USB_OHCI_TD_NUM 3
#endif
+#ifndef CONFIG_USB_OHCI_ALIGN_SIZE
+#define CONFIG_USB_OHCI_ALIGN_SIZE 64
+#endif
struct ohci_ed_hw;
struct ohci_td_hw {
struct ohci_gtd hw;
struct usbh_urb *urb;
+ bool dir_in;
uint32_t buf_start;
uint32_t length;
-} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
+} __attribute__((aligned(CONFIG_USB_OHCI_ALIGN_SIZE))); /* min is 16bytes, we use CONFIG_USB_OHCI_ALIGN_SIZE for cacheline */
struct ohci_ed_hw {
struct ohci_ed hw;
@@ -37,7 +41,7 @@ struct ohci_ed_hw {
uint32_t td_count;
uint8_t ed_type;
usb_osal_sem_t waitsem;
-} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
+} __attribute__((aligned(CONFIG_USB_OHCI_ALIGN_SIZE))); /* min is 16bytes, we use CONFIG_USB_OHCI_ALIGN_SIZE for cacheline */
struct ohci_hcd {
bool ohci_ed_used[CONFIG_USB_OHCI_ED_NUM];
diff --git a/components/drivers/usb/cherryusb/port/rp2040/README.md b/components/drivers/usb/cherryusb/port/rp2040/README.md
new file mode 100644
index 0000000000..64887e36e5
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/rp2040/README.md
@@ -0,0 +1,5 @@
+# Note
+
+## Support Chip List
+
+- RP2040/RP2350
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/rp2040/usb_dc_rp2040.c b/components/drivers/usb/cherryusb/port/rp2040/usb_dc_rp2040.c
new file mode 100644
index 0000000000..418bcd040b
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/rp2040/usb_dc_rp2040.c
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2022, HaiMianBBao
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "hardware/resets.h"
+#include "hardware/irq.h"
+#include "hardware/structs/usb.h"
+#if CHERRYUSB_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
+#include "pico/fix/rp2040_usb_device_enumeration.h"
+#endif
+
+#define usb_hw_set hw_set_alias(usb_hw)
+#define usb_hw_clear hw_clear_alias(usb_hw)
+
+#ifndef CONFIG_USBDEV_EP_NUM
+#define CONFIG_USBDEV_EP_NUM 16
+#endif
+
+#ifndef FORCE_VBUS_DETECT
+#define FORCE_VBUS_DETECT 1
+#endif
+
+/* Endpoint state */
+struct rp2040_ep_state {
+ uint16_t ep_mps; /* Endpoint max packet size */
+ uint8_t ep_type; /* Endpoint type */
+ uint8_t ep_stalled; /* Endpoint stall flag */
+ uint8_t ep_enable; /* Endpoint enable */
+ uint8_t ep_addr; /* Endpoint address */
+ uint8_t *xfer_buf;
+ uint32_t xfer_len;
+ uint32_t actual_xfer_len;
+
+ volatile uint32_t *endpoint_control; /*!< Endpoint control register */
+ volatile uint32_t *buffer_control; /*!< Buffer control register */
+ uint8_t *data_buffer; /*!< Buffer pointer in usb dpram */
+ uint8_t next_pid; /*!< Toggle after each packet (unless replying to a SETUP) */
+};
+
+/* Driver state */
+struct rp2040_udc {
+ volatile uint8_t dev_addr;
+ struct rp2040_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
+ struct rp2040_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
+ struct usb_setup_packet setup; /*!< Setup package that may be used in interrupt processing (outside the protocol stack) */
+} g_rp2040_udc;
+
+void rp2040_usbd_irq(void);
+
+/**
+ * @brief Take a buffer pointer located in the USB RAM and return as an offset of the RAM.
+ *
+ * @param buf
+ * @return uint32_t
+ */
+static inline uint32_t usb_buffer_offset(volatile uint8_t *buf)
+{
+ return (uint32_t)buf ^ (uint32_t)usb_dpram;
+}
+
+/**
+ * @brief Set up the endpoint control register for an endpoint (if applicable. Not valid for EP0).
+ *
+ * @param ep
+ */
+void usb_setup_endpoint(const struct rp2040_ep_state *ep)
+{
+ // EP0 doesn't have one so return if that is the case
+ if (!ep->endpoint_control) {
+ return;
+ }
+
+ // Get the data buffer as an offset of the USB controller's DPRAM
+ uint32_t dpram_offset = usb_buffer_offset(ep->data_buffer);
+ uint32_t reg = EP_CTRL_ENABLE_BITS |
+ EP_CTRL_INTERRUPT_PER_BUFFER |
+ (ep->ep_type << EP_CTRL_BUFFER_TYPE_LSB) |
+ dpram_offset;
+ *ep->endpoint_control = reg;
+}
+
+/**
+ * @brief Starts a transfer on a given endpoint.
+ *
+ * @param ep, the endpoint configuration.
+ * @param buf, the data buffer to send. Only applicable if the endpoint is TX
+ * @param len, the length of the data in buf (this example limits max len to one packet - 64 bytes)
+ */
+static void usb_start_transfer(struct rp2040_ep_state *ep, uint8_t *buf, uint16_t len)
+{
+ /*!< Prepare buffer control register value */
+ uint32_t val = len | USB_BUF_CTRL_AVAIL;
+
+ if (len < ep->ep_mps) {
+ val |= USB_BUF_CTRL_LAST;
+ }
+
+ if (USB_EP_DIR_IS_IN(ep->ep_addr)) {
+ /*!< Need to copy the data from the user buffer to the usb memory */
+ if (buf != NULL) {
+ memcpy((void *)ep->data_buffer, (void *)buf, len);
+ }
+ /*!< Mark as full */
+ val |= USB_BUF_CTRL_FULL;
+ }
+
+ /*!< Set pid and flip for next transfer */
+ val |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID;
+ ep->next_pid ^= 1u;
+
+ *ep->buffer_control = val;
+}
+
+int usb_dc_init(uint8_t busid)
+{
+ uint8_t *next_buffer_ptr;
+
+ memset(&g_rp2040_udc, 0, sizeof(struct rp2040_udc));
+
+ g_rp2040_udc.in_ep[0].endpoint_control = NULL;
+ g_rp2040_udc.in_ep[0].data_buffer = &usb_dpram->ep0_buf_a[0];
+ g_rp2040_udc.out_ep[0].endpoint_control = NULL;
+ g_rp2040_udc.out_ep[0].data_buffer = &usb_dpram->ep0_buf_a[0];
+
+ for (uint32_t i = 0; i < CONFIG_USBDEV_EP_NUM; i++) {
+ g_rp2040_udc.in_ep[i].buffer_control = &usb_dpram->ep_buf_ctrl[i].in;
+ g_rp2040_udc.out_ep[i].buffer_control = &usb_dpram->ep_buf_ctrl[i].out;
+
+ if (i != 0) {
+ g_rp2040_udc.in_ep[i].endpoint_control = &usb_dpram->ep_ctrl[i - 1].in;
+ g_rp2040_udc.out_ep[i].endpoint_control = &usb_dpram->ep_ctrl[i - 1].out;
+ }
+ }
+
+ next_buffer_ptr = &usb_dpram->epx_data[0];
+
+ for (uint32_t i = 1; i < CONFIG_USBDEV_EP_NUM; i++) {
+ g_rp2040_udc.in_ep[i].data_buffer = next_buffer_ptr;
+ if (i == 1) {
+ next_buffer_ptr += 1024; /* for iso video */
+ } else {
+ next_buffer_ptr += 64;
+ }
+
+ g_rp2040_udc.out_ep[i].data_buffer = next_buffer_ptr;
+ next_buffer_ptr += 64;
+ }
+
+ // Remove shared irq if it was previously added so as not to fill up shared irq slots
+ irq_remove_handler(USBCTRL_IRQ, rp2040_usbd_irq);
+
+ irq_add_shared_handler(USBCTRL_IRQ, rp2040_usbd_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY);
+
+ // Reset usb controller
+ reset_unreset_block_num_wait_blocking(RESET_USBCTRL);
+
+ /*!< Clear any previous state just in case */
+ memset(usb_hw, 0, sizeof(*usb_hw));
+ memset(usb_dpram, 0, sizeof(*usb_dpram));
+
+ /*!< Mux the controller to the onboard usb phy */
+ usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
+
+#if FORCE_VBUS_DETECT
+ // Force VBUS detect so the device thinks it is plugged into a host
+ usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
+#endif
+
+ // Enable the USB controller in device mode.
+ usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS;
+
+ // Enable an interrupt per EP0 transaction
+ usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS; // <2>
+
+ // Enable interrupts for when a buffer is done, when the bus is reset,
+ // and when a setup packet is received
+ usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS |
+ USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS |
+ (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS);
+
+ // Enable USB interrupt at processor
+ irq_set_enabled(USBCTRL_IRQ, true);
+
+ usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
+ return 0;
+}
+
+int usb_dc_deinit(uint8_t busid)
+{
+ irq_set_enabled(USBCTRL_IRQ, false);
+ // Remove shared irq if it was previously added so as not to fill up shared irq slots
+ irq_remove_handler(USBCTRL_IRQ, rp2040_usbd_irq);
+
+ usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
+ memset(&g_rp2040_udc, 0, sizeof(struct rp2040_udc));
+
+ return 0;
+}
+
+int usbd_set_address(uint8_t busid, const uint8_t addr)
+{
+ g_rp2040_udc.dev_addr = addr;
+ return 0;
+}
+
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ return -1;
+}
+
+uint8_t usbd_get_port_speed(uint8_t busid)
+{
+ return USB_SPEED_FULL;
+}
+
+int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
+
+ if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
+ g_rp2040_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_rp2040_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_rp2040_udc.out_ep[ep_idx].ep_addr = ep->bEndpointAddress;
+ g_rp2040_udc.out_ep[ep_idx].ep_enable = true;
+ /*!< Clear control reg */
+ *(g_rp2040_udc.out_ep[ep_idx].buffer_control) = 0;
+
+ usb_setup_endpoint(&g_rp2040_udc.out_ep[ep_idx]);
+ } else {
+ g_rp2040_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_rp2040_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_rp2040_udc.in_ep[ep_idx].ep_addr = ep->bEndpointAddress;
+ g_rp2040_udc.in_ep[ep_idx].ep_enable = true;
+ /*!< Clear control reg */
+ *(g_rp2040_udc.in_ep[ep_idx].buffer_control) = 0;
+
+ usb_setup_endpoint(&g_rp2040_udc.in_ep[ep_idx]);
+ }
+ return 0;
+}
+
+int usbd_ep_close(uint8_t busid, const uint8_t ep)
+{
+ if (USB_EP_DIR_IS_IN(ep)) {
+ } else if (USB_EP_DIR_IS_OUT(ep)) {
+ }
+ return 0;
+}
+
+int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
+{
+ if (USB_EP_GET_IDX(ep) == 0) {
+ /**
+ * A stall on EP0 has to be armed so it can be cleared on the next setup packet
+ */
+ usb_hw_set->ep_stall_arm = (USB_EP_DIR_IS_IN(ep)) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS;
+ }
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ *(g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].buffer_control) = USB_BUF_CTRL_STALL;
+ } else {
+ *(g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].buffer_control) = USB_BUF_CTRL_STALL;
+ }
+
+ return 0;
+}
+
+int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (ep_idx != 0) {
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].next_pid = 0;
+ *(g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].buffer_control) = ~USB_BUF_CTRL_STALL;
+ } else {
+ g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].next_pid = 0;
+ *(g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].buffer_control) = ~USB_BUF_CTRL_STALL;
+ }
+ }
+ return 0;
+}
+
+int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
+{
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ if (*(g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].buffer_control) & USB_BUF_CTRL_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
+ } else {
+ if (*(g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].buffer_control) & USB_BUF_CTRL_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
+ }
+ return 0;
+}
+
+int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (!g_rp2040_udc.in_ep[ep_idx].ep_enable) {
+ return -2;
+ }
+
+ g_rp2040_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_rp2040_udc.in_ep[ep_idx].xfer_len = data_len;
+ g_rp2040_udc.in_ep[ep_idx].actual_xfer_len = 0;
+
+ if (data_len == 0) {
+ usb_start_transfer(&g_rp2040_udc.in_ep[ep_idx], NULL, 0);
+ } else {
+ data_len = MIN(data_len, g_rp2040_udc.in_ep[ep_idx].ep_mps);
+ usb_start_transfer(&g_rp2040_udc.in_ep[ep_idx], g_rp2040_udc.in_ep[ep_idx].xfer_buf, data_len);
+ }
+
+ return 0;
+}
+
+int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+ if (!g_rp2040_udc.out_ep[ep_idx].ep_enable) {
+ return -2;
+ }
+ g_rp2040_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_rp2040_udc.out_ep[ep_idx].xfer_len = data_len;
+ g_rp2040_udc.out_ep[ep_idx].actual_xfer_len = 0;
+
+ if (data_len == 0) {
+ usb_start_transfer(&g_rp2040_udc.out_ep[ep_idx], NULL, 0);
+ } else {
+ /*!< Not zlp */
+ data_len = MIN(data_len, g_rp2040_udc.out_ep[ep_idx].ep_mps);
+ usb_start_transfer(&g_rp2040_udc.out_ep[ep_idx], g_rp2040_udc.out_ep[ep_idx].xfer_buf, data_len);
+ }
+ return 0;
+}
+
+/**
+ * @brief Notify an endpoint that a transfer has completed.
+ *
+ * @param ep, the endpoint to notify.
+ */
+static void usb_handle_ep_buff_done(struct rp2040_ep_state *ep)
+{
+ uint32_t buffer_control = *ep->buffer_control;
+ /*!< Get the transfer length for this endpoint */
+ uint16_t read_count = buffer_control & USB_BUF_CTRL_LEN_MASK;
+ /*!< Call that endpoints buffer done handler */
+ if (ep->ep_addr == 0x80) {
+ /*!< EP0 In */
+ /**
+ * Determine the current setup direction
+ */
+ switch (g_rp2040_udc.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
+ case 1:
+ /*!< Get */
+ if (g_rp2040_udc.in_ep[0].xfer_len > g_rp2040_udc.in_ep[0].ep_mps) {
+ g_rp2040_udc.in_ep[0].xfer_len -= g_rp2040_udc.in_ep[0].ep_mps;
+ g_rp2040_udc.in_ep[0].actual_xfer_len += g_rp2040_udc.in_ep[0].ep_mps;
+ usbd_event_ep_in_complete_handler(0, 0 | 0x80, g_rp2040_udc.in_ep[0].actual_xfer_len);
+ } else {
+ g_rp2040_udc.in_ep[0].actual_xfer_len += g_rp2040_udc.in_ep[0].xfer_len;
+ g_rp2040_udc.in_ep[0].xfer_len = 0;
+ /**
+ * EP0 In complete and host will send a out token to get 0 length packet
+ * In the next usbd_event_ep_in_complete_handler, stack will start read 0 length packet
+ * and host must send data1 packet.We resest the ep0 next_pid = 1 in setup interrupt head.
+ */
+ usbd_event_ep_in_complete_handler(0, 0 | 0x80, g_rp2040_udc.in_ep[0].actual_xfer_len);
+ }
+ break;
+ case 0:
+ /*!< Set */
+ if (g_rp2040_udc.dev_addr > 0) {
+ usb_hw->dev_addr_ctrl = g_rp2040_udc.dev_addr;
+ g_rp2040_udc.dev_addr = 0;
+ } else {
+ /*!< Normal status stage // Setup out...out in */
+ /**
+ * Perpar for next setup
+ */
+ }
+ break;
+ }
+
+ } else if (ep->ep_addr == 0x00) {
+ /*!< EP0 Out */
+ memcpy(g_rp2040_udc.out_ep[0].xfer_buf, g_rp2040_udc.out_ep[0].data_buffer, read_count);
+ if (read_count == 0) {
+ /*!< Normal status stage // Setup in...in out */
+ /**
+ * Perpar for next setup
+ */
+ }
+
+ g_rp2040_udc.out_ep[0].actual_xfer_len += read_count;
+ g_rp2040_udc.out_ep[0].xfer_len -= read_count;
+
+ usbd_event_ep_out_complete_handler(0, 0x00, g_rp2040_udc.out_ep[0].actual_xfer_len);
+ } else {
+ /*!< Others ep */
+ uint16_t data_len = 0;
+ if (USB_EP_DIR_IS_OUT(ep->ep_addr)) {
+ /*!< flip the pid */
+ memcpy(g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_buf, g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].data_buffer, read_count);
+ g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_buf += read_count;
+ g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].actual_xfer_len += read_count;
+ g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_len -= read_count;
+
+ if (read_count < g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].ep_mps || g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_len == 0) {
+ /*!< Out complete */
+ usbd_event_ep_out_complete_handler(0, ep->ep_addr, g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].actual_xfer_len);
+ } else {
+ /*!< Need read again */
+ data_len = MIN(g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_len, g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].ep_mps);
+ usb_start_transfer(&g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f], NULL, data_len);
+ }
+ } else {
+ if (g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len > g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps) {
+ /*!< Need tx again */
+ g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len -= g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps;
+ g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_buf += g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps;
+ g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].actual_xfer_len += g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps;
+ data_len = MIN(g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len, g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps);
+ usb_start_transfer(&g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f], g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_buf, data_len);
+ } else {
+ /*!< In complete */
+ g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].actual_xfer_len += g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len;
+ g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(0, ep->ep_addr, g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].actual_xfer_len);
+ }
+ }
+ }
+}
+
+/**
+ * @brief Find the endpoint configuration for a specified endpoint number and
+ * direction and notify it that a transfer has completed.
+ *
+ * @param ep_num
+ * @param in
+ */
+static void usb_handle_buff_done(uint8_t ep_num, bool in)
+{
+ uint8_t ep_addr = ep_num | (in ? USB_EP_DIR_IN : 0);
+ if (USB_EP_DIR_IS_OUT(ep_addr)) {
+ usb_handle_ep_buff_done(&g_rp2040_udc.out_ep[ep_num]);
+ } else {
+ usb_handle_ep_buff_done(&g_rp2040_udc.in_ep[ep_num]);
+ }
+}
+
+/**
+ * @brief Handle a "buffer status" irq. This means that one or more
+ * buffers have been sent / received. Notify each endpoint where this
+ * is the case.
+ */
+static void usb_handle_buff_status(void)
+{
+ uint32_t remaining_buffers = usb_hw->buf_status;
+
+ uint32_t bit = 1u;
+ for (uint8_t i = 0; remaining_buffers && i < USB_NUM_ENDPOINTS * 2; i++) {
+ if (remaining_buffers & bit) {
+ /*!< clear this in advance */
+ usb_hw_clear->buf_status = bit;
+ /*!< IN transfer for even i, OUT transfer for odd i */
+ usb_handle_buff_done(i >> 1u, !(i & 1u));
+ remaining_buffers &= ~bit;
+ }
+ bit <<= 1u;
+ }
+}
+
+void USBD_IRQHandler(uint8_t busid)
+{
+ uint32_t const status = usb_hw->ints;
+ uint32_t handled = 0;
+
+ if (status & USB_INTS_BUFF_STATUS_BITS) {
+ handled |= USB_INTS_BUFF_STATUS_BITS;
+ usb_handle_buff_status();
+ }
+
+ if (status & USB_INTS_SETUP_REQ_BITS) {
+ handled |= USB_INTS_SETUP_REQ_BITS;
+ memcpy((uint8_t *)&g_rp2040_udc.setup, (uint8_t const *)&usb_dpram->setup_packet, 8);
+ /**
+ * reset pid to both 1 (data and ack)
+ */
+ g_rp2040_udc.in_ep[0].next_pid = 1;
+ g_rp2040_udc.out_ep[0].next_pid = 1;
+ usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_rp2040_udc.setup);
+ usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS;
+ }
+
+#if FORCE_VBUS_DETECT == 0
+ /**
+ * Since we force VBUS detect On, device will always think it is connected and
+ * couldn't distinguish between disconnect and suspend
+ */
+ if (status & USB_INTS_DEV_CONN_DIS_BITS) {
+ handled |= USB_INTS_DEV_CONN_DIS_BITS;
+ if (usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS) {
+ /*!< Connected: nothing to do */
+ usbd_event_connect_handler(0);
+ } else {
+ /*!< Disconnected */
+ usbd_event_disconnect_handler(0);
+ }
+ usb_hw_clear->sie_status = USB_SIE_STATUS_CONNECTED_BITS;
+ }
+#endif
+
+ /**
+ * SE0 for 2.5 us or more (will last at least 10ms)
+ */
+ if (status & USB_INTS_BUS_RESET_BITS) {
+ handled |= USB_INTS_BUS_RESET_BITS;
+ usb_hw_clear->sie_status = USB_SIE_STATUS_BUS_RESET_BITS;
+
+ usb_hw->dev_addr_ctrl = 0;
+
+ for (uint8_t i = 0; i < CONFIG_USBDEV_EP_NUM - 1; i++) {
+ /*!< Start at ep1 */
+ usb_dpram->ep_ctrl[i].in = 0;
+ usb_dpram->ep_ctrl[i].out = 0;
+ }
+
+ usbd_event_reset_handler(0);
+
+#if CHERRYUSB_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
+ /**
+ * Only run enumeration walk-around if pull up is enabled
+ */
+ if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS)
+ rp2040_usb_device_enumeration_fix();
+#endif
+ }
+
+ /**
+ * Note from pico datasheet 4.1.2.6.4 (v1.2)
+ * If you enable the suspend interrupt, it is likely you will see a suspend interrupt when
+ * the device is first connected but the bus is idle. The bus can be idle for a few ms before
+ * the host begins sending start of frame packets. You will also see a suspend interrupt
+ * when the device is disconnected if you do not have a VBUS detect circuit connected. This is
+ * because without VBUS detection, it is impossible to tell the difference between
+ * being disconnected and suspended.
+ */
+ if (status & USB_INTS_DEV_SUSPEND_BITS) {
+ handled |= USB_INTS_DEV_SUSPEND_BITS;
+ /*!< Suspend */
+ usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS;
+ usbd_event_suspend_handler(0);
+ }
+
+ if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS) {
+ handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS;
+ /*!< Resume */
+ usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS;
+ usbd_event_resume_handler(0);
+ }
+
+ if (status ^ handled) {
+ USB_LOG_INFO("Unhandled IRQ 0x%x\n", (uint32_t)(status ^ handled));
+ }
+}
+
+void rp2040_usbd_irq(void)
+{
+ USBD_IRQHandler(0);
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/rp2040/usb_hc_rp2040.c b/components/drivers/usb/cherryusb/port/rp2040/usb_hc_rp2040.c
new file mode 100644
index 0000000000..90ac9b99be
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/rp2040/usb_hc_rp2040.c
@@ -0,0 +1,824 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_hub.h"
+#include "hardware/resets.h"
+#include "hardware/irq.h"
+#include "hardware/structs/usb.h"
+
+#define usb_hw_set hw_set_alias(usb_hw)
+#define usb_hw_clear hw_clear_alias(usb_hw)
+
+#define SIE_CTRL_COMMON (USB_SIE_CTRL_SOF_EN_BITS | \
+ USB_SIE_CTRL_KEEP_ALIVE_EN_BITS | \
+ USB_SIE_CTRL_PULLDOWN_EN_BITS | \
+ USB_SIE_CTRL_EP0_INT_1BUF_BITS)
+
+typedef enum {
+ USB_EP0_STATE_SETUP = 0x0, /**< SETUP DATA */
+ USB_EP0_STATE_IN_DATA, /**< IN DATA */
+ USB_EP0_STATE_IN_STATUS, /**< IN status*/
+ USB_EP0_STATE_OUT_DATA, /**< OUT DATA */
+ USB_EP0_STATE_OUT_STATUS, /**< OUT status */
+} ep0_state_t;
+
+struct rp2040_pipe {
+ uint8_t chidx;
+ bool inuse;
+ volatile uint8_t ep0_state;
+ volatile uint32_t *endpoint_control; /*!< Endpoint control register */
+ volatile uint32_t *buffer_control; /*!< Buffer control register */
+ uint8_t *data_buffer; /*!< Buffer pointer in usb dpram */
+ uint32_t buffer_size; /*!< Buffer size */
+ usb_osal_sem_t waitsem;
+ struct usbh_urb *urb;
+};
+
+struct rp2040_hcd {
+ volatile bool port_csc;
+ volatile bool port_pec;
+ volatile bool port_pe;
+ usb_osal_mutex_t ep0_mutex;
+ struct rp2040_pipe pipe_pool[1 + CONFIG_USBHOST_PIPE_NUM];
+} g_rp2040_hcd[CONFIG_USBHOST_MAX_BUS];
+
+void rp2040_usbh_irq(void);
+
+static int rp2040_pipe_alloc(struct usbh_bus *bus)
+{
+ size_t flags;
+ int chidx;
+
+ flags = usb_osal_enter_critical_section();
+ for (chidx = 1; chidx <= CONFIG_USBHOST_PIPE_NUM; chidx++) {
+ if (!g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse) {
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse = true;
+ usb_osal_leave_critical_section(flags);
+ return chidx;
+ }
+ }
+ usb_osal_leave_critical_section(flags);
+ return -1;
+}
+
+static void rp2040_pipe_free(struct rp2040_pipe *pipe)
+{
+ size_t flags;
+
+ flags = usb_osal_enter_critical_section();
+ pipe->inuse = false;
+ usb_osal_leave_critical_section(flags);
+}
+
+/**
+ * @brief Take a buffer pointer located in the USB RAM and return as an offset of the RAM.
+ *
+ * @param buf
+ * @return uint32_t
+ */
+static inline uint32_t usb_buffer_offset(volatile uint8_t *buf)
+{
+ return (uint32_t)buf ^ (uint32_t)usbh_dpram;
+}
+
+static inline uint8_t usbh_get_port_speed(void)
+{
+ return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB;
+}
+
+static inline void rp2040_init_endpoint(struct usbh_bus *bus,
+ uint8_t chidx,
+ uint8_t dev_addr,
+ uint8_t ep_addr,
+ uint8_t ep_type,
+ uint8_t ep_interval,
+ uint8_t speed)
+{
+ struct rp2040_pipe *pipe;
+ uint32_t regval;
+
+ pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
+
+ // Get the data buffer as an offset of the USB controller's DPRAM
+ uint32_t dpram_offset = usb_buffer_offset(pipe->data_buffer);
+ regval = EP_CTRL_ENABLE_BITS |
+ EP_CTRL_INTERRUPT_PER_BUFFER |
+ (ep_type << EP_CTRL_BUFFER_TYPE_LSB) |
+ dpram_offset;
+
+ if (ep_interval) {
+ regval |= (uint32_t)((ep_interval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB);
+ }
+
+ *pipe->endpoint_control = regval;
+
+ if (chidx != 0) {
+ regval = (uint32_t)(dev_addr | ((ep_addr & 0x0f) << USB_ADDR_ENDP1_ENDPOINT_LSB));
+
+ if (!(ep_addr & 0x80)) {
+ regval |= USB_ADDR_ENDP1_INTEP_DIR_BITS;
+ }
+
+ // ls device plugged to hub
+ if ((usbh_get_port_speed() == USB_SPEED_FULL) && (speed == USB_SPEED_LOW)) {
+ regval |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS;
+ }
+
+ usb_hw->int_ep_addr_ctrl[(chidx - 1)] = regval;
+
+ // Finally, enable interrupt that endpoint
+ usb_hw_set->int_ep_ctrl = 1 << chidx;
+ } else {
+ usb_hw->dev_addr_ctrl = dev_addr;
+ }
+}
+
+static inline uint32_t usb_buf_ctrl_fill(struct usbh_bus *bus, uint8_t chidx, uint8_t ep_addr, uint8_t buf_id)
+{
+ struct rp2040_pipe *pipe;
+ struct usbh_urb *urb;
+ uint32_t len;
+ uint32_t buf_ctrl;
+
+ pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
+ urb = pipe->urb;
+
+ len = MIN(urb->transfer_buffer_length, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize));
+ urb->transfer_buffer_length -= len;
+
+ buf_ctrl = len | USB_BUF_CTRL_AVAIL;
+ buf_ctrl |= urb->data_toggle ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID;
+
+ if (USB_EP_DIR_IS_OUT(ep_addr)) {
+ /*!< Need to copy the data from the user buffer to the usb memory */
+ if (urb->transfer_buffer != NULL) {
+ memcpy((void *)pipe->data_buffer + buf_id * 64, (void *)urb->transfer_buffer, len);
+ urb->transfer_buffer += len;
+ }
+ /*!< Mark as full */
+ buf_ctrl |= USB_BUF_CTRL_FULL;
+ }
+
+ if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ if (urb->transfer_buffer_length == 0) {
+ buf_ctrl |= USB_BUF_CTRL_LAST;
+ }
+ } else {
+ //TODO: handle isochronous transfer
+ }
+
+ if (buf_id)
+ buf_ctrl = buf_ctrl << 16;
+
+ return buf_ctrl;
+}
+
+/**
+ * @brief Starts a transfer on a given endpoint.
+ *
+ * @param ep, the endpoint configuration.
+ * @param buf, the data buffer to send. Only applicable if the endpoint is TX
+ * @param len, the length of the data in buf (this example limits max len to one packet - 64 bytes)
+ */
+static void usb_start_transfer(struct usbh_bus *bus, uint8_t chidx, uint8_t ep_addr)
+{
+ struct rp2040_pipe *pipe;
+ struct usbh_urb *urb;
+ uint32_t buf_ctrl;
+ uint32_t ep_ctrl;
+
+ pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
+ urb = pipe->urb;
+
+ ep_ctrl = *pipe->endpoint_control;
+ buf_ctrl = usb_buf_ctrl_fill(bus, chidx, ep_addr, 0);
+
+ if (urb->transfer_buffer_length && (ep_addr & 0x0f) == 0x00) {
+ urb->data_toggle ^= 1;
+ buf_ctrl |= usb_buf_ctrl_fill(bus, chidx, ep_addr, 1);
+
+ // Set endpoint control double buffered bit if needed
+ ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER;
+ ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER;
+ } else {
+ // Single buffered since 1 is enough
+ ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER);
+ ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER;
+ }
+ *pipe->endpoint_control = ep_ctrl;
+ *pipe->buffer_control = buf_ctrl;
+}
+
+static inline void rp2040_control_transfer_start(bool dir_in, bool isetup, uint8_t speed)
+{
+ uint32_t regval;
+
+ regval = SIE_CTRL_COMMON | USB_SIE_CTRL_START_TRANS_BITS;
+
+ if ((usbh_get_port_speed() == USB_SPEED_FULL) && (speed == USB_SPEED_LOW)) {
+ regval |= USB_SIE_CTRL_PREAMBLE_EN_BITS;
+ }
+
+ if (isetup) {
+ regval |= USB_SIE_CTRL_SEND_SETUP_BITS;
+ } else {
+ if (dir_in) {
+ regval |= USB_SIE_CTRL_RECEIVE_DATA_BITS;
+ } else {
+ regval |= USB_SIE_CTRL_SEND_DATA_BITS;
+ }
+ }
+
+ usb_hw->sie_ctrl = regval & ~USB_SIE_CTRL_START_TRANS_BITS;
+ busy_wait_at_least_cycles(12);
+ usb_hw->sie_ctrl = regval;
+}
+
+static void rp2040_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
+{
+ struct rp2040_pipe *pipe;
+
+ pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
+
+ if (pipe->ep0_state == USB_EP0_STATE_SETUP) /* fill setup */
+ {
+ pipe->urb->data_toggle = 1;
+ memcpy((uint8_t *)usbh_dpram->setup_packet, (uint8_t *)setup, 8);
+ rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
+ rp2040_control_transfer_start(false, true, urb->hport->speed);
+ } else if (pipe->ep0_state == USB_EP0_STATE_IN_DATA) /* fill in data */
+ {
+ rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
+ usb_start_transfer(bus, chidx, 0x80);
+ rp2040_control_transfer_start(true, false, urb->hport->speed);
+ } else if (pipe->ep0_state == USB_EP0_STATE_OUT_DATA) /* fill out data */
+ {
+ rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
+ usb_start_transfer(bus, chidx, 0x00);
+ rp2040_control_transfer_start(false, false, urb->hport->speed);
+ } else if (pipe->ep0_state == USB_EP0_STATE_IN_STATUS) /* fill in status */
+ {
+ urb->data_toggle = 1;
+ rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
+ usb_start_transfer(bus, chidx, 0x80);
+ rp2040_control_transfer_start(true, false, urb->hport->speed);
+ } else if (pipe->ep0_state == USB_EP0_STATE_OUT_STATUS) /* fill out status */
+ {
+ urb->data_toggle = 1;
+ rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
+ usb_start_transfer(bus, chidx, 0x00);
+ rp2040_control_transfer_start(false, false, urb->hport->speed);
+ }
+}
+
+static void rp2040_bulk_int_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
+{
+ rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), urb->ep->bInterval, urb->hport->speed);
+ usb_start_transfer(bus, chidx, urb->ep->bEndpointAddress);
+}
+
+int usb_hc_init(struct usbh_bus *bus)
+{
+ uint8_t *next_buffer_ptr;
+
+ memset(&g_rp2040_hcd[bus->hcd.hcd_id], 0, sizeof(struct rp2040_hcd));
+
+ for (uint8_t i = 0; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem = usb_osal_sem_create(0);
+ if (g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem == NULL) {
+ USB_LOG_ERR("Failed to create waitsem\r\n");
+ return -USB_ERR_NOMEM;
+ }
+ }
+
+ g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex = usb_osal_mutex_create();
+ if (g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex == NULL) {
+ USB_LOG_ERR("Failed to create ep0_mutex\r\n");
+ return -USB_ERR_NOMEM;
+ }
+
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].endpoint_control = &usbh_dpram->epx_ctrl;
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].buffer_control = &usbh_dpram->epx_buf_ctrl;
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].data_buffer = &usbh_dpram->epx_data[0];
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].buffer_size = (64 * 2);
+
+ next_buffer_ptr = &usb_dpram->epx_data[64 * 2];
+
+ for (uint8_t i = 1; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].chidx = i;
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].endpoint_control = &usbh_dpram->int_ep_ctrl[i - 1].ctrl;
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].buffer_control = &usbh_dpram->int_ep_buffer_ctrl[i - 1].ctrl;
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].data_buffer = next_buffer_ptr;
+ g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].buffer_size = (64 * 2);
+ next_buffer_ptr += (64 * 2);
+ }
+
+ // Reset usb controller
+ reset_unreset_block_num_wait_blocking(RESET_USBCTRL);
+
+ // Remove shared irq if it was previously added so as not to fill up shared irq slots
+ irq_remove_handler(USBCTRL_IRQ, rp2040_usbh_irq);
+
+ irq_add_shared_handler(USBCTRL_IRQ, rp2040_usbh_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY);
+
+ /*!< Clear any previous state just in case */
+ memset(usb_hw, 0, sizeof(*usb_hw));
+ memset(usbh_dpram, 0, sizeof(*usbh_dpram));
+
+ /*!< Mux the controller to the onboard usb phy */
+ usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
+
+ // Force VBUS detect so the device thinks it is plugged into a host
+ usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
+
+ // Enable the USB controller in device mode.
+ usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS;
+
+ usb_hw->sie_ctrl = SIE_CTRL_COMMON;
+
+ // Enable USB interrupt at processor
+ irq_set_enabled(USBCTRL_IRQ, true);
+
+ usb_hw->inte = USB_INTE_BUFF_STATUS_BITS |
+ USB_INTE_HOST_CONN_DIS_BITS |
+ USB_INTE_STALL_BITS |
+ USB_INTE_TRANS_COMPLETE_BITS |
+ USB_INTE_ERROR_RX_TIMEOUT_BITS |
+ USB_INTE_ERROR_DATA_SEQ_BITS;
+ return 0;
+}
+
+int usb_hc_deinit(struct usbh_bus *bus)
+{
+ // Enable USB interrupt at processor
+ irq_set_enabled(USBCTRL_IRQ, false);
+
+ // Remove shared irq if it was previously added so as not to fill up shared irq slots
+ irq_remove_handler(USBCTRL_IRQ, rp2040_usbh_irq);
+
+ for (uint8_t i = 0; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
+ usb_osal_sem_delete(g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem);
+ }
+
+ usb_osal_mutex_delete(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
+
+ return 0;
+}
+
+uint16_t usbh_get_frame_number(struct usbh_bus *bus)
+{
+ return usb_hw->sof_rd;
+}
+
+int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
+{
+ uint8_t nports;
+ uint8_t port;
+ uint32_t status;
+
+ nports = CONFIG_USBHOST_MAX_RHPORTS;
+ port = setup->wIndex;
+ if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) {
+ switch (setup->bRequest) {
+ case HUB_REQUEST_CLEAR_FEATURE:
+ switch (setup->wValue) {
+ case HUB_FEATURE_HUB_C_LOCALPOWER:
+ break;
+ case HUB_FEATURE_HUB_C_OVERCURRENT:
+ break;
+ default:
+ return -USB_ERR_INVAL;
+ }
+ break;
+ case HUB_REQUEST_SET_FEATURE:
+ switch (setup->wValue) {
+ case HUB_FEATURE_HUB_C_LOCALPOWER:
+ break;
+ case HUB_FEATURE_HUB_C_OVERCURRENT:
+ break;
+ default:
+ return -USB_ERR_INVAL;
+ }
+ break;
+ case HUB_REQUEST_GET_DESCRIPTOR:
+ break;
+ case HUB_REQUEST_GET_STATUS:
+ memset(buf, 0, 4);
+ break;
+ default:
+ break;
+ }
+ } else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER) {
+ switch (setup->bRequest) {
+ case HUB_REQUEST_CLEAR_FEATURE:
+ if (!port || port > nports) {
+ return -USB_ERR_INVAL;
+ }
+
+ switch (setup->wValue) {
+ case HUB_PORT_FEATURE_ENABLE:
+ break;
+ case HUB_PORT_FEATURE_SUSPEND:
+ case HUB_PORT_FEATURE_C_SUSPEND:
+ break;
+ case HUB_PORT_FEATURE_POWER:
+ break;
+ case HUB_PORT_FEATURE_C_CONNECTION:
+ g_rp2040_hcd[bus->hcd.hcd_id].port_csc = 0;
+ break;
+ case HUB_PORT_FEATURE_C_ENABLE:
+ g_rp2040_hcd[bus->hcd.hcd_id].port_pec = 0;
+ break;
+ case HUB_PORT_FEATURE_C_OVER_CURREN:
+ break;
+ case HUB_PORT_FEATURE_C_RESET:
+ break;
+ default:
+ return -USB_ERR_INVAL;
+ }
+ break;
+ case HUB_REQUEST_SET_FEATURE:
+ if (!port || port > nports) {
+ return -USB_ERR_INVAL;
+ }
+
+ switch (setup->wValue) {
+ case HUB_PORT_FEATURE_SUSPEND:
+ break;
+ case HUB_PORT_FEATURE_POWER:
+ break;
+ case HUB_PORT_FEATURE_RESET:
+ break;
+
+ default:
+ return -USB_ERR_INVAL;
+ }
+ break;
+ case HUB_REQUEST_GET_STATUS:
+ if (!port || port > nports) {
+ return -USB_ERR_INVAL;
+ }
+
+ status = 0;
+ if (g_rp2040_hcd[bus->hcd.hcd_id].port_csc) {
+ status |= (1 << HUB_PORT_FEATURE_C_CONNECTION);
+ }
+ if (g_rp2040_hcd[bus->hcd.hcd_id].port_pec) {
+ status |= (1 << HUB_PORT_FEATURE_C_ENABLE);
+ }
+
+ if (g_rp2040_hcd[bus->hcd.hcd_id].port_pe) {
+ status |= (1 << HUB_PORT_FEATURE_CONNECTION);
+ status |= (1 << HUB_PORT_FEATURE_ENABLE);
+ if (usbh_get_port_speed() == USB_SPEED_LOW) {
+ status |= (1 << HUB_PORT_FEATURE_LOWSPEED);
+ }
+ }
+
+ status |= (1 << HUB_PORT_FEATURE_POWER);
+ memcpy(buf, &status, 4);
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+int usbh_submit_urb(struct usbh_urb *urb)
+{
+ struct rp2040_pipe *pipe;
+ struct usbh_bus *bus;
+ int chidx;
+ size_t flags;
+ int ret = 0;
+
+ if (!urb || !urb->hport || !urb->ep || !urb->hport->bus) {
+ return -USB_ERR_INVAL;
+ }
+
+ if (!urb->hport->connected || !(usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS)) {
+ return -USB_ERR_NOTCONN;
+ }
+
+ if (urb->errorcode == -USB_ERR_BUSY) {
+ return -USB_ERR_BUSY;
+ }
+
+ bus = urb->hport->bus;
+
+ if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
+ chidx = 0;
+ /* all the control transfers use the only one ep0 register, we need to lock */
+ usb_osal_mutex_take(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
+ } else {
+ chidx = rp2040_pipe_alloc(bus);
+ if (chidx == -1) {
+ return -USB_ERR_NOMEM;
+ }
+ }
+
+ flags = usb_osal_enter_critical_section();
+
+ pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
+ pipe->chidx = chidx;
+ pipe->urb = urb;
+
+ urb->hcpriv = pipe;
+ urb->errorcode = -USB_ERR_BUSY;
+ urb->actual_length = 0;
+ usb_osal_leave_critical_section(flags);
+
+ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
+ case USB_ENDPOINT_TYPE_CONTROL:
+ pipe->ep0_state = USB_EP0_STATE_SETUP;
+ rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ break;
+ case USB_ENDPOINT_TYPE_BULK:
+ case USB_ENDPOINT_TYPE_INTERRUPT:
+ rp2040_bulk_int_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
+ break;
+ default:
+ break;
+ }
+
+ if (urb->timeout > 0) {
+ /* wait until timeout or sem give */
+ ret = usb_osal_sem_take(pipe->waitsem, urb->timeout);
+ if (ret < 0) {
+ goto errout_timeout;
+ }
+ urb->timeout = 0;
+ ret = urb->errorcode;
+ /* we can free pipe when waitsem is done */
+ rp2040_pipe_free(pipe);
+
+ if (chidx == 0) {
+ usb_osal_mutex_give(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
+ }
+ }
+ return ret;
+errout_timeout:
+ if (chidx == 0) {
+ usb_osal_mutex_give(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
+ }
+ urb->timeout = 0;
+ usbh_kill_urb(urb);
+ return ret;
+}
+
+int usbh_kill_urb(struct usbh_urb *urb)
+{
+ struct rp2040_pipe *pipe;
+ struct usbh_bus *bus;
+ size_t flags;
+
+ if (!urb || !urb->hcpriv || !urb->hport->bus) {
+ return -USB_ERR_INVAL;
+ }
+
+ bus = urb->hport->bus;
+
+ ARG_UNUSED(bus);
+
+ flags = usb_osal_enter_critical_section();
+
+ pipe = (struct rp2040_pipe *)urb->hcpriv;
+ urb->hcpriv = NULL;
+ urb->errorcode = -USB_ERR_SHUTDOWN;
+ pipe->urb = NULL;
+ usb_hw_clear->int_ep_ctrl = 1 << pipe->chidx;
+ usb_hw_clear->buf_status = 1 << (pipe->chidx * 2 + 0);
+ usb_hw_clear->buf_status = 1 << (pipe->chidx * 2 + 1);
+ *pipe->endpoint_control = 0;
+ *pipe->buffer_control = 0;
+
+ if (urb->timeout) {
+ usb_osal_sem_give(pipe->waitsem);
+ } else {
+ rp2040_pipe_free(pipe);
+ }
+
+ usb_osal_leave_critical_section(flags);
+
+ return 0;
+}
+
+static void rp2040_urb_waitup(struct usbh_urb *urb)
+{
+ struct rp2040_pipe *pipe;
+
+ pipe = (struct rp2040_pipe *)urb->hcpriv;
+ pipe->urb = NULL;
+ urb->hcpriv = NULL;
+
+ if (urb->timeout) {
+ usb_osal_sem_give(pipe->waitsem);
+ } else {
+ rp2040_pipe_free(pipe);
+ }
+
+ if (urb->complete) {
+ if (urb->errorcode < 0) {
+ urb->complete(urb->arg, urb->errorcode);
+ } else {
+ urb->complete(urb->arg, urb->actual_length);
+ }
+ }
+}
+
+static void rp2040_handle_buffer_status(struct usbh_bus *bus)
+{
+ struct rp2040_pipe *pipe;
+ struct usbh_urb *urb;
+ uint32_t remaining_buffers;
+ uint32_t size;
+
+ remaining_buffers = usb_hw->buf_status;
+
+ uint32_t bit = 1u;
+ if (remaining_buffers & bit) {
+ remaining_buffers &= ~bit;
+ usb_hw_clear->buf_status = bit;
+
+ pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0];
+ urb = pipe->urb;
+ switch (pipe->ep0_state) {
+ case USB_EP0_STATE_IN_DATA:
+ size = *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
+ memcpy(urb->transfer_buffer, (uint8_t *)pipe->data_buffer, size);
+
+ urb->transfer_buffer += size;
+ urb->actual_length += size;
+
+ if (*pipe->endpoint_control & EP_CTRL_DOUBLE_BUFFERED_BITS) {
+ if (size == USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ size = (*pipe->buffer_control >> 16) & USB_BUF_CTRL_LEN_MASK;
+ memcpy(urb->transfer_buffer, (uint8_t *)pipe->data_buffer + 64, size);
+
+ urb->transfer_buffer += size;
+ urb->actual_length += size;
+ }
+ }
+
+ if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
+ pipe->ep0_state = USB_EP0_STATE_OUT_STATUS;
+ rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ } else {
+ urb->data_toggle ^= 1;
+ usb_start_transfer(bus, 0, 0x80);
+ }
+ break;
+ case USB_EP0_STATE_OUT_DATA:
+ urb->actual_length += *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
+
+ if (*pipe->endpoint_control & EP_CTRL_DOUBLE_BUFFERED_BITS) {
+ urb->actual_length += (*pipe->buffer_control >> 16) & USB_BUF_CTRL_LEN_MASK;
+ }
+
+ if (urb->transfer_buffer_length == 0) {
+ pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
+ rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ } else {
+ urb->data_toggle ^= 1;
+ usb_start_transfer(bus, 0, 0x00);
+ }
+ break;
+ case USB_EP0_STATE_IN_STATUS:
+ case USB_EP0_STATE_OUT_STATUS:
+ urb->errorcode = 0;
+ rp2040_urb_waitup(urb);
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (uint8_t i = 1; remaining_buffers && i <= CONFIG_USBHOST_PIPE_NUM; i++) {
+ for (uint8_t j = 0; j < 2; j++) {
+ bit = 1 << (i * 2 + j);
+ if (remaining_buffers & bit) {
+ remaining_buffers &= ~bit;
+ usb_hw_clear->buf_status = bit;
+
+ pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i];
+ urb = pipe->urb;
+ if (urb == NULL) {
+ continue;
+ }
+
+ if (j == 0) { //IN
+ size = *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
+ memcpy(urb->transfer_buffer, (uint8_t *)pipe->data_buffer, size);
+
+ urb->transfer_buffer += size;
+ urb->actual_length += size;
+
+ urb->data_toggle ^= 1;
+ if (size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) || urb->transfer_buffer_length == 0) {
+ urb->errorcode = 0;
+ rp2040_urb_waitup(urb);
+ } else {
+ usb_start_transfer(bus, i, urb->ep->bEndpointAddress);
+ }
+ } else { //OUT
+ urb->data_toggle ^= 1;
+
+ urb->actual_length += *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
+
+ if (urb->transfer_buffer_length == 0) {
+ urb->errorcode = 0;
+ rp2040_urb_waitup(urb);
+ } else {
+ usb_start_transfer(bus, i, urb->ep->bEndpointAddress);
+ }
+ }
+ }
+ }
+ }
+}
+
+void USBH_IRQHandler(uint8_t busid)
+{
+ uint32_t status;
+ uint32_t handled = 0;
+ struct usbh_bus *bus;
+ struct rp2040_pipe *pipe;
+ struct usbh_urb *urb;
+
+ bus = &g_usbhost_bus[busid];
+ status = usb_hw->ints;
+
+ if (status & USB_INTS_HOST_CONN_DIS_BITS) {
+ handled |= USB_INTS_HOST_CONN_DIS_BITS;
+ usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS;
+ if (usbh_get_port_speed()) {
+ g_rp2040_hcd[bus->hcd.hcd_id].port_csc = 1;
+ g_rp2040_hcd[bus->hcd.hcd_id].port_pec = 1;
+ g_rp2040_hcd[bus->hcd.hcd_id].port_pe = 1;
+ bus->hcd.roothub.int_buffer[0] = (1 << 1);
+ usbh_hub_thread_wakeup(&bus->hcd.roothub);
+ } else {
+ g_rp2040_hcd[bus->hcd.hcd_id].port_csc = 1;
+ g_rp2040_hcd[bus->hcd.hcd_id].port_pec = 1;
+ g_rp2040_hcd[bus->hcd.hcd_id].port_pe = 0;
+ bus->hcd.roothub.int_buffer[0] = (1 << 1);
+ usbh_hub_thread_wakeup(&bus->hcd.roothub);
+ }
+ }
+
+ if (status & USB_INTS_STALL_BITS) {
+ handled |= USB_INTS_STALL_BITS;
+ usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS;
+ }
+
+ if (status & USB_INTS_BUFF_STATUS_BITS) {
+ handled |= USB_INTS_BUFF_STATUS_BITS;
+ rp2040_handle_buffer_status(bus);
+ }
+
+ if (status & USB_INTS_TRANS_COMPLETE_BITS) {
+ handled |= USB_INTS_TRANS_COMPLETE_BITS;
+ usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS;
+ if (usb_hw->sie_ctrl & USB_SIE_CTRL_SEND_SETUP_BITS) {
+ pipe = (struct rp2040_pipe *)&g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0];
+ urb = pipe->urb;
+ if (urb) {
+ if (urb->setup->wLength) {
+ if (urb->setup->bmRequestType & 0x80) {
+ pipe->ep0_state = USB_EP0_STATE_IN_DATA;
+ } else {
+ pipe->ep0_state = USB_EP0_STATE_OUT_DATA;
+ }
+ } else {
+ pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
+ }
+ urb->actual_length = 8;
+ rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ }
+ } else {
+ }
+ }
+
+ if (status & USB_INTS_ERROR_RX_TIMEOUT_BITS) {
+ handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS;
+ usb_hw_clear->sie_status = USB_SIE_STATUS_RX_TIMEOUT_BITS;
+ }
+
+ if (status & USB_INTS_ERROR_DATA_SEQ_BITS) {
+ handled |= USB_INTS_ERROR_DATA_SEQ_BITS;
+ usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS;
+ }
+
+ if (status ^ handled) {
+ USB_LOG_ERR("Unhandled IRQ 0x%x\n", (uint)(status ^ handled));
+ }
+}
+
+void rp2040_usbh_irq(void)
+{
+ USBH_IRQHandler(0);
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/template/usb_dc.c b/components/drivers/usb/cherryusb/port/template/usb_dc.c
new file mode 100644
index 0000000000..516b32ff4d
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/template/usb_dc.c
@@ -0,0 +1,125 @@
+#include "usbd_core.h"
+
+/* Endpoint state */
+struct usb_dc_ep_state {
+ uint16_t ep_mps; /* Endpoint max packet size */
+ uint8_t ep_type; /* Endpoint type */
+ uint8_t ep_stalled; /* Endpoint stall flag */
+ uint8_t *xfer_buf;
+ uint32_t xfer_len;
+ uint32_t actual_xfer_len;
+};
+
+/* Driver state */
+struct xxx_udc {
+ volatile uint8_t dev_addr;
+ struct usb_dc_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
+ struct usb_dc_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
+} g_xxx_udc;
+
+__WEAK void usb_dc_low_level_init(void)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(void)
+{
+}
+
+int usb_dc_init(uint8_t busid)
+{
+ memset(&g_xxx_udc, 0, sizeof(struct xxx_udc));
+
+ usb_dc_low_level_init();
+ return 0;
+}
+
+int usb_dc_deinit(uint8_t busid)
+{
+ return 0;
+}
+
+int usbd_set_address(uint8_t busid, const uint8_t addr)
+{
+ return 0;
+}
+
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ return -1;
+}
+
+uint8_t usbd_get_port_speed(uint8_t busid)
+{
+ return USB_SPEED_FULL;
+}
+
+int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
+
+ if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
+ g_xxx_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_xxx_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_xxx_udc.out_ep[ep_idx].ep_enable = true;
+ } else {
+ g_xxx_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_xxx_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_xxx_udc.in_ep[ep_idx].ep_enable = true;
+ }
+ return 0;
+}
+
+int usbd_ep_close(uint8_t busid, const uint8_t ep)
+{
+ return 0;
+}
+
+int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
+{
+ return 0;
+}
+
+int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
+{
+ return 0;
+}
+
+int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
+{
+ return 0;
+}
+
+int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint32_t tmp;
+
+ if (!data && data_len) {
+ return -1;
+ }
+
+ g_xxx_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_xxx_udc.in_ep[ep_idx].xfer_len = data_len;
+ g_xxx_udc.in_ep[ep_idx].actual_xfer_len = 0;
+
+ return 0;
+}
+
+int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+
+ g_xxx_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_xxx_udc.out_ep[ep_idx].xfer_len = data_len;
+ g_xxx_udc.out_ep[ep_idx].actual_xfer_len = 0;
+
+ return 0;
+}
+
+void USBD_IRQHandler(uint8_t busid)
+{
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/template/usb_hc.c b/components/drivers/usb/cherryusb/port/template/usb_hc.c
new file mode 100644
index 0000000000..1de1cd5047
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/template/usb_hc.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_hub.h"
+
+int usb_hc_init(struct usbh_bus *bus)
+{
+ return 0;
+}
+
+int usb_hc_deinit(struct usbh_bus *bus)
+{
+ return 0;
+}
+
+uint16_t usbh_get_frame_number(struct usbh_bus *bus)
+{
+ return 0;
+}
+
+int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
+{
+ uint8_t nports;
+ uint8_t port;
+ uint32_t status;
+
+ nports = CONFIG_USBHOST_MAX_RHPORTS;
+ port = setup->wIndex;
+ if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) {
+ switch (setup->bRequest) {
+ case HUB_REQUEST_CLEAR_FEATURE:
+ switch (setup->wValue) {
+ case HUB_FEATURE_HUB_C_LOCALPOWER:
+ break;
+ case HUB_FEATURE_HUB_C_OVERCURRENT:
+ break;
+ default:
+ return -USB_ERR_NOTSUPP;
+ }
+ break;
+ case HUB_REQUEST_SET_FEATURE:
+ switch (setup->wValue) {
+ case HUB_FEATURE_HUB_C_LOCALPOWER:
+ break;
+ case HUB_FEATURE_HUB_C_OVERCURRENT:
+ break;
+ default:
+ return -USB_ERR_NOTSUPP;
+ }
+ break;
+ case HUB_REQUEST_GET_DESCRIPTOR:
+ break;
+ case HUB_REQUEST_GET_STATUS:
+ memset(buf, 0, 4);
+ break;
+ default:
+ break;
+ }
+ } else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER) {
+ switch (setup->bRequest) {
+ case HUB_REQUEST_CLEAR_FEATURE:
+ if (!port || port > nports) {
+ return -USB_ERR_INVAL;
+ }
+
+ switch (setup->wValue) {
+ case HUB_PORT_FEATURE_ENABLE:
+ break;
+ case HUB_PORT_FEATURE_SUSPEND:
+ break;
+ case HUB_PORT_FEATURE_C_SUSPEND:
+ break;
+ case HUB_PORT_FEATURE_POWER:
+ break;
+ case HUB_PORT_FEATURE_C_CONNECTION:
+ break;
+ case HUB_PORT_FEATURE_C_ENABLE:
+ break;
+ case HUB_PORT_FEATURE_C_OVER_CURREN:
+ break;
+ case HUB_PORT_FEATURE_C_RESET:
+ break;
+ default:
+ return -USB_ERR_NOTSUPP;
+ }
+ break;
+ case HUB_REQUEST_SET_FEATURE:
+ if (!port || port > nports) {
+ return -USB_ERR_INVAL;
+ }
+
+ switch (setup->wValue) {
+ case HUB_PORT_FEATURE_SUSPEND:
+ break;
+ case HUB_PORT_FEATURE_POWER:
+ break;
+ case HUB_PORT_FEATURE_RESET:
+ break;
+
+ default:
+ return -USB_ERR_NOTSUPP;
+ }
+ break;
+ case HUB_REQUEST_GET_STATUS:
+ if (!port || port > nports) {
+ return -USB_ERR_INVAL;
+ }
+
+ memcpy(buf, &status, 4);
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+int usbh_submit_urb(struct usbh_urb *urb)
+{
+ return -USB_ERR_NOTSUPP;
+}
+
+int usbh_kill_urb(struct usbh_urb *urb)
+{
+ return -USB_ERR_NOTSUPP;
+}
+
+void USBH_IRQHandler(uint8_t busid)
+{
+}
\ No newline at end of file