diff --git a/components/drivers/usb/cherryusb/Kconfig b/components/drivers/usb/cherryusb/Kconfig
index abcb372fc3..c3bef25162 100644
--- a/components/drivers/usb/cherryusb/Kconfig
+++ b/components/drivers/usb/cherryusb/Kconfig
@@ -48,6 +48,10 @@ if RT_USING_CHERRYUSB
bool "musb_bk"
config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
+ config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
+ bool "chipidea_mcx"
+ config RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM
+ bool "chipidea_custom"
config RT_CHERRYUSB_DEVICE_BL
bool "bouffalo"
config RT_CHERRYUSB_DEVICE_CH32
@@ -162,10 +166,12 @@ if RT_USING_CHERRYUSB
bool "ehci_hpm"
config RT_CHERRYUSB_HOST_EHCI_AIC
bool "ehci_aic"
- config RT_CHERRYUSB_HOST_EHCI_NUVOTON_NUC980
- bool "ehci_nuvoton_nuc980"
- config RT_CHERRYUSB_HOST_EHCI_NUVOTON_MA35D0
- bool "ehci_nuvoton_ma35d0"
+ config RT_CHERRYUSB_HOST_EHCI_MCX
+ bool "ehci_mcx"
+ config RT_CHERRYUSB_HOST_EHCI_NUC980
+ bool "ehci_nuc980"
+ config RT_CHERRYUSB_HOST_EHCI_MA35D0
+ bool "ehci_ma35d0"
config RT_CHERRYUSB_HOST_EHCI_CUSTOM
bool "ehci_custom"
config RT_CHERRYUSB_HOST_DWC2_ST
@@ -294,7 +300,7 @@ if RT_USING_CHERRYUSB
config CONFIG_USBHOST_PLATFORM_RTL8152
bool
- config CHERRYUSB_HOST_TEMPLATE
+ config RT_CHERRYUSB_HOST_TEMPLATE
bool
prompt "Use usb host template"
default n
diff --git a/components/drivers/usb/cherryusb/README.md b/components/drivers/usb/cherryusb/README.md
index d79df88751..508211bd44 100644
--- a/components/drivers/usb/cherryusb/README.md
+++ b/components/drivers/usb/cherryusb/README.md
@@ -17,7 +17,7 @@ In order to make it easier for users to learn USB basics, enumeration, driver lo
- Class-drivers and porting-drivers are templating and simplification
- Clear API classification (slave: initialisation, registration api, command callback api, data sending and receiving api; host: initialisation, lookup api, data sending and receiving api)
-### Easy to use USB
+### Easy to use USB
In order to facilitate the use of the USB interface and to take into account the fact that users have learned about uart and dma, the following advantages have been designed for the data sending and receiving class of interface:
@@ -34,7 +34,7 @@ Taking into account USB performance issues and trying to achieve the theoretical
- Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
- Subcontracting function is handled in interrupt
-## Directoy Structure
+## Directory Structure
| Directory | Description |
|:-------------:|:---------------------------:|
@@ -65,15 +65,17 @@ CherryUSB Device Stack has the following functions:
- Support Device Firmware Upgrade CLASS (DFU)
- Support USB MIDI CLASS (MIDI)
- Support Remote NDIS (RNDIS)
-- Support WINUSB1.0、WINUSB2.0(with BOS)
+- Support WINUSB1.0、WINUSB2.0、WEBUSB、BOS
- Support Vendor class
+- Support UF2
+- Support Android Debug Bridge (Only support shell)
- Support multi device with the same USB IP
CherryUSB Device Stack resource usage (GCC 10.2 with -O2):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
-|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 |
+|usbd_core.c | 3516 | 512(default) + 320 | 0 | 0 |
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|usbd_hid.c | 364 | 0 | 0 | 0 |
@@ -87,6 +89,7 @@ The CherryUSB Host Stack has a standard enumeration implementation for devices m
CherryUSB Host Stack has the following functions:
+- Support low speed, full speed, high speed and super speed devices
- Automatic loading of supported Class drivers
- Support blocking transfers and asynchronous transfers
- Support Composite Device
@@ -98,7 +101,7 @@ CherryUSB Host Stack has the following functions:
- Support USB Audio CLASS (UAC1.0)
- Support Remote NDIS (RNDIS)
- Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm)
-- Support Vendor class
+- Support Vendor class (serial, net, wifi)
- Support USB modeswitch
- Support multi host with the same USB IP
@@ -108,7 +111,7 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
-|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | 0 |
+|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
@@ -152,6 +155,7 @@ Only standard and commercial USB IP are listed.
| DWC2(synopsys) | DWC2 | DWC2 | √ |
| MUSB(mentor) | MUSB | MUSB | √ |
| FOTG210(faraday)| FOTG210 | EHCI | √ |
+| CHIPIDEA(synopsys)| CHIPIDEA | EHCI | √ |
| CDNS2(cadence) | CDNS2 | CDNS2 | √ |
| CDNS3(cadence) | CDNS3 | XHCI | × |
| DWC3(synopsys) | DWC3 | XHCI | × |
@@ -175,17 +179,26 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
-|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
+|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
-|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.2 | Long-term |
+|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
-|Espressif | esp32s2/esp32s3 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | the same with ST |
-|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with Essemi |
-|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with Essemi |
-|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | the same with ST |
+|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
+|NXP | mcx | chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= 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
+
+CherryUSB package is available as follows:
+
+- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB)
+- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook)
+- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb)
+
## Commercial Support
Refer to https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html.
@@ -198,4 +211,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
Thanks to the following companies for their support (in no particular order).
-
\ No newline at end of file
+
diff --git a/components/drivers/usb/cherryusb/README_zh.md b/components/drivers/usb/cherryusb/README_zh.md
index 0aee5a75f7..b6d4f4bc1a 100644
--- a/components/drivers/usb/cherryusb/README_zh.md
+++ b/components/drivers/usb/cherryusb/README_zh.md
@@ -65,15 +65,17 @@ CherryUSB Device 协议栈当前实现以下功能:
- 支持 Device Firmware Upgrade CLASS (DFU)
- 支持 USB MIDI CLASS (MIDI)
- 支持 Remote NDIS (RNDIS)
-- 支持 WINUSB1.0、WINUSB2.0(带 BOS )
+- 支持 WINUSB1.0、WINUSB2.0、WEBUSB、BOS
- 支持 Vendor 类 class
+- 支持 UF2
+- 支持 Android Debug Bridge (Only support shell)
- 支持相同 USB IP 的多从机
CherryUSB Device 协议栈资源占用说明(GCC 10.2 with -O2):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
-|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 |
+|usbd_core.c | 3516 | 512(default) + 320 | 0 | 0 |
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|usbd_hid.c | 364 | 0 | 0 | 0 |
@@ -87,6 +89,7 @@ CherryUSB Host 协议栈对挂载在 roothub、外部 hub 上的设备规范了
CherryUSB Host 协议栈当前实现以下功能:
+- 支持 low speed, full speed, high speed 和 super speed 设备
- 自动加载支持的Class 驱动
- 支持阻塞式传输和异步传输
- 支持复合设备
@@ -98,7 +101,7 @@ CherryUSB Host 协议栈当前实现以下功能:
- Support USB Audio CLASS (UAC1.0)
- 支持 Remote NDIS (RNDIS)
- 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能)
-- 支持 Vendor 类 class
+- 支持 Vendor 类 class (serial, net, wifi)
- 支持 USB modeswitch
- 支持相同 USB IP 的多主机
@@ -108,7 +111,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
-|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | 0 |
+|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
@@ -152,6 +155,7 @@ x 受以下宏影响:
| DWC2(synopsys) | DWC2 | DWC2 | √ |
| MUSB(mentor) | MUSB | MUSB | √ |
| FOTG210(faraday)| FOTG210 | EHCI | √ |
+| CHIPIDEA(synopsys)| CHIPIDEA | EHCI | √ |
| CDNS2(cadence) | CDNS2 | CDNS2 | √ |
| CDNS3(cadence) | CDNS3 | XHCI | × |
| DWC3(synopsys) | DWC3 | XHCI | × |
@@ -176,20 +180,29 @@ CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
-|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
+|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
-|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.2 | Long-term |
+|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
-|Espressif | esp32s2/esp32s3 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | the same with ST |
-|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with Essemi |
-|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with Essemi |
-|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | the same with ST |
+|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
+|NXP | mcx | chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= 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 |
+## 软件包支持
+
+CherryUSB 软件包可以通过以下方式获取:
+
+- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB)
+- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook)
+- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb)
+
## 商业支持
-参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html。
+参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html 。
## 联系
diff --git a/components/drivers/usb/cherryusb/SConscript b/components/drivers/usb/cherryusb/SConscript
index ee4dc91116..8ae7d216b5 100644
--- a/components/drivers/usb/cherryusb/SConscript
+++ b/components/drivers/usb/cherryusb/SConscript
@@ -15,6 +15,8 @@ path += [cwd + '/class/vendor/net']
path += [cwd + '/class/vendor/serial']
src = []
+LIBS = []
+LIBPATH = []
CPPDEFINES = []
# USB DEVICE
@@ -56,6 +58,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
src += Glob('port/musb/usb_glue_bk.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_CUSTOM']):
src += Glob('port/musb/usb_dc_musb.c')
+ if GetDepend(['RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX']):
+ src += Glob('port/chipidea/usb_dc_chipidea.c')
+ src += Glob('port/chipidea/usb_glue_mcx.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_BL']):
src += Glob('port/bouffalolab/usb_dc_bl.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_HPM']):
@@ -68,6 +73,15 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
src += Glob('port/ch32/usb_dc_usbhs.c')
else:
src += Glob('port/ch32/usb_dc_usbfs.c')
+ if GetDepend(['RT_CHERRYUSB_DEVICE_PUSB2']):
+ path += [cwd + '/port/xhci/rt-thread']
+ src += Glob('port/pusb2/rt-thread/usb_dc_glue_phytium.c')
+ if GetDepend(['ARCH_ARMV8']):
+ LIBPATH = [cwd + '/port/pusb2']
+ LIBS = ['libpusb2_dc_a64.a']
+ if GetDepend(['ARCH_ARM_CORTEX_A']):
+ LIBPATH = [cwd + '/port/pusb2']
+ LIBS = ['libpusb2_dc_a32_softfp_neon.a']
if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_ACM']):
src += Glob('class/cdc/usbd_cdc.c')
@@ -140,10 +154,14 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
src += Glob('port/ehci/usb_hc_ehci.c')
src += Glob('port/ehci/usb_glue_aic.c')
src += Glob('port/ohci/usb_hc_ohci.c')
- if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUVOTON_NUC980']):
+ if GetDepend(['RT_CHERRYUSB_HOST_EHCI_MCX']):
+ path += [cwd + '/port/chipidea']
+ src += Glob('port/ehci/usb_hc_ehci.c')
+ src += Glob('port/ehci/usb_glue_mcx.c')
+ if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUC980']):
src += Glob('port/ehci/usb_hc_ehci.c')
src += Glob('port/ehci/usb_glue_nuc980.c')
- if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUVOTON_MA35D0']):
+ if GetDepend(['RT_CHERRYUSB_HOST_EHCI_MA35D0']):
src += Glob('port/ehci/usb_hc_ehci.c')
src += Glob('port/ehci/usb_glue_ma35d0.c')
if GetDepend(['RT_CHERRYUSB_HOST_EHCI_CUSTOM']):
@@ -169,6 +187,26 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
src += Glob('port/musb/usb_glue_bk.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_CUSTOM']):
src += Glob('port/musb/usb_hc_musb.c')
+ if GetDepend(['RT_CHERRYUSB_HOST_PUSB2']):
+ path += [cwd + '/port/pusb2/rt-thread']
+ src += Glob('port/pusb2/rt-thread/usb_hc_glue_phytium.c')
+ if GetDepend(['ARCH_ARMV8']):
+ LIBPATH = [cwd + '/port/pusb2']
+ LIBS = ['libpusb2_hc_a64.a']
+ if GetDepend(['ARCH_ARM_CORTEX_A']):
+ LIBPATH = [cwd + '/port/pusb2']
+ LIBS = ['libpusb2_hc_a32_softfp_neon.a']
+
+ if GetDepend(['RT_CHERRYUSB_HOST_XHCI']):
+ path += [cwd + '/port/xhci/phytium/rt-thread']
+ src += Glob('port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c')
+ src += Glob('port/xhci/phytium/rt-thread/usb_glue_phytium.c')
+ if GetDepend(['ARCH_ARMV8']):
+ LIBPATH = [cwd + '/port/xhci/phytium']
+ LIBS = ['libxhci_a64.a']
+ if GetDepend(['ARCH_ARM_CORTEX_A']):
+ LIBPATH = [cwd + '/port/xhci/phytium']
+ LIBS = ['libxhci_a32_softfp_neon.a']
if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM']):
src += Glob('class/cdc/usbh_cdc_acm.c')
diff --git a/components/drivers/usb/cherryusb/VERSION b/components/drivers/usb/cherryusb/VERSION
index 8a0bfa806e..cd4fba6666 100644
--- a/components/drivers/usb/cherryusb/VERSION
+++ b/components/drivers/usb/cherryusb/VERSION
@@ -1,5 +1,5 @@
VERSION_MAJOR = 1
-VERSION_MINOR = 3
-PATCHLEVEL = 1
+VERSION_MINOR = 4
+PATCHLEVEL = 0
VERSION_TWEAK = 0
EXTRAVERSION = 0
diff --git a/components/drivers/usb/cherryusb/cherryusb.cmake b/components/drivers/usb/cherryusb/cherryusb.cmake
index d8451d219d..28eec1d069 100644
--- a/components/drivers/usb/cherryusb/cherryusb.cmake
+++ b/components/drivers/usb/cherryusb/cherryusb.cmake
@@ -36,14 +36,16 @@ ${CMAKE_CURRENT_LIST_DIR}/class/audio
${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/vendor/net
${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial
+${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi
)
if(CONFIG_CHERRYUSB_DEVICE)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/core/usbd_core.c)
- if(CONFIG_CHERRYUSB_DEVICE_CDC)
- list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbd_cdc.c)
+ if(CONFIG_CHERRYUSB_DEVICE_CDC_ACM)
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbd_cdc_acm.c)
endif()
if(CONFIG_CHERRYUSB_DEVICE_HID)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/hid/usbd_hid.c)
@@ -69,6 +71,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
if(CONFIG_CHERRYUSB_DEVICE_DFU)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/dfu/usbd_dfu.c)
endif()
+ if(CONFIG_CHERRYUSB_DEVICE_ADB)
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/adb/usbd_adb.c)
+ endif()
if(DEFINED CONFIG_CHERRYUSB_DEVICE_DCD)
if("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "fsdev")
@@ -97,6 +102,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "musb_bk")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
+ elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "chipidea_mcx")
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_dc_chipidea.c)
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_glue_mcx.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "hpm")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpm/usb_dc_hpm.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "bl")
@@ -121,6 +129,9 @@ if(CONFIG_CHERRYUSB_HOST)
if(CONFIG_CHERRYUSB_HOST_CDC_ECM)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ecm.c)
endif()
+ if(CONFIG_CHERRYUSB_HOST_CDC_RNDIS)
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_rndis.c)
+ endif()
if(CONFIG_CHERRYUSB_HOST_CDC_NCM)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ncm.c)
endif()
@@ -142,18 +153,10 @@ if(CONFIG_CHERRYUSB_HOST)
endif()
if(CONFIG_CHERRYUSB_HOST_VIDEO)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/video/usbh_video.c)
- list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c)
- list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/chry_pool.c)
- list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/usbh_uvc_queue.c)
- list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb)
- list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool)
endif()
if(CONFIG_CHERRYUSB_HOST_AUDIO)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/audio/usbh_audio.c)
endif()
- if(CONFIG_CHERRYUSB_HOST_CDC_RNDIS)
- list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_rndis.c)
- endif()
if(CONFIG_CHERRYUSB_HOST_BLUETOOTH)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_bluetooth.c)
@@ -209,6 +212,9 @@ if(CONFIG_CHERRYUSB_HOST)
if(CONFIG_CHERRYUSB_HOST_PL2303)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_pl2303.c)
endif()
+ if(CONFIG_CHERRYUSB_HOST_BL616)
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi/usbh_bl616.c)
+ endif()
if(DEFINED CONFIG_CHERRYUSB_HOST_HCD)
if("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_bouffalo")
@@ -226,6 +232,12 @@ if(CONFIG_CHERRYUSB_HOST)
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_aic.c)
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci)
+ elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_mcx")
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
+ #list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_mcx.c)
+ list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci)
+ list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_nuvoton")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
@@ -260,5 +272,21 @@ if(DEFINED CONFIG_CHERRYUSB_OSAL)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_rtthread.c)
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "yoc")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_yoc.c)
+ elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf")
+ list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/osal/idf)
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/idf/usb_osal_idf.c)
+ elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "threadx")
+ list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_threadx.c)
endif()
+endif()
+
+if(CONFIG_CHERRYRB)
+list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c)
+list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb)
+endif()
+
+if(CONFIG_CHERRYMP)
+list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool.c)
+list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/usbh_uvc_queue.c)
+list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp)
endif()
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/cherryusb_config_template.h b/components/drivers/usb/cherryusb/cherryusb_config_template.h
index 493f8a4e93..4f0517bc2d 100644
--- a/components/drivers/usb/cherryusb/cherryusb_config_template.h
+++ b/components/drivers/usb/cherryusb/cherryusb_config_template.h
@@ -6,16 +6,10 @@
#ifndef CHERRYUSB_CONFIG_H
#define CHERRYUSB_CONFIG_H
-#define CHERRYUSB_VERSION 0x010301
-#define CHERRYUSB_VERSION_STR "v1.3.1"
-
/* ================ USB common Configuration ================ */
#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__)
-#define usb_malloc(size) malloc(size)
-#define usb_free(ptr) free(ptr)
-
#ifndef CONFIG_USB_DBG_LEVEL
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
#endif
@@ -72,6 +66,10 @@
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
#endif
+/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */
+// #define CONFIG_USBDEV_MSC_POLLING
+
+/* move msc read & write from isr to thread */
// #define CONFIG_USBDEV_MSC_THREAD
#ifndef CONFIG_USBDEV_MSC_PRIO
diff --git a/components/drivers/usb/cherryusb/class/adb/usbd_adb.c b/components/drivers/usb/cherryusb/class/adb/usbd_adb.c
new file mode 100644
index 0000000000..7629ea389b
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/adb/usbd_adb.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usbd_adb.h"
+
+#define ADB_OUT_EP_IDX 0
+#define ADB_IN_EP_IDX 1
+
+#define ADB_STATE_READ_MSG 0
+#define ADB_STATE_READ_DATA 1
+#define ADB_STATE_WRITE_MSG 2
+#define ADB_STATE_WRITE_DATA 3
+#define ADB_STATE_AWRITE_MSG 4
+#define ADB_STATE_AWRITE_DATA 5
+
+#define MAX_PAYLOAD_V1 (4 * 1024)
+#define MAX_PAYLOAD_V2 (256 * 1024)
+#define MAX_PAYLOAD MAX_PAYLOAD_V1
+#define A_VERSION 0x01000000
+
+#define A_SYNC 0x434e5953
+#define A_CNXN 0x4e584e43
+#define A_OPEN 0x4e45504f
+#define A_OKAY 0x59414b4f
+#define A_CLSE 0x45534c43
+#define A_WRTE 0x45545257
+#define A_AUTH 0x48545541
+
+struct adb_msg {
+ uint32_t command; /* command identifier constant (A_CNXN, ...) */
+ uint32_t arg0; /* first argument */
+ uint32_t arg1; /* second argument */
+ uint32_t data_length; /* length of payload (0 is allowed) */
+ uint32_t data_crc32; /* crc32 of data payload */
+ uint32_t magic; /* command ^ 0xffffffff */
+};
+
+struct adb_packet {
+ struct adb_msg msg;
+ uint8_t payload[MAX_PAYLOAD];
+};
+
+struct usbd_adb {
+ uint8_t state;
+ uint8_t common_state;
+ uint8_t write_state;
+ bool writable;
+ uint32_t localid;
+ uint32_t shell_remoteid;
+ uint32_t file_remoteid;
+} adb_client;
+
+static struct usbd_endpoint adb_ep_data[2];
+
+USB_NOCACHE_RAM_SECTION struct adb_packet tx_packet;
+USB_NOCACHE_RAM_SECTION struct adb_packet rx_packet;
+
+static inline uint32_t adb_packet_checksum(struct adb_packet *packet)
+{
+ uint32_t sum = 0;
+ uint32_t i;
+
+ for (i = 0; i < packet->msg.data_length; ++i) {
+ sum += (uint32_t)(packet->payload[i]);
+ }
+
+ return sum;
+}
+
+static uint32_t usbd_adb_get_remoteid(uint32_t localid)
+{
+ if (localid == ADB_SHELL_LOALID) {
+ return adb_client.shell_remoteid;
+ } else {
+ return adb_client.file_remoteid;
+ }
+}
+
+static void adb_send_msg(struct adb_packet *packet)
+{
+ adb_client.common_state = ADB_STATE_WRITE_MSG;
+
+ packet->msg.data_crc32 = adb_packet_checksum(packet);
+ packet->msg.magic = packet->msg.command ^ 0xffffffff;
+
+ usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg));
+}
+
+static void adb_send_okay(struct adb_packet *packet, uint32_t localid)
+{
+ packet->msg.command = A_OKAY;
+ packet->msg.arg0 = localid;
+ packet->msg.arg1 = usbd_adb_get_remoteid(localid);
+ packet->msg.data_length = 0;
+
+ adb_send_msg(&tx_packet);
+}
+
+static void adb_send_close(struct adb_packet *packet, uint32_t localid, uint32_t remoteid)
+{
+ packet->msg.command = A_CLSE;
+ packet->msg.arg0 = localid;
+ packet->msg.arg1 = remoteid;
+ packet->msg.data_length = 0;
+
+ adb_send_msg(&tx_packet);
+}
+
+void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ (void)ep;
+
+ if (adb_client.common_state == ADB_STATE_READ_MSG) {
+ if (nbytes != sizeof(struct adb_msg)) {
+ USB_LOG_ERR("invalid adb msg size:%d\r\n", nbytes);
+ return;
+ }
+
+ USB_LOG_DBG("command:%x arg0:%x arg1:%x len:%d\r\n",
+ rx_packet.msg.command,
+ rx_packet.msg.arg0,
+ rx_packet.msg.arg1,
+ rx_packet.msg.data_length);
+
+ if (rx_packet.msg.data_length) {
+ /* setup next out ep read transfer */
+ adb_client.common_state = ADB_STATE_READ_DATA;
+ usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, rx_packet.payload, rx_packet.msg.data_length);
+ } else {
+ if (rx_packet.msg.command == A_CLSE) {
+ adb_client.writable = false;
+ usbd_adb_notify_write_done();
+ USB_LOG_INFO("Close remoteid:%x\r\n", rx_packet.msg.arg0);
+ }
+ adb_client.common_state = ADB_STATE_READ_MSG;
+ /* setup first out ep read transfer */
+ usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
+ }
+ } else if (adb_client.common_state == ADB_STATE_READ_DATA) {
+ switch (rx_packet.msg.command) {
+ case A_SYNC:
+
+ break;
+ case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
+ char *support_feature = "device::"
+ "ro.product.name=cherryadb;"
+ "ro.product.model=cherrysh;"
+ "ro.product.device=cherryadb;"
+ "features=cmd,shell_v1";
+
+ tx_packet.msg.command = A_CNXN;
+ tx_packet.msg.arg0 = A_VERSION;
+ tx_packet.msg.arg1 = MAX_PAYLOAD;
+ tx_packet.msg.data_length = strlen(support_feature);
+ memcpy(tx_packet.payload, support_feature, strlen(support_feature));
+
+ adb_send_msg(&tx_packet);
+
+ adb_client.writable = false;
+ break;
+ case A_OPEN: /* OPEN(local-id, 0, "destination") */
+ rx_packet.payload[rx_packet.msg.data_length] = '\0';
+
+ if (strncmp((const char *)rx_packet.payload, "shell:", 6) == 0) {
+ adb_client.localid = ADB_SHELL_LOALID;
+ adb_client.shell_remoteid = rx_packet.msg.arg0;
+ adb_send_okay(&tx_packet, ADB_SHELL_LOALID);
+
+ USB_LOG_INFO("Open shell service, remoteid:%x\r\n", rx_packet.msg.arg0);
+ } else if (strncmp((const char *)rx_packet.payload, "sync:", 5) == 0) {
+ adb_client.localid = ADB_FILE_LOALID;
+ adb_client.file_remoteid = rx_packet.msg.arg0;
+ adb_send_okay(&tx_packet, ADB_FILE_LOALID);
+ USB_LOG_INFO("Open file service, remoteid:%x\r\n", rx_packet.msg.arg0);
+ }
+ break;
+ case A_OKAY:
+
+ break;
+ case A_CLSE:
+
+ break;
+ case A_WRTE: /* WRITE(local-id, remote-id, "data") */
+ if ((rx_packet.msg.arg0 == adb_client.shell_remoteid) && (rx_packet.msg.arg1 == ADB_SHELL_LOALID)) {
+ adb_send_okay(&tx_packet, rx_packet.msg.arg1);
+ } else if ((rx_packet.msg.arg0 == adb_client.file_remoteid) && (rx_packet.msg.arg1 == ADB_FILE_LOALID)) {
+ adb_send_okay(&tx_packet, rx_packet.msg.arg1);
+ } else {
+ adb_send_close(&tx_packet, 0, rx_packet.msg.arg0);
+ }
+ break;
+ case A_AUTH:
+
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void usbd_adb_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ (void)ep;
+ (void)nbytes;
+
+ if (adb_client.common_state == ADB_STATE_WRITE_MSG) {
+ if (tx_packet.msg.data_length) {
+ adb_client.common_state = ADB_STATE_WRITE_DATA;
+ usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length);
+ } else {
+ if (rx_packet.msg.command == A_WRTE) {
+ adb_client.writable = true;
+ if (adb_client.localid == ADB_SHELL_LOALID) {
+ usbd_adb_notify_shell_read(rx_packet.payload, rx_packet.msg.data_length);
+ } else {
+ }
+ }
+ adb_client.common_state = ADB_STATE_READ_MSG;
+ /* setup first out ep read transfer */
+ usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
+ }
+ } else if (adb_client.common_state == ADB_STATE_WRITE_DATA) {
+ adb_client.common_state = ADB_STATE_READ_MSG;
+ /* setup first out ep read transfer */
+ usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
+ } else if (adb_client.write_state == ADB_STATE_AWRITE_MSG) {
+ if (tx_packet.msg.data_length) {
+ adb_client.write_state = ADB_STATE_AWRITE_DATA;
+ usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length);
+ } else {
+ }
+ } else if (adb_client.write_state == ADB_STATE_AWRITE_DATA) {
+ usbd_adb_notify_write_done();
+ }
+}
+
+void adb_notify_handler(uint8_t busid, uint8_t event, void *arg)
+{
+ (void)arg;
+
+ switch (event) {
+ case USBD_EVENT_INIT:
+ break;
+ case USBD_EVENT_DEINIT:
+ break;
+ case USBD_EVENT_RESET:
+ break;
+ case USBD_EVENT_CONFIGURED:
+ adb_client.common_state = ADB_STATE_READ_MSG;
+ /* setup first out ep read transfer */
+ usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
+ break;
+
+ default:
+ break;
+ }
+}
+
+struct usbd_interface *usbd_adb_init_intf(uint8_t busid, struct usbd_interface *intf, uint8_t in_ep, uint8_t out_ep)
+{
+ (void)busid;
+
+ intf->class_interface_handler = NULL;
+ intf->class_endpoint_handler = NULL;
+ intf->vendor_handler = NULL;
+ intf->notify_handler = adb_notify_handler;
+
+ adb_ep_data[ADB_OUT_EP_IDX].ep_addr = out_ep;
+ adb_ep_data[ADB_OUT_EP_IDX].ep_cb = usbd_adb_bulk_out;
+ adb_ep_data[ADB_IN_EP_IDX].ep_addr = in_ep;
+ adb_ep_data[ADB_IN_EP_IDX].ep_cb = usbd_adb_bulk_in;
+
+ usbd_add_endpoint(busid, &adb_ep_data[ADB_OUT_EP_IDX]);
+ usbd_add_endpoint(busid, &adb_ep_data[ADB_IN_EP_IDX]);
+
+ return intf;
+}
+
+bool usbd_adb_can_write(void)
+{
+ return adb_client.writable;
+}
+
+int usbd_abd_write(uint32_t localid, const uint8_t *data, uint32_t len)
+{
+ struct adb_packet *packet;
+
+ packet = &tx_packet;
+ packet->msg.command = A_WRTE;
+ packet->msg.arg0 = localid;
+ packet->msg.arg1 = usbd_adb_get_remoteid(localid);
+ packet->msg.data_length = len;
+ memcpy(packet->payload, data, len);
+
+ packet->msg.data_crc32 = adb_packet_checksum(packet);
+ packet->msg.magic = packet->msg.command ^ 0xffffffff;
+
+ adb_client.write_state = ADB_STATE_AWRITE_MSG;
+ usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg));
+ return 0;
+}
+
+void usbd_adb_close(uint32_t localid)
+{
+ adb_send_close(&tx_packet, 0, usbd_adb_get_remoteid(localid));
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/class/adb/usbd_adb.h b/components/drivers/usb/cherryusb/class/adb/usbd_adb.h
new file mode 100644
index 0000000000..4dbc730f66
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/adb/usbd_adb.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBD_ADB_H
+#define USBD_ADB_H
+
+#include
+
+#define ADB_SHELL_LOALID 0x01
+#define ADB_FILE_LOALID 0x02
+
+// clang-format off
+#define ADB_DESCRIPTOR_INIT(bFirstInterface, in_ep, out_ep, wMaxPacketSize) \
+ USB_INTERFACE_DESCRIPTOR_INIT(bFirstInterface, 0x00, 0x02, 0xff, 0x42, 0x01, 0x02), \
+ USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x02, wMaxPacketSize, 0x00), \
+ USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x02, wMaxPacketSize, 0x00)
+// clang-format on
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct usbd_interface *usbd_adb_init_intf(uint8_t busid, struct usbd_interface *intf, uint8_t in_ep, uint8_t out_ep);
+
+void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len);
+void usbd_adb_notify_file_read(uint8_t *data, uint32_t len);
+void usbd_adb_notify_write_done(void);
+bool usbd_adb_can_write(void);
+int usbd_abd_write(uint32_t localid, const uint8_t *data, uint32_t len);
+void usbd_adb_close(uint32_t localid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBD_ADB_H */
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/class/audio/usbd_audio.c b/components/drivers/usb/cherryusb/class/audio/usbd_audio.c
index c78c8ed751..4ff3767abf 100644
--- a/components/drivers/usb/cherryusb/class/audio/usbd_audio.c
+++ b/components/drivers/usb/cherryusb/class/audio/usbd_audio.c
@@ -62,7 +62,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
setup->bRequest);
uint8_t entity_id;
- uint8_t ep;
+ uint8_t ep = 0;
uint8_t subtype = 0x01;
uint8_t control_selector;
uint8_t ch;
@@ -287,7 +287,7 @@ static void audio_notify_handler(uint8_t busid, uint8_t event, void *arg)
}
}
-struct usbd_interface *usbd_audio_init_intf(uint8_t busid,
+struct usbd_interface *usbd_audio_init_intf(uint8_t busid,
struct usbd_interface *intf,
uint16_t uac_version,
struct audio_entity_info *table,
@@ -314,31 +314,56 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid,
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume)
{
+ (void)busid;
+ (void)ep;
+ (void)ch;
+ (void)volume;
}
__WEAK int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch)
{
+ (void)busid;
+ (void)ep;
+ (void)ch;
+
return 0;
}
__WEAK void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute)
{
+ (void)busid;
+ (void)ep;
+ (void)ch;
+ (void)mute;
}
__WEAK bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch)
{
+ (void)busid;
+ (void)ep;
+ (void)ch;
+
return 0;
}
__WEAK void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
{
+ (void)busid;
+ (void)ep;
+ (void)sampling_freq;
}
__WEAK uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
{
+ (void)busid;
+ (void)ep;
+
return 0;
}
__WEAK void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sampling_freq_table)
{
+ (void)busid;
+ (void)ep;
+ (void)sampling_freq_table;
}
diff --git a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c
index 223c340b87..2f06782682 100644
--- a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c
+++ b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c
@@ -456,20 +456,26 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
static int usbh_audio_data_connect(struct usbh_hubport *hport, uint8_t intf)
{
+ (void)hport;
+ (void)intf;
return 0;
}
static int usbh_audio_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
{
+ (void)hport;
+ (void)intf;
return 0;
}
__WEAK void usbh_audio_run(struct usbh_audio *audio_class)
{
+ (void)audio_class;
}
__WEAK void usbh_audio_stop(struct usbh_audio *audio_class)
{
+ (void)audio_class;
}
const struct usbh_class_driver audio_ctrl_class_driver = {
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h
index ebf3d029e6..2cf3df1a3b 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h
+++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h
@@ -1,29 +1,13 @@
/*
- * Copyright (c) 2022, sakumisu
+ * Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBD_CDC_H
#define USBD_CDC_H
-#include "usb_cdc.h"
+// legacy for old version
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "usbd_cdc_acm.h"
-/* Init cdc acm interface driver */
-struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf);
-
-/* Setup request command callback api */
-void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
-void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
-void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr);
-void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts);
-void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* USBD_CDC_H */
+#endif
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.c b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c
similarity index 94%
rename from components/drivers/usb/cherryusb/class/cdc/usbd_cdc.c
rename to components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c
index 50d13d7d53..cf7c3c0dd9 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.c
+++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_acm.h"
const char *stop_name[] = { "1", "1.5", "2" };
const char *parity_name[] = { "N", "O", "E", "M", "S" };
@@ -85,6 +85,8 @@ static int cdc_acm_class_interface_request_handler(uint8_t busid, struct usb_set
struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf)
{
+ (void)busid;
+
intf->class_interface_handler = cdc_acm_class_interface_request_handler;
intf->class_endpoint_handler = NULL;
intf->vendor_handler = NULL;
@@ -95,10 +97,16 @@ struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interfa
__WEAK void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
{
+ (void)busid;
+ (void)intf;
+ (void)line_coding;
}
__WEAK void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
{
+ (void)busid;
+ (void)intf;
+
line_coding->dwDTERate = 2000000;
line_coding->bDataBits = 8;
line_coding->bParityType = 0;
@@ -107,12 +115,20 @@ __WEAK void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc
__WEAK void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
{
+ (void)busid;
+ (void)intf;
+ (void)dtr;
}
__WEAK void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts)
{
+ (void)busid;
+ (void)intf;
+ (void)rts;
}
__WEAK void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf)
{
+ (void)busid;
+ (void)intf;
}
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.h b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.h
new file mode 100644
index 0000000000..662c238c8c
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBD_CDC_ACM_H
+#define USBD_CDC_ACM_H
+
+#include "usb_cdc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Init cdc acm interface driver */
+struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf);
+
+/* Setup request command callback api */
+void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
+void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
+void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr);
+void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts);
+void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBD_CDC_ACM_H */
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c
index b0c1217d75..29e82ceeae 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c
+++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c
@@ -79,6 +79,10 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
"bRequest 0x%02x\r\n",
setup->bRequest);
+ (void)busid;
+ (void)data;
+ (void)len;
+
g_cmd_intf = LO_BYTE(setup->wIndex);
switch (setup->bRequest) {
@@ -105,6 +109,9 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
{
+ (void)busid;
+ (void)arg;
+
switch (event) {
case USBD_EVENT_RESET:
g_current_net_status = 0;
@@ -123,19 +130,23 @@ void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
void cdc_ecm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
+ (void)busid;
+
g_cdc_ecm_rx_data_length += nbytes;
- if (nbytes < usbd_get_ep_mps(busid, ep)) {
+ if (nbytes < usbd_get_ep_mps(0, ep)) {
g_cdc_ecm_rx_data_buffer = g_cdc_ecm_rx_buffer;
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
} else {
- usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, ep));
+ usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(0, ep));
}
}
void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
- if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
+ (void)busid;
+
+ if ((nbytes % usbd_get_ep_mps(0, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(0, ep, NULL, 0);
} else {
@@ -145,6 +156,10 @@ void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
void cdc_ecm_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
+ (void)busid;
+ (void)ep;
+ (void)nbytes;
+
if (g_current_net_status == 1) {
g_current_net_status = 2;
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, g_connect_speed_table);
@@ -242,4 +257,6 @@ void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2])
__WEAK void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len)
{
+ (void)buf;
+ (void)len;
}
diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c
index c2c953ae8e..957c6b2e1a 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c
+++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c
@@ -12,7 +12,7 @@
#define DEV_FORMAT "/dev/ttyACM%d"
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[64];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
static struct usbh_cdc_acm g_cdc_acm_class[CONFIG_USBHOST_MAX_CDC_ACM_CLASS];
static uint32_t g_devinuse = 0;
@@ -57,9 +57,9 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
setup->wIndex = cdc_acm_class->intf;
setup->wLength = 7;
- memcpy(g_cdc_acm_buf, line_coding, sizeof(struct cdc_line_coding));
+ memcpy(g_cdc_acm_buf[cdc_acm_class->minor], line_coding, sizeof(struct cdc_line_coding));
- return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf);
+ return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]);
}
int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
@@ -78,11 +78,11 @@ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
setup->wIndex = cdc_acm_class->intf;
setup->wLength = 7;
- ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf);
+ ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]);
if (ret < 0) {
return ret;
}
- memcpy(line_coding, g_cdc_acm_buf, sizeof(struct cdc_line_coding));
+ memcpy(line_coding, g_cdc_acm_buf[cdc_acm_class->minor], sizeof(struct cdc_line_coding));
return ret;
}
@@ -231,20 +231,26 @@ int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *
static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf)
{
+ (void)hport;
+ (void)intf;
return 0;
}
static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
{
+ (void)hport;
+ (void)intf;
return 0;
}
__WEAK void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
{
+ (void)cdc_acm_class;
}
__WEAK void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
{
+ (void)cdc_acm_class;
}
const struct usbh_class_driver cdc_acm_class_driver = {
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 ad05d5164c..76cfb41aa3 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c
+++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c
@@ -236,6 +236,7 @@ void usbh_cdc_ecm_rx_thread(void *argument)
uint32_t g_cdc_ecm_rx_length;
int ret;
+ (void)argument;
USB_LOG_INFO("Create cdc ecm rx thread\r\n");
// clang-format off
find_class:
@@ -306,10 +307,12 @@ int usbh_cdc_ecm_eth_output(uint32_t buflen)
__WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
{
+ (void)cdc_ecm_class;
}
__WEAK void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
{
+ (void)cdc_ecm_class;
}
const struct usbh_class_driver cdc_ecm_class_driver = {
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 99e8871e96..2456fba54a 100644
--- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c
+++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c
@@ -259,6 +259,7 @@ void usbh_cdc_ncm_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
+ (void)argument;
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
// clang-format off
find_class:
@@ -330,7 +331,7 @@ find_class:
#else
if ((g_cdc_ncm_rx_length + (16 * 1024)) > CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) {
#endif
- USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE\r\n");
+ USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE\r\n");
while (1) {
}
}
@@ -386,10 +387,12 @@ int usbh_cdc_ncm_eth_output(uint32_t buflen)
__WEAK void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
{
+ (void)cdc_ncm_class;
}
__WEAK void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
{
+ (void)cdc_ncm_class;
}
const struct usbh_class_driver cdc_ncm_class_driver = {
diff --git a/components/drivers/usb/cherryusb/class/hid/usb_hid.h b/components/drivers/usb/cherryusb/class/hid/usb_hid.h
index 5a88a34be4..b244d11972 100644
--- a/components/drivers/usb/cherryusb/class/hid/usb_hid.h
+++ b/components/drivers/usb/cherryusb/class/hid/usb_hid.h
@@ -558,26 +558,24 @@ struct usb_hid_kbd_report
};
/* Keyboard output report (1 byte) (HID B.1),
- * see USBHID_KBDOUT_* definitions
+ * see HID_KBD_OUTPUT_* definitions
*/
/* Mouse input report (HID B.2) */
struct usb_hid_mouse_report
{
uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
- uint8_t xdisp; /* X displacement */
- uint8_t ydisp; /* y displacement */
+ int8_t xdisp; /* X displacement */
+ int8_t ydisp; /* y displacement */
/* Device specific additional bytes may follow */
-#ifdef CONFIG_INPUT_MOUSE_WHEEL
uint8_t wdisp; /* Wheel displacement */
-#endif
};
/* Joystick input report (1 bytes) (HID D.1) */
struct usb_hid_js_report
{
- uint8_t xpos; /* X position */
- uint8_t ypos; /* X position */
+ int8_t xpos; /* X position */
+ int8_t ypos; /* X position */
uint8_t buttons; /* See USBHID_JSIN_* definitions */
uint8_t throttle; /* Throttle */
};
diff --git a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c
index d98b82eb84..fed749f2f4 100644
--- a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c
+++ b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c
@@ -50,6 +50,8 @@ static int hid_class_interface_request_handler(uint8_t busid, struct usb_setup_p
struct usbd_interface *usbd_hid_init_intf(uint8_t busid, struct usbd_interface *intf, const uint8_t *desc, uint32_t desc_len)
{
+ (void)busid;
+
intf->class_interface_handler = hid_class_interface_request_handler;
intf->class_endpoint_handler = NULL;
intf->vendor_handler = NULL;
@@ -60,30 +62,65 @@ struct usbd_interface *usbd_hid_init_intf(uint8_t busid, struct usbd_interface *
return intf;
}
+/*
+ * Appendix G: HID Request Support Requirements
+ *
+ * The following table enumerates the requests that need to be supported by various types of HID class devices.
+ * Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
+ * ------------------------------------------------------------------------------------------
+ * Boot Mouse Required Optional Optional Optional Required Required
+ * Non-Boot Mouse Required Optional Optional Optional Optional Optional
+ * Boot Keyboard Required Optional Required Required Required Required
+ * Non-Boot Keybrd Required Optional Required Required Optional Optional
+ * Other Device Required Optional Optional Optional Optional Optional
+ */
+
__WEAK void usbd_hid_get_report(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t **data, uint32_t *len)
{
+ (void)busid;
+ (void)intf;
+ (void)report_id;
+ (void)report_type;
(*data[0]) = 0;
*len = 1;
}
__WEAK uint8_t usbd_hid_get_idle(uint8_t busid, uint8_t intf, uint8_t report_id)
{
+ (void)busid;
+ (void)intf;
+ (void)report_id;
return 0;
}
__WEAK uint8_t usbd_hid_get_protocol(uint8_t busid, uint8_t intf)
{
+ (void)busid;
+ (void)intf;
return 0;
}
__WEAK void usbd_hid_set_report(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t *report, uint32_t report_len)
{
+ (void)busid;
+ (void)intf;
+ (void)report_id;
+ (void)report_type;
+ (void)report;
+ (void)report_len;
}
__WEAK void usbd_hid_set_idle(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t duration)
{
+ (void)busid;
+ (void)intf;
+ (void)report_id;
+ (void)duration;
}
__WEAK void usbd_hid_set_protocol(uint8_t busid, uint8_t intf, uint8_t protocol)
{
+ (void)busid;
+ (void)intf;
+ (void)protocol;
}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c
index 1761ba6f58..d2a25b3059 100644
--- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c
+++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c
@@ -12,7 +12,15 @@
#define DEV_FORMAT "/dev/input%d"
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[128];
+/* general descriptor field offsets */
+#define DESC_bLength 0 /** Length offset */
+#define DESC_bDescriptorType 1 /** Descriptor type offset */
+
+/* interface descriptor field offsets */
+#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
+#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(256, CONFIG_USB_ALIGN_SIZE)];
static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS];
static uint32_t g_devinuse = 0;
@@ -56,13 +64,13 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = HID_DESCRIPTOR_TYPE_HID_REPORT << 8;
setup->wIndex = hid_class->intf;
- setup->wLength = 128;
+ setup->wLength = hid_class->report_size;
- ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf);
+ ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
if (ret < 0) {
return ret;
}
- memcpy(buffer, g_hid_buf, ret - 8);
+ memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
return ret;
}
@@ -100,11 +108,11 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
setup->wIndex = hid_class->intf;
setup->wLength = 1;
- ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf);
+ ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
if (ret < 0) {
return ret;
}
- memcpy(buffer, g_hid_buf, 1);
+ memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
return ret;
}
@@ -147,6 +155,7 @@ int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen)
{
struct usb_setup_packet *setup;
+ int ret;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
@@ -159,13 +168,21 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
setup->wIndex = 0;
setup->wLength = buflen;
- return usbh_control_transfer(hid_class->hport, setup, buffer);
+ ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
+ if (ret < 0) {
+ return ret;
+ }
+ memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
+ return ret;
}
int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;
int ret;
+ uint8_t cur_iface = 0xff;
+ uint8_t *p;
+ bool found = false;
struct usbh_hid *hid_class = usbh_hid_class_alloc();
if (hid_class == NULL) {
@@ -178,6 +195,47 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
hport->config.intf[intf].priv = hid_class;
+ p = hport->raw_config_desc;
+ while (p[DESC_bLength]) {
+ switch (p[DESC_bDescriptorType]) {
+ case USB_DESCRIPTOR_TYPE_INTERFACE:
+ cur_iface = p[INTF_DESC_bInterfaceNumber];
+ if (cur_iface == intf) {
+ hid_class->protocol = p[7];
+ struct usb_hid_descriptor *desc = (struct usb_hid_descriptor *)(p + 9);
+
+ if (desc->bDescriptorType != HID_DESCRIPTOR_TYPE_HID) {
+ USB_LOG_ERR("HID descriptor not found\r\n");
+ return -USB_ERR_INVAL;
+ }
+
+ if (desc->subdesc[0].bDescriptorType != HID_DESCRIPTOR_TYPE_HID_REPORT) {
+ USB_LOG_ERR("HID report descriptor not found\r\n");
+ return -USB_ERR_INVAL;
+ }
+
+ hid_class->report_size = desc->subdesc[0].wDescriptorLength;
+
+ if (hid_class->report_size > sizeof(g_hid_buf[hid_class->minor])) {
+ USB_LOG_ERR("HID report descriptor too large\r\n");
+ return -USB_ERR_INVAL;
+ }
+ found = true;
+ goto found;
+ }
+ break;
+ default:
+ break;
+ }
+ /* skip to next descriptor */
+ p += p[DESC_bLength];
+ }
+
+ if (found == false) {
+ USB_LOG_ERR("HID interface not found\r\n");
+ return -USB_ERR_INVAL;
+ }
+found:
// /* 0x0 = boot protocol, 0x1 = report protocol */
// ret = usbh_hid_set_protocol(hid_class, 0x1);
// if (ret < 0) {
@@ -239,10 +297,12 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
__WEAK void usbh_hid_run(struct usbh_hid *hid_class)
{
+ (void)hid_class;
}
__WEAK void usbh_hid_stop(struct usbh_hid *hid_class)
{
+ (void)hid_class;
}
const struct usbh_class_driver hid_class_driver = {
diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h
index 17caaba277..6a6cef1645 100644
--- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h
+++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h
@@ -16,6 +16,9 @@ struct usbh_hid {
struct usbh_urb intout_urb; /* INTR OUT urb */
uint8_t report_desc[256];
+ uint16_t report_size;
+
+ uint8_t protocol;
uint8_t intf; /* interface number */
uint8_t minor;
diff --git a/components/drivers/usb/cherryusb/class/hub/usb_hub.h b/components/drivers/usb/cherryusb/class/hub/usb_hub.h
index 7956b163e7..68e0ecf17d 100644
--- a/components/drivers/usb/cherryusb/class/hub/usb_hub.h
+++ b/components/drivers/usb/cherryusb/class/hub/usb_hub.h
@@ -10,6 +10,12 @@
#define HUB_DESCRIPTOR_TYPE_HUB 0x29
#define HUB_DESCRIPTOR_TYPE_HUB3 0x2A
+#define HUB_MAX_DEPTH 5
+
+#define HUB_SUBCLASS 0x00
+#define HUB_PROTOCOL_STT 0x01
+#define HUB_PROTOCOL_MTT 0x02
+
/* Hub class requests */
#define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS
#define HUB_REQUEST_CLEAR_FEATURE USB_REQUEST_CLEAR_FEATURE
@@ -27,23 +33,31 @@
#define HUB_FEATURE_HUB_C_OVERCURRENT (0x1)
/* Port features */
-#define HUB_PORT_FEATURE_CONNECTION (0x00)
-#define HUB_PORT_FEATURE_ENABLE (0x01)
-#define HUB_PORT_FEATURE_SUSPEND (0x02)
-#define HUB_PORT_FEATURE_OVERCURRENT (0x03)
-#define HUB_PORT_FEATURE_RESET (0x04)
-#define HUB_PORT_FEATURE_L1 (0x05)
-#define HUB_PORT_FEATURE_POWER (0x08)
-#define HUB_PORT_FEATURE_LOWSPEED (0x09)
-#define HUB_PORT_FEATURE_HIGHSPEED (0x0a)
+#define HUB_PORT_FEATURE_CONNECTION (0x00)
+#define HUB_PORT_FEATURE_ENABLE (0x01)
+#define HUB_PORT_FEATURE_SUSPEND (0x02)
+#define HUB_PORT_FEATURE_OVERCURRENT (0x03)
+#define HUB_PORT_FEATURE_RESET (0x04)
+#define HUB_PORT_FEATURE_L1 (0x05) /* USB 2.0 only */
+
+#define HUB_PORT_FEATURE_POWER (0x08) /* USB 2.0 only */
+#define HUB_PORT_FEATURE_POWER_SS (0x09) /* USB 3.0 only */
+/* This is a bit tricky because HUB_PORT_FEATURE_POWER_SS and
+ HUB_PORT_FEATURE_LOWSPEED share the same bit. */
+#define HUB_PORT_FEATURE_LOWSPEED (0x09) /* USB 2.0 only */
+#define HUB_PORT_FEATURE_HIGHSPEED (0x0a) /* USB 2.0 only */
+#define HUB_PORT_FEATURE_TEST (0x0b) /* USB 2.0 only */
+#define HUB_PORT_FEATURE_INDICATOR (0x0c) /* USB 2.0 only */
+
+/* Port status change (wPortChange) */
#define HUB_PORT_FEATURE_C_CONNECTION (0x10)
-#define HUB_PORT_FEATURE_C_ENABLE (0x11)
-#define HUB_PORT_FEATURE_C_SUSPEND (0x12)
+#define HUB_PORT_FEATURE_C_ENABLE (0x11) /* USB 2.0 only */
+#define HUB_PORT_FEATURE_C_SUSPEND (0x12) /* USB 2.0 only */
#define HUB_PORT_FEATURE_C_OVER_CURREN (0x13)
#define HUB_PORT_FEATURE_C_RESET (0x14)
-#define HUB_PORT_FEATURE_TEST (0x15)
-#define HUB_PORT_FEATURE_INDICATOR (0x16)
-#define HUB_PORT_FEATURE_C_PORTL1 (0x17)
+#define HUB_PORT_FEATURE_C_BH_RESET (0x15) /* USB 3.0 only */
+#define HUB_PORT_FEATURE_C_LINK_STATE (0x16) /* USB 3.0 only */
+#define HUB_PORT_FEATURE_C_CONFIG_ERR (0x17) /* USB 3.0 only */
/* Hub status */
#define HUB_STATUS_LOCALPOWER (1 << 0)
@@ -56,23 +70,42 @@
/* Hub port status */
#define HUB_PORT_STATUS_CONNECTION (1 << 0)
#define HUB_PORT_STATUS_ENABLE (1 << 1)
-#define HUB_PORT_STATUS_SUSPEND (1 << 2)
+#define HUB_PORT_STATUS_SUSPEND (1 << 2) /* USB 2.0 only */
#define HUB_PORT_STATUS_OVERCURRENT (1 << 3)
#define HUB_PORT_STATUS_RESET (1 << 4)
-#define HUB_PORT_STATUS_L1 (1 << 5)
-#define HUB_PORT_STATUS_POWER (1 << 8)
-#define HUB_PORT_STATUS_LOW_SPEED (1 << 9)
-#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10)
-#define HUB_PORT_STATUS_TEST (1 << 11)
-#define HUB_PORT_STATUS_INDICATOR (1 << 12)
+#define HUB_PORT_STATUS_L1 (1 << 5) /* USB 2.0 only */
+
+/* Port Link State (PORT_LINK_STATE), USB 3.0 only */
+#define HUB_PORT_STATUS_LS_U0 (0x00 << 5)
+#define HUB_PORT_STATUS_LS_U1 (0x01 << 5)
+#define HUB_PORT_STATUS_LS_U2 (0x02 << 5)
+#define HUB_PORT_STATUS_LS_U3 (0x03 << 5)
+#define HUB_PORT_STATUS_LS_SS_DISABLED (0x04 << 5)
+#define HUB_PORT_STATUS_LS_RX_DETECT (0x05 << 5)
+#define HUB_PORT_STATUS_LS_SS_INACTIVE (0x06 << 5)
+#define HUB_PORT_STATUS_LS_POLLING (0x07 << 5)
+#define HUB_PORT_STATUS_LS_RECOVERY (0x08 << 5)
+#define HUB_PORT_STATUS_LS_HOT_RESET (0x09 << 5)
+#define HUB_PORT_STATUS_LS_COMP_MOD (0x0a << 5)
+#define HUB_PORT_STATUS_LS_LOOPBACK (0x0b << 5)
+
+#define HUB_PORT_STATUS_POWER (1 << 8)
+#define HUB_PORT_STATUS_POWER_SS (1 << 9) /* USB 3.0 only */
+#define HUB_PORT_STATUS_LOW_SPEED (1 << 9) /* USB 2.0 only */
+#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) /* USB 2.0 only */
+#define HUB_PORT_STATUS_TEST (1 << 11) /* USB 2.0 only */
+#define HUB_PORT_STATUS_INDICATOR (1 << 12) /* USB 2.0 only */
/* Hub port status change */
#define HUB_PORT_STATUS_C_CONNECTION (1 << 0)
-#define HUB_PORT_STATUS_C_ENABLE (1 << 1)
-#define HUB_PORT_STATUS_C_SUSPEND (1 << 2)
+#define HUB_PORT_STATUS_C_ENABLE (1 << 1) /* USB 2.0 only */
+#define HUB_PORT_STATUS_C_SUSPEND (1 << 2) /* USB 2.0 only */
#define HUB_PORT_STATUS_C_OVERCURRENT (1 << 3)
#define HUB_PORT_STATUS_C_RESET (1 << 4)
-#define HUB_PORT_STATUS_C_L1 (1 << 5)
+#define HUB_PORT_STATUS_C_L1 (1 << 5) /* USB 2.0 only */
+#define HUB_PORT_STATUS_C_BH_RESET (1 << 5) /* USB 3.0 only */
+#define HUB_PORT_STATUS_C_PORTLINK (1 << 6) /* USB 3.0 only */
+#define HUB_PORT_STATUS_C_CONFIGERR (1 << 7) /* USB 3.0 only */
/* Hub characteristics */
#define HUB_CHAR_LPSM_SHIFT (0) /* Bits 0-1: Logical Power Switching Mode */
@@ -106,6 +139,21 @@ struct usb_hub_descriptor {
#define USB_SIZEOF_HUB_DESC 9
+/* Super speed Hub descriptor */
+struct usb_hub_ss_descriptor {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bNbrPorts;
+ uint16_t wHubCharacteristics;
+ uint8_t bPwrOn2PwrGood;
+ uint8_t bHubContrCurrent;
+ uint8_t bHubHdrDecLat;
+ uint16_t wHubDelay;
+ uint8_t DeviceRemovable;
+} __PACKED;
+
+#define USB_SIZEOF_HUB_SS_DESC 11
+
/* Hub status */
struct hub_status {
uint16_t wPortStatus;
diff --git a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c
index 1745d8c0b3..a39a8d15c7 100644
--- a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c
+++ b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c
@@ -55,9 +55,7 @@ static void usbh_hub_class_free(struct usbh_hub *hub_class)
}
memset(hub_class, 0, sizeof(struct usbh_hub));
}
-#endif
-#if CONFIG_USBHOST_MAX_EXTHUBS > 0
static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
{
struct usb_setup_packet *setup;
@@ -67,15 +65,7 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
-
- /* TODO: hub descriptor has some difference between USB 2.0 and USB 3.x,
- and we havn't handle the difference here */
- if ((hub->parent->speed == USB_SPEED_SUPER) ||
- (hub->parent->speed == USB_SPEED_SUPER_PLUS)) {
- setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8;
- } else {
- setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8;
- }
+ setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8;
setup->wIndex = 0;
setup->wLength = USB_SIZEOF_HUB_DESC;
@@ -87,8 +77,8 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_DESC);
return ret;
}
-#if 0
-static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
+
+static int _usbh_hub_get_hub_ss_descriptor(struct usbh_hub *hub, uint8_t *buffer)
{
struct usb_setup_packet *setup;
int ret;
@@ -96,20 +86,20 @@ static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
setup = hub->parent->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
- setup->bRequest = HUB_REQUEST_GET_STATUS;
- setup->wValue = 0;
+ setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
+ setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8;
+
setup->wIndex = 0;
- setup->wLength = 2;
+ setup->wLength = USB_SIZEOF_HUB_SS_DESC;
ret = usbh_control_transfer(hub->parent, setup, g_hub_buf[hub->bus->busid]);
if (ret < 0) {
return ret;
}
- memcpy(buffer, g_hub_buf[hub->bus->busid], 2);
+ memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_SS_DESC);
return ret;
}
#endif
-#endif
static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
{
@@ -180,6 +170,8 @@ static int _usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length)
{
+ (void)length;
+
if (desc->bLength != USB_SIZEOF_HUB_DESC) {
USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength);
return -1;
@@ -199,6 +191,29 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length
}
return 0;
}
+
+static int parse_hub_ss_descriptor(struct usb_hub_ss_descriptor *desc, uint16_t length)
+{
+ (void)length;
+
+ if (desc->bLength < USB_SIZEOF_HUB_SS_DESC) {
+ USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength);
+ return -1;
+ } else if (desc->bDescriptorType != HUB_DESCRIPTOR_TYPE_HUB3) {
+ USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
+ return -2;
+ } else {
+ USB_LOG_RAW("SuperSpeed Hub Descriptor:\r\n");
+ USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength);
+ USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
+ USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
+ USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
+ USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
+ USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
+ USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
+ }
+ return 0;
+}
#endif
static int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
@@ -311,22 +326,65 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
hub->hub_addr = hport->dev_addr;
hub->parent = hport;
hub->bus = hport->bus;
+ hub->speed = hport->speed;
+ hport->self = hub;
hport->config.intf[intf].priv = hub;
- ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc);
- if (ret < 0) {
- return ret;
+ if (hport->depth > HUB_MAX_DEPTH) {
+ USB_LOG_ERR("Hub depth(%d) is overflow\r\n", hport->depth);
+ return -USB_ERR_INVAL;
}
- parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC);
+ /*
+ * Super-Speed hubs need to know their depth to be able to
+ * parse the bits of the route-string that correspond to
+ * their downstream port number.
+ *
+ */
+ if ((hport->depth != 0) && (hport->speed == USB_SPEED_SUPER)) {
+ ret = usbh_hub_set_depth(hub, hport->depth - 1);
+ if (ret < 0) {
+ USB_LOG_ERR("Unable to set hub depth \r\n");
+ return ret;
+ }
+ }
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ /* Get hub descriptor. */
+ if (hport->speed == USB_SPEED_SUPER) {
+ ret = _usbh_hub_get_hub_ss_descriptor(hub, (uint8_t *)&hub->hub_ss_desc);
+ if (ret < 0) {
+ return ret;
+ }
+
+ parse_hub_ss_descriptor(&hub->hub_ss_desc, USB_SIZEOF_HUB_SS_DESC);
+ hub->nports = hub->hub_ss_desc.bNbrPorts;
+ hub->powerdelay = hub->hub_ss_desc.bPwrOn2PwrGood * 2;
+ hub->tt_think = 0U;
+ } else {
+ ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc);
+ if (ret < 0) {
+ return ret;
+ }
+
+ parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC);
+ hub->nports = hub->hub_desc.bNbrPorts;
+ hub->powerdelay = hub->hub_desc.bPwrOn2PwrGood * 2;
+ hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5);
+ }
+
+ for (uint8_t port = 0; port < hub->nports; port++) {
hub->child[port].port = port + 1;
hub->child[port].parent = hub;
hub->child[port].bus = hport->bus;
}
+ if (hport->device_desc.bDeviceProtocol == HUB_PROTOCOL_MTT) {
+ hub->ismtt = 1;
+ } else {
+ hub->ismtt = 0;
+ }
+
ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
if (ep_desc->bEndpointAddress & 0x80) {
USBH_EP_INIT(hub->intin, ep_desc);
@@ -334,28 +392,16 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
return -1;
}
- if (hport->speed == USB_SPEED_SUPER) {
- uint16_t depth = 0;
- struct usbh_hubport *parent = hport->parent->parent;
- while (parent) {
- depth++;
- parent = parent->parent->parent;
- }
-
- ret = usbh_hub_set_depth(hub, depth);
- if (ret < 0) {
- return ret;
- }
- }
-
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ for (uint8_t port = 0; port < hub->nports; port++) {
ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_POWER);
if (ret < 0) {
return ret;
}
}
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ usb_osal_msleep(hub->powerdelay);
+
+ for (uint8_t port = 0; port < hub->nports; port++) {
ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
USB_LOG_INFO("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange);
if (ret < 0) {
@@ -395,7 +441,7 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
usb_osal_timer_delete(hub->int_timer);
}
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ for (uint8_t port = 0; port < hub->nports; port++) {
child = &hub->child[port];
usbh_hubport_release(child);
child->parent = NULL;
@@ -415,7 +461,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
{
struct usbh_hubport *child;
struct hub_port_status port_status;
- uint8_t portchange_index;
+ uint16_t portchange_index;
uint16_t portstatus;
uint16_t portchange;
uint16_t mask;
@@ -429,11 +475,10 @@ static void usbh_hub_events(struct usbh_hub *hub)
}
flags = usb_osal_enter_critical_section();
- portchange_index = hub->int_buffer[0];
- hub->int_buffer[0] &= ~portchange_index;
+ memcpy(&portchange_index, hub->int_buffer, 2);
usb_osal_leave_critical_section(flags);
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ for (uint8_t port = 0; port < hub->nports; port++) {
USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index);
if (!(portchange_index & (1 << (port + 1)))) {
@@ -539,12 +584,23 @@ static void usbh_hub_events(struct usbh_hub *hub)
}
}
- if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) {
- speed = USB_SPEED_HIGH;
- } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
- speed = USB_SPEED_LOW;
+ /*
+ * Figure out device speed. This is a bit tricky because
+ * HUB_PORT_STATUS_POWER_SS and HUB_PORT_STATUS_LOW_SPEED share the same bit.
+ */
+ if (portstatus & HUB_PORT_STATUS_POWER) {
+ if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) {
+ speed = USB_SPEED_HIGH;
+ } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
+ speed = USB_SPEED_LOW;
+ } else {
+ speed = USB_SPEED_FULL;
+ }
+ } else if (portstatus & HUB_PORT_STATUS_POWER_SS) {
+ speed = USB_SPEED_SUPER;
} else {
- speed = USB_SPEED_FULL;
+ USB_LOG_WRN("Port %u does not enable power\r\n", port + 1);
+ continue;
}
child = &hub->child[port];
@@ -553,6 +609,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
memset(child, 0, sizeof(struct usbh_hubport));
child->parent = hub;
+ child->depth = (hub->parent ? hub->parent->depth : 0) + 1;
child->connected = true;
child->port = port + 1;
child->speed = speed;
@@ -624,7 +681,7 @@ int usbh_hub_initialize(struct usbh_bus *bus)
hub->is_roothub = true;
hub->parent = NULL;
hub->hub_addr = 1;
- hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
+ hub->nports = CONFIG_USBHOST_MAX_RHPORTS;
hub->int_buffer = bus->hcd.roothub_intbuf;
hub->bus = bus;
@@ -652,7 +709,7 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
flags = usb_osal_enter_critical_section();
hub = &bus->hcd.roothub;
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
usbh_hubport_release(hport);
diff --git a/components/drivers/usb/cherryusb/class/hub/usbh_hub.h b/components/drivers/usb/cherryusb/class/hub/usbh_hub.h
index 1f34c53ba7..dcce660681 100644
--- a/components/drivers/usb/cherryusb/class/hub/usbh_hub.h
+++ b/components/drivers/usb/cherryusb/class/hub/usbh_hub.h
@@ -10,10 +10,6 @@
struct usbh_hub;
-#define USBH_HUB_MAX_PORTS 4
-/* Maximum size of an interrupt IN transfer */
-#define USBH_HUB_INTIN_BUFSIZE ((USBH_HUB_MAX_PORTS + 8) >> 3)
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
index 055cdc4e65..b562f47488 100644
--- a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
+++ b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
@@ -9,6 +9,8 @@
#include "usb_scsi.h"
#if defined(CONFIG_USBDEV_MSC_THREAD)
#include "usb_osal.h"
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+#include "chry_ringbuffer.h"
#endif
#define MSD_OUT_EP_IDX 0
@@ -50,6 +52,10 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_priv {
usb_osal_mq_t usbd_msc_mq;
usb_osal_thread_t usbd_msc_thread;
uint32_t nbytes;
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+ chry_ringbuffer_t msc_rb;
+ uint8_t msc_rb_pool[2];
+ uint32_t nbytes;
#endif
} g_usbd_msc[CONFIG_USBDEV_MAX_BUS];
@@ -94,9 +100,11 @@ static int msc_storage_class_interface_request_handler(uint8_t busid, struct usb
void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg)
{
+ (void)arg;
+
switch (event) {
case USBD_EVENT_INIT:
-#ifdef CONFIG_USBDEV_MSC_THREAD
+#if defined(CONFIG_USBDEV_MSC_THREAD)
g_usbd_msc[busid].usbd_msc_mq = usb_osal_mq_create(1);
if (g_usbd_msc[busid].usbd_msc_mq == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_mq\r\n");
@@ -105,10 +113,12 @@ void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg)
if (g_usbd_msc[busid].usbd_msc_thread == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_thread\r\n");
}
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+ chry_ringbuffer_init(&g_usbd_msc[busid].msc_rb, g_usbd_msc[busid].msc_rb_pool, sizeof(g_usbd_msc[busid].msc_rb_pool));
#endif
break;
case USBD_EVENT_DEINIT:
-#ifdef CONFIG_USBDEV_MSC_THREAD
+#if defined(CONFIG_USBDEV_MSC_THREAD)
if (g_usbd_msc[busid].usbd_msc_mq) {
usb_osal_mq_delete(g_usbd_msc[busid].usbd_msc_mq);
}
@@ -500,6 +510,9 @@ static bool SCSI_readCapacity10(uint8_t busid, uint8_t **data, uint32_t *len)
static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
{
+ (void)data;
+ (void)len;
+
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
return false;
@@ -522,8 +535,10 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
return false;
}
g_usbd_msc[busid].stage = MSC_DATA_IN;
-#ifdef CONFIG_USBDEV_MSC_THREAD
+#if defined(CONFIG_USBDEV_MSC_THREAD)
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+ chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
return true;
#else
return SCSI_processRead(busid);
@@ -532,6 +547,9 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
{
+ (void)data;
+ (void)len;
+
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
return false;
@@ -554,8 +572,10 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
return false;
}
g_usbd_msc[busid].stage = MSC_DATA_IN;
-#ifdef CONFIG_USBDEV_MSC_THREAD
+#if defined(CONFIG_USBDEV_MSC_THREAD)
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+ chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
return true;
#else
return SCSI_processRead(busid);
@@ -565,6 +585,10 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
{
uint32_t data_len = 0;
+
+ (void)data;
+ (void)len;
+
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
return false;
@@ -594,6 +618,10 @@ static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
{
uint32_t data_len = 0;
+
+ (void)data;
+ (void)len;
+
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
return false;
@@ -803,6 +831,8 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
+ (void)ep;
+
switch (g_usbd_msc[busid].stage) {
case MSC_READ_CBW:
if (SCSI_CBWDecode(busid, nbytes) == false) {
@@ -815,9 +845,12 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
switch (g_usbd_msc[busid].cbw.CB[0]) {
case SCSI_CMD_WRITE10:
case SCSI_CMD_WRITE12:
-#ifdef CONFIG_USBDEV_MSC_THREAD
+#if defined(CONFIG_USBDEV_MSC_THREAD)
g_usbd_msc[busid].nbytes = nbytes;
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_OUT);
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+ g_usbd_msc[busid].nbytes = nbytes;
+ chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_OUT);
#else
if (SCSI_processWrite(busid, nbytes) == false) {
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
@@ -835,13 +868,18 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
+ (void)ep;
+ (void)nbytes;
+
switch (g_usbd_msc[busid].stage) {
case MSC_DATA_IN:
switch (g_usbd_msc[busid].cbw.CB[0]) {
case SCSI_CMD_READ10:
case SCSI_CMD_READ12:
-#ifdef CONFIG_USBDEV_MSC_THREAD
+#if defined(CONFIG_USBDEV_MSC_THREAD)
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+ chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
#else
if (SCSI_processRead(busid) == false) {
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
@@ -870,7 +908,7 @@ void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
}
}
-#ifdef CONFIG_USBDEV_MSC_THREAD
+#if defined(CONFIG_USBDEV_MSC_THREAD)
static void usbdev_msc_thread(void *argument)
{
uintptr_t event;
@@ -882,7 +920,26 @@ static void usbdev_msc_thread(void *argument)
if (ret < 0) {
continue;
}
- USB_LOG_DBG("%d\r\n", event);
+ USB_LOG_DBG("event:%d\r\n", event);
+ if (event == MSC_DATA_OUT) {
+ if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
+ usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
+ }
+ } else if (event == MSC_DATA_IN) {
+ if (SCSI_processRead(busid) == false) {
+ usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
+ }
+ } else {
+ }
+ }
+}
+#elif defined(CONFIG_USBDEV_MSC_POLLING)
+void usbd_msc_polling(uint8_t busid)
+{
+ uint8_t event;
+
+ if (chry_ringbuffer_read_byte(&g_usbd_msc[busid].msc_rb, &event)) {
+ USB_LOG_DBG("event:%d\r\n", event);
if (event == MSC_DATA_OUT) {
if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
@@ -932,7 +989,7 @@ void usbd_msc_set_readonly(uint8_t busid, bool readonly)
g_usbd_msc[busid].readonly = readonly;
}
-bool usbd_msc_set_popup(uint8_t busid)
+bool usbd_msc_get_popup(uint8_t busid)
{
return g_usbd_msc[busid].popup;
}
diff --git a/components/drivers/usb/cherryusb/class/msc/usbd_msc.h b/components/drivers/usb/cherryusb/class/msc/usbd_msc.h
index c71f64a232..63a8752d71 100644
--- a/components/drivers/usb/cherryusb/class/msc/usbd_msc.h
+++ b/components/drivers/usb/cherryusb/class/msc/usbd_msc.h
@@ -23,7 +23,9 @@ int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *b
int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length);
void usbd_msc_set_readonly(uint8_t busid, bool readonly);
-bool usbd_msc_set_popup(uint8_t busid);
+bool usbd_msc_get_popup(uint8_t busid);
+
+void usbd_msc_polling(uint8_t busid);
#ifdef __cplusplus
}
diff --git a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c
index 42e12d9cb5..773b0defb0 100644
--- a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c
+++ b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c
@@ -15,7 +15,7 @@
#define MSC_INQUIRY_TIMEOUT 500
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[64];
+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];
static uint32_t g_devinuse = 0;
@@ -87,6 +87,8 @@ static void usbh_msc_cbw_dump(struct CBW *cbw)
static void usbh_msc_csw_dump(struct CSW *csw)
{
+ (void)csw;
+
USB_LOG_DBG("CSW:\r\n");
USB_LOG_DBG(" signature: 0x%08x\r\n", (unsigned int)csw->dSignature);
USB_LOG_DBG(" tag: 0x%08x\r\n", (unsigned int)csw->dTag);
@@ -182,14 +184,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;
+ cbw = (struct CBW *)g_msc_buf[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, NULL, MSC_INQUIRY_TIMEOUT);
+ return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
}
static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
@@ -197,7 +199,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;
+ cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -207,7 +209,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, g_msc_buf, MSC_INQUIRY_TIMEOUT);
+ 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);
}
static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
@@ -215,7 +217,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;
+ cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -225,7 +227,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, g_msc_buf, MSC_INQUIRY_TIMEOUT);
+ 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);
}
static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
@@ -233,7 +235,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;
+ cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -242,7 +244,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, g_msc_buf, MSC_INQUIRY_TIMEOUT);
+ 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);
}
static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message)
@@ -250,11 +252,11 @@ 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;
+ cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
- memcpy(g_msc_buf, message, 31);
+ memcpy(g_msc_buf[msc_class->sdchar - 'a'], message, 31);
- usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL, MSC_INQUIRY_TIMEOUT);
+ usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
}
static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
@@ -274,12 +276,12 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
hport->config.intf[intf].priv = msc_class;
- ret = usbh_msc_get_maxlun(msc_class, g_msc_buf);
+ ret = usbh_msc_get_maxlun(msc_class, g_msc_buf[msc_class->sdchar - 'a']);
if (ret < 0) {
return ret;
}
- USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[0] + 1);
+ USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[msc_class->sdchar - 'a'][0] + 1);
for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
@@ -376,7 +378,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
struct CBW *cbw;
/* Construct the CBW */
- cbw = (struct CBW *)g_msc_buf;
+ cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -387,7 +389,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, (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
+ 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);
}
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
@@ -395,7 +397,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;
+ cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -407,7 +409,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, (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
+ 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);
}
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
@@ -421,10 +423,12 @@ void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
__WEAK void usbh_msc_run(struct usbh_msc *msc_class)
{
+ (void)msc_class;
}
__WEAK void usbh_msc_stop(struct usbh_msc *msc_class)
{
+ (void)msc_class;
}
const struct usbh_class_driver msc_class_driver = {
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 9d3e973f22..cbc3c5d6c3 100644
--- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c
+++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c
@@ -680,6 +680,7 @@ void usbh_asix_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
+ (void)argument;
USB_LOG_INFO("Create asix rx thread\r\n");
// clang-format off
find_class:
@@ -742,7 +743,7 @@ find_class:
#else
if ((g_asix_rx_length + (16 * 1024)) > CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE) {
#endif
- USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE\r\n");
+ USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE\r\n");
while (1) {
}
}
@@ -791,10 +792,12 @@ int usbh_asix_eth_output(uint32_t buflen)
__WEAK void usbh_asix_run(struct usbh_asix *asix_class)
{
+ (void)asix_class;
}
__WEAK void usbh_asix_stop(struct usbh_asix *asix_class)
{
+ (void)asix_class;
}
static const uint16_t asix_id_table[][2] = {
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 dde665db1e..cbf7ea4f4d 100644
--- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c
+++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c
@@ -2140,6 +2140,7 @@ void usbh_rtl8152_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
+ (void)argument;
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
// clang-format off
find_class:
@@ -2210,7 +2211,7 @@ find_class:
#else
if ((g_rtl8152_rx_length + (16 * 1024)) > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) {
#endif
- USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE\r\n");
+ USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE\r\n");
while (1) {
}
}
@@ -2248,10 +2249,12 @@ int usbh_rtl8152_eth_output(uint32_t buflen)
__WEAK void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
{
+ (void)rtl8152_class;
}
__WEAK void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
{
+ (void)rtl8152_class;
}
static const uint16_t rtl_id_table[][2] = {
diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c
index 7c275e170d..92cafde3d0 100644
--- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c
+++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c
@@ -349,10 +349,12 @@ int usbh_ch34x_bulk_out_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer
__WEAK void usbh_ch34x_run(struct usbh_ch34x *ch34x_class)
{
+ (void)ch34x_class;
}
__WEAK void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class)
{
+ (void)ch34x_class;
}
static const uint16_t ch34x_id_table[][2] = {
diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c
index ae882fb60f..a82ee0f728 100644
--- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c
+++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c
@@ -10,7 +10,7 @@
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cp210x_buf[64];
-#define CONFIG_USBHOST_MAX_CP210X_CLASS 4
+#define CONFIG_USBHOST_MAX_CP210X_CLASS 1
static struct usbh_cp210x g_cp210x_class[CONFIG_USBHOST_MAX_CP210X_CLASS];
static uint32_t g_devinuse = 0;
@@ -298,10 +298,12 @@ int usbh_cp210x_bulk_out_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buf
__WEAK void usbh_cp210x_run(struct usbh_cp210x *cp210x_class)
{
+ (void)cp210x_class;
}
__WEAK void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class)
{
+ (void)cp210x_class;
}
static const uint16_t cp210x_id_table[][2] = {
diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c
index ba5aae5ede..8b58138b30 100644
--- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c
+++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c
@@ -10,7 +10,7 @@
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_ftdi_buf[64];
-#define CONFIG_USBHOST_MAX_FTDI_CLASS 4
+#define CONFIG_USBHOST_MAX_FTDI_CLASS 1
static struct usbh_ftdi g_ftdi_class[CONFIG_USBHOST_MAX_FTDI_CLASS];
static uint32_t g_devinuse = 0;
@@ -57,7 +57,7 @@ static void usbh_ftdi_caculate_baudrate(uint32_t *itdf_divisor, uint32_t actual_
}
int divisor = FTDI_USB_CLK / baudrate;
int frac_bits = 0;
- for (int i = 0; i < sizeof(frac) / sizeof(frac[0]); i++) {
+ for (uint8_t i = 0; i < sizeof(frac) / sizeof(frac[0]); i++) {
if ((divisor & 0xF) == frac[i]) {
frac_bits = i;
break;
@@ -370,10 +370,12 @@ int usbh_ftdi_bulk_out_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, u
__WEAK void usbh_ftdi_run(struct usbh_ftdi *ftdi_class)
{
+ (void)ftdi_class;
}
__WEAK void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class)
{
+ (void)ftdi_class;
}
static const uint16_t ftdi_id_table[][2] = {
diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c
index c64a1c3331..5000b4d8a7 100644
--- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c
+++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c
@@ -15,7 +15,7 @@
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_pl2303_buf[64];
-#define CONFIG_USBHOST_MAX_PL2303_CLASS 4
+#define CONFIG_USBHOST_MAX_PL2303_CLASS 1
#define UT_WRITE_VENDOR_DEVICE (USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE)
#define UT_READ_VENDOR_DEVICE (USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE)
@@ -413,10 +413,12 @@ int usbh_pl2303_bulk_out_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buf
__WEAK void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class)
{
+ (void)pl2303_class;
}
__WEAK void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
{
+ (void)pl2303_class;
}
static const uint16_t pl2303_id_table[][2] = {
diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/README.md b/components/drivers/usb/cherryusb/class/vendor/wifi/README.md
new file mode 100644
index 0000000000..18384f65d5
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/vendor/wifi/README.md
@@ -0,0 +1,6 @@
+# BL616 USB WIFI
+
+Usbwifi firmware please contact bouffalolab. You can purchase a module in the following ways:
+
+- https://iot.mi.com/moduleBrowser.html
+- https://docs.ai-thinker.com/ai_m61
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c
new file mode 100644
index 0000000000..34cbcf87e4
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_bl616.h"
+
+#undef USB_DBG_TAG
+#define USB_DBG_TAG "usbh_bl616"
+#include "usb_log.h"
+
+#define DEV_FORMAT "/dev/wifi/bl616"
+
+#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
+#define ARR_ELE_6(e) (e)[0], (e)[1], (e)[2], (e)[3], (e)[4], (e)[5]
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_tx_buffer[2048 + 512];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_rx_buffer[2048 + 512];
+
+static struct usbh_bl616 g_bl616_class;
+
+static const char *auth_to_str(uint8_t auth)
+{
+ const char *table[RNM_WIFI_AUTH_MAX] = {
+ [RNM_WIFI_AUTH_UNKNOWN] = "UNKNOWN",
+ [RNM_WIFI_AUTH_OPEN] = "OPEN",
+ [RNM_WIFI_AUTH_WEP] = "WEP",
+ [RNM_WIFI_AUTH_WPA_PSK] = "WPA-PSK",
+ [RNM_WIFI_AUTH_WPA2_PSK] = "WPA2-PSK",
+ [RNM_WIFI_AUTH_WPA_WPA2_PSK] = "WPA2-PSK/WPA-PSK",
+ [RNM_WIFI_AUTH_WPA_ENTERPRISE] = "WPA-ENT",
+ [RNM_WIFI_AUTH_WPA3_SAE] = "WPA3-SAE",
+ [RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE] = "WPA2-PSK/WPA3-SAE",
+ };
+ if (auth < RNM_WIFI_AUTH_MAX)
+ return table[auth];
+ else
+ return table[RNM_WIFI_AUTH_UNKNOWN];
+}
+
+static const char *cipher_to_str(uint8_t cipher)
+{
+ const char *table[RNM_WIFI_CIPHER_MAX] = {
+ [RNM_WIFI_CIPHER_UNKNOWN] = "UNKNOWN",
+ [RNM_WIFI_CIPHER_NONE] = "NONE",
+ [RNM_WIFI_CIPHER_WEP] = "WEP",
+ [RNM_WIFI_CIPHER_AES] = "AES",
+ [RNM_WIFI_CIPHER_TKIP] = "TKIP",
+ [RNM_WIFI_CIPHER_TKIP_AES] = "TKIP/AES",
+ };
+ if (cipher < RNM_WIFI_CIPHER_MAX)
+ return table[cipher];
+ else
+ return table[RNM_WIFI_CIPHER_UNKNOWN];
+}
+
+static int parse_get_mac_rsp_msg(struct usbh_bl616 *bl616_class, void *buf, int buf_len)
+{
+ usb_data_t *usb_hdr = buf;
+ rnm_mac_addr_ind_msg_t *rsp = buf + sizeof(usb_data_t);
+
+ if (buf_len != sizeof(usb_data_t) + sizeof(rnm_mac_addr_ind_msg_t)) {
+ return -1;
+ }
+ if (usb_hdr->type != USBWIFI_DATA_TYPE_CMD || usb_hdr->length != sizeof(rnm_mac_addr_ind_msg_t)) {
+ return -1;
+ }
+ if (rsp->hdr.cmd != BFLB_CMD_GET_MAC_ADDR || !(rsp->hdr.flags & RNM_MSG_FLAG_ACK)) {
+ return -1;
+ }
+ memcpy(bl616_class->sta_mac, rsp->sta_mac, 6);
+ memcpy(bl616_class->ap_mac, rsp->ap_mac, 6);
+
+ return 0;
+}
+
+static int usbh_bl616_bulk_in_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
+{
+ int ret;
+ struct usbh_urb *urb = &bl616_class->bulkin_urb;
+
+ usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkin, buffer, buflen, timeout, NULL, NULL);
+ ret = usbh_submit_urb(urb);
+ if (ret == 0) {
+ ret = urb->actual_length;
+ }
+ return ret;
+}
+
+static int usbh_bl616_bulk_out_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
+{
+ int ret;
+ struct usbh_urb *urb = &bl616_class->bulkout_urb;
+
+ usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkout, buffer, buflen, timeout, NULL, NULL);
+ ret = usbh_submit_urb(urb);
+ if (ret == 0) {
+ ret = urb->actual_length;
+ }
+ return ret;
+}
+
+static int usbh_bl616_get_wifi_mac(struct usbh_bl616 *bl616_class)
+{
+ int ret;
+ uint32_t msg_len;
+ usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ rnm_base_msg_t *rnm_msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
+
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+ memset(rnm_msg, 0, sizeof(rnm_base_msg_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
+ usb_hdr->length = sizeof(rnm_base_msg_t);
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ rnm_msg->cmd = BFLB_CMD_GET_MAC_ADDR;
+
+ msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
+
+ ret = usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = usbh_bl616_bulk_in_transfer(bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), 500);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = parse_get_mac_rsp_msg(bl616_class, g_bl616_rx_buffer, ret);
+ return ret;
+}
+
+static int usbh_bl616_wifi_open(struct usbh_bl616 *bl616_class)
+{
+ uint32_t msg_len;
+ usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
+
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+ memset(msg, 0, sizeof(rnm_base_msg_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
+ usb_hdr->length = sizeof(rnm_base_msg_t);
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ msg->cmd = BFLB_CMD_HELLO;
+
+ msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
+
+ return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
+}
+
+static int usbh_bl616_wifi_close(struct usbh_bl616 *bl616_class)
+{
+ uint32_t msg_len;
+ usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
+
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+ memset(msg, 0, sizeof(rnm_base_msg_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
+ usb_hdr->length = sizeof(rnm_base_msg_t);
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ msg->cmd = BFLB_CMD_UNLOAD_DRV;
+
+ msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
+
+ return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
+}
+
+int usbh_bl616_wifi_sta_connect(const char *ssid,
+ const int ssid_len,
+ const char *password,
+ const int pwd_len)
+{
+ uint32_t msg_len;
+ usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ rnm_sta_connect_msg_t *msg = (rnm_sta_connect_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
+
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+ memset(msg, 0, sizeof(rnm_sta_connect_msg_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
+ usb_hdr->length = sizeof(rnm_sta_connect_msg_t);
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ msg->hdr.cmd = BFLB_CMD_STA_CONNECT;
+ msg->hdr.msg_id = 0x0001;
+ msg->hdr.session_id = 0x0002;
+ msg->ssid_len = ssid_len;
+ memcpy(msg->ssid, ssid, ssid_len);
+ if (password) {
+ memcpy(msg->password, password, pwd_len);
+ }
+
+ msg_len = sizeof(usb_data_t) + sizeof(rnm_sta_connect_msg_t);
+
+ return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
+}
+
+int usbh_bl616_wifi_sta_disconnect(void)
+{
+ uint32_t msg_len;
+ usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
+
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+ memset(msg, 0, sizeof(rnm_base_msg_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
+ usb_hdr->length = sizeof(rnm_base_msg_t);
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ msg->cmd = BFLB_CMD_STA_DISCONNECT;
+
+ msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
+
+ return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
+}
+
+int usbh_bl616_get_wifi_scan_result(void)
+{
+ uint32_t msg_len;
+ usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
+
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+ memset(msg, 0, sizeof(rnm_base_msg_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
+ usb_hdr->length = sizeof(rnm_base_msg_t);
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ msg->cmd = BFLB_CMD_SCAN_RESULTS;
+
+ msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
+
+ return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
+}
+
+int usbh_bl616_wifi_scan(void)
+{
+ int ret;
+ uint32_t msg_len;
+ usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
+
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+ memset(msg, 0, sizeof(rnm_base_msg_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
+ usb_hdr->length = sizeof(rnm_base_msg_t);
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ msg->cmd = BFLB_CMD_SCAN;
+
+ msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
+
+ ret = usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
+ if (ret < 0) {
+ return ret;
+ }
+
+ usb_osal_msleep(500);
+ return usbh_bl616_get_wifi_scan_result();
+}
+
+static int usbh_bl616_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+ struct usb_endpoint_descriptor *ep_desc;
+ int ret = 0;
+
+ struct usbh_bl616 *bl616_class = &g_bl616_class;
+
+ memset(bl616_class, 0, sizeof(struct usbh_bl616));
+
+ bl616_class->hport = hport;
+ bl616_class->intf = intf;
+
+ hport->config.intf[intf].priv = bl616_class;
+
+ for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
+ ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
+
+ if (ep_desc->bEndpointAddress & 0x80) {
+ USBH_EP_INIT(bl616_class->bulkin, ep_desc);
+ } else {
+ USBH_EP_INIT(bl616_class->bulkout, ep_desc);
+ }
+ }
+
+ usbh_bl616_get_wifi_mac(bl616_class);
+ usbh_bl616_wifi_close(bl616_class);
+ usbh_bl616_wifi_open(bl616_class);
+
+ USB_LOG_INFO("BL616 WIFI STA MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
+ bl616_class->sta_mac[0],
+ bl616_class->sta_mac[1],
+ bl616_class->sta_mac[2],
+ bl616_class->sta_mac[3],
+ bl616_class->sta_mac[4],
+ bl616_class->sta_mac[5]);
+
+ USB_LOG_INFO("BL616 WIFI AP MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
+ bl616_class->ap_mac[0],
+ bl616_class->ap_mac[1],
+ bl616_class->ap_mac[2],
+ bl616_class->ap_mac[3],
+ bl616_class->ap_mac[4],
+ bl616_class->ap_mac[5]);
+
+ strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
+
+ USB_LOG_INFO("Register BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname);
+
+ usbh_bl616_run(bl616_class);
+ return ret;
+}
+
+static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+ int ret = 0;
+
+ struct usbh_bl616 *bl616_class = (struct usbh_bl616 *)hport->config.intf[intf].priv;
+
+ if (bl616_class) {
+ if (bl616_class->bulkin) {
+ usbh_kill_urb(&bl616_class->bulkin_urb);
+ }
+
+ if (bl616_class->bulkout) {
+ usbh_kill_urb(&bl616_class->bulkout_urb);
+ }
+
+ if (hport->config.intf[intf].devname[0] != '\0') {
+ USB_LOG_INFO("Unregister BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname);
+ usbh_bl616_stop(bl616_class);
+ }
+
+ memset(bl616_class, 0, sizeof(struct usbh_bl616));
+ }
+
+ return ret;
+}
+
+void usbh_bl616_rx_thread(void *argument)
+{
+ int ret;
+ usb_data_t *usb_hdr;
+ rnm_base_msg_t *msg;
+ rnm_sta_ip_update_ind_msg_t *ipmsg;
+ rnm_scan_ind_msg_t *scanmsg;
+ uint8_t *data;
+
+ (void)argument;
+ USB_LOG_INFO("Create bl616 wifi rx thread\r\n");
+
+ while (1) {
+ ret = usbh_bl616_bulk_in_transfer(&g_bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), USB_OSAL_WAITING_FOREVER);
+ if (ret < 0) {
+ break;
+ }
+
+ usb_hdr = (usb_data_t *)g_bl616_rx_buffer;
+
+ if (usb_hdr->type == USBWIFI_DATA_TYPE_CMD) {
+ msg = (rnm_base_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
+
+ switch (msg->cmd) {
+ case BFLB_CMD_STA_CONNECTED_IND:
+ USB_LOG_INFO("AP connected\n");
+ g_bl616_class.connect_status = true;
+ usbh_bl616_sta_connect_callback();
+
+ break;
+ case BFLB_CMD_STA_DISCONNECTED_IND:
+ if (g_bl616_class.connect_status == true) {
+ g_bl616_class.connect_status = false;
+ USB_LOG_INFO("AP disconnected\n");
+ usbh_bl616_sta_disconnect_callback();
+ }
+ break;
+ case BFLB_CMD_STA_IP_UPDATE_IND:
+ ipmsg = (rnm_sta_ip_update_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
+
+ USB_LOG_INFO("WIFI IP update\r\n");
+ USB_LOG_INFO("WIFI IPv4 Address : %d:%d:%d:%d\r\n",
+ ipmsg->ip4_addr[0],
+ ipmsg->ip4_addr[1],
+ ipmsg->ip4_addr[2],
+ ipmsg->ip4_addr[3]);
+ USB_LOG_INFO("WIFI IPv4 Mask : %d:%d:%d:%d\r\n",
+ ipmsg->ip4_mask[0],
+ ipmsg->ip4_mask[1],
+ ipmsg->ip4_mask[2],
+ ipmsg->ip4_mask[3]);
+ USB_LOG_INFO("WIFI IPv4 Gateway : %d:%d:%d:%d\r\n\r\n",
+ ipmsg->ip4_gw[0],
+ ipmsg->ip4_gw[1],
+ ipmsg->ip4_gw[2],
+ ipmsg->ip4_gw[3]);
+
+ g_bl616_class.mode = BL_MODE_STA;
+ usbh_bl616_sta_update_ip(ipmsg->ip4_addr, ipmsg->ip4_mask, ipmsg->ip4_gw);
+ break;
+ case BFLB_CMD_SCAN_RESULTS:
+ scanmsg = (rnm_scan_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
+ USB_LOG_INFO("WIFI scan result:\r\n");
+ for (uint32_t i = 0; i < scanmsg->num; ++i) {
+ struct bf1b_wifi_scan_record *r = &scanmsg->records[i];
+ USB_LOG_INFO("BSSID " MAC_FMT ", channel %u, rssi %d, auth %s, cipher %s, SSID %s\r\n",
+ ARR_ELE_6(r->bssid), r->channel, r->rssi,
+ auth_to_str(r->auth_mode), cipher_to_str(r->cipher), r->ssid);
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (usb_hdr->type == USBWIFI_DATA_TYPE_PKT) {
+ data = (uint8_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
+ usbh_bl616_eth_input(data, usb_hdr->length);
+ } else {
+ }
+ }
+
+ USB_LOG_INFO("Delete bl616 wifi rx thread\r\n");
+ usb_osal_thread_delete(NULL);
+}
+
+uint8_t *usbh_bl616_get_eth_txbuf(void)
+{
+ return (g_bl616_tx_buffer + sizeof(usb_data_t));
+}
+
+int usbh_bl616_eth_output(uint32_t buflen)
+{
+ usb_data_t *usb_hdr;
+ uint32_t txlen;
+
+ if (g_bl616_class.connect_status == false) {
+ return -USB_ERR_NOTCONN;
+ }
+
+ usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
+ memset(usb_hdr, 0, sizeof(usb_data_t));
+
+ usb_hdr->type = USBWIFI_DATA_TYPE_PKT;
+ usb_hdr->length = buflen;
+ usb_hdr->payload_offset = sizeof(usb_data_t);
+
+ txlen = buflen + sizeof(usb_data_t);
+ if (!(txlen % USB_GET_MAXPACKETSIZE(g_bl616_class.bulkout->wMaxPacketSize))) {
+ txlen += 1;
+ }
+ USB_LOG_DBG("txlen:%d\r\n", txlen);
+
+ usbh_bulk_urb_fill(&g_bl616_class.bulkout_urb, g_bl616_class.hport, g_bl616_class.bulkout, g_bl616_tx_buffer, txlen, USB_OSAL_WAITING_FOREVER, NULL, NULL);
+ return usbh_submit_urb(&g_bl616_class.bulkout_urb);
+}
+
+int wifi_sta_connect(int argc, char **argv)
+{
+ if (argc < 3) {
+ USB_LOG_ERR("Usage: %s \r\n", argv[0]);
+ return -1;
+ }
+ usbh_bl616_wifi_sta_connect(argv[1], strlen(argv[1]), argv[2], strlen(argv[2]));
+ return 0;
+}
+
+int wifi_scan(int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+
+ usbh_bl616_wifi_scan();
+ return 0;
+}
+
+__WEAK void usbh_bl616_run(struct usbh_bl616 *bl616_class)
+{
+ (void)bl616_class;
+}
+
+__WEAK void usbh_bl616_stop(struct usbh_bl616 *bl616_class)
+{
+ (void)bl616_class;
+}
+
+static const uint16_t bl616_id_table[][2] = {
+ { 0x349b, 0x616f },
+ { 0, 0 },
+};
+
+static const struct usbh_class_driver bl616_class_driver = {
+ .driver_name = "bl616_wifi",
+ .connect = usbh_bl616_connect,
+ .disconnect = usbh_bl616_disconnect
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info bl616_class_info = {
+ .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
+ .class = 0xff,
+ .subclass = 0x00,
+ .protocol = 0x00,
+ .id_table = bl616_id_table,
+ .class_driver = &bl616_class_driver
+};
diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h
new file mode 100644
index 0000000000..6ec5a7a8ab
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_BL616_H
+#define USBH_BL616_H
+
+#define USBWIFI_DATA_TYPE_CMD 0xA55A
+#define USBWIFI_DATA_TYPE_PKT 0x6996
+
+#define USB_DATA_FLAG_AP_PKT (1u << 0)
+
+typedef enum {
+ BFLB_CMD_REBOOT = 0,
+ BFLB_CMD_RESET,
+ BFLB_CMD_HELLO,
+ BFLB_CMD_PING,
+
+ BFLB_CMD_GET_MAC_ADDR,
+
+ // Scan
+ BFLB_CMD_SCAN,
+ BFLB_CMD_SCAN_RESULTS,
+
+ // STA
+ BFLB_CMD_STA_CONNECT,
+ BFLB_CMD_STA_DISCONNECT,
+ BFLB_CMD_STA_CONNECTED_IND,
+ BFLB_CMD_STA_DISCONNECTED_IND,
+ BFLB_CMD_STA_IP_UPDATE_IND,
+ BFLB_CMD_STA_SET_AUTO_RECONNECT,
+ BFLB_CMD_STA_GET_LINK_STATUS,
+
+ // AP
+ BFLB_CMD_AP_START,
+ BFLB_CMD_AP_STOP,
+ BFLB_CMD_AP_STARTED_IND,
+ BFLB_CMD_AP_STOPPED_IND,
+ BFLB_CMD_AP_GET_STA_LIST,
+
+ // Monitor
+ BFLB_CMD_MONITOR_START,
+ BFLB_CMD_MONITOR_STOP,
+ BFLB_CMD_MONITOR_SET_CHANNEL,
+ BFLB_CMD_MONITOR_GET_CHANNEL,
+
+ BFLB_CMD_SET_LPM_MODE,
+
+ // OTA
+ BFLB_CMD_GET_DEV_VERSION,
+ BFLB_CMD_OTA,
+
+ BFLB_CMD_EXT,
+
+ BFLB_CMD_USER_EXT,
+ BFLB_CMD_UNLOAD_DRV,
+
+ BFLB_CMD_MAX,
+} bflb_cmd_t;
+
+typedef enum {
+ STATUS_OK,
+ STATUS_NOMEM = 128,
+ STATUS_INVALID_INPUT,
+ STATUS_INVALID_MODE,
+ STATUS_ERR_UNSPECIFIED,
+ STATUS_NOT_IMPLEMENTED,
+} cmd_status_t;
+
+typedef enum {
+ RNM_WIFI_AUTH_UNKNOWN = 0,
+ RNM_WIFI_AUTH_OPEN,
+ RNM_WIFI_AUTH_WEP,
+ RNM_WIFI_AUTH_WPA_PSK,
+ RNM_WIFI_AUTH_WPA2_PSK,
+ RNM_WIFI_AUTH_WPA_WPA2_PSK,
+ RNM_WIFI_AUTH_WPA_ENTERPRISE,
+ RNM_WIFI_AUTH_WPA3_SAE,
+ RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE,
+ RNM_WIFI_AUTH_MAX,
+} rnm_wifi_auth_mode_t;
+
+typedef enum {
+ RNM_WIFI_CIPHER_UNKNOWN = 0,
+ RNM_WIFI_CIPHER_NONE,
+ RNM_WIFI_CIPHER_WEP,
+ RNM_WIFI_CIPHER_AES,
+ RNM_WIFI_CIPHER_TKIP,
+ RNM_WIFI_CIPHER_TKIP_AES,
+ RNM_WIFI_CIPHER_MAX,
+} rnm_wifi_cipher_t;
+
+/* common header */
+typedef struct {
+ uint16_t cmd;
+ // flag ACK is used by server to indicate a response to client
+#define RNM_MSG_FLAG_ACK (1 << 0)
+ // flag TRANSPARENT is never transfered to peer but used locally
+#define RNM_MSG_FLAG_TRANSPARENT (1 << 1)
+ // flag ASYNC is used by server to notify client events such as STA_CONNECTED
+#define RNM_MSG_FLAG_ASYNC (1 << 2)
+ uint16_t flags;
+ uint16_t status;
+ uint16_t msg_id;
+ uint16_t session_id;
+ uint16_t msg_id_replying;
+} rnm_base_msg_t;
+
+typedef struct {
+ rnm_base_msg_t hdr;
+} rnm_ack_msg_t;
+
+typedef struct {
+ rnm_base_msg_t hdr;
+ uint8_t sta_mac[6];
+ uint8_t ap_mac[6];
+} rnm_mac_addr_ind_msg_t;
+
+typedef struct {
+ rnm_base_msg_t hdr;
+ uint16_t ssid_len;
+ uint8_t ssid[32];
+ uint8_t password[64];
+} rnm_sta_connect_msg_t;
+
+typedef struct {
+ rnm_base_msg_t hdr;
+ uint8_t ip4_addr[4];
+ uint8_t ip4_mask[4];
+ uint8_t ip4_gw[4];
+ uint8_t ip4_dns1[4];
+ uint8_t ip4_dns2[4];
+ uint8_t gw_mac[6];
+} rnm_sta_ip_update_ind_msg_t;
+
+struct bf1b_wifi_scan_record {
+ uint8_t bssid[6];
+ // TODO use compressed SSID encoding to save room
+ uint8_t ssid[32 + 1];
+ uint16_t channel;
+ int8_t rssi;
+ uint8_t auth_mode;
+ uint8_t cipher;
+} __PACKED;
+
+typedef struct {
+ rnm_base_msg_t hdr;
+ uint16_t num;
+ struct bf1b_wifi_scan_record records[];
+} rnm_scan_ind_msg_t;
+
+typedef enum {
+ BL_MODE_NONE,
+ BL_MODE_STA, // card is STA
+ BL_MODE_AP, // card is AP
+ BL_MODE_STA_AP, // card is STA&AP
+ BL_MODE_SNIFFER, // card is sniffer
+ BL_MODE_MAX,
+} bl_wifi_mode_t;
+
+typedef struct {
+ uint16_t type;
+ uint16_t length;
+ uint16_t flags;
+ uint16_t payload_offset;
+ uint32_t rsvd[8];
+ uint8_t payload[];
+} __attribute__((aligned(4))) usb_data_t;
+
+struct usbh_bl616 {
+ struct usbh_hubport *hport;
+ struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
+ struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
+
+ struct usbh_urb bulkout_urb;
+ struct usbh_urb bulkin_urb;
+
+ uint8_t intf;
+
+ uint8_t sta_mac[6];
+ uint8_t ap_mac[6];
+ uint8_t mode;
+ bool connect_status;
+
+ void *user_data;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int usbh_bl616_wifi_sta_connect(const char *ssid,
+ const int ssid_len,
+ const char *password,
+ const int pwd_len);
+
+int usbh_bl616_wifi_sta_disconnect(void);
+int usbh_bl616_wifi_scan(void);
+
+void usbh_bl616_sta_connect_callback(void);
+void usbh_bl616_sta_disconnect_callback(void);
+void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4]);
+
+uint8_t *usbh_bl616_get_eth_txbuf(void);
+int usbh_bl616_eth_output(uint32_t buflen);
+void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen);
+void usbh_bl616_rx_thread(void *argument);
+
+void usbh_bl616_run(struct usbh_bl616 *bl616_class);
+void usbh_bl616_stop(struct usbh_bl616 *bl616_class);
+
+int wifi_sta_connect(int argc, char **argv);
+int wifi_scan(int argc, char **argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_BL616_H */
diff --git a/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c
new file mode 100644
index 0000000000..519d1d36cf
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2024 Till Harbaum
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbh_core.h"
+#include "usbh_xbox.h"
+
+#define DEV_FORMAT "/dev/xbox%d"
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_xbox_buf[128];
+
+static struct usbh_xbox g_xbox_class[CONFIG_USBHOST_MAX_XBOX_CLASS];
+static uint32_t g_devinuse = 0;
+
+static struct usbh_xbox *usbh_xbox_class_alloc(void)
+{
+ int devno;
+
+ for (devno = 0; devno < CONFIG_USBHOST_MAX_XBOX_CLASS; devno++) {
+ if ((g_devinuse & (1 << devno)) == 0) {
+ g_devinuse |= (1 << devno);
+ memset(&g_xbox_class[devno], 0, sizeof(struct usbh_xbox));
+ g_xbox_class[devno].minor = devno;
+ return &g_xbox_class[devno];
+ }
+ }
+ return NULL;
+}
+
+static void usbh_xbox_class_free(struct usbh_xbox *xbox_class)
+{
+ int devno = xbox_class->minor;
+
+ if (devno >= 0 && devno < 32) {
+ g_devinuse &= ~(1 << devno);
+ }
+ memset(xbox_class, 0, sizeof(struct usbh_xbox));
+}
+
+int usbh_xbox_connect(struct usbh_hubport *hport, uint8_t intf)
+{
+ struct usb_endpoint_descriptor *ep_desc;
+
+ struct usbh_xbox *xbox_class = usbh_xbox_class_alloc();
+ if (xbox_class == NULL) {
+ USB_LOG_ERR("Fail to alloc xbox_class\r\n");
+ return -USB_ERR_NOMEM;
+ }
+
+ xbox_class->hport = hport;
+ xbox_class->intf = intf;
+
+ hport->config.intf[intf].priv = xbox_class;
+
+ for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
+ ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
+ if (ep_desc->bEndpointAddress & 0x80) {
+ USBH_EP_INIT(xbox_class->intin, ep_desc);
+ } else {
+ USBH_EP_INIT(xbox_class->intout, ep_desc);
+ }
+ }
+
+ snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, xbox_class->minor);
+
+ USB_LOG_INFO("Register XBOX Class:%s\r\n", hport->config.intf[intf].devname);
+
+ usbh_xbox_run(xbox_class);
+ return 0;
+}
+
+int usbh_xbox_disconnect(struct usbh_hubport *hport, uint8_t intf)
+{
+ int ret = 0;
+
+ struct usbh_xbox *xbox_class = (struct usbh_xbox *)hport->config.intf[intf].priv;
+
+ if (xbox_class) {
+ if (xbox_class->intin) {
+ usbh_kill_urb(&xbox_class->intin_urb);
+ }
+
+ if (xbox_class->intout) {
+ usbh_kill_urb(&xbox_class->intout_urb);
+ }
+
+ if (hport->config.intf[intf].devname[0] != '\0') {
+ USB_LOG_INFO("Unregister XBOX Class:%s\r\n", hport->config.intf[intf].devname);
+ usbh_xbox_stop(xbox_class);
+ }
+
+ usbh_xbox_class_free(xbox_class);
+ }
+
+ return ret;
+}
+
+__WEAK void usbh_xbox_run(struct usbh_xbox *xbox_class)
+{
+}
+
+__WEAK void usbh_xbox_stop(struct usbh_xbox *xbox_class)
+{
+}
+
+const struct usbh_class_driver xbox_class_driver = {
+ .driver_name = "xbox",
+ .connect = usbh_xbox_connect,
+ .disconnect = usbh_xbox_disconnect
+};
+
+static const uint16_t xbox_id_table[][2] = {
+ { 0x0079, 0x18d4 }, // GPD Win 2 X-Box Controller
+ { 0x03eb, 0xff01 }, // Wooting One (Legacy)
+ { 0x03eb, 0xff02 }, // Wooting Two (Legacy)
+ { 0x044f, 0xb326 }, // Thrustmaster Gamepad GP XID
+ { 0x045e, 0x028e }, // Microsoft X-Box 360 pad
+ { 0x045e, 0x028f }, // Microsoft X-Box 360 pad v2
+ { 0x046d, 0xc21d }, // Logitech Gamepad F310
+ { 0x046d, 0xc21e }, // Logitech Gamepad F510
+ { 0x046d, 0xc21f }, // Logitech Gamepad F710
+ { 0x046d, 0xc242 }, // Logitech Chillstream Controller
+ { 0x046d, 0xcaa3 }, // Logitech DriveFx Racing Wheel
+ { 0x056e, 0x2004 }, // Elecom JC-U3613M
+ { 0x06a3, 0xf51a }, // Saitek P3600
+ { 0x0738, 0x4716 }, // Mad Catz Wired Xbox 360 Controller
+ { 0x0738, 0x4718 }, // Mad Catz Street Fighter IV FightStick SE
+ { 0x0738, 0x4726 }, // Mad Catz Xbox 360 Controller
+ { 0x0738, 0x4736 }, // Mad Catz MicroCon Gamepad
+ { 0x0738, 0x4740 }, // Mad Catz Beat Pad
+ { 0x0738, 0x9871 }, // Mad Catz Portable Drum
+ { 0x0738, 0xb726 }, // Mad Catz Xbox controller - MW2
+ { 0x0738, 0xbeef }, // Mad Catz JOYTECH NEO SE Advanced GamePad
+ { 0x0738, 0xcb02 }, // Saitek Cyborg Rumble Pad - PC/Xbox 360
+ { 0x0738, 0xcb03 }, // Saitek P3200 Rumble Pad - PC/Xbox 360
+ { 0x0738, 0xcb29 }, // Saitek Aviator Stick AV8R02
+ { 0x0738, 0xf738 }, // Super SFIV FightStick TE S
+ { 0x07ff, 0xffff }, // Mad Catz GamePad
+ { 0x0e6f, 0x0113 }, // Afterglow AX.1 Gamepad for Xbox 360
+ { 0x0e6f, 0x011f }, // Rock Candy Gamepad Wired Controller
+ { 0x0e6f, 0x0131 }, // PDP EA Sports Controller
+ { 0x0e6f, 0x0133 }, // Xbox 360 Wired Controller
+ { 0x0e6f, 0x0201 }, // Pelican PL-3601 'TSZ' Wired Xbox 360 Controller
+ { 0x0e6f, 0x0213 }, // Afterglow Gamepad for Xbox 360
+ { 0x0e6f, 0x021f }, // Rock Candy Gamepad for Xbox 360
+ { 0x0e6f, 0x0301 }, // Logic3 Controller
+ { 0x0e6f, 0x0401 }, // Logic3 Controller
+ { 0x0e6f, 0x0413 }, // Afterglow AX.1 Gamepad for Xbox 360
+ { 0x0e6f, 0x0501 }, // PDP Xbox 360 Controller
+ { 0x0e6f, 0xf900 }, // PDP Afterglow AX.1
+ { 0x0f0d, 0x000a }, // Hori Co. DOA4 FightStick
+ { 0x0f0d, 0x000c }, // Hori PadEX Turbo
+ { 0x1038, 0x1430 }, // SteelSeries Stratus Duo
+ { 0x1038, 0x1431 }, // SteelSeries Stratus Duo
+ { 0x11c9, 0x55f0 }, // Nacon GC-100XF
+ { 0x1209, 0x2882 }, // Ardwiino Controller
+ { 0x12ab, 0x0301 }, // PDP AFTERGLOW AX.1
+ { 0x1430, 0x4748 }, // RedOctane Guitar Hero X-plorer
+ { 0x1430, 0xf801 }, // RedOctane Controller
+ { 0x146b, 0x0601 }, // BigBen Interactive XBOX 360 Controller
+ { 0x1532, 0x0037 }, // Razer Sabertooth
+ { 0x15e4, 0x3f00 }, // Power A Mini Pro Elite
+ { 0x15e4, 0x3f0a }, // Xbox Airflo wired controller
+ { 0x15e4, 0x3f10 }, // Batarang Xbox 360 controller
+ { 0x162e, 0xbeef }, // Joytech Neo-Se Take2
+ { 0x1689, 0xfd00 }, // Razer Onza Tournament Edition
+ { 0x1689, 0xfd01 }, // Razer Onza Classic Edition
+ { 0x1689, 0xfe00 }, // Razer Sabertooth
+ { 0x1949, 0x041a }, // Amazon Game Controller
+ { 0x1bad, 0x0002 }, // Harmonix Rock Band Guitar
+ { 0x1bad, 0xf016 }, // Mad Catz Xbox 360 Controller
+ { 0x1bad, 0xf021 }, // Mad Cats Ghost Recon FS GamePad
+ { 0x1bad, 0xf023 }, // MLG Pro Circuit Controller (Xbox)
+ { 0x1bad, 0xf025 }, // Mad Catz Call Of Duty
+ { 0x1bad, 0xf027 }, // Mad Catz FPS Pro
+ { 0x1bad, 0xf028 }, // Street Fighter IV FightPad
+ { 0x1bad, 0xf030 }, // Mad Catz Xbox 360 MC2 MicroCon Racing Wheel
+ { 0x1bad, 0xf036 }, // Mad Catz MicroCon GamePad Pro
+ { 0x1bad, 0xf038 }, // Street Fighter IV FightStick TE
+ { 0x1bad, 0xf501 }, // HoriPad EX2 Turbo
+ { 0x1bad, 0xf506 }, // Hori Real Arcade Pro.EX Premium VLX
+ { 0x1bad, 0xf900 }, // Harmonix Xbox 360 Controller
+ { 0x1bad, 0xf901 }, // Gamestop Xbox 360 Controller
+ { 0x1bad, 0xf903 }, // Tron Xbox 360 controller
+ { 0x1bad, 0xf904 }, // PDP Versus Fighting Pad
+ { 0x1bad, 0xfa01 }, // MadCatz GamePad
+ { 0x1bad, 0xfd00 }, // Razer Onza TE
+ { 0x1bad, 0xfd01 }, // Razer Onza
+ { 0x20d6, 0x2001 }, // BDA Xbox Series X Wired Controller
+ { 0x20d6, 0x281f }, // PowerA Wired Controller For Xbox 360
+ { 0x24c6, 0x5300 }, // PowerA MINI PROEX Controller
+ { 0x24c6, 0x5303 }, // Xbox Airflo wired controller
+ { 0x24c6, 0x530a }, // Xbox 360 Pro EX Controller
+ { 0x24c6, 0x531a }, // PowerA Pro Ex
+ { 0x24c6, 0x5397 }, // FUS1ON Tournament Controller
+ { 0x24c6, 0x5500 }, // Hori XBOX 360 EX 2 with Turbo
+ { 0x24c6, 0x5501 }, // Hori Real Arcade Pro VX-SA
+ { 0x24c6, 0x5506 }, // Hori SOULCALIBUR V Stick
+ { 0x24c6, 0x550d }, // Hori GEM Xbox controller
+ { 0x24c6, 0x5b00 }, // ThrustMaster Ferrari 458 Racing Wheel
+ { 0x24c6, 0x5b02 }, // Thrustmaster, Inc. GPX Controller
+ { 0x24c6, 0x5b03 }, // Thrustmaster Ferrari 458 Racing Wheel
+ { 0x24c6, 0x5d04 }, // Razer Sabertooth
+ { 0x24c6, 0xfafe }, // Rock Candy Gamepad for Xbox 360
+ { 0x2563, 0x058d }, // OneXPlayer Gamepad
+ { 0x2dc8, 0x3106 }, // 8BitDo Ultimate Wireless / Pro 2 Wired Controller
+ { 0x2dc8, 0x3109 }, // 8BitDo Ultimate Wireless Bluetooth
+ { 0x31e3, 0x1100 }, // Wooting One
+ { 0x31e3, 0x1200 }, // Wooting Two
+ { 0x31e3, 0x1210 }, // Wooting Lekker
+ { 0x31e3, 0x1220 }, // Wooting Two HE
+ { 0x31e3, 0x1230 }, // Wooting Two HE (ARM)
+ { 0x31e3, 0x1300 }, // Wooting 60HE (AVR)
+ { 0x31e3, 0x1310 }, // Wooting 60HE (ARM)
+ { 0x3285, 0x0607 }, // Nacon GC-100
+ { 0x413d, 0x2104 }, // Black Shark Green Ghost Gamepad
+ { 0x0000, 0x0000 } // end of list
+};
+
+CLASS_INFO_DEFINE const struct usbh_class_info xbox_custom_class_info = {
+ .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
+ .class = USB_DEVICE_CLASS_VEND_SPECIFIC,
+ .subclass = 0x5d,
+ .protocol = 0x01,
+ .id_table = xbox_id_table,
+ .class_driver = &xbox_class_driver
+};
diff --git a/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.h b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.h
new file mode 100644
index 0000000000..85d467249e
--- /dev/null
+++ b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Till Harbaum
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USBH_XBOX_H
+#define USBH_XBOX_H
+
+struct usbh_xbox {
+ struct usbh_hubport *hport;
+ struct usb_endpoint_descriptor *intin; /* INTR IN endpoint */
+ struct usb_endpoint_descriptor *intout; /* INTR OUT endpoint */
+ struct usbh_urb intin_urb; /* INTR IN urb */
+ struct usbh_urb intout_urb; /* INTR OUT urb */
+
+ uint8_t intf; /* interface number */
+ uint8_t minor;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void usbh_xbox_run(struct usbh_xbox *xbox_class);
+void usbh_xbox_stop(struct usbh_xbox *xbox_class);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBH_XBOX_H */
diff --git a/components/drivers/usb/cherryusb/class/video/usbd_video.c b/components/drivers/usb/cherryusb/class/video/usbd_video.c
index b11fa6ad31..ee8ca5ee30 100644
--- a/components/drivers/usb/cherryusb/class/video/usbd_video.c
+++ b/components/drivers/usb/cherryusb/class/video/usbd_video.c
@@ -24,6 +24,8 @@ static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_pa
{
uint8_t control_selector = (uint8_t)(setup->wValue >> 8);
+ (void)busid;
+
switch (control_selector) {
case VIDEO_VC_VIDEO_POWER_MODE_CONTROL:
switch (setup->bRequest) {
diff --git a/components/drivers/usb/cherryusb/class/video/usbh_video.c b/components/drivers/usb/cherryusb/class/video/usbh_video.c
index 0d3f79f7f2..c5458a403d 100644
--- a/components/drivers/usb/cherryusb/class/video/usbh_video.c
+++ b/components/drivers/usb/cherryusb/class/video/usbh_video.c
@@ -495,20 +495,26 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
static int usbh_video_streaming_connect(struct usbh_hubport *hport, uint8_t intf)
{
+ (void)hport;
+ (void)intf;
return 0;
}
static int usbh_video_streaming_disconnect(struct usbh_hubport *hport, uint8_t intf)
{
+ (void)hport;
+ (void)intf;
return 0;
}
__WEAK void usbh_video_run(struct usbh_video *video_class)
{
+ (void)video_class;
}
__WEAK void usbh_video_stop(struct usbh_video *video_class)
{
+ (void)video_class;
}
const struct usbh_class_driver video_ctrl_class_driver = {
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c
index c357b25a2c..61bcd290d1 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c
+++ b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c
@@ -102,6 +102,8 @@ static void rndis_notify_rsp(void)
static int rndis_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
{
+ (void)busid;
+
switch (setup->bRequest) {
case CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
rndis_encapsulated_cmd_handler(*data, setup->wLength);
@@ -152,6 +154,8 @@ static int rndis_init_cmd_handler(uint8_t *data, uint32_t len)
rndis_initialize_msg_t *cmd = (rndis_initialize_msg_t *)data;
rndis_initialize_cmplt_t *resp;
+ (void)len;
+
resp = ((rndis_initialize_cmplt_t *)rndis_encapsulated_resp_buffer);
resp->RequestId = cmd->RequestId;
resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
@@ -177,6 +181,9 @@ static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len)
{
rndis_halt_msg_t *resp;
+ (void)data;
+ (void)len;
+
resp = ((rndis_halt_msg_t *)rndis_encapsulated_resp_buffer);
resp->MessageLength = 0;
@@ -192,6 +199,8 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
uint8_t *infomation_buffer;
uint32_t infomation_len = 0;
+ (void)len;
+
resp = ((rndis_query_cmplt_t *)rndis_encapsulated_resp_buffer);
resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
resp->RequestId = cmd->RequestId;
@@ -338,6 +347,8 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len)
rndis_set_cmplt_t *resp;
rndis_config_parameter_t *param;
+ (void)len;
+
resp = ((rndis_set_cmplt_t *)rndis_encapsulated_resp_buffer);
resp->RequestId = cmd->RequestId;
resp->MessageType = REMOTE_NDIS_SET_CMPLT;
@@ -394,6 +405,9 @@ static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len)
// rndis_reset_msg_t *cmd = (rndis_reset_msg_t *)data;
rndis_reset_cmplt_t *resp;
+ (void)data;
+ (void)len;
+
resp = ((rndis_reset_cmplt_t *)rndis_encapsulated_resp_buffer);
resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
resp->MessageLength = sizeof(rndis_reset_cmplt_t);
@@ -412,6 +426,8 @@ static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len)
rndis_keepalive_msg_t *cmd = (rndis_keepalive_msg_t *)data;
rndis_keepalive_cmplt_t *resp;
+ (void)len;
+
resp = ((rndis_keepalive_cmplt_t *)rndis_encapsulated_resp_buffer);
resp->RequestId = cmd->RequestId;
resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
@@ -425,6 +441,9 @@ static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len)
static void rndis_notify_handler(uint8_t busid, uint8_t event, void *arg)
{
+ (void)busid;
+ (void)arg;
+
switch (event) {
case USBD_EVENT_RESET:
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
@@ -445,6 +464,9 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
rndis_data_packet_t *hdr;
+ (void)busid;
+ (void)ep;
+
hdr = (rndis_data_packet_t *)g_rndis_rx_buffer;
g_rndis_rx_data_buffer = g_rndis_rx_buffer;
if ((hdr->MessageType != REMOTE_NDIS_PACKET_MSG) || (nbytes < hdr->MessageLength)) {
@@ -461,7 +483,9 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
- if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
+ (void)busid;
+
+ if ((nbytes % usbd_get_ep_mps(0, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(0, ep, NULL, 0);
} else {
@@ -471,6 +495,10 @@ void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
void rndis_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
+ (void)busid;
+ (void)ep;
+ (void)nbytes;
+
//USB_LOG_DBG("len:%d\r\n", nbytes);
}
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c
index e73eeb0385..9f78866ab5 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c
+++ b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c
@@ -365,14 +365,18 @@ delete :
__WEAK void usbh_bluetooth_hci_read_callback(uint8_t *data, uint32_t len)
{
+ (void)data;
+ (void)len;
}
__WEAK void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class)
{
+ (void)bluetooth_class;
}
__WEAK void usbh_bluetooth_stop(struct usbh_bluetooth *bluetooth_class)
{
+ (void)bluetooth_class;
}
static const struct usbh_class_driver bluetooth_class_driver = {
diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c
index e722e50ceb..2b45fb1a07 100644
--- a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c
+++ b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c
@@ -26,6 +26,7 @@ static struct usbh_rndis g_rndis_class;
static int usbh_rndis_get_notification(struct usbh_rndis *rndis_class)
{
+ (void)rndis_class;
// int ret;
// struct usbh_urb *urb = &rndis_class->intin_urb;
@@ -460,6 +461,8 @@ void usbh_rndis_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
+ (void)argument;
+
USB_LOG_INFO("Create rndis rx thread\r\n");
// clang-format off
find_class:
@@ -531,7 +534,7 @@ find_class:
#else
if ((g_rndis_rx_length + (16 * 1024)) > CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) {
#endif
- USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE\r\n");
+ USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE\r\n");
while (1) {
}
}
@@ -581,10 +584,12 @@ int usbh_rndis_eth_output(uint32_t buflen)
__WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class)
{
+ (void)rndis_class;
}
__WEAK void usbh_rndis_stop(struct usbh_rndis *rndis_class)
{
+ (void)rndis_class;
}
static const struct usbh_class_driver rndis_class_driver = {
diff --git a/components/drivers/usb/cherryusb/common/usb_dc.h b/components/drivers/usb/cherryusb/common/usb_dc.h
index a10869aacc..1f2fdddddc 100644
--- a/components/drivers/usb/cherryusb/common/usb_dc.h
+++ b/components/drivers/usb/cherryusb/common/usb_dc.h
@@ -33,6 +33,13 @@ int usb_dc_deinit(uint8_t busid);
*/
int usbd_set_address(uint8_t busid, const uint8_t addr);
+/**
+ * @brief Set remote wakeup feature
+ *
+ * @return On success will return 0, and others indicate fail.
+ */
+int usbd_set_remote_wakeup(uint8_t busid);
+
/**
* @brief Get USB device speed
*
diff --git a/components/drivers/usb/cherryusb/common/usb_def.h b/components/drivers/usb/cherryusb/common/usb_def.h
index aea3d6ad5a..27b4d82155 100644
--- a/components/drivers/usb/cherryusb/common/usb_def.h
+++ b/components/drivers/usb/cherryusb/common/usb_def.h
@@ -614,7 +614,7 @@ struct usb_webusb_url_descriptor {
char URL[];
} __PACKED;
-struct usb_webusb_url_ex_descriptor {
+struct usb_webusb_descriptor {
uint8_t vendor_code;
const uint8_t *string;
uint32_t string_len;
diff --git a/components/drivers/usb/cherryusb/common/usb_log.h b/components/drivers/usb/cherryusb/common/usb_log.h
index 923e8006c7..9074ed9752 100644
--- a/components/drivers/usb/cherryusb/common/usb_log.h
+++ b/components/drivers/usb/cherryusb/common/usb_log.h
@@ -82,4 +82,31 @@ void usb_assert(const char *filename, int linenum);
usb_assert(__FILE__, __LINE__); \
} while (0)
+#define ___is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static inline void usb_hexdump(const void *ptr, uint32_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ uint32_t i, j;
+
+ for (i = 0; i < buflen; i += 16) {
+ CONFIG_USB_PRINTF("%08X:", i);
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen) {
+ if ((j % 8) == 0) {
+ CONFIG_USB_PRINTF(" ");
+ }
+
+ CONFIG_USB_PRINTF("%02X ", buf[i + j]);
+ } else
+ CONFIG_USB_PRINTF(" ");
+ CONFIG_USB_PRINTF(" ");
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ CONFIG_USB_PRINTF("%c", ___is_print(buf[i + j]) ? buf[i + j] : '.');
+ CONFIG_USB_PRINTF("\n");
+ }
+}
+
#endif /* USB_LOG_H */
diff --git a/components/drivers/usb/cherryusb/common/usb_osal.h b/components/drivers/usb/cherryusb/common/usb_osal.h
index f487c48599..a3380d1339 100644
--- a/components/drivers/usb/cherryusb/common/usb_osal.h
+++ b/components/drivers/usb/cherryusb/common/usb_osal.h
@@ -58,4 +58,7 @@ void usb_osal_leave_critical_section(size_t flag);
void usb_osal_msleep(uint32_t delay);
+void *usb_osal_malloc(size_t size);
+void usb_osal_free(void *ptr);
+
#endif /* USB_OSAL_H */
diff --git a/components/drivers/usb/cherryusb/common/usb_version.h b/components/drivers/usb/cherryusb/common/usb_version.h
new file mode 100644
index 0000000000..384f278d46
--- /dev/null
+++ b/components/drivers/usb/cherryusb/common/usb_version.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef USB_VERSION_H
+#define USB_VERSION_H
+
+#ifdef CHERRYUSB_VERSION
+#warning "Please do not define CHERRYUSB_VERSION in usb_config.h"
+#undef CHERRYUSB_VERSION
+#endif
+#ifdef CHERRYUSB_VERSION_STR
+#warning "Please do not define CHERRYUSB_VERSION_STR in usb_config.h"
+#undef CHERRYUSB_VERSION_STR
+#endif
+
+#define CHERRYUSB_VERSION 0x010400
+#define CHERRYUSB_VERSION_STR "v1.4.0"
+
+#endif
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/core/usbd_core.c b/components/drivers/usb/cherryusb/core/usbd_core.c
index e072d8a2a5..4742da6a0e 100644
--- a/components/drivers/usb/cherryusb/core/usbd_core.c
+++ b/components/drivers/usb/cherryusb/core/usbd_core.c
@@ -45,12 +45,18 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
struct usb_msosv1_descriptor *msosv1_desc;
struct usb_msosv2_descriptor *msosv2_desc;
struct usb_bos_descriptor *bos_desc;
+ struct usb_webusb_descriptor *webusb_url_desc;
#endif
/* Buffer used for storing standard, class and vendor request data */
USB_MEM_ALIGNX uint8_t req_data[CONFIG_USBDEV_REQUEST_BUFFER_LEN];
/** Currently selected configuration */
uint8_t configuration;
+ uint8_t device_address;
+ bool self_powered;
+ bool remote_wakeup_support;
+ bool remote_wakeup_enabled;
+ bool is_suspend;
#ifdef CONFIG_USBDEV_ADVANCE_DESC
uint8_t speed;
#endif
@@ -99,9 +105,9 @@ static bool is_device_configured(uint8_t busid)
static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descriptor *ep)
{
USB_LOG_DBG("Open ep:0x%02x type:%u mps:%u\r\n",
- ep->bEndpointAddress,
- USB_GET_ENDPOINT_TYPE(ep->bmAttributes),
- USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize));
+ ep->bEndpointAddress,
+ USB_GET_ENDPOINT_TYPE(ep->bmAttributes),
+ USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize));
if (ep->bEndpointAddress & 0x80) {
g_usbd_core[busid].tx_msg[ep->bEndpointAddress & 0x7f].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
@@ -126,8 +132,8 @@ static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descripto
static bool usbd_reset_endpoint(uint8_t busid, const struct usb_endpoint_descriptor *ep)
{
USB_LOG_DBG("Close ep:0x%02x type:%u\r\n",
- ep->bEndpointAddress,
- USB_GET_ENDPOINT_TYPE(ep->bmAttributes));
+ ep->bEndpointAddress,
+ USB_GET_ENDPOINT_TYPE(ep->bmAttributes));
return usbd_ep_close(busid, ep->bEndpointAddress) == 0 ? true : false;
}
@@ -174,6 +180,9 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
break;
}
desc_len = ((desc[CONF_DESC_wTotalLength]) | (desc[CONF_DESC_wTotalLength + 1] << 8));
+
+ g_usbd_core[busid].self_powered = (desc[7] & USB_CONFIG_POWERED_MASK) ? true : false;
+ g_usbd_core[busid].remote_wakeup_support = (desc[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false;
break;
case USB_DESCRIPTOR_TYPE_STRING:
if (index == USB_OSDESC_STRING_DESC_INDEX) {
@@ -336,6 +345,9 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
*/
*len = (p[CONF_DESC_wTotalLength]) |
(p[CONF_DESC_wTotalLength + 1] << 8);
+
+ g_usbd_core[busid].self_powered = (p[7] & USB_CONFIG_POWERED_MASK) ? true : false;
+ g_usbd_core[busid].remote_wakeup_support = (p[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false;
} else {
/* normally length is at offset 0 */
*len = p[DESC_bLength];
@@ -522,6 +534,12 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
/* bit 0: self-powered */
/* bit 1: remote wakeup */
(*data)[0] = 0x00;
+ if (g_usbd_core[busid].self_powered) {
+ (*data)[0] |= USB_GETSTATUS_SELF_POWERED;
+ }
+ if (g_usbd_core[busid].remote_wakeup_enabled) {
+ (*data)[0] |= USB_GETSTATUS_REMOTE_WAKEUP;
+ }
(*data)[1] = 0x00;
*len = 2;
break;
@@ -530,8 +548,10 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
case USB_REQUEST_SET_FEATURE:
if (value == USB_FEATURE_REMOTE_WAKEUP) {
if (setup->bRequest == USB_REQUEST_SET_FEATURE) {
+ g_usbd_core[busid].remote_wakeup_enabled = true;
g_usbd_core[busid].event_handler(busid, USBD_EVENT_SET_REMOTE_WAKEUP);
} else {
+ g_usbd_core[busid].remote_wakeup_enabled = false;
g_usbd_core[busid].event_handler(busid, USBD_EVENT_CLR_REMOTE_WAKEUP);
}
} else if (value == USB_FEATURE_TEST_MODE) {
@@ -543,6 +563,7 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
break;
case USB_REQUEST_SET_ADDRESS:
+ g_usbd_core[busid].device_address = value;
usbd_set_address(busid, value);
*len = 0;
break;
@@ -556,17 +577,20 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
break;
case USB_REQUEST_GET_CONFIGURATION:
- *data = (uint8_t *)&g_usbd_core[busid].configuration;
+ (*data)[0] = g_usbd_core[busid].configuration;
*len = 1;
break;
case USB_REQUEST_SET_CONFIGURATION:
value &= 0xFF;
- if (!usbd_set_configuration(busid, value, 0)) {
+ if (value == 0) {
+ g_usbd_core[busid].configuration = 0;
+ } else if (!usbd_set_configuration(busid, value, 0)) {
ret = false;
} else {
g_usbd_core[busid].configuration = value;
+ g_usbd_core[busid].is_suspend = false;
usbd_class_event_notify_handler(busid, USBD_EVENT_CONFIGURED, NULL);
g_usbd_core[busid].event_handler(busid, USBD_EVENT_CONFIGURED);
}
@@ -600,6 +624,16 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
uint8_t type = HI_BYTE(setup->wValue);
uint8_t intf_num = LO_BYTE(setup->wIndex);
bool ret = true;
+ const uint8_t *p;
+ uint32_t desc_len = 0;
+ uint32_t current_desc_len = 0;
+ uint8_t cur_iface = 0xFF;
+
+#ifdef CONFIG_USBDEV_ADVANCE_DESC
+ p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed);
+#else
+ p = (uint8_t *)g_usbd_core[busid].descriptors;
+#endif
/* Only when device is configured, then interface requests can be valid. */
if (!is_device_configured(busid)) {
@@ -614,7 +648,39 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
break;
case USB_REQUEST_GET_DESCRIPTOR:
- if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */
+ if (type == 0x21) { /* HID_DESCRIPTOR_TYPE_HID */
+ while (p[DESC_bLength] != 0U) {
+ switch (p[DESC_bDescriptorType]) {
+ case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+ current_desc_len = 0;
+ desc_len = (p[CONF_DESC_wTotalLength]) |
+ (p[CONF_DESC_wTotalLength + 1] << 8);
+
+ break;
+
+ case USB_DESCRIPTOR_TYPE_INTERFACE:
+ cur_iface = p[INTF_DESC_bInterfaceNumber];
+ break;
+ case 0x21:
+ if (cur_iface == intf_num) {
+ *data = (uint8_t *)p;
+ //memcpy(*data, p, p[DESC_bLength]);
+ *len = p[DESC_bLength];
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* skip to next descriptor */
+ p += p[DESC_bLength];
+ current_desc_len += p[DESC_bLength];
+ if (current_desc_len >= desc_len && desc_len) {
+ break;
+ }
+ }
+ } else if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */
for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) {
struct usbd_interface *intf = g_usbd_core[busid].intf[i];
@@ -663,6 +729,7 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet
{
uint8_t ep = (uint8_t)setup->wIndex;
bool ret = true;
+ uint8_t stalled;
/* Only when device is configured, then endpoint requests can be valid. */
if (!is_device_configured(busid)) {
@@ -671,7 +738,12 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet
switch (setup->bRequest) {
case USB_REQUEST_GET_STATUS:
- (*data)[0] = 0x00;
+ usbd_ep_is_stalled(busid, ep, &stalled);
+ if (stalled) {
+ (*data)[0] = 0x01;
+ } else {
+ (*data)[0] = 0x00;
+ }
(*data)[1] = 0x00;
*len = 2;
break;
@@ -841,10 +913,12 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
return -1;
}
}
- } else if (g_usbd_core[busid].descriptors->webusb_url_descriptor) {
+ }
+
+ if (g_usbd_core[busid].descriptors->webusb_url_descriptor) {
if (setup->bRequest == g_usbd_core[busid].descriptors->webusb_url_descriptor->vendor_code) {
switch (setup->wIndex) {
- case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
+ case WEBUSB_REQUEST_GET_URL:
desclen = g_usbd_core[busid].descriptors->webusb_url_descriptor->string_len;
*data = (uint8_t *)g_usbd_core[busid].descriptors->webusb_url_descriptor->string;
//memcpy(*data, g_usbd_core[busid].descriptors->webusb_url_descriptor->string, desclen);
@@ -897,6 +971,22 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
}
}
}
+
+ if (g_usbd_core[busid].webusb_url_desc) {
+ if (setup->bRequest == g_usbd_core[busid].webusb_url_desc->vendor_code) {
+ switch (setup->wIndex) {
+ case WEBUSB_REQUEST_GET_URL:
+ desclen = g_usbd_core[busid].webusb_url_desc->string_len;
+ *data = (uint8_t *)g_usbd_core[busid].webusb_url_desc->string;
+ //memcpy(*data, g_usbd_core[busid].webusb_url_desc->string, desclen);
+ *len = desclen;
+ return 0;
+ default:
+ USB_LOG_ERR("unknown vendor code\r\n");
+ return -1;
+ }
+ }
+ }
#endif
for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) {
struct usbd_interface *intf = g_usbd_core[busid].intf[i];
@@ -985,17 +1075,22 @@ void usbd_event_disconnect_handler(uint8_t busid)
void usbd_event_resume_handler(uint8_t busid)
{
+ g_usbd_core[busid].is_suspend = false;
g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESUME);
}
void usbd_event_suspend_handler(uint8_t busid)
{
- g_usbd_core[busid].event_handler(busid, USBD_EVENT_SUSPEND);
+ if (g_usbd_core[busid].device_address > 0) {
+ g_usbd_core[busid].is_suspend = true;
+ g_usbd_core[busid].event_handler(busid, USBD_EVENT_SUSPEND);
+ }
}
void usbd_event_reset_handler(uint8_t busid)
{
usbd_set_address(busid, 0);
+ g_usbd_core[busid].device_address = 0;
g_usbd_core[busid].configuration = 0;
#ifdef CONFIG_USBDEV_ADVANCE_DESC
g_usbd_core[busid].speed = USB_SPEED_UNKNOWN;
@@ -1091,6 +1186,8 @@ void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
+ (void)ep;
+
g_usbd_core[busid].ep0_data_buf += nbytes;
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
@@ -1130,6 +1227,8 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
+ (void)ep;
+
if (nbytes > 0) {
g_usbd_core[busid].ep0_data_buf += nbytes;
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
@@ -1213,6 +1312,11 @@ void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc)
{
g_usbd_core[busid].bos_desc = desc;
}
+
+void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc)
+{
+ g_usbd_core[busid].webusb_url_desc = desc;
+}
#endif
void usbd_add_interface(uint8_t busid, struct usbd_interface *intf)
@@ -1256,7 +1360,30 @@ bool usb_device_is_configured(uint8_t busid)
return g_usbd_core[busid].configuration;
}
-int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
+bool usb_device_is_suspend(uint8_t busid)
+{
+ return g_usbd_core[busid].is_suspend;
+}
+
+int usbd_send_remote_wakeup(uint8_t busid)
+{
+ if (g_usbd_core[busid].remote_wakeup_support && g_usbd_core[busid].remote_wakeup_enabled && g_usbd_core[busid].is_suspend) {
+ return usbd_set_remote_wakeup(busid);
+ } else {
+ if (!g_usbd_core[busid].remote_wakeup_support) {
+ USB_LOG_ERR("device does not support remote wakeup\r\n");
+ }
+ if (!g_usbd_core[busid].remote_wakeup_enabled) {
+ USB_LOG_ERR("device remote wakeup is not enabled\r\n");
+ }
+ if (!g_usbd_core[busid].is_suspend) {
+ USB_LOG_ERR("device is not in suspend state\r\n");
+ }
+ return -1;
+ }
+}
+
+int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
{
int ret;
struct usbd_bus *bus;
@@ -1279,9 +1406,9 @@ int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint
int usbd_deinitialize(uint8_t busid)
{
- g_usbd_core[busid].intf_offset = 0;
- usb_dc_deinit(busid);
- usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT);
+ usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
+ usb_dc_deinit(busid);
+ g_usbd_core[busid].intf_offset = 0;
return 0;
}
diff --git a/components/drivers/usb/cherryusb/core/usbd_core.h b/components/drivers/usb/cherryusb/core/usbd_core.h
index 01335f2faf..71bdb29ba2 100644
--- a/components/drivers/usb/cherryusb/core/usbd_core.h
+++ b/components/drivers/usb/cherryusb/core/usbd_core.h
@@ -23,6 +23,7 @@ extern "C" {
#include "usb_log.h"
#include "usb_dc.h"
#include "usb_memcpy.h"
+#include "usb_version.h"
enum usbd_event_type {
/* USB DCD IRQ */
@@ -71,13 +72,13 @@ struct usb_descriptor {
const char *(*string_descriptor_callback)(uint8_t speed, uint8_t index);
const struct usb_msosv1_descriptor *msosv1_descriptor;
const struct usb_msosv2_descriptor *msosv2_descriptor;
- const struct usb_webusb_url_ex_descriptor *webusb_url_descriptor;
+ const struct usb_webusb_descriptor *webusb_url_descriptor;
const struct usb_bos_descriptor *bos_descriptor;
};
struct usbd_bus {
uint8_t busid;
- uint32_t reg_base;
+ uintptr_t reg_base;
};
extern struct usbd_bus g_usbdev_bus[];
@@ -93,6 +94,7 @@ void usbd_desc_register(uint8_t busid, const uint8_t *desc);
void usbd_msosv1_desc_register(uint8_t busid, struct usb_msosv1_descriptor *desc);
void usbd_msosv2_desc_register(uint8_t busid, struct usb_msosv2_descriptor *desc);
void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc);
+void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc);
#endif
void usbd_add_interface(uint8_t busid, struct usbd_interface *intf);
@@ -101,8 +103,10 @@ void usbd_add_endpoint(uint8_t busid, struct usbd_endpoint *ep);
uint16_t usbd_get_ep_mps(uint8_t busid, uint8_t ep);
uint8_t usbd_get_ep_mult(uint8_t busid, uint8_t ep);
bool usb_device_is_configured(uint8_t busid);
+bool usb_device_is_suspend(uint8_t busid);
+int usbd_send_remote_wakeup(uint8_t busid);
-int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event));
+int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event));
int usbd_deinitialize(uint8_t busid);
#ifdef __cplusplus
diff --git a/components/drivers/usb/cherryusb/core/usbh_core.c b/components/drivers/usb/cherryusb/core/usbh_core.c
index d1fc769d50..ab7c107beb 100644
--- a/components/drivers/usb/cherryusb/core/usbh_core.c
+++ b/components/drivers/usb/cherryusb/core/usbh_core.c
@@ -486,7 +486,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
goto errout;
}
USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumInterfaces);
- hport->raw_config_desc = usb_malloc(wTotalLength);
+ hport->raw_config_desc = usb_osal_malloc(wTotalLength);
if (hport->raw_config_desc == NULL) {
ret = -USB_ERR_NOMEM;
USB_LOG_ERR("No memory to alloc for raw_config_desc\r\n");
@@ -549,7 +549,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wLength = 16;
ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
- if (ret < 0 && (ret != -EPERM)) {
+ if (ret < 0 && (ret != -USB_ERR_STALL)) {
USB_LOG_ERR("Failed to get msosv1 compat id,errorcode:%d\r\n", ret);
goto errout;
}
@@ -576,7 +576,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
errout:
if (hport->raw_config_desc) {
- usb_free(hport->raw_config_desc);
+ usb_osal_free(hport->raw_config_desc);
hport->raw_config_desc = NULL;
}
return ret;
@@ -600,7 +600,7 @@ void usbh_hubport_release(struct usbh_hubport *hport)
}
}
-static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base)
+static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_base)
{
memset(bus, 0, sizeof(struct usbh_bus));
bus->busid = busid;
@@ -613,7 +613,7 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base
usb_slist_add_tail(&g_bus_head, &bus->list);
}
-int usbh_initialize(uint8_t busid, uint32_t reg_base)
+int usbh_initialize(uint8_t busid, uintptr_t reg_base)
{
struct usbh_bus *bus;
@@ -731,7 +731,7 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn
struct usbh_hub *hub_next;
void *priv;
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
if (hport->connected) {
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
@@ -760,8 +760,9 @@ static void usbh_list_all_interface_driver(struct usbh_hub *hub)
{
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
+ const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
if (hport->connected) {
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
@@ -770,11 +771,12 @@ static void usbh_list_all_interface_driver(struct usbh_hub *hub)
USB_LOG_RAW("\t");
}
- USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s\r\n",
+ USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n",
hport->port,
hport->dev_addr,
itf,
- hport->config.intf[itf].class_driver->driver_name);
+ hport->config.intf[itf].class_driver->driver_name,
+ speed_table[hport->speed]);
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
hub_next = hport->config.intf[itf].priv;
@@ -794,7 +796,7 @@ static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
if (hport->connected) {
USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
@@ -888,7 +890,7 @@ int lsusb(int argc, char **argv)
USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
bus->busid,
hub->index,
- hub->hub_desc.bNbrPorts);
+ hub->nports);
usbh_list_all_interface_driver(hub);
}
}
diff --git a/components/drivers/usb/cherryusb/core/usbh_core.h b/components/drivers/usb/cherryusb/core/usbh_core.h
index 3210988575..6674fcb495 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_version.h"
#ifdef __cplusplus
extern "C" {
@@ -101,6 +102,9 @@ struct usbh_hubport {
uint8_t port; /* Hub port index */
uint8_t dev_addr; /* device address */
uint8_t speed; /* device speed */
+ uint8_t depth; /* distance from root hub */
+ uint8_t route; /* route string */
+ uint8_t slot_id; /* slot id */
struct usb_device_descriptor device_desc;
struct usbh_configuration config;
const char *iManufacturer;
@@ -109,6 +113,7 @@ struct usbh_hubport {
uint8_t *raw_config_desc;
struct usb_setup_packet *setup;
struct usbh_hub *parent;
+ struct usbh_hub *self; /* if this hubport is a hub */
struct usbh_bus *bus;
struct usb_endpoint_descriptor ep0;
struct usbh_urb ep0_urb;
@@ -120,7 +125,13 @@ struct usbh_hub {
bool is_roothub;
uint8_t index;
uint8_t hub_addr;
- struct usb_hub_descriptor hub_desc;
+ uint8_t speed;
+ uint8_t nports;
+ uint8_t powerdelay;
+ uint8_t tt_think;
+ bool ismtt;
+ struct usb_hub_descriptor hub_desc; /* USB 2.0 only */
+ struct usb_hub_ss_descriptor hub_ss_desc; /* USB 3.0 only */
struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS];
struct usbh_hubport *parent;
struct usbh_bus *bus;
@@ -143,9 +154,9 @@ struct usbh_devaddr_map {
};
struct usbh_hcd {
- uint32_t reg_base;
+ uintptr_t reg_base;
uint8_t hcd_id;
- uint8_t roothub_intbuf[1];
+ uint8_t roothub_intbuf[2]; /* at most 15 roothub ports */
struct usbh_hub roothub;
};
@@ -261,7 +272,7 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
*/
int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting);
-int usbh_initialize(uint8_t busid, uint32_t reg_base);
+int usbh_initialize(uint8_t busid, uintptr_t reg_base);
int usbh_deinitialize(uint8_t busid);
void *usbh_find_class_instance(const char *devname);
diff --git a/components/drivers/usb/cherryusb/demo/adb/cherryadb.png b/components/drivers/usb/cherryusb/demo/adb/cherryadb.png
new file mode 100644
index 0000000000..512586b954
Binary files /dev/null and b/components/drivers/usb/cherryusb/demo/adb/cherryadb.png differ
diff --git a/components/drivers/usb/cherryusb/demo/adb/cherrysh_port.c b/components/drivers/usb/cherryusb/demo/adb/cherrysh_port.c
new file mode 100644
index 0000000000..85971724f7
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/adb/cherrysh_port.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "event_groups.h"
+#include "csh.h"
+#include "usbd_core.h"
+#include "usbd_adb.h"
+#include "chry_ringbuffer.h"
+
+static chry_ringbuffer_t shell_rb;
+static uint8_t mempool[1024];
+
+#ifndef task_repl_PRIORITY
+#define task_repl_PRIORITY (configMAX_PRIORITIES - 4U)
+#endif
+
+#ifndef task_exec_PRIORITY
+#define task_exec_PRIORITY (configMAX_PRIORITIES - 5U)
+#endif
+
+static chry_shell_t csh;
+static volatile bool login = false;
+
+static StaticTask_t task_buffer_repl;
+static StaticTask_t task_buffer_exec;
+
+static StackType_t task_stack_repl[1024];
+static StackType_t task_stack_exec[1024];
+
+static TaskHandle_t task_hdl_repl = NULL;
+static TaskHandle_t task_hdl_exec = NULL;
+
+static EventGroupHandle_t event_hdl;
+static StaticEventGroup_t event_grp;
+
+void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len)
+{
+ chry_ringbuffer_write(&shell_rb, data, len);
+
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xEventGroupSetBitsFromISR(event_hdl, 0x10, &xHigherPriorityTaskWoken);
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+}
+
+void usbd_adb_notify_write_done(void)
+{
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xEventGroupSetBitsFromISR(event_hdl, 0x20, &xHigherPriorityTaskWoken);
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+}
+
+static uint16_t csh_sput_cb(chry_readline_t *rl, const void *data, uint16_t size)
+{
+ (void)rl;
+
+ if (!usb_device_is_configured(0)) {
+ return size;
+ }
+
+ if (usbd_adb_can_write() && size) {
+ usbd_abd_write(ADB_SHELL_LOALID, data, size);
+ xEventGroupWaitBits(event_hdl, 0x20, pdTRUE, pdFALSE, portMAX_DELAY);
+ }
+
+ return size;
+}
+
+static uint16_t csh_sget_cb(chry_readline_t *rl, void *data, uint16_t size)
+{
+ (void)rl;
+
+ return chry_ringbuffer_read(&shell_rb, data, size);
+}
+
+static void wait_char(void)
+{
+ EventBits_t event;
+wait:
+ /* In order to lock the log from being disrupted , wait for REPL task execution to complete */
+ event = xEventGroupWaitBits(event_hdl, (0x10 | 0x01 | 0x04), pdTRUE, pdFALSE, portMAX_DELAY);
+ if ((event & 0x10) == 0) {
+ if (event & 0x01) {
+ chry_readline_erase_line(&csh.rl);
+ xEventGroupSetBits(event_hdl, 0x02);
+ }
+ if (event & 0x04) {
+ chry_readline_edit_refresh(&csh.rl);
+ xEventGroupSetBits(event_hdl, 0x08);
+ }
+
+ goto wait;
+ }
+}
+
+static void task_repl(void *param)
+{
+ (void)param;
+ int ret;
+ volatile uint8_t *pexec = (void *)&csh.exec;
+
+ for (;;) {
+ restart:
+ if (login) {
+ goto repl;
+ } else {
+ }
+
+ ret = csh_login(&csh);
+ if (ret == 0) {
+ login = true;
+ } else if (ret == 1) {
+ /*!< no enough char */
+ wait_char();
+ continue;
+ } else {
+ continue;
+ }
+
+ repl:
+ ret = chry_shell_task_repl(&csh);
+
+ if (ret == -1) {
+ /*!< error */
+ goto restart;
+ } else if (ret == 1) {
+ /*!< no enough char */
+ wait_char();
+ } else {
+ /*!< restart */
+ }
+
+ /*!< check flag */
+ if (*pexec == CSH_STATUS_EXEC_DONE) {
+ *pexec = CSH_STATUS_EXEC_IDLE;
+ chry_readline_auto_refresh(&csh.rl, true);
+ chry_readline_ignore(&csh.rl, false);
+ chry_readline_edit_refresh(&csh.rl);
+ }
+
+ if (login == false) {
+ chry_readline_erase_line(&csh.rl);
+ csh.rl.noblock = false;
+ }
+ }
+}
+
+static void task_exec(void *param)
+{
+ (void)param;
+
+ /*!< execute shell command */
+ chry_shell_task_exec(&csh);
+
+ /*!< notify REPL task execute done */
+ xEventGroupSetBits(event_hdl, 0x10);
+
+ /*!< wait for REPL task delete */
+ vTaskSuspend(NULL);
+}
+
+int chry_shell_port_create_context(chry_shell_t *csh, int argc, const char **argv)
+{
+ volatile TaskHandle_t *p_task_hdl_exec = (void *)&task_hdl_exec;
+ (void)csh;
+ (void)argc;
+ (void)argv;
+
+ if (*p_task_hdl_exec != NULL) {
+ vTaskDelete(*p_task_hdl_exec);
+ }
+
+ *p_task_hdl_exec = xTaskCreateStatic(task_exec, "task_exec", 1024U, NULL, task_exec_PRIORITY, task_stack_exec, &task_buffer_exec);
+ return 0;
+}
+
+void chry_shell_port_default_handler(chry_shell_t *csh, int sig)
+{
+ volatile uint8_t *pexec = (void *)&csh->exec;
+ volatile TaskHandle_t *p_task_hdl_exec = (void *)&task_hdl_exec;
+
+ switch (sig) {
+ case CSH_SIGINT:
+ case CSH_SIGQUIT:
+ case CSH_SIGKILL:
+ case CSH_SIGTERM:
+ break;
+ default:
+ return;
+ }
+
+ /*!< force delete task */
+ if (*p_task_hdl_exec != NULL) {
+ vTaskDelete(task_hdl_exec);
+ *p_task_hdl_exec = NULL;
+ }
+
+ switch (sig) {
+ case CSH_SIGINT:
+ csh->rl.sput(&csh->rl, "^SIGINT" CONFIG_CSH_NEWLINE, sizeof("^SIGINT" CONFIG_CSH_NEWLINE) - 1);
+ break;
+ case CSH_SIGQUIT:
+ csh->rl.sput(&csh->rl, "^SIGQUIT" CONFIG_CSH_NEWLINE, sizeof("^SIGQUIT" CONFIG_CSH_NEWLINE) - 1);
+ break;
+ case CSH_SIGKILL:
+ csh->rl.sput(&csh->rl, "^SIGKILL" CONFIG_CSH_NEWLINE, sizeof("^SIGKILL" CONFIG_CSH_NEWLINE) - 1);
+ break;
+ case CSH_SIGTERM:
+ csh->rl.sput(&csh->rl, "^SIGTERM" CONFIG_CSH_NEWLINE, sizeof("^SIGTERM" CONFIG_CSH_NEWLINE) - 1);
+ break;
+ default:
+ return;
+ }
+
+ *pexec = CSH_STATUS_EXEC_IDLE;
+ chry_readline_auto_refresh(&csh->rl, true);
+ chry_readline_ignore(&csh->rl, false);
+ chry_readline_edit_refresh(&csh->rl);
+}
+
+int shell_init(bool need_login)
+{
+ chry_shell_init_t csh_init;
+
+ if (chry_ringbuffer_init(&shell_rb, mempool, sizeof(mempool))) {
+ return -1;
+ }
+
+ if (need_login) {
+ login = false;
+ } else {
+ login = true;
+ }
+
+ /*!< I/O callback */
+ csh_init.sput = csh_sput_cb;
+ csh_init.sget = csh_sget_cb;
+
+#if defined(CONFIG_CSH_SYMTAB) && CONFIG_CSH_SYMTAB
+ extern const int __fsymtab_start;
+ extern const int __fsymtab_end;
+ extern const int __vsymtab_start;
+ extern const int __vsymtab_end;
+
+ /*!< get table from ld symbol */
+ csh_init.command_table_beg = &__fsymtab_start;
+ csh_init.command_table_end = &__fsymtab_end;
+ csh_init.variable_table_beg = &__vsymtab_start;
+ csh_init.variable_table_end = &__vsymtab_end;
+#endif
+
+#if defined(CONFIG_CSH_PROMPTEDIT) && CONFIG_CSH_PROMPTEDIT
+ static char csh_prompt_buffer[128];
+
+ /*!< set prompt buffer */
+ csh_init.prompt_buffer = csh_prompt_buffer;
+ csh_init.prompt_buffer_size = sizeof(csh_prompt_buffer);
+#endif
+
+#if defined(CONFIG_CSH_HISTORY) && CONFIG_CSH_HISTORY
+ static char csh_history_buffer[128];
+
+ /*!< set history buffer */
+ csh_init.history_buffer = csh_history_buffer;
+ csh_init.history_buffer_size = sizeof(csh_history_buffer);
+#endif
+
+#if defined(CONFIG_CSH_LNBUFF_STATIC) && CONFIG_CSH_LNBUFF_STATIC
+ static char csh_line_buffer[128];
+
+ /*!< set linebuffer */
+ csh_init.line_buffer = csh_line_buffer;
+ csh_init.line_buffer_size = sizeof(csh_line_buffer);
+#endif
+
+ csh_init.uid = 0;
+ csh_init.user[0] = "cherry";
+
+ /*!< The port hash function is required,
+ and the strcmp attribute is used weakly by default,
+ int chry_shell_port_hash_strcmp(const char *hash, const char *str); */
+ csh_init.hash[0] = "12345678"; /*!< If there is no password, set to NULL */
+ csh_init.host = "cherryadb";
+ csh_init.user_data = NULL;
+
+ int ret = chry_shell_init(&csh, &csh_init);
+ if (ret) {
+ return -1;
+ }
+
+ task_hdl_exec = NULL;
+ event_hdl = xEventGroupCreateStatic(&event_grp);
+ task_hdl_repl = xTaskCreateStatic(task_repl, "task_repl", 1024U, NULL, task_repl_PRIORITY, task_stack_repl, &task_buffer_repl);
+
+ return 0;
+}
+
+void shell_lock(void)
+{
+ xEventGroupSetBits(event_hdl, 0x01);
+ xEventGroupWaitBits(event_hdl, 0x02, pdTRUE, pdTRUE, portMAX_DELAY);
+}
+
+void shell_unlock(void)
+{
+ xEventGroupSetBits(event_hdl, 0x04);
+ xEventGroupWaitBits(event_hdl, 0x08, pdTRUE, pdTRUE, portMAX_DELAY);
+}
+
+static int csh_exit(int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+
+ usbd_adb_close(ADB_SHELL_LOALID);
+
+ return 0;
+}
+CSH_SCMD_EXPORT_ALIAS(csh_exit, exit, );
+
+#define __ENV_PATH "/sbin:/bin"
+const char ENV_PATH[] = __ENV_PATH;
+CSH_RVAR_EXPORT(ENV_PATH, PATH, sizeof(__ENV_PATH));
+
+#define __ENV_ZERO ""
+const char ENV_ZERO[] = __ENV_ZERO;
+CSH_RVAR_EXPORT(ENV_ZERO, ZERO, sizeof(__ENV_ZERO));
diff --git a/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c b/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c
new file mode 100644
index 0000000000..0c367d8aca
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usbd_adb.h"
+
+/*!< endpoint address */
+#define WINUSB_IN_EP 0x81
+#define WINUSB_OUT_EP 0x02
+
+#define USBD_VID 0xFFFF
+#define USBD_PID 0xFFFF
+#define USBD_MAX_POWER 100
+#define USBD_LANGID_STRING 1033
+
+/*!< config descriptor size */
+#define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
+
+#ifdef CONFIG_USB_HS
+#define WINUSB_MAX_MPS 512
+#else
+#define WINUSB_MAX_MPS 64
+#endif
+
+#define WCID_VENDOR_CODE 0x17
+#define ADB_INTF_NUM 0
+
+__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
+ ///////////////////////////////////////
+ /// MS OS string descriptor
+ ///////////////////////////////////////
+ 0x12, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ /* MSFT100 */
+ 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
+ '1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */
+ WCID_VENDOR_CODE, /* bVendorCode */
+ 0x00, /* bReserved */
+};
+
+__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
+ ///////////////////////////////////////
+ /// WCID descriptor
+ ///////////////////////////////////////
+ 0x28, 0x00, 0x00, 0x00, /* dwLength */
+ 0x00, 0x01, /* bcdVersion */
+ 0x04, 0x00, /* wIndex */
+ 0x01, /* bCount */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
+
+ ///////////////////////////////////////
+ /// WCID function descriptor
+ ///////////////////////////////////////
+ ADB_INTF_NUM, /* bFirstInterfaceNumber */
+ 0x01, /* bReserved */
+ /* Compatible ID */
+ 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8: WINUSB */
+ /* */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
+};
+
+__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties[142] __ALIGN_END = {
+ ///////////////////////////////////////
+ /// WCID property descriptor
+ ///////////////////////////////////////
+ 0x8e, 0x00, 0x00, 0x00, /* dwLength */
+ 0x00, 0x01, /* bcdVersion */
+ 0x05, 0x00, /* wIndex */
+ 0x01, 0x00, /* wCount */
+
+ ///////////////////////////////////////
+ /// registry propter descriptor
+ ///////////////////////////////////////
+ 0x84, 0x00, 0x00, 0x00, /* dwSize */
+ 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
+ 0x28, 0x00, /* wPropertyNameLength */
+ /* DeviceInterfaceGUID */
+ 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
+ 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
+ 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
+ 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
+ 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
+ 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
+ /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
+ '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
+ 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
+ '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
+ '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
+ '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
+ 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
+ '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
+ 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
+ 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
+ '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
+};
+
+const uint8_t *WINUSB_IFx_WCIDProperties[] = {
+ WINUSB_IF0_WCIDProperties,
+};
+
+struct usb_msosv1_descriptor msosv1_desc = {
+ .string = WCID_StringDescriptor_MSOS,
+ .vendor_code = WCID_VENDOR_CODE,
+ .compat_id = WINUSB_WCIDDescriptor,
+ .comp_id_property = WINUSB_IFx_WCIDProperties,
+};
+
+/*!< global descriptor */
+static const uint8_t adb_descriptor[] = {
+ USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
+ USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+ ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS),
+ ///////////////////////////////////////
+ /// string0 descriptor
+ ///////////////////////////////////////
+ USB_LANGID_INIT(USBD_LANGID_STRING),
+ ///////////////////////////////////////
+ /// string1 descriptor
+ ///////////////////////////////////////
+ 0x14, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
+ 0x14, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'A', 0x00, /* wcChar6 */
+ 'D', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ///////////////////////////////////////
+ /// string3 descriptor
+ ///////////////////////////////////////
+ 0x1C, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'A', 0x00, /* wcChar6 */
+ 'D', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ '2', 0x00, /* wcChar9 */
+ '0', 0x00, /* wcChar10 */
+ '2', 0x00, /* wcChar11 */
+ '4', 0x00, /* wcChar12 */
+#ifdef CONFIG_USB_HS
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x01,
+ 0x40,
+ 0x01,
+ 0x00,
+#endif
+ 0x00
+};
+
+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;
+ }
+}
+
+static struct usbd_interface intf0;
+
+extern int shell_init(bool need_login);
+void cherryadb_init(uint8_t busid, uint32_t reg_base)
+{
+ /* default password is : 12345678 */
+ /* shell_init() must be called in-task */
+ if (0 != shell_init(false)) {
+ /* shell failed to be initialized */
+ printf("Failed to initialize shell\r\n");
+ for (;;) {
+ ;
+ }
+ }
+
+ usbd_desc_register(busid, adb_descriptor);
+ 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 a80a221a68..b0d631e23b 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
@@ -212,7 +212,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
-void audio_v1_init(uint8_t busid, uint32_t reg_base)
+void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v1_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 1));
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 fbd53e31af..6275de1c98 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
@@ -238,7 +238,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
-void audio_v1_init(uint8_t busid, uint32_t reg_base)
+void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v1_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 2));
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 bf85762c7c..69fff0c566 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
@@ -229,7 +229,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
-void audio_v2_init(uint8_t busid, uint32_t reg_base)
+void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v2_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
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 e8afabe622..9bf4c2c5db 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
@@ -346,7 +346,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
-void audio_v2_init(uint8_t busid, uint32_t reg_base)
+void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v2_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4));
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 3fc7a48b1e..928aaaf6eb 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
@@ -247,7 +247,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
-void audio_v2_init(uint8_t busid, uint32_t reg_base)
+void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v2_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
diff --git a/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.c b/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.c
new file mode 100644
index 0000000000..c4c6ee5f67
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ * Copyright (c) 2024, Egahp
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "bootuf2.h"
+#include "usbd_core.h"
+
+char file_INFO[] = {
+ "CherryUSB UF2 BOOT\r\n"
+ "Model: " CONFIG_PRODUCT "\r\n"
+ "Board-ID: " CONFIG_BOARD "\r\n"
+};
+
+const char file_IDEX[] = {
+ "\n"
+ ""
+ ""
+ ""
+ ""
+ "\n"
+};
+
+const char file_JOIN[] = {
+ "\n"
+ ""
+ ""
+ ""
+ ""
+ "\n"
+};
+
+const char file_ID__[12] = BOOTUF2_FAMILYID_ARRAY;
+
+static struct bootuf2_FILE files[] = {
+ [0] = { .Name = file_ID__, .Content = NULL, .FileSize = 0 },
+ [1] = { .Name = "INFO_UF2TXT", .Content = file_INFO, .FileSize = sizeof(file_INFO) - 1 },
+ [2] = { .Name = "INDEX HTM", .Content = file_IDEX, .FileSize = sizeof(file_IDEX) - 1 },
+ [3] = { .Name = "JOIN HTM", .Content = file_JOIN, .FileSize = sizeof(file_JOIN) - 1 },
+};
+
+struct bootuf2_data {
+ const struct bootuf2_DBR *const DBR;
+ struct bootuf2_STATE *const STATE;
+ uint8_t *const fbuff;
+ uint8_t *const erase;
+ size_t page_count;
+ uint8_t *const cache;
+ const size_t cache_size;
+ uint32_t cached_address;
+ size_t cached_bytes;
+};
+
+/*!< define DBRs */
+static const struct bootuf2_DBR bootuf2_DBR = {
+ .JMPInstruction = { 0xEB, 0x3C, 0x90 },
+ .OEM = "UF2 UF2 ",
+ .BPB = {
+ .BytesPerSector = CONFIG_BOOTUF2_SECTOR_SIZE,
+ .SectorsPerCluster = CONFIG_BOOTUF2_SECTOR_PER_CLUSTER,
+ .ReservedSectors = CONFIG_BOOTUF2_SECTOR_RESERVED,
+ .NumberOfFAT = CONFIG_BOOTUF2_NUM_OF_FAT,
+ .RootEntries = CONFIG_BOOTUF2_ROOT_ENTRIES,
+ .Sectors = (BOOTUF2_SECTORS(0) > 0xFFFF) ? 0 : BOOTUF2_SECTORS(0),
+ .MediaDescriptor = 0xF8,
+ .SectorsPerFAT = BOOTUF2_SECTORS_PER_FAT(0),
+ .SectorsPerTrack = 1,
+ .Heads = 1,
+ .HiddenSectors = 0,
+ .SectorsOver32MB = (BOOTUF2_SECTORS(0) > 0xFFFF) ? BOOTUF2_SECTORS(0) : 0,
+ .BIOSDrive = 0x80,
+ .Reserved = 0,
+ .ExtendBootSignature = 0x29,
+ .VolumeSerialNumber = 0x00420042,
+ .VolumeLabel = "CHERRYUF2",
+ .FileSystem = "FAT16 ",
+ },
+};
+
+/*!< define mask */
+static uint8_t __attribute__((aligned(4))) bootuf2_mask[BOOTUF2_BLOCKSMAX / 8 + 1] = { 0 };
+
+/*!< define state */
+static struct bootuf2_STATE bootuf2_STATE = {
+ .NumberOfBlock = 0,
+ .NumberOfWritten = 0,
+ .Mask = bootuf2_mask,
+ .Enable = 1,
+};
+
+/*!< define flash cache */
+static uint8_t __attribute__((aligned(4))) bootuf2_disk_cache[CONFIG_BOOTUF2_CACHE_SIZE];
+
+/*!< define flash buff */
+static uint8_t __attribute__((aligned(4))) bootuf2_disk_fbuff[256];
+
+/*!< define erase flag buff */
+static uint8_t __attribute__((aligned(4))) bootuf2_disk_erase[BOOTUF2_DIVCEIL(CONFIG_BOOTUF2_PAGE_COUNTMAX, 8)];
+
+/*!< define disk */
+static struct bootuf2_data bootuf2_disk = {
+ .DBR = &bootuf2_DBR,
+ .STATE = &bootuf2_STATE,
+ .fbuff = bootuf2_disk_fbuff,
+ .erase = bootuf2_disk_erase,
+ .cache = bootuf2_disk_cache,
+ .cache_size = sizeof(bootuf2_disk_cache),
+};
+
+static void fname_copy(char *dst, char const *src, uint16_t len)
+{
+ for (size_t i = 0; i < len; ++i) {
+ if (*src)
+ *dst++ = *src++;
+ else
+ *dst++ = ' ';
+ }
+}
+
+static void fcalculate_cluster(struct bootuf2_data *ctx)
+{
+ /*!< init files cluster */
+ uint16_t cluster_beg = 2;
+ for (int i = 0; i < ARRAY_SIZE(files); i++) {
+ files[i].ClusterBeg = cluster_beg;
+ files[i].ClusterEnd = -1 + cluster_beg +
+ BOOTUF2_DIVCEIL(files[i].FileSize,
+ ctx->DBR->BPB.BytesPerSector *
+ ctx->DBR->BPB.SectorsPerCluster);
+ cluster_beg = files[i].ClusterEnd + 1;
+ }
+}
+
+static int ffind_by_cluster(uint32_t cluster)
+{
+ if (cluster >= 0xFFF0) {
+ return -1;
+ }
+
+ for (uint32_t i = 0; i < ARRAY_SIZE(files); i++) {
+ if ((files[i].ClusterBeg <= cluster) &&
+ (cluster <= files[i].ClusterEnd)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static bool bootuf2block_check_writable(struct bootuf2_STATE *STATE,
+ struct bootuf2_BLOCK *uf2, uint32_t block_max)
+{
+ if (uf2->NumberOfBlock) {
+ if (uf2->BlockIndex < block_max) {
+ uint8_t mask = 1 << (uf2->BlockIndex % 8);
+ uint32_t pos = uf2->BlockIndex / 8;
+
+ if ((STATE->Mask[pos] & mask) == 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static void bootuf2block_state_update(struct bootuf2_STATE *STATE,
+ struct bootuf2_BLOCK *uf2, uint32_t block_max)
+{
+ if (uf2->NumberOfBlock) {
+ if (STATE->NumberOfBlock != uf2->NumberOfBlock) {
+ if ((uf2->NumberOfBlock >= BOOTUF2_BLOCKSMAX) ||
+ STATE->NumberOfBlock) {
+ /*!< uf2 block only can be update once */
+ /*!< this will cause never auto reboot */
+ STATE->NumberOfBlock = 0xffffffff;
+ } else {
+ STATE->NumberOfBlock = uf2->NumberOfBlock;
+ }
+ }
+
+ if (uf2->BlockIndex < block_max) {
+ uint8_t mask = 1 << (uf2->BlockIndex % 8);
+ uint32_t pos = uf2->BlockIndex / 8;
+
+ if ((STATE->Mask[pos] & mask) == 0) {
+ STATE->Mask[pos] |= mask;
+ STATE->NumberOfWritten++;
+ }
+ }
+ }
+
+ USB_LOG_DBG("UF2 block total %d written %d index %d\r\n",
+ uf2->NumberOfBlock, STATE->NumberOfWritten, uf2->BlockIndex);
+}
+
+static bool bootuf2block_state_check(struct bootuf2_STATE *STATE)
+{
+ return (STATE->NumberOfWritten >= STATE->NumberOfBlock) &&
+ STATE->NumberOfBlock;
+}
+
+static int bootuf2_flash_flush(struct bootuf2_data *ctx)
+{
+ int err;
+
+ if (ctx->cached_bytes == 0) {
+ return 0;
+ }
+
+ err = bootuf2_flash_write(ctx->cached_address, ctx->cache, ctx->cached_bytes);
+
+ if (err) {
+ USB_LOG_ERR("UF2 slot flash write error %d at offset %08lx len %d\r\n",
+ err, ctx->cached_address, ctx->cached_bytes);
+ return -1;
+ }
+
+ ctx->cached_bytes = 0;
+
+ return 0;
+}
+
+int bootuf2_flash_write_internal(struct bootuf2_data *ctx, struct bootuf2_BLOCK *uf2)
+{
+ /*!< 1.cache not empty and address not continue */
+ /*!< 2.cache full */
+ if ((ctx->cached_bytes && ((ctx->cached_address + ctx->cached_bytes) != uf2->TargetAddress)) ||
+ (ctx->cached_bytes == ctx->cache_size)) {
+ int err = bootuf2_flash_flush(ctx);
+ if (err)
+ return err;
+ }
+
+ /*!< write len always is 256, cache_size always is a multiple of 256 */
+ memcpy(ctx->cache + ctx->cached_bytes, uf2->Data, uf2->PayloadSize);
+
+ ctx->cached_address = uf2->TargetAddress - ctx->cached_bytes;
+ ctx->cached_bytes += uf2->PayloadSize;
+
+ return 0;
+}
+
+void bootuf2_init(void)
+{
+ struct bootuf2_data *ctx;
+
+ ctx = &bootuf2_disk;
+
+ fcalculate_cluster(ctx);
+
+ ctx->cached_bytes = 0;
+ ctx->cached_address = 0;
+}
+
+int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count)
+{
+ struct bootuf2_data *ctx;
+
+ ctx = &bootuf2_disk;
+
+ while (sector_count) {
+ memset(buff, 0, ctx->DBR->BPB.BytesPerSector);
+
+ uint32_t sector_relative = start_sector;
+
+ /*!< DBR sector */
+ if (start_sector == BOOTUF2_SECTOR_DBR_END) {
+ memcpy(buff, ctx->DBR, sizeof(struct bootuf2_DBR));
+ buff[510] = 0x55;
+ buff[511] = 0xaa;
+ }
+ /*!< FAT sector */
+ else if (start_sector < BOOTUF2_SECTOR_FAT_END(ctx->DBR)) {
+ uint16_t *buff16 = (uint16_t *)buff;
+
+ sector_relative -= BOOTUF2_SECTOR_RSVD_END(ctx->DBR);
+
+ /*!< Perform the same operation on all FAT tables */
+ while (sector_relative >= ctx->DBR->BPB.SectorsPerFAT) {
+ sector_relative -= ctx->DBR->BPB.SectorsPerFAT;
+ }
+
+ uint16_t cluster_unused = files[ARRAY_SIZE(files) - 1].ClusterEnd + 1;
+ uint16_t cluster_absolute_first = sector_relative *
+ BOOTUF2_FAT16_PER_SECTOR(ctx->DBR);
+
+ /*!< cluster used link to chain, or unsed */
+ for (uint16_t i = 0, cluster_absolute = cluster_absolute_first;
+ i < BOOTUF2_FAT16_PER_SECTOR(ctx->DBR);
+ i++, cluster_absolute++) {
+ if (cluster_absolute >= cluster_unused)
+ buff16[i] = 0;
+ else
+ buff16[i] = cluster_absolute + 1;
+ }
+
+ /*!< cluster 0 and 1 */
+ if (sector_relative == 0) {
+ buff[0] = ctx->DBR->BPB.MediaDescriptor;
+ buff[1] = 0xff;
+ buff16[1] = 0xffff;
+ }
+
+ /*!< cluster end of file */
+ for (uint32_t i = 0; i < ARRAY_SIZE(files); i++) {
+ uint16_t cluster_file_last = files[i].ClusterEnd;
+
+ if (cluster_file_last >= cluster_absolute_first) {
+ uint16_t idx = cluster_file_last - cluster_absolute_first;
+ if (idx < BOOTUF2_FAT16_PER_SECTOR(ctx->DBR)) {
+ buff16[idx] = 0xffff;
+ }
+ }
+ }
+ }
+ /*!< root entries */
+ else if (start_sector < BOOTUF2_SECTOR_ROOT_END(ctx->DBR)) {
+ sector_relative -= BOOTUF2_SECTOR_FAT_END(ctx->DBR);
+
+ struct bootuf2_ENTRY *ent = (void *)buff;
+ int remain_entries = BOOTUF2_ENTRY_PER_SECTOR(ctx->DBR);
+
+ uint32_t file_index_first;
+
+ /*!< volume label entry */
+ if (sector_relative == 0) {
+ fname_copy(ent->Name, (char const *)ctx->DBR->BPB.VolumeLabel, 11);
+ ent->Attribute = 0x28;
+ ent++;
+ remain_entries--;
+ file_index_first = 0;
+ } else {
+ /*!< -1 to account for volume label in first sector */
+ file_index_first = sector_relative * BOOTUF2_ENTRY_PER_SECTOR(ctx->DBR) - 1;
+ }
+
+ for (uint32_t idx = file_index_first;
+ (remain_entries > 0) && (idx < ARRAY_SIZE(files));
+ idx++, ent++) {
+ const uint32_t cluster_beg = files[idx].ClusterBeg;
+
+ const struct bootuf2_FILE *f = &files[idx];
+
+ if ((0 == f->FileSize) &&
+ (0 != idx)) {
+ continue;
+ }
+
+ fname_copy(ent->Name, f->Name, 11);
+ ent->Attribute = 0x05;
+ ent->CreateTimeTeenth = BOOTUF2_SECONDS_INT % 2 * 100;
+ ent->CreateTime = BOOTUF2_DOS_TIME;
+ ent->CreateDate = BOOTUF2_DOS_DATE;
+ ent->LastAccessDate = BOOTUF2_DOS_DATE;
+ ent->FirstClustH16 = cluster_beg >> 16;
+ ent->UpdateTime = BOOTUF2_DOS_TIME;
+ ent->UpdateDate = BOOTUF2_DOS_DATE;
+ ent->FirstClustL16 = cluster_beg & 0xffff;
+ ent->FileSize = f->FileSize;
+ }
+ }
+ /*!< data */
+ else if (start_sector < BOOTUF2_SECTOR_DATA_END(ctx->DBR)) {
+ sector_relative -= BOOTUF2_SECTOR_ROOT_END(ctx->DBR);
+
+ int fid = ffind_by_cluster(2 + sector_relative / ctx->DBR->BPB.SectorsPerCluster);
+
+ if (fid >= 0) {
+ const struct bootuf2_FILE *f = &files[fid];
+
+ uint32_t sector_relative_file =
+ sector_relative -
+ (files[fid].ClusterBeg - 2) * ctx->DBR->BPB.SectorsPerCluster;
+
+ size_t fcontent_offset = sector_relative_file * ctx->DBR->BPB.BytesPerSector;
+ size_t fcontent_length = f->FileSize;
+
+ if (fcontent_length > fcontent_offset) {
+ const void *src = (void *)((uint8_t *)(f->Content) + fcontent_offset);
+ size_t copy_size = fcontent_length - fcontent_offset;
+
+ if (copy_size > ctx->DBR->BPB.BytesPerSector) {
+ copy_size = ctx->DBR->BPB.BytesPerSector;
+ }
+
+ memcpy(buff, src, copy_size);
+ }
+ }
+ }
+ /*!< unknown sector, ignore */
+
+ start_sector++;
+ sector_count--;
+ buff += ctx->DBR->BPB.BytesPerSector;
+ }
+
+ return 0;
+}
+
+int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t sector_count)
+{
+ struct bootuf2_data *ctx;
+
+ ctx = &bootuf2_disk;
+
+ while (sector_count) {
+ struct bootuf2_BLOCK *uf2 = (void *)buff;
+
+ if (!((uf2->MagicStart0 == BOOTUF2_MAGIC_START0) &&
+ (uf2->MagicStart1 == BOOTUF2_MAGIC_START1) &&
+ (uf2->MagicEnd == BOOTUF2_MAGIC_END) &&
+ (uf2->Flags & BOOTUF2_FLAG_FAMILID_PRESENT) &&
+ !(uf2->Flags & BOOTUF2_FLAG_NOT_MAIN_FLASH))) {
+ goto next;
+ }
+
+ if (uf2->FamilyID == CONFIG_BOOTUF2_FAMILYID) {
+ if (bootuf2block_check_writable(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX)) {
+ bootuf2_flash_write_internal(ctx, uf2);
+ bootuf2block_state_update(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX);
+ } else {
+ USB_LOG_DBG("UF2 block %d already written\r\n",
+ uf2->BlockIndex);
+ }
+ } else {
+ USB_LOG_DBG("UF2 block illegal id %08x\r\n", uf2->FamilyID);
+ }
+
+ next:
+ start_sector++;
+ sector_count--;
+ buff += ctx->DBR->BPB.BytesPerSector;
+ }
+
+ return 0;
+}
+
+uint16_t bootuf2_get_sector_size(void)
+{
+ return bootuf2_disk.DBR->BPB.BytesPerSector;
+}
+
+uint32_t bootuf2_get_sector_count(void)
+{
+ return bootuf2_disk.DBR->BPB.SectorsOver32MB + bootuf2_disk.DBR->BPB.Sectors;
+}
+
+bool bootuf2_is_write_done(void)
+{
+ if (bootuf2block_state_check(bootuf2_disk.STATE)) {
+ bootuf2_flash_flush(&bootuf2_disk);
+ USB_LOG_DBG("UF2 update ok\r\n");
+ return true;
+ } else {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.h b/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.h
new file mode 100644
index 0000000000..ec31d3ea79
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ * Copyright (c) 2024, Egahp
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef BOOTUF2_H
+#define BOOTUF2_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifndef __PACKED
+#define __PACKED __attribute__((packed))
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array) \
+ ((int)((sizeof(array) / sizeof((array)[0]))))
+#endif
+
+struct bootuf2_BLOCK
+{
+ // 32 byte header
+ uint32_t MagicStart0;
+ uint32_t MagicStart1;
+ uint32_t Flags;
+ uint32_t TargetAddress;
+ uint32_t PayloadSize;
+ uint32_t BlockIndex;
+ uint32_t NumberOfBlock;
+ uint32_t FamilyID; // or file_size
+ uint8_t Data[476];
+ uint32_t MagicEnd;
+} __PACKED;
+//BUILD_ASSERT(sizeof(struct bootuf2_BLOCK) == 512, "bootuf2_BLOCK not sector sized");
+
+struct bootuf2_STATE
+{
+ uint32_t NumberOfBlock;
+ uint32_t NumberOfWritten;
+ uint8_t *const Mask;
+ uint8_t Enable;
+};
+
+struct bootuf2_DBR
+{
+ /*!< offset 0 */
+ uint8_t JMPInstruction[3];
+ /*!< offset 3 */
+ uint8_t OEM[8];
+ /*!< offset 11 */
+ struct
+ {
+ uint16_t BytesPerSector;
+ uint8_t SectorsPerCluster;
+ uint16_t ReservedSectors;
+ uint8_t NumberOfFAT;
+ uint16_t RootEntries;
+ uint16_t Sectors;
+ uint8_t MediaDescriptor;
+ uint16_t SectorsPerFAT;
+ uint16_t SectorsPerTrack;
+ uint16_t Heads;
+ uint32_t HiddenSectors;
+ uint32_t SectorsOver32MB;
+ uint8_t BIOSDrive;
+ uint8_t Reserved;
+ uint8_t ExtendBootSignature;
+ uint32_t VolumeSerialNumber;
+ uint8_t VolumeLabel[11];
+ uint8_t FileSystem[8];
+ } __PACKED BPB;
+ /*!< offset 62 */
+ /*!< BootLoader */
+ /*!< offset 511 */
+ /*!< 0x55 0xAA */
+} __PACKED;
+//BUILD_ASSERT(sizeof(struct bootuf2_DBR) == 62, "bootuf2_DBR size must be 62 byte");
+
+struct bootuf2_ENTRY
+{
+ char Name[11];
+ uint8_t Attribute;
+ uint8_t NTReserved;
+ uint8_t CreateTimeTeenth;
+ uint16_t CreateTime;
+ uint16_t CreateDate;
+ uint16_t LastAccessDate;
+ uint16_t FirstClustH16;
+ uint16_t UpdateTime;
+ uint16_t UpdateDate;
+ uint16_t FirstClustL16;
+ uint32_t FileSize;
+} __PACKED;
+//BUILD_ASSERT(sizeof(struct bootuf2_ENTRY) == 32, "bootuf2_ENTRY size must be 32 byte");
+
+struct bootuf2_FILE
+{
+ const char *const Name;
+ const void *const Content;
+ uint32_t FileSize;
+ uint16_t ClusterBeg;
+ uint16_t ClusterEnd;
+};
+
+#define BOOTUF2_DIVCEIL(_v, _d) (((_v) / (_d)) + ((_v) % (_d) ? 1 : 0))
+
+#define BOOTUF2_MAGIC_START0 0x0A324655u
+#define BOOTUF2_MAGIC_START1 0x9E5D5157u
+#define BOOTUF2_MAGIC_SERIAL 0x251B18BDu
+#define BOOTUF2_MAGIC_END 0x0AB16F30u
+
+#define BOOTUF2_FLAG_NOT_MAIN_FLASH 0x00000001u
+#define BOOTUF2_FLAG_FILE_CONTAINER 0x00001000u
+#define BOOTUF2_FLAG_FAMILID_PRESENT 0x00002000u
+#define BOOTUF2_FLAG_MD5_PRESENT 0x00004000u
+
+#define BOOTUF2_CMD_READ 0
+#define BOOTUF2_CMD_SYNC 1
+
+#define BOOTUF2_BLOCKSMAX (((CONFIG_BOOTUF2_FLASHMAX) / 256) + (((CONFIG_BOOTUF2_FLASHMAX) % 256) ? 1 : 0))
+
+#define BOOTUF2_FAMILYID_POSNUM(n) (((CONFIG_BOOTUF2_FAMILYID) / (0x10000000 >> ((n) * 4))) % 0x10)
+#define BOOTUF2_FAMILYID_ARRAY \
+ { \
+ ((BOOTUF2_FAMILYID_POSNUM(0) >= 10) ? BOOTUF2_FAMILYID_POSNUM(0) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(0) + '0'), \
+ ((BOOTUF2_FAMILYID_POSNUM(1) >= 10) ? BOOTUF2_FAMILYID_POSNUM(1) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(1) + '0'), \
+ ((BOOTUF2_FAMILYID_POSNUM(2) >= 10) ? BOOTUF2_FAMILYID_POSNUM(2) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(2) + '0'), \
+ ((BOOTUF2_FAMILYID_POSNUM(3) >= 10) ? BOOTUF2_FAMILYID_POSNUM(3) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(3) + '0'), \
+ ((BOOTUF2_FAMILYID_POSNUM(4) >= 10) ? BOOTUF2_FAMILYID_POSNUM(4) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(4) + '0'), \
+ ((BOOTUF2_FAMILYID_POSNUM(5) >= 10) ? BOOTUF2_FAMILYID_POSNUM(5) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(5) + '0'), \
+ ((BOOTUF2_FAMILYID_POSNUM(6) >= 10) ? BOOTUF2_FAMILYID_POSNUM(6) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(6) + '0'), \
+ ((BOOTUF2_FAMILYID_POSNUM(7) >= 10) ? BOOTUF2_FAMILYID_POSNUM(7) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(7) + '0'), \
+ ('I'), \
+ ('D'), \
+ (' '), \
+ ('\0'), \
+ };
+
+#define BOOTUF2_FAT16_PER_SECTOR(pDBR) (pDBR->BPB.BytesPerSector / 2)
+#define BOOTUF2_ENTRY_PER_SECTOR(pDBR) (pDBR->BPB.BytesPerSector / sizeof(struct bootuf2_ENTRY))
+#define BOOTUF2_CLUSTERSMAX (0xFFF0 - 2)
+#define BOOTUF2_SECTOR_DBR_END (0)
+#define BOOTUF2_SECTOR_RSVD_END(pDBR) BOOTUF2_SECTOR_DBR_END + (pDBR->BPB.ReservedSectors)
+#define BOOTUF2_SECTOR_FAT_END(pDBR) BOOTUF2_SECTOR_RSVD_END(pDBR) + (pDBR->BPB.SectorsPerFAT * pDBR->BPB.NumberOfFAT)
+#define BOOTUF2_SECTOR_ROOT_END(pDBR) BOOTUF2_SECTOR_FAT_END(pDBR) + (pDBR->BPB.RootEntries / (pDBR->BPB.BytesPerSector / sizeof(struct bootuf2_ENTRY)))
+#define BOOTUF2_SECTOR_DATA_END(pDBR) (pDBR->BPB.Sectors + pDBR->BPB.SectorsOver32MB)
+
+#define BOOTUF2_SECTORS_PER_FAT(n) \
+ BOOTUF2_DIVCEIL(BOOTUF2_CLUSTERSMAX, (CONFIG_BOOTUF2_SECTOR_SIZE / 2))
+#define BOOTUF2_SECTORS_FOR_ENTRIES(n) \
+ (CONFIG_BOOTUF2_ROOT_ENTRIES / (CONFIG_BOOTUF2_SECTOR_SIZE / sizeof(struct bootuf2_ENTRY)))
+#define BOOTUF2_SECTORS(n) \
+ (CONFIG_BOOTUF2_SECTOR_RESERVED + \
+ CONFIG_BOOTUF2_NUM_OF_FAT * BOOTUF2_SECTORS_PER_FAT(n) + \
+ BOOTUF2_SECTORS_FOR_ENTRIES(n) + \
+ BOOTUF2_CLUSTERSMAX * CONFIG_BOOTUF2_SECTOR_PER_CLUSTER)
+
+#define BOOTUF2_YEAR_INT ( \
+ (__DATE__[7u] - '0') * 1000u + \
+ (__DATE__[8u] - '0') * 100u + \
+ (__DATE__[9u] - '0') * 10u + \
+ (__DATE__[10u] - '0') * 1u)
+
+#define BOOTUF2_MONTH_INT ( \
+ (__DATE__[2u] == 'n' && __DATE__[1u] == 'a') ? 1u /*Jan*/ \
+ : (__DATE__[2u] == 'b') ? 2u /*Feb*/ \
+ : (__DATE__[2u] == 'r' && __DATE__[1u] == 'a') ? 3u /*Mar*/ \
+ : (__DATE__[2u] == 'r') ? 4u /*Apr*/ \
+ : (__DATE__[2u] == 'y') ? 5u /*May*/ \
+ : (__DATE__[2u] == 'n') ? 6u /*Jun*/ \
+ : (__DATE__[2u] == 'l') ? 7u /*Jul*/ \
+ : (__DATE__[2u] == 'g') ? 8u /*Aug*/ \
+ : (__DATE__[2u] == 'p') ? 9u /*Sep*/ \
+ : (__DATE__[2u] == 't') ? 10u /*Oct*/ \
+ : (__DATE__[2u] == 'v') ? 11u /*Nov*/ \
+ : 12u /*Dec*/)
+
+#define BOOTUF2_DAY_INT ( \
+ (__DATE__[4u] == ' ' ? 0 : __DATE__[4u] - '0') * 10u + \
+ (__DATE__[5u] - '0'))
+
+#define BOOTUF2_HOUR_INT ( \
+ (__TIME__[0u] == '?' ? 0 : __TIME__[0u] - '0') * 10u + (__TIME__[1u] == '?' ? 0 : __TIME__[1u] - '0'))
+
+#define BOOTUF2_MINUTE_INT ( \
+ (__TIME__[3u] == '?' ? 0 : __TIME__[3u] - '0') * 10u + (__TIME__[4u] == '?' ? 0 : __TIME__[4u] - '0'))
+
+#define BOOTUF2_SECONDS_INT ( \
+ (__TIME__[6u] == '?' ? 0 : __TIME__[6u] - '0') * 10u + (__TIME__[7u] == '?' ? 0 : __TIME__[7u] - '0'))
+
+#define BOOTUF2_DOS_DATE ( \
+ ((BOOTUF2_YEAR_INT - 1980u) << 9u) | \
+ (BOOTUF2_MONTH_INT << 5u) | \
+ (BOOTUF2_DAY_INT << 0u))
+
+#define BOOTUF2_DOS_TIME ( \
+ (BOOTUF2_HOUR_INT << 11u) | \
+ (BOOTUF2_MINUTE_INT << 5u) | \
+ (BOOTUF2_SECONDS_INT << 0u))
+
+void bootuf2_init(void);
+int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count);
+int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t sector_count);
+uint16_t bootuf2_get_sector_size(void);
+uint32_t bootuf2_get_sector_count(void);
+
+bool bootuf2_is_write_done(void);
+
+void boot2uf2_flash_init(void);
+int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size);
+
+#endif /* BOOTUF2_H */
diff --git a/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2_config.h b/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2_config.h
new file mode 100644
index 0000000000..307d09d2d1
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2_config.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef BOOTUF2_CONFIG_H
+#define BOOTUF2_CONFIG_H
+
+#define CONFIG_PRODUCT "CherryUSB"
+#define CONFIG_BOARD "CherryUSB BOARD"
+#define CONFIG_BOOTUF2_INDEX_URL "https://github.com/cherry-embedded"
+#define CONFIG_BOOTUF2_JOIN_URL "http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GyH2M5XfWTHQzmZis4ClpgvfdObPrvtk&authKey=LmcLhfno%2BiW51wmgVC%2F8WoYwUXqiclzWDHMU1Jy1d6S8cECJ4Q7bfJ%2FTe67RLakI&noverify=0&group_code=642693751"
+
+#define CONFIG_BOOTUF2_CACHE_SIZE 4096
+#define CONFIG_BOOTUF2_SECTOR_SIZE 512
+#define CONFIG_BOOTUF2_SECTOR_PER_CLUSTER 2
+#define CONFIG_BOOTUF2_SECTOR_RESERVED 1
+#define CONFIG_BOOTUF2_NUM_OF_FAT 2
+#define CONFIG_BOOTUF2_ROOT_ENTRIES 64
+
+#define CONFIG_BOOTUF2_FAMILYID 0xFFFFFFFF
+#define CONFIG_BOOTUF2_FLASHMAX 0x800000
+#define CONFIG_BOOTUF2_PAGE_COUNTMAX 1024
+
+#endif
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/demo/bootuf2/cherryuf2.png b/components/drivers/usb/cherryusb/demo/bootuf2/cherryuf2.png
new file mode 100644
index 0000000000..aff7ee4df8
Binary files /dev/null and b/components/drivers/usb/cherryusb/demo/bootuf2/cherryuf2.png differ
diff --git a/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c b/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c
new file mode 100644
index 0000000000..7702e48f21
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usbd_msc.h"
+#include "bootuf2.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_bootuf2_descriptor[] = {
+ USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
+ USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+ MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
+ ///////////////////////////////////////
+ /// string0 descriptor
+ ///////////////////////////////////////
+ USB_LANGID_INIT(USBD_LANGID_STRING),
+ ///////////////////////////////////////
+ /// string1 descriptor
+ ///////////////////////////////////////
+ 0x14, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
+ 0x26, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ' ', 0x00, /* wcChar9 */
+ 'U', 0x00, /* wcChar10 */
+ 'F', 0x00, /* wcChar11 */
+ '2', 0x00, /* wcChar12 */
+ ' ', 0x00, /* wcChar13 */
+ 'D', 0x00, /* wcChar14 */
+ 'E', 0x00, /* wcChar15 */
+ 'M', 0x00, /* wcChar16 */
+ 'O', 0x00, /* wcChar17 */
+ ///////////////////////////////////////
+ /// string3 descriptor
+ ///////////////////////////////////////
+ 0x16, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ '2', 0x00, /* wcChar0 */
+ '0', 0x00, /* wcChar1 */
+ '2', 0x00, /* wcChar2 */
+ '2', 0x00, /* wcChar3 */
+ '1', 0x00, /* wcChar4 */
+ '2', 0x00, /* wcChar5 */
+ '3', 0x00, /* wcChar6 */
+ '4', 0x00, /* wcChar7 */
+ '5', 0x00, /* wcChar8 */
+ '6', 0x00, /* wcChar9 */
+#ifdef CONFIG_USB_HS
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+#endif
+ 0x00
+};
+
+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:
+ bootuf2_init();
+ 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 = bootuf2_get_sector_count();
+ *block_size = bootuf2_get_sector_size();
+
+ USB_LOG_INFO("sector count:%d, sector size:%d\n", *block_num, *block_size);
+}
+int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
+{
+ boot2uf2_read_sector(sector, buffer, length / bootuf2_get_sector_size());
+ return 0;
+}
+
+int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
+{
+ bootuf2_write_sector(sector, buffer, length / bootuf2_get_sector_size());
+ return 0;
+}
+
+static struct usbd_interface intf0;
+
+void msc_bootuf2_init(uint8_t busid, uintptr_t reg_base)
+{
+ boot2uf2_flash_init();
+ usbd_desc_register(busid, msc_bootuf2_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);
+}
+
+void boot2uf2_flash_init(void)
+{
+}
+
+int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size)
+{
+ USB_LOG_INFO("address:%08x, size:%d\n", address, size);
+ return 0;
+}
\ No newline at end of file
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 93a3dc1391..e64a0a52f9 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
@@ -5,7 +5,7 @@
*/
#include "usbd_core.h"
#include "usbd_msc.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_acm.h"
#include "usbd_hid.h"
/*!< endpoint address */
@@ -301,7 +301,7 @@ struct usbd_interface intf1;
struct usbd_interface intf2;
struct usbd_interface intf3;
-void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uint32_t reg_base)
+void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, cdc_acm_hid_msc_descriptor);
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 7ab5810633..9b53aa8be9 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_acm.h"
#include "usbd_msc.h"
/*!< endpoint address */
@@ -247,7 +247,7 @@ struct usbd_interface intf0;
struct usbd_interface intf1;
struct usbd_interface intf2;
-void cdc_acm_msc_init(uint8_t busid, uint32_t reg_base)
+void cdc_acm_msc_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &cdc_msc_descriptor);
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 fa3eb650e8..3d9dabf408 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_acm.h"
/*!< endpoint address */
#define CDC_IN_EP 0x81
@@ -223,7 +223,7 @@ struct usbd_interface intf5;
struct usbd_interface intf6;
struct usbd_interface intf7;
-void cdc_acm_multi_init(uint8_t busid, uint32_t reg_base)
+void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, cdc_descriptor);
diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c
index 490b71694b..402f934652 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_acm.h"
/*!< endpoint address */
#define CDC_IN_EP 0x81
@@ -174,7 +174,7 @@ struct usbd_endpoint cdc_in_ep = {
static struct usbd_interface intf0;
static struct usbd_interface intf1;
-void cdc_acm_init(uint8_t busid, uint32_t reg_base)
+void cdc_acm_init(uint8_t busid, uintptr_t reg_base)
{
const uint8_t data[10] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
diff --git a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c
index fd58a299d9..37ad1ea024 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c
@@ -269,7 +269,7 @@ struct usbd_interface intf1;
* sudo ifconfig enxaabbccddeeff up
* sudo dhcpclient enxaabbccddeeff
*/
-void cdc_ecm_init(uint8_t busid, uint32_t reg_base)
+void cdc_ecm_init(uint8_t busid, uintptr_t reg_base)
{
cdc_ecm_lwip_init();
diff --git a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c
index cb4aef620a..cd20842a02 100644
--- a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c
+++ b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c
@@ -304,7 +304,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
struct usbd_interface intf0;
struct usbd_interface intf1;
-void cdc_rndis_init(uint8_t busid, uint32_t reg_base)
+void cdc_rndis_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef RT_USING_LWIP
rt_usbd_rndis_init();
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 1d947024fd..aaad7681a8 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
@@ -169,7 +169,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
struct usbd_interface intf0;
-void dfu_flash_init(uint8_t busid, uint32_t reg_base)
+void dfu_flash_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, dfu_flash_descriptor);
usbd_add_interface(busid, usbd_dfu_init_intf(&intf0));
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 92bca37be9..1ef5d547a4 100644
--- a/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c
+++ b/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c
@@ -272,7 +272,7 @@ static struct usbd_endpoint custom_out_ep = {
*/
struct usbd_interface intf0;
-void hid_custom_init(uint8_t busid, uint32_t reg_base)
+void hid_custom_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE));
diff --git a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c
index 5e106f2614..ace3fed0d1 100644
--- a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c
+++ b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c
@@ -221,7 +221,7 @@ static struct usbd_endpoint hid_in_ep = {
struct usbd_interface intf0;
-void hid_keyboard_init(uint8_t busid, uint32_t reg_base)
+void hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
diff --git a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c
index d335601b9b..6b2e690e3f 100644
--- a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c
+++ b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c
@@ -9,7 +9,7 @@
/*!< endpoint address */
#define HID_INT_EP 0x81
#define HID_INT_EP_SIZE 4
-#define HID_INT_EP_INTERVAL 10
+#define HID_INT_EP_INTERVAL 1
#define USBD_VID 0xffff
#define USBD_PID 0xffff
@@ -239,7 +239,7 @@ static struct usbd_endpoint hid_in_ep = {
struct usbd_interface intf0;
-void hid_mouse_init(uint8_t busid, uint32_t reg_base)
+void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
@@ -254,20 +254,59 @@ void hid_mouse_init(uint8_t busid, uint32_t reg_base)
mouse_cfg.y = 0;
}
-/**
- * @brief hid mouse test
- * @pre none
- * @param[in] none
- * @retval none
- */
+#define CURSOR_STEP 2U
+#define CURSOR_WIDTH 20U
+
+void draw_circle(uint8_t *buf)
+{
+ static int32_t move_cnt = 0;
+ static uint8_t step_x_y = 0;
+ static int8_t x = 0, y = 0;
+
+ move_cnt++;
+ if (move_cnt > CURSOR_WIDTH) {
+ step_x_y++;
+ step_x_y = step_x_y % 4;
+ move_cnt = 0;
+ }
+ switch (step_x_y) {
+ case 0: {
+ y = 0;
+ x = CURSOR_STEP;
+
+ } break;
+
+ case 1: {
+ x = 0;
+ y = CURSOR_STEP;
+
+ } break;
+
+ case 2: {
+ y = 0;
+ x = (int8_t)(-CURSOR_STEP);
+
+ } break;
+
+ case 3: {
+ x = 0;
+ y = (int8_t)(-CURSOR_STEP);
+
+ } break;
+ }
+
+ buf[0] = 0;
+ buf[1] = x;
+ buf[2] = y;
+ buf[3] = 0;
+}
+
+/* https://cps-check.com/cn/polling-rate-check */
void hid_mouse_test(uint8_t busid)
{
int counter = 0;
while (counter < 1000) {
- /*!< move mouse pointer */
- mouse_cfg.x += 40;
- mouse_cfg.y += 0;
-
+ draw_circle((uint8_t *)&mouse_cfg);
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
if (ret < 0) {
return;
diff --git a/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c
new file mode 100644
index 0000000000..6ce67a4979
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usbd_hid.h"
+
+/*!< endpoint address */
+#define HID_INT_EP 0x81
+#define HID_INT_EP_SIZE 4
+#define HID_INT_EP_INTERVAL 1
+
+#define USBD_VID 0xffff
+#define USBD_PID 0xffff
+#define USBD_MAX_POWER 100
+#define USBD_LANGID_STRING 1033
+
+/*!< config descriptor size */
+#define USB_HID_CONFIG_DESC_SIZ 34
+/*!< report descriptor size */
+#define HID_MOUSE_REPORT_DESC_SIZE 74
+
+/*!< global descriptor */
+const uint8_t hid_descriptor[] = {
+ USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
+ USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
+
+ /************** Descriptor of Joystick Mouse interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: HID */
+ 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ 0, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of Joystick Mouse HID ********************/
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Mouse endpoint ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
+ HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
+ 0x00,
+ HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+ ///////////////////////////////////////
+ /// string0 descriptor
+ ///////////////////////////////////////
+ USB_LANGID_INIT(USBD_LANGID_STRING),
+ ///////////////////////////////////////
+ /// string1 descriptor
+ ///////////////////////////////////////
+ 0x14, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
+ 0x26, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ' ', 0x00, /* wcChar9 */
+ 'H', 0x00, /* wcChar10 */
+ 'I', 0x00, /* wcChar11 */
+ 'D', 0x00, /* wcChar12 */
+ ' ', 0x00, /* wcChar13 */
+ 'D', 0x00, /* wcChar14 */
+ 'E', 0x00, /* wcChar15 */
+ 'M', 0x00, /* wcChar16 */
+ 'O', 0x00, /* wcChar17 */
+ ///////////////////////////////////////
+ /// string3 descriptor
+ ///////////////////////////////////////
+ 0x16, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ '2', 0x00, /* wcChar0 */
+ '0', 0x00, /* wcChar1 */
+ '2', 0x00, /* wcChar2 */
+ '2', 0x00, /* wcChar3 */
+ '1', 0x00, /* wcChar4 */
+ '2', 0x00, /* wcChar5 */
+ '3', 0x00, /* wcChar6 */
+ '4', 0x00, /* wcChar7 */
+ '5', 0x00, /* wcChar8 */
+ '6', 0x00, /* wcChar9 */
+#ifdef CONFIG_USB_HS
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+#endif
+ 0x00
+};
+
+/*!< hid mouse report descriptor */
+static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
+ 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+ 0x09, 0x02, // USAGE (Mouse)
+ 0xA1, 0x01, // COLLECTION (Application)
+ 0x09, 0x01, // USAGE (Pointer)
+
+ 0xA1, 0x00, // COLLECTION (Physical)
+ 0x05, 0x09, // USAGE_PAGE (Button)
+ 0x19, 0x01, // USAGE_MINIMUM (Button 1)
+ 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
+
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x25, 0x01, // LOGICAL_MAXIMUM (1)
+ 0x95, 0x03, // REPORT_COUNT (3)
+ 0x75, 0x01, // REPORT_SIZE (1)
+
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
+ 0x95, 0x01, // REPORT_COUNT (1)
+ 0x75, 0x05, // REPORT_SIZE (5)
+ 0x81, 0x01, // INPUT (Cnst,Var,Abs)
+
+ 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+ 0x09, 0x30, // USAGE (X)
+ 0x09, 0x31, // USAGE (Y)
+ 0x09, 0x38,
+
+ 0x15, 0x81, // LOGICAL_MINIMUM (-127)
+ 0x25, 0x7F, // LOGICAL_MAXIMUM (127)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x95, 0x03, // REPORT_COUNT (2)
+
+ 0x81, 0x06, // INPUT (Data,Var,Rel)
+ 0xC0, 0x09,
+ 0x3c, 0x05,
+ 0xff, 0x09,
+
+ 0x01, 0x15,
+ 0x00, 0x25,
+ 0x01, 0x75,
+ 0x01, 0x95,
+
+ 0x02, 0xb1,
+ 0x22, 0x75,
+ 0x06, 0x95,
+ 0x01, 0xb1,
+
+ 0x01, 0xc0 // END_COLLECTION
+};
+
+/*!< mouse report struct */
+struct hid_mouse {
+ uint8_t buttons;
+ int8_t x;
+ int8_t y;
+ int8_t wheel;
+};
+
+/*!< mouse report */
+static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg;
+
+#define HID_STATE_IDLE 0
+#define HID_STATE_BUSY 1
+
+/*!< hid state ! Data can be sent only when state is idle */
+static volatile uint8_t hid_state = HID_STATE_IDLE;
+
+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:
+ hid_state = HID_STATE_IDLE;
+ break;
+ case USBD_EVENT_SET_REMOTE_WAKEUP:
+ break;
+ case USBD_EVENT_CLR_REMOTE_WAKEUP:
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* function ------------------------------------------------------------------*/
+static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ hid_state = HID_STATE_IDLE;
+}
+
+/*!< endpoint call back */
+static struct usbd_endpoint hid_in_ep = {
+ .ep_cb = usbd_hid_int_callback,
+ .ep_addr = HID_INT_EP
+};
+
+static struct usbd_interface intf0;
+
+void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
+{
+ usbd_desc_register(busid, hid_descriptor);
+ 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);
+
+ usbd_initialize(busid, reg_base, usbd_event_handler);
+
+ /*!< init mouse report data */
+ mouse_cfg.buttons = 0;
+ mouse_cfg.wheel = 0;
+ mouse_cfg.x = 0;
+ mouse_cfg.y = 0;
+}
+
+#define CURSOR_STEP 2U
+#define CURSOR_WIDTH 20U
+
+void draw_circle(uint8_t *buf)
+{
+ static int32_t move_cnt = 0;
+ static uint8_t step_x_y = 0;
+ static int8_t x = 0, y = 0;
+
+ move_cnt++;
+ if (move_cnt > CURSOR_WIDTH) {
+ step_x_y++;
+ step_x_y = step_x_y % 4;
+ move_cnt = 0;
+ }
+ switch (step_x_y) {
+ case 0: {
+ y = 0;
+ x = CURSOR_STEP;
+
+ } break;
+
+ case 1: {
+ x = 0;
+ y = CURSOR_STEP;
+
+ } break;
+
+ case 2: {
+ y = 0;
+ x = (int8_t)(-CURSOR_STEP);
+
+ } break;
+
+ case 3: {
+ x = 0;
+ y = (int8_t)(-CURSOR_STEP);
+
+ } break;
+ }
+
+ buf[0] = 0;
+ buf[1] = x;
+ buf[2] = y;
+ buf[3] = 0;
+}
+
+/* https://cps-check.com/cn/polling-rate-check */
+void hid_mouse_test(uint8_t busid)
+{
+ static uint32_t count = 1000;
+ int ret;
+
+ // if (gpio_read_pin(GPIO_PIN) == 1) {
+ // ret = usbd_send_remote_wakeup(busid);
+ // if (ret < 0) {
+ // return;
+ // }
+ // count = 5000;
+ // }
+
+ while (count) {
+ draw_circle((uint8_t *)&mouse_cfg);
+ int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
+ if (ret < 0) {
+ return;
+ }
+ hid_state = HID_STATE_BUSY;
+ while (hid_state == HID_STATE_BUSY) {
+ }
+
+ count--;
+ }
+}
diff --git a/components/drivers/usb/cherryusb/demo/midi_template.c b/components/drivers/usb/cherryusb/demo/midi_template.c
index d09a94305a..766d2952e2 100644
--- a/components/drivers/usb/cherryusb/demo/midi_template.c
+++ b/components/drivers/usb/cherryusb/demo/midi_template.c
@@ -202,7 +202,7 @@ struct usbd_endpoint midi_in_ep = {
.ep_cb = usbd_midi_bulk_in
};
-void midi_init(uint8_t busid, uint32_t reg_base)
+void midi_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, midi_descriptor);
usbd_add_interface(busid, &intf0);
diff --git a/components/drivers/usb/cherryusb/demo/msc_ram_template.c b/components/drivers/usb/cherryusb/demo/msc_ram_template.c
index 933cd884a7..cd38bdfbf5 100644
--- a/components/drivers/usb/cherryusb/demo/msc_ram_template.c
+++ b/components/drivers/usb/cherryusb/demo/msc_ram_template.c
@@ -154,12 +154,19 @@ int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *
return 0;
}
-struct usbd_interface intf0;
+static struct usbd_interface intf0;
-void msc_ram_init(uint8_t busid, uint32_t reg_base)
+void msc_ram_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, msc_ram_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);
}
+
+#if defined(CONFIG_USBDEV_MSC_POLLING)
+void msc_ram_polling(uint8_t busid)
+{
+ usbd_msc_polling(busid);
+}
+#endif
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/demo/msc_storage_template.c b/components/drivers/usb/cherryusb/demo/msc_storage_template.c
index a335164356..73bc4d4541 100644
--- a/components/drivers/usb/cherryusb/demo/msc_storage_template.c
+++ b/components/drivers/usb/cherryusb/demo/msc_storage_template.c
@@ -154,7 +154,7 @@ int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *
return 0;
}
-void msc_storage_init(uint8_t busid, uint32_t reg_base)
+void msc_storage_init(uint8_t busid, uintptr_t reg_base)
{
rt_err_t res;
diff --git a/components/drivers/usb/cherryusb/demo/usb_host.c b/components/drivers/usb/cherryusb/demo/usb_host.c
index 8c8ac22a0d..7198418893 100644
--- a/components/drivers/usb/cherryusb/demo/usb_host.c
+++ b/components/drivers/usb/cherryusb/demo/usb_host.c
@@ -120,7 +120,7 @@ void usbh_hid_callback(void *arg, int nbytes)
struct usbh_hid *hid_class = (struct usbh_hid *)arg;
if (nbytes > 0) {
- for (size_t i = 0; i < nbytes; i++) {
+ for (int i = 0; i < nbytes; i++) {
USB_LOG_RAW("0x%02x ", hid_buffer[i]);
}
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
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 97f1743a5c..87906ee787 100644
--- a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c
@@ -416,7 +416,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
-void composite_init(uint8_t busid, uint32_t reg_base)
+void composite_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_audio_hid_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
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 adfb879d5f..e9d5fe845f 100644
--- a/components/drivers/usb/cherryusb/demo/video_static_h264_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_static_h264_template.c
@@ -192,7 +192,7 @@ static struct usbd_endpoint video_in_ep = {
struct usbd_interface intf0;
struct usbd_interface intf1;
-void video_init(uint8_t busid, uint32_t reg_base)
+void video_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
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 85b659d463..c167c8a29f 100644
--- a/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c
@@ -192,7 +192,7 @@ static struct usbd_endpoint video_in_ep = {
struct usbd_interface intf0;
struct usbd_interface intf1;
-void video_init(uint8_t busid, uint32_t reg_base)
+void video_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
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 febbaf9b6a..0ee736a9f8 100644
--- a/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c
+++ b/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c
@@ -194,7 +194,7 @@ static struct usbd_endpoint video_in_ep = {
struct usbd_interface intf0;
struct usbd_interface intf1;
-void video_init(uint8_t busid, uint32_t reg_base)
+void video_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
diff --git a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c
new file mode 100644
index 0000000000..142a195c89
--- /dev/null
+++ b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2024, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "usbd_core.h"
+#include "usbd_hid.h"
+
+#define USBD_VID 0xffff
+#define USBD_PID 0xffff
+#define USBD_MAX_POWER 100
+#define USBD_LANGID_STRING 1033
+
+#define HID_INT_EP 0x81
+#define HID_INT_EP_SIZE 8
+#define HID_INT_EP_INTERVAL 10
+
+#define USB_HID_CONFIG_DESC_SIZ (34 + 9)
+#define HID_KEYBOARD_REPORT_DESC_SIZE 63
+
+#define USBD_WEBUSB_VENDOR_CODE (0x22)
+#define USBD_WINUSB_VENDOR_CODE (0x21)
+
+#define USBD_WINUSB_DESC_SET_LEN (0xB2)
+#define URL_DESCRIPTOR_LENGTH (3 + 36)
+
+#define USBD_WEBUSB_INTF_NUM 0x01
+
+#define WEBUSB_URL_STRINGS \
+ 'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', \
+ 'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '/', 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B',
+
+const uint8_t USBD_WinUSBDescriptorSetDescriptor[USBD_WINUSB_DESC_SET_LEN] = {
+ // Microsoft OS 2.0 描述符集标头
+ 0x0A, 0x00, // Descriptor size (10 bytes)
+ 0x00, 0x00, // MS OS 2.0 descriptor set header
+ 0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000)
+ USBD_WINUSB_DESC_SET_LEN, 0x00, // Size, MS OS 2.0 descriptor set
+
+ // Microsoft OS 2.0 配置子集标头
+ 0x08, 0x00, // wLength
+ 0x01, 0x00, // wDescriptorType
+ 0x00, // 适用于配置 1
+ 0x00, // bReserved
+ 0XA8, 0X00, // Size, MS OS 2.0 configuration subset
+
+ // Microsoft OS 2.0 功能子集头
+ 0x08, 0x00, // Descriptor size (8 bytes)
+ 0x02, 0x00, // MS OS 2.0 function subset header
+ USBD_WEBUSB_INTF_NUM, // bFirstInterface
+ 0x00, // 必须设置为 0
+ 0xA0, 0x00,
+
+ // Microsoft OS 2.0 兼容 ID 描述符
+ // 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容
+ 0x14, 0x00, // wLength 20
+ 0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID
+ 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ // Microsoft OS 2.0 注册表属性描述符
+ // 注册表属性分配设备接口 GUID
+ 0x84, 0x00, //wLength: 132
+ 0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9)
+ 0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15)
+ 0x2a, 0x00, //wPropertyNameLength:
+ //bPropertyName: “DeviceInterfaceGUID”
+ 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
+ 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00,
+ 0x00, 0x00,
+ 0x50, 0x00, // wPropertyDataLength
+ //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
+ '{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00,
+ 'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00,
+ '9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00,
+ '8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
+ URL_DESCRIPTOR_LENGTH,
+ WEBUSB_URL_TYPE,
+ WEBUSB_URL_SCHEME_HTTPS,
+ WEBUSB_URL_STRINGS
+};
+
+#define USBD_BOS_WTOTALLENGTH 0x39
+
+#define LANDING_PAGE 0x01
+uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = {
+ // BOS描述符
+ 0x05, // bLength 固长为5
+ 0x0F, // bDescriptorType 固定为15
+ USBD_BOS_WTOTALLENGTH, 0x00, // wTotalLength BOS描述符的总大小
+ 0x02, // bNumDeviceCaps BOS描述符中独立设备功能特性描述符的数量
+
+ // WebUSB 平台功能描述符
+ 0x18, // Descriptor size (24 bytes)
+ 0x10, // Descriptor type (Device Capability) 设备功能描述符
+ 0x05, // Capability type (Platform) 平台描述符
+ 0x00, // Reserved
+
+ // WebUSB Platform Capability ID (3408b638-09a9-47a0-8bfd-a0768815b665)
+ // 平台功能 UUID 将此标识为WebUSB 平台功能描述符,它提供有关设备的基本信息
+ 0x38, 0xB6, 0x08, 0x34,
+ 0xA9, 0x09,
+ 0xA0, 0x47,
+ 0x8B, 0xFD,
+ 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
+
+ 0x00, 0x01, // WebUSB version 1.0
+ USBD_WEBUSB_VENDOR_CODE, // Vendor-assigned WebUSB request code
+ LANDING_PAGE, // Landing page
+
+ // Microsoft 平台功能描述符
+ // 标头
+ 0x1C, // Descriptor size (28 bytes)
+ 0x10, // Descriptor type (Device Capability)
+ 0x05, // Capability type (Platform)
+ 0x00, // Reserved
+
+ 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
+ 0x89, 0x45, 0xC7, 0x4C,
+ 0x9C, 0xD2, 0x65, 0x9D,
+ 0x9E, 0x64, 0x8A, 0x9F,
+
+ // 描述符集信息结构
+ 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 * dwWindowsVersion 最低兼容 Windows 版本 */
+
+ USBD_WINUSB_DESC_SET_LEN, 0X00, /* wDescriptorSetTotalLength */
+
+ USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
+ 0X00 /* bAltEnumCode */
+};
+
+struct usb_webusb_descriptor webusb_url_desc = {
+ .vendor_code = USBD_WEBUSB_VENDOR_CODE,
+ .string = USBD_WebUSBURLDescriptor,
+ .string_len = USBD_WINUSB_DESC_SET_LEN
+};
+
+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
+};
+
+static const uint8_t webusb_hid_descriptor[] = {
+ USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
+ USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+
+ /************** Descriptor of Joystick Mouse interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: HID */
+ 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ 0, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of Joystick Mouse HID ********************/
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Mouse endpoint ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
+ HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
+ 0x00,
+ HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+ USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00),
+ ///////////////////////////////////////
+ /// string0 descriptor
+ ///////////////////////////////////////
+ USB_LANGID_INIT(USBD_LANGID_STRING),
+ ///////////////////////////////////////
+ /// string1 descriptor
+ ///////////////////////////////////////
+ 0x14, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
+ 0x26, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ' ', 0x00, /* wcChar9 */
+ 'H', 0x00, /* wcChar10 */
+ 'I', 0x00, /* wcChar11 */
+ 'D', 0x00, /* wcChar12 */
+ ' ', 0x00, /* wcChar13 */
+ 'D', 0x00, /* wcChar14 */
+ 'E', 0x00, /* wcChar15 */
+ 'M', 0x00, /* wcChar16 */
+ 'O', 0x00, /* wcChar17 */
+ ///////////////////////////////////////
+ /// string3 descriptor
+ ///////////////////////////////////////
+ 0x16, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ '2', 0x00, /* wcChar0 */
+ '0', 0x00, /* wcChar1 */
+ '2', 0x00, /* wcChar2 */
+ '2', 0x00, /* wcChar3 */
+ '1', 0x00, /* wcChar4 */
+ '2', 0x00, /* wcChar5 */
+ '3', 0x00, /* wcChar6 */
+ '4', 0x00, /* wcChar7 */
+ '5', 0x00, /* wcChar8 */
+ '6', 0x00, /* wcChar9 */
+#ifdef CONFIG_USB_HS
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+#endif
+ 0x00
+};
+
+/* USB HID device Configuration Descriptor */
+static uint8_t hid_desc[9] __ALIGN_END = {
+ /* 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,
+};
+
+static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
+ 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+ 0x09, 0x06, // USAGE (Keyboard)
+ 0xa1, 0x01, // COLLECTION (Application)
+ 0x05, 0x07, // USAGE_PAGE (Keyboard)
+ 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
+ 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x25, 0x01, // LOGICAL_MAXIMUM (1)
+ 0x75, 0x01, // REPORT_SIZE (1)
+ 0x95, 0x08, // REPORT_COUNT (8)
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
+ 0x95, 0x01, // REPORT_COUNT (1)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x81, 0x03, // INPUT (Cnst,Var,Abs)
+ 0x95, 0x05, // REPORT_COUNT (5)
+ 0x75, 0x01, // REPORT_SIZE (1)
+ 0x05, 0x08, // USAGE_PAGE (LEDs)
+ 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
+ 0x29, 0x05, // USAGE_MAXIMUM (Kana)
+ 0x91, 0x02, // OUTPUT (Data,Var,Abs)
+ 0x95, 0x01, // REPORT_COUNT (1)
+ 0x75, 0x03, // REPORT_SIZE (3)
+ 0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
+ 0x95, 0x06, // REPORT_COUNT (6)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x25, 0xFF, // LOGICAL_MAXIMUM (255)
+ 0x05, 0x07, // USAGE_PAGE (Keyboard)
+ 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
+ 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
+ 0x81, 0x00, // INPUT (Data,Ary,Abs)
+ 0xc0 // END_COLLECTION
+};
+
+#define HID_STATE_IDLE 0
+#define HID_STATE_BUSY 1
+
+/*!< hid state ! Data can be sent only when state is idle */
+static volatile uint8_t hid_state = HID_STATE_IDLE;
+
+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:
+ hid_state = HID_STATE_IDLE;
+ break;
+ case USBD_EVENT_SET_REMOTE_WAKEUP:
+ break;
+ case USBD_EVENT_CLR_REMOTE_WAKEUP:
+ break;
+
+ default:
+ break;
+ }
+}
+
+void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
+{
+ hid_state = HID_STATE_IDLE;
+}
+
+static struct usbd_endpoint hid_in_ep = {
+ .ep_cb = usbd_hid_int_callback,
+ .ep_addr = HID_INT_EP
+};
+
+static struct usbd_interface intf0;
+
+void webusb_hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
+{
+ usbd_desc_register(busid, webusb_hid_descriptor);
+ usbd_bos_desc_register(busid, &bos_desc);
+ usbd_msosv2_desc_register(busid, &msosv2_desc);
+ usbd_webusb_desc_register(busid, &webusb_url_desc);
+ 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);
+
+ usbd_initialize(busid, reg_base, usbd_event_handler);
+}
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[64];
+
+void hid_keyboard_test(uint8_t busid)
+{
+ const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ memcpy(write_buffer, sendbuffer, 8);
+ int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
+ if (ret < 0) {
+ return;
+ }
+ hid_state = HID_STATE_BUSY;
+ while (hid_state == HID_STATE_BUSY) {
+ }
+}
diff --git a/components/drivers/usb/cherryusb/demo/webusb_template.c b/components/drivers/usb/cherryusb/demo/webusb_template.c
deleted file mode 100644
index dc8bc573ff..0000000000
--- a/components/drivers/usb/cherryusb/demo/webusb_template.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include "usbd_core.h"
-
-#define MS_OS_20_DESCRIPTOR_LENGTH (0xB2)
-
-#define WEBUSB_URL_STRINGS \
- 'd', 'e', 'v', 'a', 'n', 'l', 'a', 'i', '.', 'g', 'i', 't', 'h', 'u', 'b', '.', 'i', 'o', '/', 'w', 'e', 'b', 'd', 'f', 'u', '/', 'd', 'f', 'u', '-', 'u', 't', 'i', 'l'
-
-#define WL_REQUEST_WEBUSB (0x22)
-#define WL_REQUEST_WINUSB (0x21)
-
-#define URL_DESCRIPTOR_LENGTH 0x2C
-
-// 描述符集信息
-const uint8_t MS_OS_20_DESCRIPTOR_SET[MS_OS_20_DESCRIPTOR_LENGTH] = {
- // Microsoft OS 2.0 描述符集标头
- 0x0A, 0x00, // Descriptor size (10 bytes)
- 0x00, 0x00, // MS OS 2.0 descriptor set header
- 0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000)
- MS_OS_20_DESCRIPTOR_LENGTH, 0x00, // Size, MS OS 2.0 descriptor set
-
- // Microsoft OS 2.0 配置子集标头
- 0x08, 0x00, // wLength
- 0x01, 0x00, // wDescriptorType
- 0x00, // 适用于配置 1
- 0x00, // bReserved
- 0XA8, 0X00, // Size, MS OS 2.0 configuration subset
-
- // Microsoft OS 2.0 功能子集头
- 0x08, 0x00, // Descriptor size (8 bytes)
- 0x02, 0x00, // MS OS 2.0 function subset header
- 0x01, // 第2个接口
- 0x00, // 必须设置为 0
- 0xA0, 0x00,
-
- // Microsoft OS 2.0 兼容 ID 描述符
- // 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容
- 0x14, 0x00, // wLength 20
- 0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID
- 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- // Microsoft OS 2.0 注册表属性描述符
- // 注册表属性分配设备接口 GUID
- 0x84, 0x00, //wLength: 132
- 0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9)
- 0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15)
- 0x2a, 0x00, //wPropertyNameLength:
- //bPropertyName: “DeviceInterfaceGUID”
- 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
- 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00,
- 0x00, 0x00,
- 0x50, 0x00, // wPropertyDataLength
- //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
- '{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00,
- 'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00,
- '9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00,
- '8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
- URL_DESCRIPTOR_LENGTH,
- WEBUSB_URL_TYPE,
- WEBUSB_URL_SCHEME_HTTPS,
- WEBUSB_URL_STRINGS
-};
-
-struct usb_webusb_url_ex_descriptor webusb_url_desc = {
- .vendor_code = WL_REQUEST_WEBUSB,
- .string = MS_OS_20_DESCRIPTOR_SET,
- .string_len = MS_OS_20_DESCRIPTOR_LENGTH
-};
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c
index c1fbba934f..fddf8be159 100644
--- a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c
+++ b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_acm.h"
#define WCID_VENDOR_CODE 0x17
@@ -151,18 +151,16 @@ __ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = {
const uint8_t *WINUSB_IFx_WCIDProperties[] = {
WINUSB_IF0_WCIDProperties,
+#if DOUBLE_WINUSB == 1
WINUSB_IF1_WCIDProperties,
+#endif
};
struct usb_msosv1_descriptor msosv1_desc = {
.string = WCID_StringDescriptor_MSOS,
.vendor_code = WCID_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
-#if DOUBLE_WINUSB == 0
- .comp_id_property = &WINUSB_IF0_WCIDProperties,
-#else
.comp_id_property = WINUSB_IFx_WCIDProperties,
-#endif
};
#define WINUSB_IN_EP 0x81
@@ -446,7 +444,7 @@ struct usbd_interface intf1;
#endif
-void winusb_init(uint8_t busid, uint32_t reg_base)
+void winusb_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, winusb_descriptor);
usbd_msosv1_desc_register(busid, &msosv1_desc);
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 8fe6e995ab..811f630965 100644
--- a/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c
+++ b/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_acm.h"
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02
@@ -318,7 +318,7 @@ struct usb_bos_descriptor bos_desc = {
.string_len = USBD_BOS_WTOTALLENGTH
};
-void winusbv2_init(uint8_t busid, uint32_t reg_base)
+void winusbv2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, winusbv2_descriptor);
usbd_bos_desc_register(busid, &bos_desc);
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 8df623edbe..c33cfa76c3 100644
--- a/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c
+++ b/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c
@@ -422,7 +422,7 @@ struct usb_bos_descriptor bos_desc = {
.string_len = USBD_BOS_WTOTALLENGTH
};
-void winusbv2_init(uint8_t busid, uint32_t reg_base)
+void winusbv2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, winusbv2_descriptor);
usbd_bos_desc_register(busid, &bos_desc);
diff --git a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
index 18b66a4961..e8cbce3a79 100644
--- a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
+++ b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
@@ -129,7 +129,7 @@ struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_
timer = rt_malloc(sizeof(struct usb_osal_timer));
memset(timer, 0, sizeof(struct usb_osal_timer));
- timer->timer = (void *)rt_timer_create("usb_tim", handler, argument, timeout_ms, is_period ? (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER) : (RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER));
+ timer->timer = (void *)rt_timer_create(name, handler, argument, timeout_ms, is_period ? (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER) : (RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER));
if (timer->timer == NULL) {
return NULL;
}
@@ -167,3 +167,13 @@ void usb_osal_msleep(uint32_t delay)
{
rt_thread_mdelay(delay);
}
+
+void *usb_osal_malloc(size_t size)
+{
+ return rt_malloc(size);
+}
+
+void usb_osal_free(void *ptr)
+{
+ rt_free(ptr);
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c b/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c
index 643aa3ddd6..79ab320746 100644
--- a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c
+++ b/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c
@@ -7,11 +7,11 @@
#endif
#if IDLE_THREAD_STACK_SIZE < 2048
-#error "IDLE_THREAD_STACK_SIZE must be greater than 2048"
+#error "IDLE_THREAD_STACK_SIZE must be greater than or equal to 2048"
#endif
#if RT_TIMER_THREAD_STACK_SIZE < 2048
-#error "RT_TIMER_THREAD_STACK_SIZE must be greater than 2048"
+#error "RT_TIMER_THREAD_STACK_SIZE must be greater than or equal to 2048"
#endif
#endif
diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c b/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c
index 12799e67b2..745ea5ea29 100644
--- a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c
+++ b/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c
@@ -36,17 +36,6 @@ void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
bflb_l1c_dcache_invalidate_range(addr, size);
}
}
-#elif defined(SOC_HPM5000) || defined(SOC_HPM6000)
-#include "hpm_l1c_drv.h"
-
-void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
-{
- if (ops == RT_HW_CACHE_FLUSH) {
- l1c_dc_flush((uint32_t)addr, size);
- } else {
- l1c_dc_invalidate((uint32_t)addr, size);
- }
-}
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t msc_sector[512];
diff --git a/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c b/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c
index 6f45329c96..b6859f8d5a 100644
--- a/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c
+++ b/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c
@@ -613,6 +613,23 @@ int usbd_set_address(uint8_t busid, const uint8_t addr)
return 0;
}
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ uint32_t regval;
+
+ regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
+ regval |= USB_CAP_RMWAKUP;
+ putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
+
+ bflb_mtimer_delay_ms(10);
+
+ regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
+ regval &= ~USB_CAP_RMWAKUP;
+ putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
+
+ return 0;
+}
+
uint8_t usbd_get_port_speed(uint8_t busid)
{
uint8_t speed = 3;
@@ -638,7 +655,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
uint8_t ep_idx = USB_EP_GET_IDX(ep_addr);
- if ((ep_idx > 4) && (ep_idx < 9)) {
+ if (ep_idx > 4) {
return 0;
}
@@ -822,6 +839,29 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
{
+ uint32_t regval;
+
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (ep_idx == 0) {
+ } else {
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
+ if (regval & USB_STL_OEP1) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
+ } else {
+ regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
+ if (regval & USB_STL_IEP1) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
+ }
+ }
+
return 0;
}
@@ -1019,12 +1059,11 @@ void USBD_IRQHandler(uint8_t busid)
}
#ifdef CONFIG_USBDEV_TEST_MODE
-void usbd_execute_test_mode(struct usb_setup_packet *setup)
+void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode)
{
uint32_t regval;
- uint8_t index = setup->wIndex >> 8;
- switch (index) {
+ switch (test_mode) {
case 1: // Test_J
{
regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
diff --git a/components/drivers/usb/cherryusb/port/chipidea/README.md b/components/drivers/usb/cherryusb/port/chipidea/README.md
new file mode 100644
index 0000000000..6a43f79d6d
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/chipidea/README.md
@@ -0,0 +1,14 @@
+# Note
+
+## Support Chip List
+
+### NXP
+
+Modify USB_NOCACHE_RAM_SECTION
+
+```
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".NonCacheable")))
+```
+
+- IMRT10XX/IMRT11XX
+- MCXN9XX/MCXN236
diff --git a/components/drivers/usb/cherryusb/port/chipidea/usb_chipidea_reg.h b/components/drivers/usb/cherryusb/port/chipidea/usb_chipidea_reg.h
new file mode 100644
index 0000000000..4867ef5996
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/chipidea/usb_chipidea_reg.h
@@ -0,0 +1,2249 @@
+/*
+ * Copyright (c) 2021-2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+
+#ifndef HPM_USB_H
+#define HPM_USB_H
+
+#define __R volatile const /* Define "read-only" permission */
+#define __RW volatile /* Define "read-write" permission */
+#define __W volatile /* Define "write-only" permission */
+
+typedef struct {
+ __R uint8_t RESERVED0[128]; /* 0x0 - 0x7F: Reserved */
+ __RW uint32_t GPTIMER0LD; /* 0x80: General Purpose Timer #0 Load Register */
+ __RW uint32_t GPTIMER0CTRL; /* 0x84: General Purpose Timer #0 Controller Register */
+ __RW uint32_t GPTIMER1LD; /* 0x88: General Purpose Timer #1 Load Register */
+ __RW uint32_t GPTIMER1CTRL; /* 0x8C: General Purpose Timer #1 Controller Register */
+ __RW uint32_t SBUSCFG; /* 0x90: System Bus Config Register */
+ __R uint8_t RESERVED1[172]; /* 0x94 - 0x13F: Reserved */
+ __RW uint32_t USBCMD; /* 0x140: USB Command Register */
+ __RW uint32_t USBSTS; /* 0x144: USB Status Register */
+ __RW uint32_t USBINTR; /* 0x148: Interrupt Enable Register */
+ __RW uint32_t FRINDEX; /* 0x14C: USB Frame Index Register */
+ __R uint8_t RESERVED2[4]; /* 0x150 - 0x153: Reserved */
+ union {
+ __RW uint32_t DEVICEADDR; /* 0x154: Device Address Register */
+ __RW uint32_t PERIODICLISTBASE; /* 0x154: Frame List Base Address Register */
+ };
+ union {
+ __RW uint32_t ASYNCLISTADDR; /* 0x158: Next Asynch. Address Register */
+ __RW uint32_t ENDPTLISTADDR; /* 0x158: Endpoint List Address Register */
+ };
+ __R uint8_t RESERVED3[4]; /* 0x15C - 0x15F: Reserved */
+ __RW uint32_t BURSTSIZE; /* 0x160: Programmable Burst Size Register */
+ __RW uint32_t TXFILLTUNING; /* 0x164: TX FIFO Fill Tuning Register */
+ __R uint8_t RESERVED4[16]; /* 0x168 - 0x177: Reserved */
+ __RW uint32_t ENDPTNAK; /* 0x178: Endpoint NAK Register */
+ __RW uint32_t ENDPTNAKEN; /* 0x17C: Endpoint NAK Enable Register */
+ __R uint8_t RESERVED5[4]; /* 0x180 - 0x183: Reserved */
+ __RW uint32_t PORTSC1; /* 0x184: Port Status & Control */
+ __R uint8_t RESERVED6[28]; /* 0x188 - 0x1A3: Reserved */
+ __RW uint32_t OTGSC; /* 0x1A4: On-The-Go Status & control Register */
+ __RW uint32_t USBMODE; /* 0x1A8: USB Device Mode Register */
+ __RW uint32_t ENDPTSETUPSTAT; /* 0x1AC: Endpoint Setup Status Register */
+ __RW uint32_t ENDPTPRIME; /* 0x1B0: Endpoint Prime Register */
+ __RW uint32_t ENDPTFLUSH; /* 0x1B4: Endpoint Flush Register */
+ __R uint32_t ENDPTSTAT; /* 0x1B8: Endpoint Status Register */
+ __RW uint32_t ENDPTCOMPLETE; /* 0x1BC: Endpoint Complete Register */
+ __RW uint32_t ENDPTCTRL[8]; /* 0x1C0 - 0x1DC: Endpoint Control0 Register... Endpoint Control7 Register */
+} CHIPIDEA_TypeDef;
+
+
+/* Bitfield definition for register: GPTIMER0LD */
+/*
+ * GPTLD (RW)
+ *
+ * GPTLD
+ * General Purpose Timer Load Value
+ * These bit fields are loaded to GPTCNT bits when GPTRST bit is set '1b'.
+ * This value represents the time in microseconds minus 1 for the timer duration.
+ * Example: for a one millisecond timer, load 1000-1=999 or 0x0003E7.
+ * NOTE: Max value is 0xFFFFFF or 16.777215 seconds.
+ */
+#define USB_GPTIMER0LD_GPTLD_MASK (0xFFFFFFUL)
+#define USB_GPTIMER0LD_GPTLD_SHIFT (0U)
+#define USB_GPTIMER0LD_GPTLD_SET(x) (((uint32_t)(x) << USB_GPTIMER0LD_GPTLD_SHIFT) & USB_GPTIMER0LD_GPTLD_MASK)
+#define USB_GPTIMER0LD_GPTLD_GET(x) (((uint32_t)(x) & USB_GPTIMER0LD_GPTLD_MASK) >> USB_GPTIMER0LD_GPTLD_SHIFT)
+
+/* Bitfield definition for register: GPTIMER0CTRL */
+/*
+ * GPTRUN (RW)
+ *
+ * GPTRUN
+ * General Purpose Timer Run
+ * GPTCNT bits are not effected when setting or clearing this bit.
+ * 0 - Stop counting
+ * 1 - Run
+ */
+#define USB_GPTIMER0CTRL_GPTRUN_MASK (0x80000000UL)
+#define USB_GPTIMER0CTRL_GPTRUN_SHIFT (31U)
+#define USB_GPTIMER0CTRL_GPTRUN_SET(x) (((uint32_t)(x) << USB_GPTIMER0CTRL_GPTRUN_SHIFT) & USB_GPTIMER0CTRL_GPTRUN_MASK)
+#define USB_GPTIMER0CTRL_GPTRUN_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTRUN_MASK) >> USB_GPTIMER0CTRL_GPTRUN_SHIFT)
+
+/*
+ * GPTRST (WO)
+ *
+ * GPTRST
+ * General Purpose Timer Reset
+ * 0 - No action
+ * 1 - Load counter value from GPTLD bits in n_GPTIMER0LD
+ */
+#define USB_GPTIMER0CTRL_GPTRST_MASK (0x40000000UL)
+#define USB_GPTIMER0CTRL_GPTRST_SHIFT (30U)
+#define USB_GPTIMER0CTRL_GPTRST_SET(x) (((uint32_t)(x) << USB_GPTIMER0CTRL_GPTRST_SHIFT) & USB_GPTIMER0CTRL_GPTRST_MASK)
+#define USB_GPTIMER0CTRL_GPTRST_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTRST_MASK) >> USB_GPTIMER0CTRL_GPTRST_SHIFT)
+
+/*
+ * GPTMODE (RW)
+ *
+ * GPTMODE
+ * General Purpose Timer Mode
+ * In one shot mode, the timer will count down to zero, generate an interrupt, and stop until the counter is
+ * reset by software;
+ * In repeat mode, the timer will count down to zero, generate an interrupt and automatically reload the
+ * counter value from GPTLD bits to start again.
+ * 0 - One Shot Mode
+ * 1 - Repeat Mode
+ */
+#define USB_GPTIMER0CTRL_GPTMODE_MASK (0x1000000UL)
+#define USB_GPTIMER0CTRL_GPTMODE_SHIFT (24U)
+#define USB_GPTIMER0CTRL_GPTMODE_SET(x) (((uint32_t)(x) << USB_GPTIMER0CTRL_GPTMODE_SHIFT) & USB_GPTIMER0CTRL_GPTMODE_MASK)
+#define USB_GPTIMER0CTRL_GPTMODE_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTMODE_MASK) >> USB_GPTIMER0CTRL_GPTMODE_SHIFT)
+
+/*
+ * GPTCNT (RO)
+ *
+ * GPTCNT
+ * General Purpose Timer Counter.
+ * This field is the count value of the countdown timer.
+ */
+#define USB_GPTIMER0CTRL_GPTCNT_MASK (0xFFFFFFUL)
+#define USB_GPTIMER0CTRL_GPTCNT_SHIFT (0U)
+#define USB_GPTIMER0CTRL_GPTCNT_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTCNT_MASK) >> USB_GPTIMER0CTRL_GPTCNT_SHIFT)
+
+/* Bitfield definition for register: GPTIMER1LD */
+/*
+ * GPTLD (RW)
+ *
+ * GPTLD
+ * General Purpose Timer Load Value
+ * These bit fields are loaded to GPTCNT bits when GPTRST bit is set '1b'.
+ * This value represents the time in microseconds minus 1 for the timer duration.
+ * Example: for a one millisecond timer, load 1000-1=999 or 0x0003E7.
+ * NOTE: Max value is 0xFFFFFF or 16.777215 seconds.
+ */
+#define USB_GPTIMER1LD_GPTLD_MASK (0xFFFFFFUL)
+#define USB_GPTIMER1LD_GPTLD_SHIFT (0U)
+#define USB_GPTIMER1LD_GPTLD_SET(x) (((uint32_t)(x) << USB_GPTIMER1LD_GPTLD_SHIFT) & USB_GPTIMER1LD_GPTLD_MASK)
+#define USB_GPTIMER1LD_GPTLD_GET(x) (((uint32_t)(x) & USB_GPTIMER1LD_GPTLD_MASK) >> USB_GPTIMER1LD_GPTLD_SHIFT)
+
+/* Bitfield definition for register: GPTIMER1CTRL */
+/*
+ * GPTRUN (RW)
+ *
+ * GPTRUN
+ * General Purpose Timer Run
+ * GPTCNT bits are not effected when setting or clearing this bit.
+ * 0 - Stop counting
+ * 1 - Run
+ */
+#define USB_GPTIMER1CTRL_GPTRUN_MASK (0x80000000UL)
+#define USB_GPTIMER1CTRL_GPTRUN_SHIFT (31U)
+#define USB_GPTIMER1CTRL_GPTRUN_SET(x) (((uint32_t)(x) << USB_GPTIMER1CTRL_GPTRUN_SHIFT) & USB_GPTIMER1CTRL_GPTRUN_MASK)
+#define USB_GPTIMER1CTRL_GPTRUN_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTRUN_MASK) >> USB_GPTIMER1CTRL_GPTRUN_SHIFT)
+
+/*
+ * GPTRST (WO)
+ *
+ * GPTRST
+ * General Purpose Timer Reset
+ * 0 - No action
+ * 1 - Load counter value from GPTLD bits in USB_n_GPTIMER1LD
+ */
+#define USB_GPTIMER1CTRL_GPTRST_MASK (0x40000000UL)
+#define USB_GPTIMER1CTRL_GPTRST_SHIFT (30U)
+#define USB_GPTIMER1CTRL_GPTRST_SET(x) (((uint32_t)(x) << USB_GPTIMER1CTRL_GPTRST_SHIFT) & USB_GPTIMER1CTRL_GPTRST_MASK)
+#define USB_GPTIMER1CTRL_GPTRST_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTRST_MASK) >> USB_GPTIMER1CTRL_GPTRST_SHIFT)
+
+/*
+ * GPTMODE (RW)
+ *
+ * GPTMODE
+ * General Purpose Timer Mode
+ * In one shot mode, the timer will count down to zero, generate an interrupt, and stop until the counter is
+ * reset by software. In repeat mode, the timer will count down to zero, generate an interrupt and
+ * automatically reload the counter value from GPTLD bits to start again.
+ * 0 - One Shot Mode
+ * 1 - Repeat Mode
+ */
+#define USB_GPTIMER1CTRL_GPTMODE_MASK (0x1000000UL)
+#define USB_GPTIMER1CTRL_GPTMODE_SHIFT (24U)
+#define USB_GPTIMER1CTRL_GPTMODE_SET(x) (((uint32_t)(x) << USB_GPTIMER1CTRL_GPTMODE_SHIFT) & USB_GPTIMER1CTRL_GPTMODE_MASK)
+#define USB_GPTIMER1CTRL_GPTMODE_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTMODE_MASK) >> USB_GPTIMER1CTRL_GPTMODE_SHIFT)
+
+/*
+ * GPTCNT (RO)
+ *
+ * GPTCNT
+ * General Purpose Timer Counter.
+ * This field is the count value of the countdown timer.
+ */
+#define USB_GPTIMER1CTRL_GPTCNT_MASK (0xFFFFFFUL)
+#define USB_GPTIMER1CTRL_GPTCNT_SHIFT (0U)
+#define USB_GPTIMER1CTRL_GPTCNT_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTCNT_MASK) >> USB_GPTIMER1CTRL_GPTCNT_SHIFT)
+
+/* Bitfield definition for register: SBUSCFG */
+/*
+ * AHBBRST (RW)
+ *
+ * AHBBRST
+ * AHB master interface Burst configuration
+ * These bits control AHB master transfer type sequence (or priority).
+ * NOTE: This register overrides n_BURSTSIZE register when its value is not zero.
+ * 000 - Incremental burst of unspecified length only
+ * 001 - INCR4 burst, then single transfer
+ * 010 - INCR8 burst, INCR4 burst, then single transfer
+ * 011 - INCR16 burst, INCR8 burst, INCR4 burst, then single transfer
+ * 100 - Reserved, don't use
+ * 101 - INCR4 burst, then incremental burst of unspecified length
+ * 110 - INCR8 burst, INCR4 burst, then incremental burst of unspecified length
+ * 111 - INCR16 burst, INCR8 burst, INCR4 burst, then incremental burst of unspecified length
+ */
+#define USB_SBUSCFG_AHBBRST_MASK (0x7U)
+#define USB_SBUSCFG_AHBBRST_SHIFT (0U)
+#define USB_SBUSCFG_AHBBRST_SET(x) (((uint32_t)(x) << USB_SBUSCFG_AHBBRST_SHIFT) & USB_SBUSCFG_AHBBRST_MASK)
+#define USB_SBUSCFG_AHBBRST_GET(x) (((uint32_t)(x) & USB_SBUSCFG_AHBBRST_MASK) >> USB_SBUSCFG_AHBBRST_SHIFT)
+
+/* Bitfield definition for register: USBCMD */
+/*
+ * ITC (RW)
+ *
+ * ITC
+ * Interrupt Threshold Control -Read/Write.
+ * The system software uses this field to set the maximum rate at which the host/device controller will issue interrupts.
+ * ITC contains the maximum interrupt interval measured in micro-frames. Valid values are
+ * shown below.
+ * Value Maximum Interrupt Interval
+ * 00000000 - Immediate (no threshold)
+ * 00000001 - 1 micro-frame
+ * 00000010 - 2 micro-frames
+ * 00000100 - 4 micro-frames
+ * 00001000 - 8 micro-frames
+ * 00010000 - 16 micro-frames
+ * 00100000 - 32 micro-frames
+ * 01000000 - 64 micro-frames
+ */
+#define USB_USBCMD_ITC_MASK (0xFF0000UL)
+#define USB_USBCMD_ITC_SHIFT (16U)
+#define USB_USBCMD_ITC_SET(x) (((uint32_t)(x) << USB_USBCMD_ITC_SHIFT) & USB_USBCMD_ITC_MASK)
+#define USB_USBCMD_ITC_GET(x) (((uint32_t)(x) & USB_USBCMD_ITC_MASK) >> USB_USBCMD_ITC_SHIFT)
+
+/*
+ * FS_2 (RW)
+ *
+ * FS_2
+ * Frame List Size - (Read/Write or Read Only). [host mode only]
+ * This field is Read/Write only if Programmable Frame List Flag in the HCCPARAMS registers is set to one.
+ * This field specifies the size of the frame list that controls which bits in the Frame Index Register should be used for the Frame List Current index.
+ * NOTE: This field is made up from USBCMD bits 15, 3 and 2.
+ * Value Meaning
+ * 0b000 - 1024 elements (4096 bytes) Default value
+ * 0b001 - 512 elements (2048 bytes)
+ * 0b010 - 256 elements (1024 bytes)
+ * 0b011 - 128 elements (512 bytes)
+ * 0b100 - 64 elements (256 bytes)
+ * 0b101 - 32 elements (128 bytes)
+ * 0b110 - 16 elements (64 bytes)
+ * 0b111 - 8 elements (32 bytes)
+ */
+#define USB_USBCMD_FS_2_MASK (0x8000U)
+#define USB_USBCMD_FS_2_SHIFT (15U)
+#define USB_USBCMD_FS_2_SET(x) (((uint32_t)(x) << USB_USBCMD_FS_2_SHIFT) & USB_USBCMD_FS_2_MASK)
+#define USB_USBCMD_FS_2_GET(x) (((uint32_t)(x) & USB_USBCMD_FS_2_MASK) >> USB_USBCMD_FS_2_SHIFT)
+
+/*
+ * ATDTW (RW)
+ *
+ * ATDTW
+ * Add dTD TripWire - Read/Write. [device mode only]
+ * This bit is used as a semaphore to ensure proper addition of a new dTD to an active (primed) endpoint's
+ * linked list. This bit is set and cleared by software.
+ * This bit would also be cleared by hardware when state machine is hazard region for which adding a dTD
+ * to a primed endpoint may go unrecognized.
+ */
+#define USB_USBCMD_ATDTW_MASK (0x4000U)
+#define USB_USBCMD_ATDTW_SHIFT (14U)
+#define USB_USBCMD_ATDTW_SET(x) (((uint32_t)(x) << USB_USBCMD_ATDTW_SHIFT) & USB_USBCMD_ATDTW_MASK)
+#define USB_USBCMD_ATDTW_GET(x) (((uint32_t)(x) & USB_USBCMD_ATDTW_MASK) >> USB_USBCMD_ATDTW_SHIFT)
+
+/*
+ * SUTW (RW)
+ *
+ * SUTW
+ * Setup TripWire - Read/Write. [device mode only]
+ * This bit is used as a semaphore to ensure that the setup data payload of 8 bytes is extracted from a QH by the DCD without being corrupted.
+ * If the setup lockout mode is off (SLOM bit in USB core register n_USBMODE, see USBMODE ) then
+ * there is a hazard when new setup data arrives while the DCD is copying the setup data payload
+ * from the QH for a previous setup packet. This bit is set and cleared by software.
+ * This bit would also be cleared by hardware when a hazard detected.
+ */
+#define USB_USBCMD_SUTW_MASK (0x2000U)
+#define USB_USBCMD_SUTW_SHIFT (13U)
+#define USB_USBCMD_SUTW_SET(x) (((uint32_t)(x) << USB_USBCMD_SUTW_SHIFT) & USB_USBCMD_SUTW_MASK)
+#define USB_USBCMD_SUTW_GET(x) (((uint32_t)(x) & USB_USBCMD_SUTW_MASK) >> USB_USBCMD_SUTW_SHIFT)
+
+/*
+ * ASPE (RW)
+ *
+ * ASPE
+ * Asynchronous Schedule Park Mode Enable - Read/Write.
+ * If the Asynchronous Park Capability bit in the HCCPARAMS register is a one, then this bit defaults to a 1h and is R/W.
+ * Otherwise the bit must be a zero and is RO. Software uses this bit to enable or disable Park mode.
+ * When this bit is one, Park mode is enabled. When this bit is a zero, Park mode is disabled.
+ * NOTE: ASPE bit reset value: '0b' for OTG controller .
+ */
+#define USB_USBCMD_ASPE_MASK (0x800U)
+#define USB_USBCMD_ASPE_SHIFT (11U)
+#define USB_USBCMD_ASPE_SET(x) (((uint32_t)(x) << USB_USBCMD_ASPE_SHIFT) & USB_USBCMD_ASPE_MASK)
+#define USB_USBCMD_ASPE_GET(x) (((uint32_t)(x) & USB_USBCMD_ASPE_MASK) >> USB_USBCMD_ASPE_SHIFT)
+
+/*
+ * ASP (RW)
+ *
+ * ASP
+ * Asynchronous Schedule Park Mode Count - Read/Write.
+ * If the Asynchronous Park Capability bit in the HCCPARAMS register is a one, then this field defaults to 3h and is R/W. Otherwise it defaults to zero and is Read-Only.
+ * It contains a count of the number of successive transactions the host controller is allowed to
+ * execute from a high-speed queue head on the Asynchronous schedule before continuing traversal of the Asynchronous schedule.
+ * Valid values are 1h to 3h. Software must not write a zero to this bit when Park Mode Enable is a one as this will result in undefined behavior.
+ * This field is set to 3h in all controller core.
+ */
+#define USB_USBCMD_ASP_MASK (0x300U)
+#define USB_USBCMD_ASP_SHIFT (8U)
+#define USB_USBCMD_ASP_SET(x) (((uint32_t)(x) << USB_USBCMD_ASP_SHIFT) & USB_USBCMD_ASP_MASK)
+#define USB_USBCMD_ASP_GET(x) (((uint32_t)(x) & USB_USBCMD_ASP_MASK) >> USB_USBCMD_ASP_SHIFT)
+
+/*
+ * IAA (RW)
+ *
+ * IAA
+ * Interrupt on Async Advance Doorbell - Read/Write.
+ * This bit is used as a doorbell by software to tell the host controller to issue an interrupt the next time it advances asynchronous schedule. Software must write a 1 to this bit to ring the doorbell.
+ * When the host controller has evicted all appropriate cached schedule states,
+ * it sets the Interrupt on Async Advance status bit in the USBSTS register.
+ * If the Interrupt on Sync Advance Enable bit in the USBINTR register is one, then the host controller will assert an interrupt at the next interrupt threshold.
+ * The host controller sets this bit to zero after it has set the Interrupt on Sync Advance status bit in the USBSTS register to one.
+ * Software should not write a one to this bit when the asynchronous schedule is inactive. Doing so will yield undefined results.
+ * This bit is only used in host mode. Writing a one to this bit when device mode is selected will have undefined results.
+ */
+#define USB_USBCMD_IAA_MASK (0x40U)
+#define USB_USBCMD_IAA_SHIFT (6U)
+#define USB_USBCMD_IAA_SET(x) (((uint32_t)(x) << USB_USBCMD_IAA_SHIFT) & USB_USBCMD_IAA_MASK)
+#define USB_USBCMD_IAA_GET(x) (((uint32_t)(x) & USB_USBCMD_IAA_MASK) >> USB_USBCMD_IAA_SHIFT)
+
+/*
+ * ASE (RW)
+ *
+ * ASE
+ * Asynchronous Schedule Enable - Read/Write. Default 0b.
+ * This bit controls whether the host controller skips processing the Asynchronous Schedule.
+ * Only the host controller uses this bit.
+ * Values Meaning
+ * 0 - Do not process the Asynchronous Schedule.
+ * 1 - Use the ASYNCLISTADDR register to access the Asynchronous Schedule.
+ */
+#define USB_USBCMD_ASE_MASK (0x20U)
+#define USB_USBCMD_ASE_SHIFT (5U)
+#define USB_USBCMD_ASE_SET(x) (((uint32_t)(x) << USB_USBCMD_ASE_SHIFT) & USB_USBCMD_ASE_MASK)
+#define USB_USBCMD_ASE_GET(x) (((uint32_t)(x) & USB_USBCMD_ASE_MASK) >> USB_USBCMD_ASE_SHIFT)
+
+/*
+ * PSE (RW)
+ *
+ * PSE
+ * Periodic Schedule Enable- Read/Write. Default 0b.
+ * This bit controls whether the host controller skips processing the Periodic Schedule.
+ * Only the host controller uses this bit.
+ * Values Meaning
+ * 0 - Do not process the Periodic Schedule
+ * 1 - Use the PERIODICLISTBASE register to access the Periodic Schedule.
+ */
+#define USB_USBCMD_PSE_MASK (0x10U)
+#define USB_USBCMD_PSE_SHIFT (4U)
+#define USB_USBCMD_PSE_SET(x) (((uint32_t)(x) << USB_USBCMD_PSE_SHIFT) & USB_USBCMD_PSE_MASK)
+#define USB_USBCMD_PSE_GET(x) (((uint32_t)(x) & USB_USBCMD_PSE_MASK) >> USB_USBCMD_PSE_SHIFT)
+
+/*
+ * FS_1 (RW)
+ *
+ * FS_1
+ * See description at bit 15
+ */
+#define USB_USBCMD_FS_1_MASK (0xCU)
+#define USB_USBCMD_FS_1_SHIFT (2U)
+#define USB_USBCMD_FS_1_SET(x) (((uint32_t)(x) << USB_USBCMD_FS_1_SHIFT) & USB_USBCMD_FS_1_MASK)
+#define USB_USBCMD_FS_1_GET(x) (((uint32_t)(x) & USB_USBCMD_FS_1_MASK) >> USB_USBCMD_FS_1_SHIFT)
+
+/*
+ * RST (RW)
+ *
+ * RST
+ * Controller Reset (RESET) - Read/Write. Software uses this bit to reset the controller.
+ * This bit is set to zero by the Host/Device Controller when the reset process is complete. Software cannot terminate the reset process early by writing a zero to this register.
+ * Host operation mode:
+ * When software writes a one to this bit, the Controller resets its internal pipelines, timers, counters, state machines etc. to their initial value.
+ * Any transaction currently in progress on USB is immediately terminated. A USB reset is not driven on downstream ports.
+ * Software should not set this bit to a one when the HCHalted bit in the USBSTS register is a zero.
+ * Attempting to reset an actively running host controller will result in undefined behavior.
+ * Device operation mode:
+ * When software writes a one to this bit, the Controller resets its internal pipelines, timers, counters, state machines etc. to their initial value.
+ * Writing a one to this bit when the device is in the attached state is not recommended, because the effect on an attached host is undefined.
+ * In order to ensure that the device is not in an attached state before initiating a device controller reset, all primed endpoints should be flushed and the USBCMD Run/Stop bit should be set to 0.
+ */
+#define USB_USBCMD_RST_MASK (0x2U)
+#define USB_USBCMD_RST_SHIFT (1U)
+#define USB_USBCMD_RST_SET(x) (((uint32_t)(x) << USB_USBCMD_RST_SHIFT) & USB_USBCMD_RST_MASK)
+#define USB_USBCMD_RST_GET(x) (((uint32_t)(x) & USB_USBCMD_RST_MASK) >> USB_USBCMD_RST_SHIFT)
+
+/*
+ * RS (RW)
+ *
+ * RS
+ * Run/Stop (RS) - Read/Write. Default 0b. 1=Run. 0=Stop.
+ * Host operation mode:
+ * When set to '1b', the Controller proceeds with the execution of the schedule. The Controller continues execution as long as this bit is set to a one.
+ * When this bit is set to 0, the Host Controller completes the current transaction on the USB and then halts.
+ * The HC Halted bit in the status register indicates when the Controller has finished the transaction and has entered the stopped state.
+ * Software should not write a one to this field unless the controller is in the Halted state (that is, HCHalted in the USBSTS register is a one).
+ * Device operation mode:
+ * Writing a one to this bit will cause the controller to enable a pull-up on D+ and initiate an attach event.
+ * This control bit is not directly connected to the pull-up enable, as the pull-up will become disabled upon transitioning into high-speed mode.
+ * Software should use this bit to prevent an attach event before the controller has been properly initialized. Writing a 0 to this will cause a detach event.
+ */
+#define USB_USBCMD_RS_MASK (0x1U)
+#define USB_USBCMD_RS_SHIFT (0U)
+#define USB_USBCMD_RS_SET(x) (((uint32_t)(x) << USB_USBCMD_RS_SHIFT) & USB_USBCMD_RS_MASK)
+#define USB_USBCMD_RS_GET(x) (((uint32_t)(x) & USB_USBCMD_RS_MASK) >> USB_USBCMD_RS_SHIFT)
+
+/* Bitfield definition for register: USBSTS */
+/*
+ * TI1 (RWC)
+ *
+ * TI1
+ * General Purpose Timer Interrupt 1(GPTINT1)--R/WC.
+ * This bit is set when the counter in the GPTIMER1CTRL register transitions to zero, writing a one to this
+ * bit will clear it.
+ */
+#define USB_USBSTS_TI1_MASK (0x2000000UL)
+#define USB_USBSTS_TI1_SHIFT (25U)
+#define USB_USBSTS_TI1_SET(x) (((uint32_t)(x) << USB_USBSTS_TI1_SHIFT) & USB_USBSTS_TI1_MASK)
+#define USB_USBSTS_TI1_GET(x) (((uint32_t)(x) & USB_USBSTS_TI1_MASK) >> USB_USBSTS_TI1_SHIFT)
+
+/*
+ * TI0 (RWC)
+ *
+ * TI0
+ * General Purpose Timer Interrupt 0(GPTINT0)--R/WC.
+ * This bit is set when the counter in the GPTIMER0CTRL register transitions to zero, writing a one to this
+ * bit clears it.
+ */
+#define USB_USBSTS_TI0_MASK (0x1000000UL)
+#define USB_USBSTS_TI0_SHIFT (24U)
+#define USB_USBSTS_TI0_SET(x) (((uint32_t)(x) << USB_USBSTS_TI0_SHIFT) & USB_USBSTS_TI0_MASK)
+#define USB_USBSTS_TI0_GET(x) (((uint32_t)(x) & USB_USBSTS_TI0_MASK) >> USB_USBSTS_TI0_SHIFT)
+
+/*
+ * UPI (RWC)
+ *
+ * USB Host Periodic Interrupt – RWC. Default = 0b.
+ * This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction
+ * where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set and the TD was from the periodic schedule.
+ * This bit is also set by the Host Controller when a short packet is detected and the packet is on the periodic schedule.
+ * A short packet is when the actual number of bytes received was less than expected.
+ * This bit is not used by the device controller and will always be zero.
+ */
+#define USB_USBSTS_UPI_MASK (0x80000UL)
+#define USB_USBSTS_UPI_SHIFT (19U)
+#define USB_USBSTS_UPI_SET(x) (((uint32_t)(x) << USB_USBSTS_UPI_SHIFT) & USB_USBSTS_UPI_MASK)
+#define USB_USBSTS_UPI_GET(x) (((uint32_t)(x) & USB_USBSTS_UPI_MASK) >> USB_USBSTS_UPI_SHIFT)
+
+/*
+ * UAI (RWC)
+ *
+ * USB Host Asynchronous Interrupt – RWC. Default = 0b.
+ * This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction
+ * where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set AND the TD was from the asynchronous schedule.
+ * This bit is also set by the Host when a short packet is detected and the packet is on the asynchronous schedule.
+ * A short packet is when the actual number of bytes received was less than expected.
+ * This bit is not used by the device controller and will always be zero
+ */
+#define USB_USBSTS_UAI_MASK (0x40000UL)
+#define USB_USBSTS_UAI_SHIFT (18U)
+#define USB_USBSTS_UAI_SET(x) (((uint32_t)(x) << USB_USBSTS_UAI_SHIFT) & USB_USBSTS_UAI_MASK)
+#define USB_USBSTS_UAI_GET(x) (((uint32_t)(x) & USB_USBSTS_UAI_MASK) >> USB_USBSTS_UAI_SHIFT)
+
+/*
+ * NAKI (RO)
+ *
+ * NAKI
+ * NAK Interrupt Bit--RO.
+ * This bit is set by hardware when for a particular endpoint both the TX/RX Endpoint NAK bit and
+ * corresponding TX/RX Endpoint NAK Enable bit are set. This bit is automatically cleared by hardware
+ * when all Enabled TX/RX Endpoint NAK bits are cleared.
+ */
+#define USB_USBSTS_NAKI_MASK (0x10000UL)
+#define USB_USBSTS_NAKI_SHIFT (16U)
+#define USB_USBSTS_NAKI_GET(x) (((uint32_t)(x) & USB_USBSTS_NAKI_MASK) >> USB_USBSTS_NAKI_SHIFT)
+
+/*
+ * AS (RO)
+ *
+ * AS
+ * Asynchronous Schedule Status - Read Only.
+ * This bit reports the current real status of the Asynchronous Schedule. When set to zero the asynchronous schedule status is disabled and if set to one the status is enabled.
+ * The Host Controller is not required to immediately disable or enable the Asynchronous Schedule when software transitions the Asynchronous Schedule Enable bit in the USBCMD register.
+ * When this bit and the Asynchronous Schedule Enable bit are the same value, the Asynchronous Schedule is either enabled (1) or disabled (0).
+ * Only used in the host operation mode.
+ */
+#define USB_USBSTS_AS_MASK (0x8000U)
+#define USB_USBSTS_AS_SHIFT (15U)
+#define USB_USBSTS_AS_GET(x) (((uint32_t)(x) & USB_USBSTS_AS_MASK) >> USB_USBSTS_AS_SHIFT)
+
+/*
+ * PS (RO)
+ *
+ * PS
+ * Periodic Schedule Status - Read Only.
+ * This bit reports the current real status of the Periodic Schedule. When set to zero the periodic schedule is disabled, and if set to one the status is enabled.
+ * The Host Controller is not required to immediately disable or enable the Periodic Schedule when software transitions the Periodic Schedule Enable bit in the USBCMD register.
+ * When this bit and the Periodic Schedule Enable bit are the same value, the Periodic Schedule is either enabled (1) or disabled (0).
+ * Only used in the host operation mode.
+ */
+#define USB_USBSTS_PS_MASK (0x4000U)
+#define USB_USBSTS_PS_SHIFT (14U)
+#define USB_USBSTS_PS_GET(x) (((uint32_t)(x) & USB_USBSTS_PS_MASK) >> USB_USBSTS_PS_SHIFT)
+
+/*
+ * RCL (RO)
+ *
+ * RCL
+ * Reclamation - Read Only.
+ * This is a read-only status bit used to detect an empty asynchronous schedule.
+ * Only used in the host operation mode.
+ */
+#define USB_USBSTS_RCL_MASK (0x2000U)
+#define USB_USBSTS_RCL_SHIFT (13U)
+#define USB_USBSTS_RCL_GET(x) (((uint32_t)(x) & USB_USBSTS_RCL_MASK) >> USB_USBSTS_RCL_SHIFT)
+
+/*
+ * HCH (RO)
+ *
+ * HCH
+ * HCHaIted - Read Only.
+ * This bit is a zero whenever the Run/Stop bit is a one.
+ * The Controller sets this bit to one after it has stopped executing because of the Run/Stop bit being set to 0,
+ * either by software or by the Controller hardware (for example, an internal error).
+ * Only used in the host operation mode.
+ * Default value is '0b' for OTG core .
+ * This is because OTG core is not operating as host in default. Please see CM bit in USB_n_USBMODE
+ * register.
+ * NOTE: HCH bit reset value: '0b' for OTG controller core .
+ */
+#define USB_USBSTS_HCH_MASK (0x1000U)
+#define USB_USBSTS_HCH_SHIFT (12U)
+#define USB_USBSTS_HCH_GET(x) (((uint32_t)(x) & USB_USBSTS_HCH_MASK) >> USB_USBSTS_HCH_SHIFT)
+
+/*
+ * SLI (RWC)
+ *
+ * SLI
+ * DCSuspend - R/WC.
+ * When a controller enters a suspend state from an active state, this bit will be set to a one. The device controller clears the bit upon exiting from a suspend state.
+ * Only used in device operation mode.
+ */
+#define USB_USBSTS_SLI_MASK (0x100U)
+#define USB_USBSTS_SLI_SHIFT (8U)
+#define USB_USBSTS_SLI_SET(x) (((uint32_t)(x) << USB_USBSTS_SLI_SHIFT) & USB_USBSTS_SLI_MASK)
+#define USB_USBSTS_SLI_GET(x) (((uint32_t)(x) & USB_USBSTS_SLI_MASK) >> USB_USBSTS_SLI_SHIFT)
+
+/*
+ * SRI (RWC)
+ *
+ * SRI
+ * SOF Received - R/WC.
+ * When the device controller detects a Start Of (micro) Frame, this bit will be set to a one.
+ * When a SOF is extremely late, the device controller will automatically set this bit to indicate that an SOF was expected.
+ * Therefore, this bit will be set roughly every 1ms in device FS mode and every 125ms in HS mode and will be synchronized to the actual SOF that is received.
+ * Because the device controller is initialized to FS before connect, this bit will be set at an interval of 1ms during the prelude to connect and chirp.
+ * In host mode, this bit will be set every 125us and can be used by host controller driver as a time base.
+ * Software writes a 1 to this bit to clear it.
+ */
+#define USB_USBSTS_SRI_MASK (0x80U)
+#define USB_USBSTS_SRI_SHIFT (7U)
+#define USB_USBSTS_SRI_SET(x) (((uint32_t)(x) << USB_USBSTS_SRI_SHIFT) & USB_USBSTS_SRI_MASK)
+#define USB_USBSTS_SRI_GET(x) (((uint32_t)(x) & USB_USBSTS_SRI_MASK) >> USB_USBSTS_SRI_SHIFT)
+
+/*
+ * URI (RWC)
+ *
+ * URI
+ * USB Reset Received - R/WC.
+ * When the device controller detects a USB Reset and enters the default state, this bit will be set to a one.
+ * Software can write a 1 to this bit to clear the USB Reset Received status bit.
+ * Only used in device operation mode.
+ */
+#define USB_USBSTS_URI_MASK (0x40U)
+#define USB_USBSTS_URI_SHIFT (6U)
+#define USB_USBSTS_URI_SET(x) (((uint32_t)(x) << USB_USBSTS_URI_SHIFT) & USB_USBSTS_URI_MASK)
+#define USB_USBSTS_URI_GET(x) (((uint32_t)(x) & USB_USBSTS_URI_MASK) >> USB_USBSTS_URI_SHIFT)
+
+/*
+ * AAI (RWC)
+ *
+ * AAI
+ * Interrupt on Async Advance - R/WC.
+ * System software can force the host controller to issue an interrupt the next time the host controller advances the asynchronous schedule
+ * by writing a one to the Interrupt on Async Advance Doorbell bit in the n_USBCMD register. This status bit indicates the assertion of that interrupt source.
+ * Only used in host operation mode.
+ */
+#define USB_USBSTS_AAI_MASK (0x20U)
+#define USB_USBSTS_AAI_SHIFT (5U)
+#define USB_USBSTS_AAI_SET(x) (((uint32_t)(x) << USB_USBSTS_AAI_SHIFT) & USB_USBSTS_AAI_MASK)
+#define USB_USBSTS_AAI_GET(x) (((uint32_t)(x) & USB_USBSTS_AAI_MASK) >> USB_USBSTS_AAI_SHIFT)
+
+/*
+ * SEI (RWC)
+ *
+ * System Error – RWC. Default = 0b.
+ * In the BVCI implementation of the USBHS core, this bit is not used, and will always be cleared to '0b'.
+ * In the AMBA implementation, this bit will be set to '1b' when an Error response is seen by the master interface (HRESP[1:0]=ERROR)
+ */
+#define USB_USBSTS_SEI_MASK (0x10U)
+#define USB_USBSTS_SEI_SHIFT (4U)
+#define USB_USBSTS_SEI_SET(x) (((uint32_t)(x) << USB_USBSTS_SEI_SHIFT) & USB_USBSTS_SEI_MASK)
+#define USB_USBSTS_SEI_GET(x) (((uint32_t)(x) & USB_USBSTS_SEI_MASK) >> USB_USBSTS_SEI_SHIFT)
+
+/*
+ * FRI (RWC)
+ *
+ * FRI
+ * Frame List Rollover - R/WC.
+ * The Host Controller sets this bit to a one when the Frame List Index rolls over from its maximum value to
+ * zero. The exact value at which the rollover occurs depends on the frame list size. For example. If the
+ * frame list size (as programmed in the Frame List Size field of the USB_n_USBCMD register) is 1024, the
+ * Frame Index Register rolls over every time FRINDEX [13] toggles. Similarly, if the size is 512, the Host
+ * Controller sets this bit to a one every time FHINDEX [12] toggles.
+ * Only used in host operation mode.
+ */
+#define USB_USBSTS_FRI_MASK (0x8U)
+#define USB_USBSTS_FRI_SHIFT (3U)
+#define USB_USBSTS_FRI_SET(x) (((uint32_t)(x) << USB_USBSTS_FRI_SHIFT) & USB_USBSTS_FRI_MASK)
+#define USB_USBSTS_FRI_GET(x) (((uint32_t)(x) & USB_USBSTS_FRI_MASK) >> USB_USBSTS_FRI_SHIFT)
+
+/*
+ * PCI (RWC)
+ *
+ * PCI
+ * Port Change Detect - R/WC.
+ * The Host Controller sets this bit to a one when on any port a Connect Status occurs, a Port Enable/Disable Change occurs,
+ * or the Force Port Resume bit is set as the result of a J-K transition on the suspended port.
+ * The Device Controller sets this bit to a one when the port controller enters the full or high-speed operational state.
+ * When the port controller exits the full or high-speed operation states due to Reset or Suspend events,
+ * the notification mechanisms are the USB Reset Received bit and the DCSuspend bits Respectively.
+ */
+#define USB_USBSTS_PCI_MASK (0x4U)
+#define USB_USBSTS_PCI_SHIFT (2U)
+#define USB_USBSTS_PCI_SET(x) (((uint32_t)(x) << USB_USBSTS_PCI_SHIFT) & USB_USBSTS_PCI_MASK)
+#define USB_USBSTS_PCI_GET(x) (((uint32_t)(x) & USB_USBSTS_PCI_MASK) >> USB_USBSTS_PCI_SHIFT)
+
+/*
+ * UEI (RWC)
+ *
+ * UEI
+ * USB Error Interrupt (USBERRINT) - R/WC.
+ * When completion of a USB transaction results in an error condition, this bit is set by the Host/Device Controller.
+ * This bit is set along with the USBINT bit, if the TD on which the error interrupt occurred also had its interrupt on complete (IOC) bit set.
+ */
+#define USB_USBSTS_UEI_MASK (0x2U)
+#define USB_USBSTS_UEI_SHIFT (1U)
+#define USB_USBSTS_UEI_SET(x) (((uint32_t)(x) << USB_USBSTS_UEI_SHIFT) & USB_USBSTS_UEI_MASK)
+#define USB_USBSTS_UEI_GET(x) (((uint32_t)(x) & USB_USBSTS_UEI_MASK) >> USB_USBSTS_UEI_SHIFT)
+
+/*
+ * UI (RWC)
+ *
+ * UI
+ * USB Interrupt (USBINT) - R/WC.
+ * This bit is set by the Host/Device Controller when the cause of an interrupt is a completion of a USB
+ * transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set.
+ * This bit is also set by the Host/Device Controller when a short packet is detected. A short packet is when
+ * the actual number of bytes received was less than the expected number of bytes.
+ */
+#define USB_USBSTS_UI_MASK (0x1U)
+#define USB_USBSTS_UI_SHIFT (0U)
+#define USB_USBSTS_UI_SET(x) (((uint32_t)(x) << USB_USBSTS_UI_SHIFT) & USB_USBSTS_UI_MASK)
+#define USB_USBSTS_UI_GET(x) (((uint32_t)(x) & USB_USBSTS_UI_MASK) >> USB_USBSTS_UI_SHIFT)
+
+/* Bitfield definition for register: USBINTR */
+/*
+ * TIE1 (RW)
+ *
+ * TIE1
+ * General Purpose Timer #1 Interrupt Enable
+ * When this bit is one and the TI1 bit in n_USBSTS register is a one the controller will issue an interrupt.
+ */
+#define USB_USBINTR_TIE1_MASK (0x2000000UL)
+#define USB_USBINTR_TIE1_SHIFT (25U)
+#define USB_USBINTR_TIE1_SET(x) (((uint32_t)(x) << USB_USBINTR_TIE1_SHIFT) & USB_USBINTR_TIE1_MASK)
+#define USB_USBINTR_TIE1_GET(x) (((uint32_t)(x) & USB_USBINTR_TIE1_MASK) >> USB_USBINTR_TIE1_SHIFT)
+
+/*
+ * TIE0 (RW)
+ *
+ * TIE0
+ * General Purpose Timer #0 Interrupt Enable
+ * When this bit is one and the TI0 bit in n_USBSTS register is a one the controller will issue an interrupt.
+ */
+#define USB_USBINTR_TIE0_MASK (0x1000000UL)
+#define USB_USBINTR_TIE0_SHIFT (24U)
+#define USB_USBINTR_TIE0_SET(x) (((uint32_t)(x) << USB_USBINTR_TIE0_SHIFT) & USB_USBINTR_TIE0_MASK)
+#define USB_USBINTR_TIE0_GET(x) (((uint32_t)(x) & USB_USBINTR_TIE0_MASK) >> USB_USBINTR_TIE0_SHIFT)
+
+/*
+ * UPIE (RW)
+ *
+ * UPIE
+ * USB Host Periodic Interrupt Enable
+ * When this bit is one, and the UPI bit in the n_USBSTS register is one, host controller will issue an
+ * interrupt at the next interrupt threshold.
+ */
+#define USB_USBINTR_UPIE_MASK (0x80000UL)
+#define USB_USBINTR_UPIE_SHIFT (19U)
+#define USB_USBINTR_UPIE_SET(x) (((uint32_t)(x) << USB_USBINTR_UPIE_SHIFT) & USB_USBINTR_UPIE_MASK)
+#define USB_USBINTR_UPIE_GET(x) (((uint32_t)(x) & USB_USBINTR_UPIE_MASK) >> USB_USBINTR_UPIE_SHIFT)
+
+/*
+ * UAIE (RW)
+ *
+ * UAIE
+ * USB Host Asynchronous Interrupt Enable
+ * When this bit is one, and the UAI bit in the n_USBSTS register is one, host controller will issue an
+ * interrupt at the next interrupt threshold.
+ */
+#define USB_USBINTR_UAIE_MASK (0x40000UL)
+#define USB_USBINTR_UAIE_SHIFT (18U)
+#define USB_USBINTR_UAIE_SET(x) (((uint32_t)(x) << USB_USBINTR_UAIE_SHIFT) & USB_USBINTR_UAIE_MASK)
+#define USB_USBINTR_UAIE_GET(x) (((uint32_t)(x) & USB_USBINTR_UAIE_MASK) >> USB_USBINTR_UAIE_SHIFT)
+
+/*
+ * NAKE (RO)
+ *
+ * NAKE
+ * NAK Interrupt Enable
+ * When this bit is one and the NAKI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ */
+#define USB_USBINTR_NAKE_MASK (0x10000UL)
+#define USB_USBINTR_NAKE_SHIFT (16U)
+#define USB_USBINTR_NAKE_GET(x) (((uint32_t)(x) & USB_USBINTR_NAKE_MASK) >> USB_USBINTR_NAKE_SHIFT)
+
+/*
+ * SLE (RW)
+ *
+ * SLE
+ * Sleep Interrupt Enable
+ * When this bit is one and the SLI bit in n_n_USBSTS register is a one the controller will issue an interrupt.
+ * Only used in device operation mode.
+ */
+#define USB_USBINTR_SLE_MASK (0x100U)
+#define USB_USBINTR_SLE_SHIFT (8U)
+#define USB_USBINTR_SLE_SET(x) (((uint32_t)(x) << USB_USBINTR_SLE_SHIFT) & USB_USBINTR_SLE_MASK)
+#define USB_USBINTR_SLE_GET(x) (((uint32_t)(x) & USB_USBINTR_SLE_MASK) >> USB_USBINTR_SLE_SHIFT)
+
+/*
+ * SRE (RW)
+ *
+ * SRE
+ * SOF Received Interrupt Enable
+ * When this bit is one and the SRI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ */
+#define USB_USBINTR_SRE_MASK (0x80U)
+#define USB_USBINTR_SRE_SHIFT (7U)
+#define USB_USBINTR_SRE_SET(x) (((uint32_t)(x) << USB_USBINTR_SRE_SHIFT) & USB_USBINTR_SRE_MASK)
+#define USB_USBINTR_SRE_GET(x) (((uint32_t)(x) & USB_USBINTR_SRE_MASK) >> USB_USBINTR_SRE_SHIFT)
+
+/*
+ * URE (RW)
+ *
+ * URE
+ * USB Reset Interrupt Enable
+ * When this bit is one and the URI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ * Only used in device operation mode.
+ */
+#define USB_USBINTR_URE_MASK (0x40U)
+#define USB_USBINTR_URE_SHIFT (6U)
+#define USB_USBINTR_URE_SET(x) (((uint32_t)(x) << USB_USBINTR_URE_SHIFT) & USB_USBINTR_URE_MASK)
+#define USB_USBINTR_URE_GET(x) (((uint32_t)(x) & USB_USBINTR_URE_MASK) >> USB_USBINTR_URE_SHIFT)
+
+/*
+ * AAE (RW)
+ *
+ * AAE
+ * Async Advance Interrupt Enable
+ * When this bit is one and the AAI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ * Only used in host operation mode.
+ */
+#define USB_USBINTR_AAE_MASK (0x20U)
+#define USB_USBINTR_AAE_SHIFT (5U)
+#define USB_USBINTR_AAE_SET(x) (((uint32_t)(x) << USB_USBINTR_AAE_SHIFT) & USB_USBINTR_AAE_MASK)
+#define USB_USBINTR_AAE_GET(x) (((uint32_t)(x) & USB_USBINTR_AAE_MASK) >> USB_USBINTR_AAE_SHIFT)
+
+/*
+ * SEE (RW)
+ *
+ * SEE
+ * System Error Interrupt Enable
+ * When this bit is one and the SEI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ * Only used in host operation mode.
+ */
+#define USB_USBINTR_SEE_MASK (0x10U)
+#define USB_USBINTR_SEE_SHIFT (4U)
+#define USB_USBINTR_SEE_SET(x) (((uint32_t)(x) << USB_USBINTR_SEE_SHIFT) & USB_USBINTR_SEE_MASK)
+#define USB_USBINTR_SEE_GET(x) (((uint32_t)(x) & USB_USBINTR_SEE_MASK) >> USB_USBINTR_SEE_SHIFT)
+
+/*
+ * FRE (RW)
+ *
+ * FRE
+ * Frame List Rollover Interrupt Enable
+ * When this bit is one and the FRI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ * Only used in host operation mode.
+ */
+#define USB_USBINTR_FRE_MASK (0x8U)
+#define USB_USBINTR_FRE_SHIFT (3U)
+#define USB_USBINTR_FRE_SET(x) (((uint32_t)(x) << USB_USBINTR_FRE_SHIFT) & USB_USBINTR_FRE_MASK)
+#define USB_USBINTR_FRE_GET(x) (((uint32_t)(x) & USB_USBINTR_FRE_MASK) >> USB_USBINTR_FRE_SHIFT)
+
+/*
+ * PCE (RW)
+ *
+ * PCE
+ * Port Change Detect Interrupt Enable
+ * When this bit is one and the PCI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ */
+#define USB_USBINTR_PCE_MASK (0x4U)
+#define USB_USBINTR_PCE_SHIFT (2U)
+#define USB_USBINTR_PCE_SET(x) (((uint32_t)(x) << USB_USBINTR_PCE_SHIFT) & USB_USBINTR_PCE_MASK)
+#define USB_USBINTR_PCE_GET(x) (((uint32_t)(x) & USB_USBINTR_PCE_MASK) >> USB_USBINTR_PCE_SHIFT)
+
+/*
+ * UEE (RWC)
+ *
+ * UEE
+ * USB Error Interrupt Enable
+ * When this bit is one and the UEI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ */
+#define USB_USBINTR_UEE_MASK (0x2U)
+#define USB_USBINTR_UEE_SHIFT (1U)
+#define USB_USBINTR_UEE_SET(x) (((uint32_t)(x) << USB_USBINTR_UEE_SHIFT) & USB_USBINTR_UEE_MASK)
+#define USB_USBINTR_UEE_GET(x) (((uint32_t)(x) & USB_USBINTR_UEE_MASK) >> USB_USBINTR_UEE_SHIFT)
+
+/*
+ * UE (RW)
+ *
+ * UE
+ * USB Interrupt Enable
+ * When this bit is one and the UI bit in n_USBSTS register is a one the controller will issue an interrupt.
+ */
+#define USB_USBINTR_UE_MASK (0x1U)
+#define USB_USBINTR_UE_SHIFT (0U)
+#define USB_USBINTR_UE_SET(x) (((uint32_t)(x) << USB_USBINTR_UE_SHIFT) & USB_USBINTR_UE_MASK)
+#define USB_USBINTR_UE_GET(x) (((uint32_t)(x) & USB_USBINTR_UE_MASK) >> USB_USBINTR_UE_SHIFT)
+
+/* Bitfield definition for register: FRINDEX */
+/*
+ * FRINDEX (RW)
+ *
+ * FRINDEX
+ * Frame Index.
+ * The value, in this register, increments at the end of each time frame (micro-frame). Bits [N: 3] are used for the Frame List current index.
+ * This means that each location of the frame list is accessed 8 times (frames or micro-frames) before moving to the next index.
+ * The following illustrates values of N based on the value of the Frame List Size field in the USBCMD register, when used in host mode.
+ * USBCMD [Frame List Size] Number Elements N
+ * In device mode the value is the current frame number of the last frame transmitted. It is not used as an index.
+ * In either mode bits 2:0 indicate the current microframe.
+ * The bit field values description below is represented as (Frame List Size) Number Elements N.
+ * 00000000000000 - (1024) 12
+ * 00000000000001 - (512) 11
+ * 00000000000010 - (256) 10
+ * 00000000000011 - (128) 9
+ * 00000000000100 - (64) 8
+ * 00000000000101 - (32) 7
+ * 00000000000110 - (16) 6
+ * 00000000000111 - (8) 5
+ */
+#define USB_FRINDEX_FRINDEX_MASK (0x3FFFU)
+#define USB_FRINDEX_FRINDEX_SHIFT (0U)
+#define USB_FRINDEX_FRINDEX_SET(x) (((uint32_t)(x) << USB_FRINDEX_FRINDEX_SHIFT) & USB_FRINDEX_FRINDEX_MASK)
+#define USB_FRINDEX_FRINDEX_GET(x) (((uint32_t)(x) & USB_FRINDEX_FRINDEX_MASK) >> USB_FRINDEX_FRINDEX_SHIFT)
+
+/* Bitfield definition for register: DEVICEADDR */
+/*
+ * USBADR (RW)
+ *
+ * USBADR
+ * Device Address.
+ * These bits correspond to the USB device address
+ */
+#define USB_DEVICEADDR_USBADR_MASK (0xFE000000UL)
+#define USB_DEVICEADDR_USBADR_SHIFT (25U)
+#define USB_DEVICEADDR_USBADR_SET(x) (((uint32_t)(x) << USB_DEVICEADDR_USBADR_SHIFT) & USB_DEVICEADDR_USBADR_MASK)
+#define USB_DEVICEADDR_USBADR_GET(x) (((uint32_t)(x) & USB_DEVICEADDR_USBADR_MASK) >> USB_DEVICEADDR_USBADR_SHIFT)
+
+/*
+ * USBADRA (RW)
+ *
+ * USBADRA
+ * Device Address Advance. Default=0.
+ * When this bit is '0', any writes to USBADR are instantaneous.
+ * When this bit is written to a '1' at the same time or before USBADR is written, the write to the USBADR field is staged and held in a hidden register.
+ * After an IN occurs on endpoint 0 and is ACKed, USBADR will be loaded from the holding register.
+ * Hardware will automatically clear this bit on the following conditions:
+ * 1) IN is ACKed to endpoint 0. (USBADR is updated from staging register).
+ * 2) OUT/SETUP occur to endpoint 0. (USBADR is not updated).
+ * 3) Device Reset occurs (USBADR is reset to 0).
+ * NOTE: After the status phase of the SET_ADDRESS descriptor, the DCD has 2 ms to program the USBADR field.
+ * This mechanism will ensure this specification is met when the DCD can not write of the device address within 2ms from the SET_ADDRESS status phase.
+ * If the DCD writes the USBADR with USBADRA=1 after the SET_ADDRESS data phase (before the prime of the status phase),
+ * the USBADR will be programmed instantly at the correct time and meet the 2ms USB requirement.
+ */
+#define USB_DEVICEADDR_USBADRA_MASK (0x1000000UL)
+#define USB_DEVICEADDR_USBADRA_SHIFT (24U)
+#define USB_DEVICEADDR_USBADRA_SET(x) (((uint32_t)(x) << USB_DEVICEADDR_USBADRA_SHIFT) & USB_DEVICEADDR_USBADRA_MASK)
+#define USB_DEVICEADDR_USBADRA_GET(x) (((uint32_t)(x) & USB_DEVICEADDR_USBADRA_MASK) >> USB_DEVICEADDR_USBADRA_SHIFT)
+
+/* Bitfield definition for register: PERIODICLISTBASE */
+/*
+ * BASEADR (RW)
+ *
+ * BASEADR
+ * Base Address (Low).
+ * These bits correspond to memory address signals [31:12], respectively.
+ * Only used by the host controller.
+ */
+#define USB_PERIODICLISTBASE_BASEADR_MASK (0xFFFFF000UL)
+#define USB_PERIODICLISTBASE_BASEADR_SHIFT (12U)
+#define USB_PERIODICLISTBASE_BASEADR_SET(x) (((uint32_t)(x) << USB_PERIODICLISTBASE_BASEADR_SHIFT) & USB_PERIODICLISTBASE_BASEADR_MASK)
+#define USB_PERIODICLISTBASE_BASEADR_GET(x) (((uint32_t)(x) & USB_PERIODICLISTBASE_BASEADR_MASK) >> USB_PERIODICLISTBASE_BASEADR_SHIFT)
+
+/* Bitfield definition for register: ASYNCLISTADDR */
+/*
+ * ASYBASE (RW)
+ *
+ * ASYBASE
+ * Link Pointer Low (LPL).
+ * These bits correspond to memory address signals [31:5], respectively. This field may only reference a
+ * Queue Head (QH).
+ * Only used by the host controller.
+ */
+#define USB_ASYNCLISTADDR_ASYBASE_MASK (0xFFFFFFE0UL)
+#define USB_ASYNCLISTADDR_ASYBASE_SHIFT (5U)
+#define USB_ASYNCLISTADDR_ASYBASE_SET(x) (((uint32_t)(x) << USB_ASYNCLISTADDR_ASYBASE_SHIFT) & USB_ASYNCLISTADDR_ASYBASE_MASK)
+#define USB_ASYNCLISTADDR_ASYBASE_GET(x) (((uint32_t)(x) & USB_ASYNCLISTADDR_ASYBASE_MASK) >> USB_ASYNCLISTADDR_ASYBASE_SHIFT)
+
+/* Bitfield definition for register: ENDPTLISTADDR */
+/*
+ * EPBASE (RW)
+ *
+ * EPBASE
+ * Endpoint List Pointer(Low). These bits correspond to memory address signals [31:11], respectively.
+ * This field will reference a list of up to 32 Queue Head (QH) (that is, one queue head per endpoint & direction).
+ */
+#define USB_ENDPTLISTADDR_EPBASE_MASK (0xFFFFF800UL)
+#define USB_ENDPTLISTADDR_EPBASE_SHIFT (11U)
+#define USB_ENDPTLISTADDR_EPBASE_SET(x) (((uint32_t)(x) << USB_ENDPTLISTADDR_EPBASE_SHIFT) & USB_ENDPTLISTADDR_EPBASE_MASK)
+#define USB_ENDPTLISTADDR_EPBASE_GET(x) (((uint32_t)(x) & USB_ENDPTLISTADDR_EPBASE_MASK) >> USB_ENDPTLISTADDR_EPBASE_SHIFT)
+
+/* Bitfield definition for register: BURSTSIZE */
+/*
+ * TXPBURST (RW)
+ *
+ * TXPBURST
+ * Programmable TX Burst Size.
+ * Default value is determined by TXBURST bits in n_HWTXBUF.
+ * This register represents the maximum length of a the burst in 32-bit words while moving data from system
+ * memory to the USB bus.
+ */
+#define USB_BURSTSIZE_TXPBURST_MASK (0xFF00U)
+#define USB_BURSTSIZE_TXPBURST_SHIFT (8U)
+#define USB_BURSTSIZE_TXPBURST_SET(x) (((uint32_t)(x) << USB_BURSTSIZE_TXPBURST_SHIFT) & USB_BURSTSIZE_TXPBURST_MASK)
+#define USB_BURSTSIZE_TXPBURST_GET(x) (((uint32_t)(x) & USB_BURSTSIZE_TXPBURST_MASK) >> USB_BURSTSIZE_TXPBURST_SHIFT)
+
+/*
+ * RXPBURST (RW)
+ *
+ * RXPBURST
+ * Programmable RX Burst Size.
+ * Default value is determined by TXBURST bits in n_HWRXBUF.
+ * This register represents the maximum length of a the burst in 32-bit words while moving data from the
+ * USB bus to system memory.
+ */
+#define USB_BURSTSIZE_RXPBURST_MASK (0xFFU)
+#define USB_BURSTSIZE_RXPBURST_SHIFT (0U)
+#define USB_BURSTSIZE_RXPBURST_SET(x) (((uint32_t)(x) << USB_BURSTSIZE_RXPBURST_SHIFT) & USB_BURSTSIZE_RXPBURST_MASK)
+#define USB_BURSTSIZE_RXPBURST_GET(x) (((uint32_t)(x) & USB_BURSTSIZE_RXPBURST_MASK) >> USB_BURSTSIZE_RXPBURST_SHIFT)
+
+/* Bitfield definition for register: TXFILLTUNING */
+/*
+ * TXFIFOTHRES (RW)
+ *
+ * TXFIFOTHRES
+ * FIFO Burst Threshold. (Read/Write)
+ * This register controls the number of data bursts that are posted to the TX latency FIFO in host mode before the packet begins on to the bus.
+ * The minimum value is 2 and this value should be a low as possible to maximize USB performance.
+ * A higher value can be used in systems with unpredictable latency and/or insufficient bandwidth
+ * where the FIFO may underrun because the data transferred from the latency FIFO to USB occurs before it can be replenished from system memory.
+ * This value is ignored if the Stream Disable bit in USB_n_USBMODE register is set.
+ */
+#define USB_TXFILLTUNING_TXFIFOTHRES_MASK (0x3F0000UL)
+#define USB_TXFILLTUNING_TXFIFOTHRES_SHIFT (16U)
+#define USB_TXFILLTUNING_TXFIFOTHRES_SET(x) (((uint32_t)(x) << USB_TXFILLTUNING_TXFIFOTHRES_SHIFT) & USB_TXFILLTUNING_TXFIFOTHRES_MASK)
+#define USB_TXFILLTUNING_TXFIFOTHRES_GET(x) (((uint32_t)(x) & USB_TXFILLTUNING_TXFIFOTHRES_MASK) >> USB_TXFILLTUNING_TXFIFOTHRES_SHIFT)
+
+/*
+ * TXSCHHEALTH (RWC)
+ *
+ * TXSCHHEALTH
+ * Scheduler Health Counter. (Read/Write To Clear)
+ * Table continues on the next page
+ * This register increments when the host controller fails to fill the TX latency FIFO to the level programmed by TXFIFOTHRES
+ * before running out of time to send the packet before the next Start-Of-Frame.
+ * This health counter measures the number of times this occurs to provide feedback to selecting a proper TXSCHOH.
+ * Writing to this register will clear the counter and this counter will max. at 31.
+ */
+#define USB_TXFILLTUNING_TXSCHHEALTH_MASK (0x1F00U)
+#define USB_TXFILLTUNING_TXSCHHEALTH_SHIFT (8U)
+#define USB_TXFILLTUNING_TXSCHHEALTH_SET(x) (((uint32_t)(x) << USB_TXFILLTUNING_TXSCHHEALTH_SHIFT) & USB_TXFILLTUNING_TXSCHHEALTH_MASK)
+#define USB_TXFILLTUNING_TXSCHHEALTH_GET(x) (((uint32_t)(x) & USB_TXFILLTUNING_TXSCHHEALTH_MASK) >> USB_TXFILLTUNING_TXSCHHEALTH_SHIFT)
+
+/*
+ * TXSCHOH (RW)
+ *
+ * TXSCHOH
+ * Scheduler Overhead. (Read/Write) [Default = 0]
+ * This register adds an additional fixed offset to the schedule time estimator described above as Tff.
+ * As an approximation, the value chosen for this register should limit the number of back-off events captured
+ * in the TXSCHHEALTH to less than 10 per second in a highly utilized bus.
+ * Choosing a value that is too high for this register is not desired as it can needlessly reduce USB utilization.
+ * The time unit represented in this register is 1.267us when a device is connected in High-Speed Mode.
+ * The time unit represented in this register is 6.333us when a device is connected in Low/Full Speed Mode.
+ * Default value is '08h' for OTG controller core .
+ */
+#define USB_TXFILLTUNING_TXSCHOH_MASK (0x7FU)
+#define USB_TXFILLTUNING_TXSCHOH_SHIFT (0U)
+#define USB_TXFILLTUNING_TXSCHOH_SET(x) (((uint32_t)(x) << USB_TXFILLTUNING_TXSCHOH_SHIFT) & USB_TXFILLTUNING_TXSCHOH_MASK)
+#define USB_TXFILLTUNING_TXSCHOH_GET(x) (((uint32_t)(x) & USB_TXFILLTUNING_TXSCHOH_MASK) >> USB_TXFILLTUNING_TXSCHOH_SHIFT)
+
+/* Bitfield definition for register: ENDPTNAK */
+/*
+ * EPTN (RWC)
+ *
+ * EPTN
+ * TX Endpoint NAK - R/WC.
+ * Each TX endpoint has 1 bit in this field. The bit is set when the
+ * device sends a NAK handshake on a received IN token for the corresponding endpoint.
+ * Bit [N] - Endpoint #[N], N is 0-7
+ */
+#define USB_ENDPTNAK_EPTN_MASK (0xFFFF0000UL)
+#define USB_ENDPTNAK_EPTN_SHIFT (16U)
+#define USB_ENDPTNAK_EPTN_SET(x) (((uint32_t)(x) << USB_ENDPTNAK_EPTN_SHIFT) & USB_ENDPTNAK_EPTN_MASK)
+#define USB_ENDPTNAK_EPTN_GET(x) (((uint32_t)(x) & USB_ENDPTNAK_EPTN_MASK) >> USB_ENDPTNAK_EPTN_SHIFT)
+
+/*
+ * EPRN (RWC)
+ *
+ * EPRN
+ * RX Endpoint NAK - R/WC.
+ * Each RX endpoint has 1 bit in this field. The bit is set when the
+ * device sends a NAK handshake on a received OUT or PING token for the corresponding endpoint.
+ * Bit [N] - Endpoint #[N], N is 0-7
+ */
+#define USB_ENDPTNAK_EPRN_MASK (0xFFFFU)
+#define USB_ENDPTNAK_EPRN_SHIFT (0U)
+#define USB_ENDPTNAK_EPRN_SET(x) (((uint32_t)(x) << USB_ENDPTNAK_EPRN_SHIFT) & USB_ENDPTNAK_EPRN_MASK)
+#define USB_ENDPTNAK_EPRN_GET(x) (((uint32_t)(x) & USB_ENDPTNAK_EPRN_MASK) >> USB_ENDPTNAK_EPRN_SHIFT)
+
+/* Bitfield definition for register: ENDPTNAKEN */
+/*
+ * EPTNE (RW)
+ *
+ * EPTNE
+ * TX Endpoint NAK Enable - R/W.
+ * Each bit is an enable bit for the corresponding TX Endpoint NAK bit. If this bit is set and the
+ * corresponding TX Endpoint NAK bit is set, the NAK Interrupt bit is set.
+ * Bit [N] - Endpoint #[N], N is 0-7
+ */
+#define USB_ENDPTNAKEN_EPTNE_MASK (0xFFFF0000UL)
+#define USB_ENDPTNAKEN_EPTNE_SHIFT (16U)
+#define USB_ENDPTNAKEN_EPTNE_SET(x) (((uint32_t)(x) << USB_ENDPTNAKEN_EPTNE_SHIFT) & USB_ENDPTNAKEN_EPTNE_MASK)
+#define USB_ENDPTNAKEN_EPTNE_GET(x) (((uint32_t)(x) & USB_ENDPTNAKEN_EPTNE_MASK) >> USB_ENDPTNAKEN_EPTNE_SHIFT)
+
+/*
+ * EPRNE (RW)
+ *
+ * EPRNE
+ * RX Endpoint NAK Enable - R/W.
+ * Each bit is an enable bit for the corresponding RX Endpoint NAK bit. If this bit is set and the
+ * corresponding RX Endpoint NAK bit is set, the NAK Interrupt bit is set.
+ * Bit [N] - Endpoint #[N], N is 0-7
+ */
+#define USB_ENDPTNAKEN_EPRNE_MASK (0xFFFFU)
+#define USB_ENDPTNAKEN_EPRNE_SHIFT (0U)
+#define USB_ENDPTNAKEN_EPRNE_SET(x) (((uint32_t)(x) << USB_ENDPTNAKEN_EPRNE_SHIFT) & USB_ENDPTNAKEN_EPRNE_MASK)
+#define USB_ENDPTNAKEN_EPRNE_GET(x) (((uint32_t)(x) & USB_ENDPTNAKEN_EPRNE_MASK) >> USB_ENDPTNAKEN_EPRNE_SHIFT)
+
+/* Bitfield definition for register: PORTSC1 */
+/*
+ * STS (RW)
+ *
+ * STS
+ * Serial Transceiver Select
+ * 1 Serial Interface Engine is selected
+ * 0 Parallel Interface signals is selected
+ * Serial Interface Engine can be used in combination with UTMI+/ULPI physical interface to provide FS/LS signaling instead of the parallel interface signals.
+ * When this bit is set '1b', serial interface engine will be used instead of parallel interface signals.
+ */
+#define USB_PORTSC1_STS_MASK (0x20000000UL)
+#define USB_PORTSC1_STS_SHIFT (29U)
+#define USB_PORTSC1_STS_SET(x) (((uint32_t)(x) << USB_PORTSC1_STS_SHIFT) & USB_PORTSC1_STS_MASK)
+#define USB_PORTSC1_STS_GET(x) (((uint32_t)(x) & USB_PORTSC1_STS_MASK) >> USB_PORTSC1_STS_SHIFT)
+
+/*
+ * PTW (RW)
+ *
+ * PTW
+ * Parallel Transceiver Width
+ * This bit has no effect if serial interface engine is used.
+ * 0 - Select the 8-bit UTMI interface [60MHz]
+ * 1 - Select the 16-bit UTMI interface [30MHz]
+ */
+#define USB_PORTSC1_PTW_MASK (0x10000000UL)
+#define USB_PORTSC1_PTW_SHIFT (28U)
+#define USB_PORTSC1_PTW_SET(x) (((uint32_t)(x) << USB_PORTSC1_PTW_SHIFT) & USB_PORTSC1_PTW_MASK)
+#define USB_PORTSC1_PTW_GET(x) (((uint32_t)(x) & USB_PORTSC1_PTW_MASK) >> USB_PORTSC1_PTW_SHIFT)
+
+/*
+ * PSPD (RO)
+ *
+ * PSPD
+ * Port Speed - Read Only.
+ * This register field indicates the speed at which the port is operating.
+ * 00 - Full Speed
+ * 01 - Low Speed
+ * 10 - High Speed
+ * 11 - Undefined
+ */
+#define USB_PORTSC1_PSPD_MASK (0xC000000UL)
+#define USB_PORTSC1_PSPD_SHIFT (26U)
+#define USB_PORTSC1_PSPD_GET(x) (((uint32_t)(x) & USB_PORTSC1_PSPD_MASK) >> USB_PORTSC1_PSPD_SHIFT)
+
+/*
+ * PFSC (RW)
+ *
+ * PFSC
+ * Port Force Full Speed Connect - Read/Write. Default = 0b.
+ * When this bit is set to '1b', the port will be forced to only connect at Full Speed, It disables the chirp
+ * sequence that allows the port to identify itself as High Speed.
+ * 0 - Normal operation
+ * 1 - Forced to full speed
+ */
+#define USB_PORTSC1_PFSC_MASK (0x1000000UL)
+#define USB_PORTSC1_PFSC_SHIFT (24U)
+#define USB_PORTSC1_PFSC_SET(x) (((uint32_t)(x) << USB_PORTSC1_PFSC_SHIFT) & USB_PORTSC1_PFSC_MASK)
+#define USB_PORTSC1_PFSC_GET(x) (((uint32_t)(x) & USB_PORTSC1_PFSC_MASK) >> USB_PORTSC1_PFSC_SHIFT)
+
+/*
+ * PHCD (RW)
+ *
+ * PHCD
+ * PHY Low Power Suspend - Clock Disable (PLPSCD) - Read/Write. Default = 0b.
+ * When this bit is set to '1b', the PHY clock is disabled. Reading this bit will indicate the status of the PHY
+ * clock.
+ * NOTE: The PHY clock cannot be disabled if it is being used as the system clock.
+ * In device mode, The PHY can be put into Low Power Suspend when the device is not running (USBCMD
+ * Run/Stop=0b) or the host has signalled suspend (PORTSC1 SUSPEND=1b). PHY Low power suspend
+ * will be cleared automatically when the host initials resume. Before forcing a resume from the device, the
+ * device controller driver must clear this bit.
+ * In host mode, the PHY can be put into Low Power Suspend when the downstream device has been put
+ * into suspend mode or when no downstream device is connected. Low power suspend is completely
+ * under the control of software.
+ * 0 - Enable PHY clock
+ * 1 - Disable PHY clock
+ */
+#define USB_PORTSC1_PHCD_MASK (0x800000UL)
+#define USB_PORTSC1_PHCD_SHIFT (23U)
+#define USB_PORTSC1_PHCD_SET(x) (((uint32_t)(x) << USB_PORTSC1_PHCD_SHIFT) & USB_PORTSC1_PHCD_MASK)
+#define USB_PORTSC1_PHCD_GET(x) (((uint32_t)(x) & USB_PORTSC1_PHCD_MASK) >> USB_PORTSC1_PHCD_SHIFT)
+
+/*
+ * WKOC (RW)
+ *
+ * WKOC
+ * Wake on Over-current Enable (WKOC_E) - Read/Write. Default = 0b.
+ * Writing this bit to a one enables the port to be sensitive to over-current conditions as wake-up events.
+ * This field is zero if Port Power(PORTSC1) is zero.
+ */
+#define USB_PORTSC1_WKOC_MASK (0x400000UL)
+#define USB_PORTSC1_WKOC_SHIFT (22U)
+#define USB_PORTSC1_WKOC_SET(x) (((uint32_t)(x) << USB_PORTSC1_WKOC_SHIFT) & USB_PORTSC1_WKOC_MASK)
+#define USB_PORTSC1_WKOC_GET(x) (((uint32_t)(x) & USB_PORTSC1_WKOC_MASK) >> USB_PORTSC1_WKOC_SHIFT)
+
+/*
+ * WKDC (RW)
+ *
+ * WKDC
+ * Wake on Disconnect Enable (WKDSCNNT_E) - Read/Write. Default=0b. Writing this bit to a one enables
+ * the port to be sensitive to device disconnects as wake-up events.
+ * This field is zero if Port Power(PORTSC1) is zero or in device mode.
+ */
+#define USB_PORTSC1_WKDC_MASK (0x200000UL)
+#define USB_PORTSC1_WKDC_SHIFT (21U)
+#define USB_PORTSC1_WKDC_SET(x) (((uint32_t)(x) << USB_PORTSC1_WKDC_SHIFT) & USB_PORTSC1_WKDC_MASK)
+#define USB_PORTSC1_WKDC_GET(x) (((uint32_t)(x) & USB_PORTSC1_WKDC_MASK) >> USB_PORTSC1_WKDC_SHIFT)
+
+/*
+ * WKCN (RW)
+ *
+ * WKCN
+ * Wake on Connect Enable (WKCNNT_E) - Read/Write. Default=0b.
+ * Writing this bit to a one enables the port to be sensitive to device connects as wake-up events.
+ * This field is zero if Port Power(PORTSC1) is zero or in device mode.
+ */
+#define USB_PORTSC1_WKCN_MASK (0x100000UL)
+#define USB_PORTSC1_WKCN_SHIFT (20U)
+#define USB_PORTSC1_WKCN_SET(x) (((uint32_t)(x) << USB_PORTSC1_WKCN_SHIFT) & USB_PORTSC1_WKCN_MASK)
+#define USB_PORTSC1_WKCN_GET(x) (((uint32_t)(x) & USB_PORTSC1_WKCN_MASK) >> USB_PORTSC1_WKCN_SHIFT)
+
+/*
+ * PTC (RW)
+ *
+ * PTC
+ * Port Test Control - Read/Write. Default = 0000b.
+ * Refer to Port Test Mode for the operational model for using these test modes and the USB Specification Revision 2.0, Chapter 7 for details on each test mode.
+ * The FORCE_ENABLE_FS and FORCE ENABLE_LS are extensions to the test mode support specified in the EHCI specification.
+ * Writing the PTC field to any of the FORCE_ENABLE_{HS/FS/LS} values will force the port into the connected and enabled state at the selected speed.
+ * Writing the PTC field back to TEST_MODE_DISABLE will allow the port state machines to progress normally from that point.
+ * NOTE: Low speed operations are not supported as a peripheral device.
+ * Any other value than zero indicates that the port is operating in test mode.
+ * Value Specific Test
+ * 0000 - TEST_MODE_DISABLE
+ * 0001 - J_STATE
+ * 0010 - K_STATE
+ * 0011 - SE0 (host) / NAK (device)
+ * 0100 - Packet
+ * 0101 - FORCE_ENABLE_HS
+ * 0110 - FORCE_ENABLE_FS
+ * 0111 - FORCE_ENABLE_LS
+ * 1000-1111 - Reserved
+ */
+#define USB_PORTSC1_PTC_MASK (0xF0000UL)
+#define USB_PORTSC1_PTC_SHIFT (16U)
+#define USB_PORTSC1_PTC_SET(x) (((uint32_t)(x) << USB_PORTSC1_PTC_SHIFT) & USB_PORTSC1_PTC_MASK)
+#define USB_PORTSC1_PTC_GET(x) (((uint32_t)(x) & USB_PORTSC1_PTC_MASK) >> USB_PORTSC1_PTC_SHIFT)
+
+/*
+ * PP (RW)
+ *
+ * PP
+ * Port Power (PP)-Read/Write or Read Only.
+ * The function of this bit depends on the value of the Port Power Switching (PPC) field in the HCSPARAMS register. The behavior is as follows:
+ * PPC
+ * PP Operation
+ * 0
+ * 1b Read Only - Host controller does not have port power control switches. Each port is hard-wired to power.
+ * 1
+ * 1b/0b - Read/Write. OTG controller requires port power control switches. This bit represents the current setting of the switch (0=off, 1=on).
+ * When power is not available on a port (that is, PP equals a 0), the port is non-functional and will not report attaches, detaches, etc.
+ * When an over-current condition is detected on a powered port and PPC is a one,
+ * the PP bit in each affected port may be transitional by the host controller driver from a one to a zero (removing power from the port).
+ * This feature is implemented in all controller cores (PPC = 1).
+ */
+#define USB_PORTSC1_PP_MASK (0x1000U)
+#define USB_PORTSC1_PP_SHIFT (12U)
+#define USB_PORTSC1_PP_SET(x) (((uint32_t)(x) << USB_PORTSC1_PP_SHIFT) & USB_PORTSC1_PP_MASK)
+#define USB_PORTSC1_PP_GET(x) (((uint32_t)(x) & USB_PORTSC1_PP_MASK) >> USB_PORTSC1_PP_SHIFT)
+
+/*
+ * LS (RO)
+ *
+ * LS
+ * Line Status-Read Only. These bits reflect the current logical levels of the D+ (bit 11) and D- (bit 10) signal
+ * lines.
+ * In host mode, the use of linestate by the host controller driver is not necessary (unlike EHCI), because
+ * the port controller state machine and the port routing manage the connection of LS and FS.
+ * In device mode, the use of linestate by the device controller driver is not necessary.
+ * The encoding of the bits are:
+ * Bits [11:10] Meaning
+ * 00 - SE0
+ * 01 - K-state
+ * 10 - J-state
+ * 11 - Undefined
+ */
+#define USB_PORTSC1_LS_MASK (0xC00U)
+#define USB_PORTSC1_LS_SHIFT (10U)
+#define USB_PORTSC1_LS_GET(x) (((uint32_t)(x) & USB_PORTSC1_LS_MASK) >> USB_PORTSC1_LS_SHIFT)
+
+/*
+ * HSP (RO)
+ *
+ * HSP
+ * High-Speed Port - Read Only. Default = 0b.
+ * When the bit is one, the host/device connected to the port is in high-speed mode and if set to zero, the
+ * host/device connected to the port is not in a high-speed mode.
+ * NOTE: HSP is redundant with PSPD(bit 27, 26) but remained for compatibility.
+ */
+#define USB_PORTSC1_HSP_MASK (0x200U)
+#define USB_PORTSC1_HSP_SHIFT (9U)
+#define USB_PORTSC1_HSP_GET(x) (((uint32_t)(x) & USB_PORTSC1_HSP_MASK) >> USB_PORTSC1_HSP_SHIFT)
+
+/*
+ * PR (RW)
+ *
+ * PR
+ * Port Reset - Read/Write or Read Only. Default = 0b.
+ * In Host Mode: Read/Write. 1=Port is in Reset. 0=Port is not in Reset. Default 0.
+ * When software writes a one to this bit the bus-reset sequence as defined in the USB Specification Revision 2.0 is started.
+ * This bit will automatically change to zero after the reset sequence is complete.
+ * This behavior is different from EHCI where the host controller driver is required to set this bit to a zero after the reset duration is timed in the driver.
+ * In Device Mode: This bit is a read only status bit. Device reset from the USB bus is also indicated in the USBSTS register.
+ */
+#define USB_PORTSC1_PR_MASK (0x100U)
+#define USB_PORTSC1_PR_SHIFT (8U)
+#define USB_PORTSC1_PR_SET(x) (((uint32_t)(x) << USB_PORTSC1_PR_SHIFT) & USB_PORTSC1_PR_MASK)
+#define USB_PORTSC1_PR_GET(x) (((uint32_t)(x) & USB_PORTSC1_PR_MASK) >> USB_PORTSC1_PR_SHIFT)
+
+/*
+ * SUSP (RW)
+ *
+ * SUSP
+ * Suspend - Read/Write or Read Only. Default = 0b.
+ * 1=Port in suspend state. 0=Port not in suspend state.
+ * In Host Mode: Read/Write.
+ * Port Enabled Bit and Suspend bit of this register define the port states as follows:
+ * Bits [Port Enabled, Suspend] Port State
+ * 0x Disable
+ * 10 Enable
+ * 11 Suspend
+ * When in suspend state, downstream propagation of data is blocked on this port, except for port reset.
+ * The blocking occurs at the end of the current transaction if a transaction was in progress when this bit was written to 1.
+ * In the suspend state, the port is sensitive to resume detection.
+ * Note that the bit status does not change until the port is suspended and that there may be a delay in suspending a port if there is a transaction currently in progress on the USB.
+ * The host controller will unconditionally set this bit to zero when software sets the Force Port Resume bit to zero. The host controller ignores a write of zero to this bit.
+ * If host software sets this bit to a one when the port is not enabled (that is, Port enabled bit is a zero) the results are undefined.
+ * This field is zero if Port Power(PORTSC1) is zero in host mode.
+ * In Device Mode: Read Only.
+ * In device mode this bit is a read only status bit.
+ */
+#define USB_PORTSC1_SUSP_MASK (0x80U)
+#define USB_PORTSC1_SUSP_SHIFT (7U)
+#define USB_PORTSC1_SUSP_SET(x) (((uint32_t)(x) << USB_PORTSC1_SUSP_SHIFT) & USB_PORTSC1_SUSP_MASK)
+#define USB_PORTSC1_SUSP_GET(x) (((uint32_t)(x) & USB_PORTSC1_SUSP_MASK) >> USB_PORTSC1_SUSP_SHIFT)
+
+/*
+ * FPR (RW)
+ *
+ * FPR
+ * Force Port Resume -Read/Write. 1= Resume detected/driven on port. 0=No resume (K-state) detected driven on port. Default = 0.
+ * In Host Mode:
+ * Software sets this bit to one to drive resume signaling. The Host Controller sets this bit to one if a J-to-K transition is detected while the port is in the Suspend state.
+ * When this bit transitions to a one because a J-to-K transition is detected, the Port Change Detect bit in the USBSTS register is also set to one.
+ * This bit will automatically change to zero after the resume sequence is complete.
+ * This behavior is different from EHCI where the host controller driver is required to set this bit to a zero after the resume duration is timed in the driver.
+ * Note that when the Host controller owns the port, the resume sequence follows the defined sequence documented in the USB Specification Revision 2.0.
+ * The resume signaling (Full-speed 'K') is driven on the port as long as this bit remains a one. This bit will remain a one until the port has switched to the high-speed idle.
+ * Writing a zero has no effect because the port controller will time the resume operation, clear the bit the port control state switches to HS or FS idle.
+ * This field is zero if Port Power(PORTSC1) is zero in host mode.
+ * This bit is not-EHCI compatible.
+ * In Device mode:
+ * After the device has been in Suspend State for 5ms or more, software must set this bit to one to drive resume signaling before clearing.
+ * The Device Controller will set this bit to one if a J-to-K transition is detected while the port is in the Suspend state.
+ * The bit will be cleared when the device returns to normal operation.
+ * Also, when this bit wil be cleared because a K-to-J transition detected, the Port Change Detect bit in the USBSTS register is also set to one.
+ */
+#define USB_PORTSC1_FPR_MASK (0x40U)
+#define USB_PORTSC1_FPR_SHIFT (6U)
+#define USB_PORTSC1_FPR_SET(x) (((uint32_t)(x) << USB_PORTSC1_FPR_SHIFT) & USB_PORTSC1_FPR_MASK)
+#define USB_PORTSC1_FPR_GET(x) (((uint32_t)(x) & USB_PORTSC1_FPR_MASK) >> USB_PORTSC1_FPR_SHIFT)
+
+/*
+ * OCC (RW)
+ *
+ * OCC
+ * Over-current Change-R/WC. Default=0.
+ * This bit is set '1b' by hardware when there is a change to Over-current Active. Software can clear this bit by writing a one to this bit position.
+ */
+#define USB_PORTSC1_OCC_MASK (0x20U)
+#define USB_PORTSC1_OCC_SHIFT (5U)
+#define USB_PORTSC1_OCC_SET(x) (((uint32_t)(x) << USB_PORTSC1_OCC_SHIFT) & USB_PORTSC1_OCC_MASK)
+#define USB_PORTSC1_OCC_GET(x) (((uint32_t)(x) & USB_PORTSC1_OCC_MASK) >> USB_PORTSC1_OCC_SHIFT)
+
+/*
+ * OCA (RO)
+ *
+ * OCA
+ * Over-current Active-Read Only. Default 0.
+ * This bit will automatically transition from one to zero when the over current condition is removed.
+ * 0 - This port does not have an over-current condition.
+ * 1 - This port currently has an over-current condition
+ */
+#define USB_PORTSC1_OCA_MASK (0x10U)
+#define USB_PORTSC1_OCA_SHIFT (4U)
+#define USB_PORTSC1_OCA_GET(x) (((uint32_t)(x) & USB_PORTSC1_OCA_MASK) >> USB_PORTSC1_OCA_SHIFT)
+
+/*
+ * PEC (RWC)
+ *
+ * PEC
+ * Port Enable/Disable Change-R/WC. 1=Port enabled/disabled status has changed. 0=No change. Default = 0.
+ * In Host Mode:
+ * For the root hub, this bit is set to a one only when a port is disabled due to disconnect on the port or
+ * due to the appropriate conditions existing at the EOF2 point (See Chapter 11 of the USB Specification).
+ * Software clears this by writing a one to it.
+ * This field is zero if Port Power(PORTSC1) is zero.
+ * In Device mode:
+ * The device port is always enabled, so this bit is always '0b'.
+ */
+#define USB_PORTSC1_PEC_MASK (0x8U)
+#define USB_PORTSC1_PEC_SHIFT (3U)
+#define USB_PORTSC1_PEC_SET(x) (((uint32_t)(x) << USB_PORTSC1_PEC_SHIFT) & USB_PORTSC1_PEC_MASK)
+#define USB_PORTSC1_PEC_GET(x) (((uint32_t)(x) & USB_PORTSC1_PEC_MASK) >> USB_PORTSC1_PEC_SHIFT)
+
+/*
+ * PE (RWC)
+ *
+ * PE
+ * Port Enabled/Disabled-Read/Write. 1=Enable. 0=Disable. Default 0.
+ * In Host Mode:
+ * Ports can only be enabled by the host controller as a part of the reset and enable. Software cannot enable a port by writing a one to this field.
+ * Ports can be disabled by either a fault condition (disconnect event or other fault condition) or by the host software.
+ * Note that the bit status does not change until the port state actually changes. There may be a delay in disabling or enabling a port due to other host controller and bus events.
+ * When the port is disabled, (0b) downstream propagation of data is blocked except for reset.
+ * This field is zero if Port Power(PORTSC1) is zero in host mode.
+ * In Device Mode:
+ * The device port is always enabled, so this bit is always '1b'.
+ */
+#define USB_PORTSC1_PE_MASK (0x4U)
+#define USB_PORTSC1_PE_SHIFT (2U)
+#define USB_PORTSC1_PE_SET(x) (((uint32_t)(x) << USB_PORTSC1_PE_SHIFT) & USB_PORTSC1_PE_MASK)
+#define USB_PORTSC1_PE_GET(x) (((uint32_t)(x) & USB_PORTSC1_PE_MASK) >> USB_PORTSC1_PE_SHIFT)
+
+/*
+ * CSC (RWC)
+ *
+ * CSC
+ * Connect Status Change-R/WC. 1 =Change in Current Connect Status. 0=No change. Default 0.
+ * In Host Mode:
+ * Indicates a change has occurred in the port's Current Connect Status.
+ * The host/device controller sets this bit for all changes to the port device connect status, even if system software has not cleared an existing connect status change.
+ * For example, the insertion status changes twice before system software has cleared the changed condition,
+ * hub hardware will be 'setting' an already-set bit (that is, the bit will remain set). Software clears this bit by writing a one to it.
+ * This field is zero if Port Power(PORTSC1) is zero in host mode.
+ * In Device Mode:
+ * This bit is undefined in device controller mode.
+ */
+#define USB_PORTSC1_CSC_MASK (0x2U)
+#define USB_PORTSC1_CSC_SHIFT (1U)
+#define USB_PORTSC1_CSC_SET(x) (((uint32_t)(x) << USB_PORTSC1_CSC_SHIFT) & USB_PORTSC1_CSC_MASK)
+#define USB_PORTSC1_CSC_GET(x) (((uint32_t)(x) & USB_PORTSC1_CSC_MASK) >> USB_PORTSC1_CSC_SHIFT)
+
+/*
+ * CCS (RWC)
+ *
+ * CCS
+ * Current Connect Status-Read Only.
+ * In Host Mode:
+ * 1=Device is present on port. 0=No device is present. Default = 0.
+ * This value reflects the current state of the port, and may not correspond directly to the event that caused the Connect Status Change bit (Bit 1) to be set.
+ * This field is zero if Port Power(PORTSC1) is zero in host mode.
+ * In Device Mode:
+ * 1=Attached. 0=Not Attached. Default=0.
+ * A one indicates that the device successfully attached and is operating in either high speed or full speed as indicated by the High Speed Port bit in this register.
+ * A zero indicates that the device did not attach successfully or was forcibly disconnected by the software writing a zero to the Run bit in the USBCMD register.
+ * It does not state the device being disconnected or Suspended.
+ */
+#define USB_PORTSC1_CCS_MASK (0x1U)
+#define USB_PORTSC1_CCS_SHIFT (0U)
+#define USB_PORTSC1_CCS_SET(x) (((uint32_t)(x) << USB_PORTSC1_CCS_SHIFT) & USB_PORTSC1_CCS_MASK)
+#define USB_PORTSC1_CCS_GET(x) (((uint32_t)(x) & USB_PORTSC1_CCS_MASK) >> USB_PORTSC1_CCS_SHIFT)
+
+/* Bitfield definition for register: OTGSC */
+/*
+ * ASVIE (RW)
+ *
+ * ASVIE
+ * A Session Valid Interrupt Enable - Read/Write.
+ */
+#define USB_OTGSC_ASVIE_MASK (0x4000000UL)
+#define USB_OTGSC_ASVIE_SHIFT (26U)
+#define USB_OTGSC_ASVIE_SET(x) (((uint32_t)(x) << USB_OTGSC_ASVIE_SHIFT) & USB_OTGSC_ASVIE_MASK)
+#define USB_OTGSC_ASVIE_GET(x) (((uint32_t)(x) & USB_OTGSC_ASVIE_MASK) >> USB_OTGSC_ASVIE_SHIFT)
+
+/*
+ * AVVIE (RW)
+ *
+ * AVVIE
+ * A VBus Valid Interrupt Enable - Read/Write.
+ * Setting this bit enables the A VBus valid interrupt.
+ */
+#define USB_OTGSC_AVVIE_MASK (0x2000000UL)
+#define USB_OTGSC_AVVIE_SHIFT (25U)
+#define USB_OTGSC_AVVIE_SET(x) (((uint32_t)(x) << USB_OTGSC_AVVIE_SHIFT) & USB_OTGSC_AVVIE_MASK)
+#define USB_OTGSC_AVVIE_GET(x) (((uint32_t)(x) & USB_OTGSC_AVVIE_MASK) >> USB_OTGSC_AVVIE_SHIFT)
+
+/*
+ * IDIE (RW)
+ *
+ * IDIE
+ * USB ID Interrupt Enable - Read/Write.
+ * Setting this bit enables the USB ID interrupt.
+ */
+#define USB_OTGSC_IDIE_MASK (0x1000000UL)
+#define USB_OTGSC_IDIE_SHIFT (24U)
+#define USB_OTGSC_IDIE_SET(x) (((uint32_t)(x) << USB_OTGSC_IDIE_SHIFT) & USB_OTGSC_IDIE_MASK)
+#define USB_OTGSC_IDIE_GET(x) (((uint32_t)(x) & USB_OTGSC_IDIE_MASK) >> USB_OTGSC_IDIE_SHIFT)
+
+/*
+ * ASVIS (RWC)
+ *
+ * ASVIS
+ * A Session Valid Interrupt Status - Read/Write to Clear.
+ * This bit is set when VBus has either risen above or fallen below the A session valid threshold.
+ * Software must write a one to clear this bit.
+ */
+#define USB_OTGSC_ASVIS_MASK (0x40000UL)
+#define USB_OTGSC_ASVIS_SHIFT (18U)
+#define USB_OTGSC_ASVIS_SET(x) (((uint32_t)(x) << USB_OTGSC_ASVIS_SHIFT) & USB_OTGSC_ASVIS_MASK)
+#define USB_OTGSC_ASVIS_GET(x) (((uint32_t)(x) & USB_OTGSC_ASVIS_MASK) >> USB_OTGSC_ASVIS_SHIFT)
+
+/*
+ * AVVIS (RWC)
+ *
+ * AVVIS
+ * A VBus Valid Interrupt Status - Read/Write to Clear.
+ * This bit is set when VBus has either risen above or fallen below the VBus valid threshold on an A device.
+ * Software must write a one to clear this bit.
+ */
+#define USB_OTGSC_AVVIS_MASK (0x20000UL)
+#define USB_OTGSC_AVVIS_SHIFT (17U)
+#define USB_OTGSC_AVVIS_SET(x) (((uint32_t)(x) << USB_OTGSC_AVVIS_SHIFT) & USB_OTGSC_AVVIS_MASK)
+#define USB_OTGSC_AVVIS_GET(x) (((uint32_t)(x) & USB_OTGSC_AVVIS_MASK) >> USB_OTGSC_AVVIS_SHIFT)
+
+/*
+ * IDIS (RWC)
+ *
+ * IDIS
+ * USB ID Interrupt Status - Read/Write.
+ * This bit is set when a change on the ID input has been detected.
+ * Software must write a one to clear this bit.
+ */
+#define USB_OTGSC_IDIS_MASK (0x10000UL)
+#define USB_OTGSC_IDIS_SHIFT (16U)
+#define USB_OTGSC_IDIS_SET(x) (((uint32_t)(x) << USB_OTGSC_IDIS_SHIFT) & USB_OTGSC_IDIS_MASK)
+#define USB_OTGSC_IDIS_GET(x) (((uint32_t)(x) & USB_OTGSC_IDIS_MASK) >> USB_OTGSC_IDIS_SHIFT)
+
+/*
+ * ASV (RO)
+ *
+ * ASV
+ * A Session Valid - Read Only.
+ * Indicates VBus is above the A session valid threshold.
+ */
+#define USB_OTGSC_ASV_MASK (0x400U)
+#define USB_OTGSC_ASV_SHIFT (10U)
+#define USB_OTGSC_ASV_GET(x) (((uint32_t)(x) & USB_OTGSC_ASV_MASK) >> USB_OTGSC_ASV_SHIFT)
+
+/*
+ * AVV (RO)
+ *
+ * AVV
+ * A VBus Valid - Read Only.
+ * Indicates VBus is above the A VBus valid threshold.
+ */
+#define USB_OTGSC_AVV_MASK (0x200U)
+#define USB_OTGSC_AVV_SHIFT (9U)
+#define USB_OTGSC_AVV_GET(x) (((uint32_t)(x) & USB_OTGSC_AVV_MASK) >> USB_OTGSC_AVV_SHIFT)
+
+/*
+ * ID (RO)
+ *
+ * ID
+ * USB ID - Read Only.
+ * 0 = A device, 1 = B device
+ */
+#define USB_OTGSC_ID_MASK (0x100U)
+#define USB_OTGSC_ID_SHIFT (8U)
+#define USB_OTGSC_ID_GET(x) (((uint32_t)(x) & USB_OTGSC_ID_MASK) >> USB_OTGSC_ID_SHIFT)
+
+/*
+ * IDPU (RW)
+ *
+ * IDPU
+ * ID Pullup - Read/Write
+ * This bit provide control over the ID pull-up resistor; 0 = off, 1 = on [default]. When this bit is 0, the ID input
+ * will not be sampled.
+ */
+#define USB_OTGSC_IDPU_MASK (0x20U)
+#define USB_OTGSC_IDPU_SHIFT (5U)
+#define USB_OTGSC_IDPU_SET(x) (((uint32_t)(x) << USB_OTGSC_IDPU_SHIFT) & USB_OTGSC_IDPU_MASK)
+#define USB_OTGSC_IDPU_GET(x) (((uint32_t)(x) & USB_OTGSC_IDPU_MASK) >> USB_OTGSC_IDPU_SHIFT)
+
+/*
+ * VC (RW)
+ *
+ * VC
+ * VBUS Charge - Read/Write.
+ * Setting this bit causes the VBus line to be charged. This is used for VBus pulsing during SRP.
+ */
+#define USB_OTGSC_VC_MASK (0x2U)
+#define USB_OTGSC_VC_SHIFT (1U)
+#define USB_OTGSC_VC_SET(x) (((uint32_t)(x) << USB_OTGSC_VC_SHIFT) & USB_OTGSC_VC_MASK)
+#define USB_OTGSC_VC_GET(x) (((uint32_t)(x) & USB_OTGSC_VC_MASK) >> USB_OTGSC_VC_SHIFT)
+
+/*
+ * VD (RW)
+ *
+ * VD
+ * VBUS_Discharge - Read/Write.
+ * Setting this bit causes VBus to discharge through a resistor.
+ */
+#define USB_OTGSC_VD_MASK (0x1U)
+#define USB_OTGSC_VD_SHIFT (0U)
+#define USB_OTGSC_VD_SET(x) (((uint32_t)(x) << USB_OTGSC_VD_SHIFT) & USB_OTGSC_VD_MASK)
+#define USB_OTGSC_VD_GET(x) (((uint32_t)(x) & USB_OTGSC_VD_MASK) >> USB_OTGSC_VD_SHIFT)
+
+/* Bitfield definition for register: USBMODE */
+/*
+ * SDIS (RW)
+ *
+ * SDIS
+ * Stream Disable Mode. (0 - Inactive [default]; 1 - Active)
+ * Device Mode: Setting to a '1' disables double priming on both RX and TX for low bandwidth systems.
+ * This mode ensures that when the RX and TX buffers are sufficient to contain an entire packet that the standard double buffering scheme is disabled to prevent overruns/underruns in bandwidth limited systems.
+ * Note: In High Speed Mode, all packets received are responded to with a NYET handshake when stream disable is active.
+ * Host Mode: Setting to a '1' ensures that overruns/underruns of the latency FIFO are eliminated for low bandwidth systems
+ * where the RX and TX buffers are sufficient to contain the entire packet. Enabling stream disable also has the effect of ensuring the TX latency is filled to capacity before the packet is launched onto the USB.
+ * NOTE: Time duration to pre-fill the FIFO becomes significant when stream disable is active. See TXFILLTUNING and TXTTFILLTUNING [MPH Only] to characterize the adjustments needed for
+ * the scheduler when using this feature.
+ * NOTE: The use of this feature substantially limits of the overall USB performance that can be achieved.
+ */
+#define USB_USBMODE_SDIS_MASK (0x10U)
+#define USB_USBMODE_SDIS_SHIFT (4U)
+#define USB_USBMODE_SDIS_SET(x) (((uint32_t)(x) << USB_USBMODE_SDIS_SHIFT) & USB_USBMODE_SDIS_MASK)
+#define USB_USBMODE_SDIS_GET(x) (((uint32_t)(x) & USB_USBMODE_SDIS_MASK) >> USB_USBMODE_SDIS_SHIFT)
+
+/*
+ * SLOM (RW)
+ *
+ * SLOM
+ * Setup Lockout Mode. In device mode, this bit controls behavior of the setup lock mechanism. See Control Endpoint Operation Model .
+ * 0 - Setup Lockouts On (default);
+ * 1 - Setup Lockouts Off. DCD requires use of Setup Data Buffer Tripwire in USBCMD.
+ */
+#define USB_USBMODE_SLOM_MASK (0x8U)
+#define USB_USBMODE_SLOM_SHIFT (3U)
+#define USB_USBMODE_SLOM_SET(x) (((uint32_t)(x) << USB_USBMODE_SLOM_SHIFT) & USB_USBMODE_SLOM_MASK)
+#define USB_USBMODE_SLOM_GET(x) (((uint32_t)(x) & USB_USBMODE_SLOM_MASK) >> USB_USBMODE_SLOM_SHIFT)
+
+/*
+ * ES (RW)
+ *
+ * ES
+ * Endian Select - Read/Write. This bit can change the byte alignment of the transfer buffers to match the
+ * host microprocessor. The bit fields in the microprocessor interface and the data structures are unaffected
+ * by the value of this bit because they are based upon the 32-bit word.
+ * Bit Meaning
+ * 0 - Little Endian [Default]
+ * 1 - Big Endian
+ */
+#define USB_USBMODE_ES_MASK (0x4U)
+#define USB_USBMODE_ES_SHIFT (2U)
+#define USB_USBMODE_ES_SET(x) (((uint32_t)(x) << USB_USBMODE_ES_SHIFT) & USB_USBMODE_ES_MASK)
+#define USB_USBMODE_ES_GET(x) (((uint32_t)(x) & USB_USBMODE_ES_MASK) >> USB_USBMODE_ES_SHIFT)
+
+/*
+ * CM (RW)
+ *
+ * CM
+ * Controller Mode - R/WO. Controller mode is defaulted to the proper mode for host only and device only
+ * implementations. For those designs that contain both host & device capability, the controller defaults to
+ * an idle state and needs to be initialized to the desired operating mode after reset. For combination host/
+ * device controllers, this register can only be written once after reset. If it is necessary to switch modes,
+ * software must reset the controller by writing to the RESET bit in the USBCMD register before
+ * reprogramming this register.
+ * For OTG controller core, reset value is '00b'.
+ * 00 - Idle [Default for combination host/device]
+ * 01 - Reserved
+ * 10 - Device Controller [Default for device only controller]
+ * 11 - Host Controller [Default for host only controller]
+ */
+#define USB_USBMODE_CM_MASK (0x3U)
+#define USB_USBMODE_CM_SHIFT (0U)
+#define USB_USBMODE_CM_SET(x) (((uint32_t)(x) << USB_USBMODE_CM_SHIFT) & USB_USBMODE_CM_MASK)
+#define USB_USBMODE_CM_GET(x) (((uint32_t)(x) & USB_USBMODE_CM_MASK) >> USB_USBMODE_CM_SHIFT)
+
+/* Bitfield definition for register: ENDPTSETUPSTAT */
+/*
+ * ENDPTSETUPSTAT (RWC)
+ *
+ * ENDPTSETUPSTAT
+ * Setup Endpoint Status. For every setup transaction that is received, a corresponding bit in this register is set to one.
+ * Software must clear or acknowledge the setup transfer by writing a one to a respective bit after it has read the setup data from Queue head.
+ * The response to a setup packet as in the order of operations and total response time is crucial to limit bus time outs while the setup lock out mechanism is engaged.
+ * This register is only used in device mode.
+ */
+#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_MASK (0xFFFFU)
+#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT (0U)
+#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SET(x) (((uint32_t)(x) << USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT) & USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_MASK)
+#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_GET(x) (((uint32_t)(x) & USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_MASK) >> USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT)
+
+/* Bitfield definition for register: ENDPTPRIME */
+/*
+ * PETB (RWS)
+ *
+ * PETB
+ * Prime Endpoint Transmit Buffer - R/WS. For each endpoint a corresponding bit is used to request that a
+ * buffer is prepared for a transmit operation in order to respond to a USB IN/INTERRUPT transaction.
+ * Software should write a one to the corresponding bit when posting a new transfer descriptor to an
+ * endpoint queue head. Hardware automatically uses this bit to begin parsing for a new transfer descriptor
+ * from the queue head and prepare a transmit buffer. Hardware clears this bit when the associated
+ * endpoint(s) is (are) successfully primed.
+ * NOTE: These bits are momentarily set by hardware during hardware re-priming operations when a dTD
+ * is retired, and the dQH is updated.
+ * PETB[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTPRIME_PETB_MASK (0xFFFF0000UL)
+#define USB_ENDPTPRIME_PETB_SHIFT (16U)
+#define USB_ENDPTPRIME_PETB_SET(x) (((uint32_t)(x) << USB_ENDPTPRIME_PETB_SHIFT) & USB_ENDPTPRIME_PETB_MASK)
+#define USB_ENDPTPRIME_PETB_GET(x) (((uint32_t)(x) & USB_ENDPTPRIME_PETB_MASK) >> USB_ENDPTPRIME_PETB_SHIFT)
+
+/*
+ * PERB (RWS)
+ *
+ * PERB
+ * Prime Endpoint Receive Buffer - R/WS. For each endpoint, a corresponding bit is used to request a buffer prepare for a receive operation for when a USB host initiates a USB OUT transaction.
+ * Software should write a one to the corresponding bit whenever posting a new transfer descriptor to an endpoint queue head.
+ * Hardware automatically uses this bit to begin parsing for a new transfer descriptor from the queue head and prepare a receive buffer.
+ * Hardware clears this bit when the associated endpoint(s) is (are) successfully primed.
+ * NOTE: These bits are momentarily set by hardware during hardware re-priming operations when a dTD
+ * is retired, and the dQH is updated.
+ * PERB[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTPRIME_PERB_MASK (0xFFFFU)
+#define USB_ENDPTPRIME_PERB_SHIFT (0U)
+#define USB_ENDPTPRIME_PERB_SET(x) (((uint32_t)(x) << USB_ENDPTPRIME_PERB_SHIFT) & USB_ENDPTPRIME_PERB_MASK)
+#define USB_ENDPTPRIME_PERB_GET(x) (((uint32_t)(x) & USB_ENDPTPRIME_PERB_MASK) >> USB_ENDPTPRIME_PERB_SHIFT)
+
+/* Bitfield definition for register: ENDPTFLUSH */
+/*
+ * FETB (RWS)
+ *
+ * FETB
+ * Flush Endpoint Transmit Buffer - R/WS. Writing one to a bit(s) in this register causes the associated endpoint(s) to clear any primed buffers.
+ * If a packet is in progress for one of the associated endpoints, then that transfer continues until completion.
+ * Hardware clears this register after the endpoint flush operation is successful.
+ * FETB[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTFLUSH_FETB_MASK (0xFFFF0000UL)
+#define USB_ENDPTFLUSH_FETB_SHIFT (16U)
+#define USB_ENDPTFLUSH_FETB_SET(x) (((uint32_t)(x) << USB_ENDPTFLUSH_FETB_SHIFT) & USB_ENDPTFLUSH_FETB_MASK)
+#define USB_ENDPTFLUSH_FETB_GET(x) (((uint32_t)(x) & USB_ENDPTFLUSH_FETB_MASK) >> USB_ENDPTFLUSH_FETB_SHIFT)
+
+/*
+ * FERB (RWS)
+ *
+ * FERB
+ * Flush Endpoint Receive Buffer - R/WS. Writing one to a bit(s) causes the associated endpoint(s) to clear any primed buffers.
+ * If a packet is in progress for one of the associated endpoints, then that transfer continues until completion.
+ * Hardware clears this register after the endpoint flush operation is successful.
+ * FERB[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTFLUSH_FERB_MASK (0xFFFFU)
+#define USB_ENDPTFLUSH_FERB_SHIFT (0U)
+#define USB_ENDPTFLUSH_FERB_SET(x) (((uint32_t)(x) << USB_ENDPTFLUSH_FERB_SHIFT) & USB_ENDPTFLUSH_FERB_MASK)
+#define USB_ENDPTFLUSH_FERB_GET(x) (((uint32_t)(x) & USB_ENDPTFLUSH_FERB_MASK) >> USB_ENDPTFLUSH_FERB_SHIFT)
+
+/* Bitfield definition for register: ENDPTSTAT */
+/*
+ * ETBR (RO)
+ *
+ * ETBR
+ * Endpoint Transmit Buffer Ready -- Read Only. One bit for each endpoint indicates status of the respective endpoint buffer.
+ * This bit is set to one by the hardware as a response to receiving a command from a corresponding bit in the ENDPTPRIME register.
+ * There is always a delay between setting a bit in the ENDPTPRIME register and endpoint indicating ready.
+ * This delay time varies based upon the current USB traffic and the number of bits set in the ENDPRIME register.
+ * Buffer ready is cleared by USB reset, by the USB DMA system, or through the ENDPTFLUSH register.
+ * NOTE: These bits are momentarily cleared by hardware during hardware endpoint re-priming operations when a dTD is retired, and the dQH is updated.
+ * ETBR[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTSTAT_ETBR_MASK (0xFFFF0000UL)
+#define USB_ENDPTSTAT_ETBR_SHIFT (16U)
+#define USB_ENDPTSTAT_ETBR_GET(x) (((uint32_t)(x) & USB_ENDPTSTAT_ETBR_MASK) >> USB_ENDPTSTAT_ETBR_SHIFT)
+
+/*
+ * ERBR (RO)
+ *
+ * ERBR
+ * Endpoint Receive Buffer Ready -- Read Only. One bit for each endpoint indicates status of the respective
+ * endpoint buffer. This bit is set to a one by the hardware as a response to receiving a command from a
+ * corresponding bit in the ENDPRIME register. There is always a delay between setting a bit in the
+ * ENDPRIME register and endpoint indicating ready. This delay time varies based upon the current USB
+ * traffic and the number of bits set in the ENDPRIME register. Buffer ready is cleared by USB reset, by the
+ * USB DMA system, or through the ENDPTFLUSH register.
+ * NOTE: These bits are momentarily cleared by hardware during hardware endpoint re-priming operations
+ * when a dTD is retired, and the dQH is updated.
+ * ERBR[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTSTAT_ERBR_MASK (0xFFFFU)
+#define USB_ENDPTSTAT_ERBR_SHIFT (0U)
+#define USB_ENDPTSTAT_ERBR_GET(x) (((uint32_t)(x) & USB_ENDPTSTAT_ERBR_MASK) >> USB_ENDPTSTAT_ERBR_SHIFT)
+
+/* Bitfield definition for register: ENDPTCOMPLETE */
+/*
+ * ETCE (RWC)
+ *
+ * ETCE
+ * Endpoint Transmit Complete Event - R/WC. Each bit indicates a transmit event (IN/INTERRUPT) occurred and software should read the corresponding endpoint queue to determine the endpoint status.
+ * If the corresponding IOC bit is set in the Transfer Descriptor, then this bit is set simultaneously with the USBINT . Writing one clears the corresponding bit in this register.
+ * ETCE[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTCOMPLETE_ETCE_MASK (0xFFFF0000UL)
+#define USB_ENDPTCOMPLETE_ETCE_SHIFT (16U)
+#define USB_ENDPTCOMPLETE_ETCE_SET(x) (((uint32_t)(x) << USB_ENDPTCOMPLETE_ETCE_SHIFT) & USB_ENDPTCOMPLETE_ETCE_MASK)
+#define USB_ENDPTCOMPLETE_ETCE_GET(x) (((uint32_t)(x) & USB_ENDPTCOMPLETE_ETCE_MASK) >> USB_ENDPTCOMPLETE_ETCE_SHIFT)
+
+/*
+ * ERCE (RWC)
+ *
+ * ERCE
+ * Endpoint Receive Complete Event - RW/C. Each bit indicates a received event (OUT/SETUP) occurred
+ * and software should read the corresponding endpoint queue to determine the transfer status. If the
+ * corresponding IOC bit is set in the Transfer Descriptor, then this bit is set simultaneously with the
+ * USBINT . Writing one clears the corresponding bit in this register.
+ * ERCE[N] - Endpoint #N, N is in 0..7
+ */
+#define USB_ENDPTCOMPLETE_ERCE_MASK (0xFFFFU)
+#define USB_ENDPTCOMPLETE_ERCE_SHIFT (0U)
+#define USB_ENDPTCOMPLETE_ERCE_SET(x) (((uint32_t)(x) << USB_ENDPTCOMPLETE_ERCE_SHIFT) & USB_ENDPTCOMPLETE_ERCE_MASK)
+#define USB_ENDPTCOMPLETE_ERCE_GET(x) (((uint32_t)(x) & USB_ENDPTCOMPLETE_ERCE_MASK) >> USB_ENDPTCOMPLETE_ERCE_SHIFT)
+
+/* Bitfield definition for register array: ENDPTCTRL */
+/*
+ * TXE (RW)
+ *
+ * TXE
+ * TX Endpoint Enable
+ * 0 Disabled [Default]
+ * 1 Enabled
+ * An Endpoint should be enabled only after it has been configured.
+ */
+#define USB_ENDPTCTRL_TXE_MASK (0x800000UL)
+#define USB_ENDPTCTRL_TXE_SHIFT (23U)
+#define USB_ENDPTCTRL_TXE_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXE_SHIFT) & USB_ENDPTCTRL_TXE_MASK)
+#define USB_ENDPTCTRL_TXE_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXE_MASK) >> USB_ENDPTCTRL_TXE_SHIFT)
+
+/*
+ * TXR (WS)
+ *
+ * TXR
+ * TX Data Toggle Reset (WS)
+ * Write 1 - Reset PID Sequence
+ * Whenever a configuration event is received for this Endpoint, software must write a one to this bit in order
+ * to synchronize the data PID's between the Host and device.
+ */
+#define USB_ENDPTCTRL_TXR_MASK (0x400000UL)
+#define USB_ENDPTCTRL_TXR_SHIFT (22U)
+#define USB_ENDPTCTRL_TXR_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXR_SHIFT) & USB_ENDPTCTRL_TXR_MASK)
+#define USB_ENDPTCTRL_TXR_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXR_MASK) >> USB_ENDPTCTRL_TXR_SHIFT)
+
+/*
+ * TXT (RW)
+ *
+ * TXT
+ * TX Endpoint Type - Read/Write
+ * 00 Control
+ * 01 Isochronous
+ * 10 Bulk
+ * 11 Interrupt
+ */
+#define USB_ENDPTCTRL_TXT_MASK (0xC0000UL)
+#define USB_ENDPTCTRL_TXT_SHIFT (18U)
+#define USB_ENDPTCTRL_TXT_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXT_SHIFT) & USB_ENDPTCTRL_TXT_MASK)
+#define USB_ENDPTCTRL_TXT_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXT_MASK) >> USB_ENDPTCTRL_TXT_SHIFT)
+
+/*
+ * TXS (RW)
+ *
+ * TXS
+ * TX Endpoint Stall - Read/Write
+ * 0 End Point OK
+ * 1 End Point Stalled
+ * This bit will be cleared automatically upon receipt of a SETUP request if this Endpoint is configured
+ * as a Control Endpoint and this bit will continue to be cleared by hardware until the associated ENDPTSETUPSTAT bit is cleared.
+ * Software can write a one to this bit to force the endpoint to return a STALL handshake to the Host.
+ * This control will continue to STALL until this bit is either cleared by software or automatically cleared as above for control endpoints.
+ * NOTE: [CONTROL ENDPOINT TYPES ONLY]: there is a slight delay (50 clocks max) between the ENDPTSETUPSTAT begin cleared and hardware continuing to clear this bit.
+ * In most systems, it is unlikely the DCD software will observe this delay. However, should the DCD observe that the stall bit is not set after writing a one to it then follow this procedure:
+ * continually write this stall bit until it is set or until a new setup has been received by checking the associated endptsetupstat Bit.
+ */
+#define USB_ENDPTCTRL_TXS_MASK (0x10000UL)
+#define USB_ENDPTCTRL_TXS_SHIFT (16U)
+#define USB_ENDPTCTRL_TXS_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXS_SHIFT) & USB_ENDPTCTRL_TXS_MASK)
+#define USB_ENDPTCTRL_TXS_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXS_MASK) >> USB_ENDPTCTRL_TXS_SHIFT)
+
+/*
+ * RXE (RW)
+ *
+ * RXE
+ * RX Endpoint Enable
+ * 0 Disabled [Default]
+ * 1 Enabled
+ * An Endpoint should be enabled only after it has been configured.
+ */
+#define USB_ENDPTCTRL_RXE_MASK (0x80U)
+#define USB_ENDPTCTRL_RXE_SHIFT (7U)
+#define USB_ENDPTCTRL_RXE_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXE_SHIFT) & USB_ENDPTCTRL_RXE_MASK)
+#define USB_ENDPTCTRL_RXE_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXE_MASK) >> USB_ENDPTCTRL_RXE_SHIFT)
+
+/*
+ * RXR (WS)
+ *
+ * RXR
+ * RX Data Toggle Reset (WS)
+ * Write 1 - Reset PID Sequence
+ * Whenever a configuration event is received for this Endpoint, software must write a one to this bit in order
+ * to synchronize the data PID's between the host and device.
+ */
+#define USB_ENDPTCTRL_RXR_MASK (0x40U)
+#define USB_ENDPTCTRL_RXR_SHIFT (6U)
+#define USB_ENDPTCTRL_RXR_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXR_SHIFT) & USB_ENDPTCTRL_RXR_MASK)
+#define USB_ENDPTCTRL_RXR_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXR_MASK) >> USB_ENDPTCTRL_RXR_SHIFT)
+
+/*
+ * RXT (RW)
+ *
+ * RXT
+ * RX Endpoint Type - Read/Write
+ * 00 Control
+ * 01 Isochronous
+ * 10 Bulk
+ * 11 Interrupt
+ */
+#define USB_ENDPTCTRL_RXT_MASK (0xCU)
+#define USB_ENDPTCTRL_RXT_SHIFT (2U)
+#define USB_ENDPTCTRL_RXT_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXT_SHIFT) & USB_ENDPTCTRL_RXT_MASK)
+#define USB_ENDPTCTRL_RXT_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXT_MASK) >> USB_ENDPTCTRL_RXT_SHIFT)
+
+/*
+ * RXS (RW)
+ *
+ * RXS
+ * RX Endpoint Stall - Read/Write
+ * 0 End Point OK. [Default]
+ * 1 End Point Stalled
+ * This bit is set automatically upon receipt of a SETUP request if this Endpoint is configured as a Control
+ * Endpointand this bit will continue to be cleared by hardware until the associated ENDPTSETUPSTAT bit
+ * is cleared.
+ * Software can write a one to this bit to force the endpoint to return a STALL handshake to the Host. This
+ * control will continue to STALL until this bit is either cleared by software or automatically cleared as above
+ * for control endpoints.
+ * NOTE: [CONTROL ENDPOINT TYPES ONLY]: there is a slight delay (50 clocks max) between the
+ * ENDPTSETUPSTAT begin cleared and hardware continuing to clear this bit. In most systems, it
+ * is unlikely the DCD software will observe this delay. However, should the DCD observe that the
+ * stall bit is not set after writing a one to it then follow this procedure: continually write this stall bit
+ * until it is set or until a new setup has been received by checking the associated endptsetupstat
+ * Bit.
+ */
+#define USB_ENDPTCTRL_RXS_MASK (0x1U)
+#define USB_ENDPTCTRL_RXS_SHIFT (0U)
+#define USB_ENDPTCTRL_RXS_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXS_SHIFT) & USB_ENDPTCTRL_RXS_MASK)
+#define USB_ENDPTCTRL_RXS_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXS_MASK) >> USB_ENDPTCTRL_RXS_SHIFT)
+
+/* Bitfield definition for register: OTG_CTRL0 */
+/*
+ * OTG_WKDPDMCHG_EN (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_MASK (0x2000000UL)
+#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SHIFT (25U)
+#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SHIFT) & USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_MASK)
+#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_MASK) >> USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SHIFT)
+
+/*
+ * AUTORESUME_EN (RW)
+ *
+ */
+#define USB_OTG_CTRL0_AUTORESUME_EN_MASK (0x80000UL)
+#define USB_OTG_CTRL0_AUTORESUME_EN_SHIFT (19U)
+#define USB_OTG_CTRL0_AUTORESUME_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_AUTORESUME_EN_SHIFT) & USB_OTG_CTRL0_AUTORESUME_EN_MASK)
+#define USB_OTG_CTRL0_AUTORESUME_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_AUTORESUME_EN_MASK) >> USB_OTG_CTRL0_AUTORESUME_EN_SHIFT)
+
+/*
+ * OTG_VBUS_WAKEUP_EN (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK (0x20000UL)
+#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SHIFT (17U)
+#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SHIFT) & USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK)
+#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK) >> USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SHIFT)
+
+/*
+ * OTG_ID_WAKEUP_EN (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_MASK (0x10000UL)
+#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SHIFT (16U)
+#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SHIFT) & USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_MASK)
+#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_MASK) >> USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SHIFT)
+
+/*
+ * OTG_VBUS_SOURCE_SEL (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_MASK (0x2000U)
+#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SHIFT (13U)
+#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SHIFT) & USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_MASK)
+#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_MASK) >> USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SHIFT)
+
+/*
+ * OTG_UTMI_SUSPENDM_SW (RW)
+ *
+ * default 0 for naneng usbphy
+ */
+#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_MASK (0x1000U)
+#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SHIFT (12U)
+#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SHIFT) & USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_MASK)
+#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_MASK) >> USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SHIFT)
+
+/*
+ * OTG_UTMI_RESET_SW (RW)
+ *
+ * default 1 for naneng usbphy
+ */
+#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_MASK (0x800U)
+#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SHIFT (11U)
+#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SHIFT) & USB_OTG_CTRL0_OTG_UTMI_RESET_SW_MASK)
+#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_UTMI_RESET_SW_MASK) >> USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SHIFT)
+
+/*
+ * OTG_WAKEUP_INT_ENABLE (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK (0x400U)
+#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SHIFT (10U)
+#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SHIFT) & USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK)
+#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK) >> USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SHIFT)
+
+/*
+ * OTG_POWER_MASK (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_POWER_MASK_MASK (0x200U)
+#define USB_OTG_CTRL0_OTG_POWER_MASK_SHIFT (9U)
+#define USB_OTG_CTRL0_OTG_POWER_MASK_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_POWER_MASK_SHIFT) & USB_OTG_CTRL0_OTG_POWER_MASK_MASK)
+#define USB_OTG_CTRL0_OTG_POWER_MASK_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_POWER_MASK_MASK) >> USB_OTG_CTRL0_OTG_POWER_MASK_SHIFT)
+
+/*
+ * OTG_OVER_CUR_POL (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_MASK (0x100U)
+#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_SHIFT (8U)
+#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_OVER_CUR_POL_SHIFT) & USB_OTG_CTRL0_OTG_OVER_CUR_POL_MASK)
+#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_OVER_CUR_POL_MASK) >> USB_OTG_CTRL0_OTG_OVER_CUR_POL_SHIFT)
+
+/*
+ * OTG_OVER_CUR_DIS (RW)
+ *
+ */
+#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_MASK (0x80U)
+#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SHIFT (7U)
+#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SHIFT) & USB_OTG_CTRL0_OTG_OVER_CUR_DIS_MASK)
+#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_OVER_CUR_DIS_MASK) >> USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SHIFT)
+
+/*
+ * SER_MODE_SUSPEND_EN (RW)
+ *
+ * for naneng usbphy, only switch to serial mode when suspend
+ */
+#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_MASK (0x10U)
+#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SHIFT (4U)
+#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SHIFT) & USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_MASK)
+#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_MASK) >> USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SHIFT)
+
+/* Bitfield definition for register: PHY_CTRL0 */
+/*
+ * GPIO_ID_SEL_N (RW)
+ *
+ */
+#define USB_PHY_CTRL0_GPIO_ID_SEL_N_MASK (0x2000000UL)
+#define USB_PHY_CTRL0_GPIO_ID_SEL_N_SHIFT (25U)
+#define USB_PHY_CTRL0_GPIO_ID_SEL_N_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_GPIO_ID_SEL_N_SHIFT) & USB_PHY_CTRL0_GPIO_ID_SEL_N_MASK)
+#define USB_PHY_CTRL0_GPIO_ID_SEL_N_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_GPIO_ID_SEL_N_MASK) >> USB_PHY_CTRL0_GPIO_ID_SEL_N_SHIFT)
+
+/*
+ * ID_DIG_OVERRIDE (RW)
+ *
+ */
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_MASK (0x4000U)
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_SHIFT (14U)
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_ID_DIG_OVERRIDE_SHIFT) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_MASK)
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_MASK) >> USB_PHY_CTRL0_ID_DIG_OVERRIDE_SHIFT)
+
+/*
+ * SESS_VALID_OVERRIDE (RW)
+ *
+ */
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK (0x2000U)
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SHIFT (13U)
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SHIFT) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK)
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK) >> USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SHIFT)
+
+/*
+ * VBUS_VALID_OVERRIDE (RW)
+ *
+ */
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK (0x1000U)
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SHIFT (12U)
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SHIFT) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK)
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK) >> USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SHIFT)
+
+/*
+ * ID_DIG_OVERRIDE_EN (RW)
+ *
+ */
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_MASK (0x4U)
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SHIFT (2U)
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SHIFT) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_MASK)
+#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_MASK) >> USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SHIFT)
+
+/*
+ * SESS_VALID_OVERRIDE_EN (RW)
+ *
+ */
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK (0x2U)
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SHIFT (1U)
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SHIFT) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK)
+#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK) >> USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SHIFT)
+
+/*
+ * VBUS_VALID_OVERRIDE_EN (RW)
+ *
+ */
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK (0x1U)
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SHIFT (0U)
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SHIFT) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK)
+#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK) >> USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SHIFT)
+
+/* Bitfield definition for register: PHY_CTRL1 */
+/*
+ * UTMI_CFG_RST_N (RW)
+ *
+ */
+#define USB_PHY_CTRL1_UTMI_CFG_RST_N_MASK (0x100000UL)
+#define USB_PHY_CTRL1_UTMI_CFG_RST_N_SHIFT (20U)
+#define USB_PHY_CTRL1_UTMI_CFG_RST_N_SET(x) (((uint32_t)(x) << USB_PHY_CTRL1_UTMI_CFG_RST_N_SHIFT) & USB_PHY_CTRL1_UTMI_CFG_RST_N_MASK)
+#define USB_PHY_CTRL1_UTMI_CFG_RST_N_GET(x) (((uint32_t)(x) & USB_PHY_CTRL1_UTMI_CFG_RST_N_MASK) >> USB_PHY_CTRL1_UTMI_CFG_RST_N_SHIFT)
+
+/*
+ * UTMI_OTG_SUSPENDM (RW)
+ *
+ * OTG suspend, not utmi_suspendm
+ */
+#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_MASK (0x2U)
+#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SHIFT (1U)
+#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SET(x) (((uint32_t)(x) << USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SHIFT) & USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_MASK)
+#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_GET(x) (((uint32_t)(x) & USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_MASK) >> USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SHIFT)
+
+/* Bitfield definition for register: TOP_STATUS */
+/*
+ * WAKEUP_INT_STATUS (RW)
+ *
+ */
+#define USB_TOP_STATUS_WAKEUP_INT_STATUS_MASK (0x80000000UL)
+#define USB_TOP_STATUS_WAKEUP_INT_STATUS_SHIFT (31U)
+#define USB_TOP_STATUS_WAKEUP_INT_STATUS_SET(x) (((uint32_t)(x) << USB_TOP_STATUS_WAKEUP_INT_STATUS_SHIFT) & USB_TOP_STATUS_WAKEUP_INT_STATUS_MASK)
+#define USB_TOP_STATUS_WAKEUP_INT_STATUS_GET(x) (((uint32_t)(x) & USB_TOP_STATUS_WAKEUP_INT_STATUS_MASK) >> USB_TOP_STATUS_WAKEUP_INT_STATUS_SHIFT)
+
+/* Bitfield definition for register: PHY_STATUS */
+/*
+ * UTMI_CLK_VALID (RW)
+ *
+ */
+#define USB_PHY_STATUS_UTMI_CLK_VALID_MASK (0x80000000UL)
+#define USB_PHY_STATUS_UTMI_CLK_VALID_SHIFT (31U)
+#define USB_PHY_STATUS_UTMI_CLK_VALID_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_UTMI_CLK_VALID_SHIFT) & USB_PHY_STATUS_UTMI_CLK_VALID_MASK)
+#define USB_PHY_STATUS_UTMI_CLK_VALID_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_UTMI_CLK_VALID_MASK) >> USB_PHY_STATUS_UTMI_CLK_VALID_SHIFT)
+
+/*
+ * LINE_STATE (RW)
+ *
+ */
+#define USB_PHY_STATUS_LINE_STATE_MASK (0xC0U)
+#define USB_PHY_STATUS_LINE_STATE_SHIFT (6U)
+#define USB_PHY_STATUS_LINE_STATE_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_LINE_STATE_SHIFT) & USB_PHY_STATUS_LINE_STATE_MASK)
+#define USB_PHY_STATUS_LINE_STATE_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_LINE_STATE_MASK) >> USB_PHY_STATUS_LINE_STATE_SHIFT)
+
+/*
+ * HOST_DISCONNECT (RW)
+ *
+ */
+#define USB_PHY_STATUS_HOST_DISCONNECT_MASK (0x20U)
+#define USB_PHY_STATUS_HOST_DISCONNECT_SHIFT (5U)
+#define USB_PHY_STATUS_HOST_DISCONNECT_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_HOST_DISCONNECT_SHIFT) & USB_PHY_STATUS_HOST_DISCONNECT_MASK)
+#define USB_PHY_STATUS_HOST_DISCONNECT_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_HOST_DISCONNECT_MASK) >> USB_PHY_STATUS_HOST_DISCONNECT_SHIFT)
+
+/*
+ * ID_DIG (RW)
+ *
+ */
+#define USB_PHY_STATUS_ID_DIG_MASK (0x10U)
+#define USB_PHY_STATUS_ID_DIG_SHIFT (4U)
+#define USB_PHY_STATUS_ID_DIG_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_ID_DIG_SHIFT) & USB_PHY_STATUS_ID_DIG_MASK)
+#define USB_PHY_STATUS_ID_DIG_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_ID_DIG_MASK) >> USB_PHY_STATUS_ID_DIG_SHIFT)
+
+/*
+ * UTMI_SESS_VALID (RW)
+ *
+ */
+#define USB_PHY_STATUS_UTMI_SESS_VALID_MASK (0x4U)
+#define USB_PHY_STATUS_UTMI_SESS_VALID_SHIFT (2U)
+#define USB_PHY_STATUS_UTMI_SESS_VALID_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_UTMI_SESS_VALID_SHIFT) & USB_PHY_STATUS_UTMI_SESS_VALID_MASK)
+#define USB_PHY_STATUS_UTMI_SESS_VALID_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_UTMI_SESS_VALID_MASK) >> USB_PHY_STATUS_UTMI_SESS_VALID_SHIFT)
+
+/*
+ * VBUS_VALID (RW)
+ *
+ */
+#define USB_PHY_STATUS_VBUS_VALID_MASK (0x1U)
+#define USB_PHY_STATUS_VBUS_VALID_SHIFT (0U)
+#define USB_PHY_STATUS_VBUS_VALID_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_VBUS_VALID_SHIFT) & USB_PHY_STATUS_VBUS_VALID_MASK)
+#define USB_PHY_STATUS_VBUS_VALID_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_VBUS_VALID_MASK) >> USB_PHY_STATUS_VBUS_VALID_SHIFT)
+
+
+
+/* ENDPTCTRL register group index macro definition */
+#define USB_ENDPTCTRL_ENDPTCTRL0 (0UL)
+#define USB_ENDPTCTRL_ENDPTCTRL1 (1UL)
+#define USB_ENDPTCTRL_ENDPTCTRL2 (2UL)
+#define USB_ENDPTCTRL_ENDPTCTRL3 (3UL)
+#define USB_ENDPTCTRL_ENDPTCTRL4 (4UL)
+#define USB_ENDPTCTRL_ENDPTCTRL5 (5UL)
+#define USB_ENDPTCTRL_ENDPTCTRL6 (6UL)
+#define USB_ENDPTCTRL_ENDPTCTRL7 (7UL)
+
+
+#endif /* HPM_USB_H */
diff --git a/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c b/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c
new file mode 100644
index 0000000000..3d1971653d
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c
@@ -0,0 +1,707 @@
+#include "usbd_core.h"
+#include "usb_chipidea_reg.h"
+
+#define USB_OTG_DEV ((CHIPIDEA_TypeDef *)g_usbdev_bus[busid].reg_base)
+
+#define CHIPIDEA_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
+#define QTD_COUNT_EACH_ENDPOINT (8U)
+
+/* ENDPTCTRL */
+enum {
+ ENDPTCTRL_STALL = CHIPIDEA_BITSMASK(1, 0),
+ ENDPTCTRL_TYPE = CHIPIDEA_BITSMASK(3, 2),
+ ENDPTCTRL_TOGGLE_INHIBIT = CHIPIDEA_BITSMASK(1, 5),
+ ENDPTCTRL_TOGGLE_RESET = CHIPIDEA_BITSMASK(1, 6),
+ ENDPTCTRL_ENABLE = CHIPIDEA_BITSMASK(1, 7),
+};
+
+/* USBSTS, USBINTR */
+enum {
+ intr_usb = CHIPIDEA_BITSMASK(1, 0),
+ intr_error = CHIPIDEA_BITSMASK(1, 1),
+ intr_port_change = CHIPIDEA_BITSMASK(1, 2),
+ intr_reset = CHIPIDEA_BITSMASK(1, 6),
+ intr_sof = CHIPIDEA_BITSMASK(1, 7),
+ intr_suspend = CHIPIDEA_BITSMASK(1, 8),
+ intr_nak = CHIPIDEA_BITSMASK(1, 16)
+};
+
+/* Queue Transfer Descriptor */
+typedef struct {
+ /* Word 0: Next QTD Pointer */
+ volatile uint32_t next; /* Next link pointer This field contains the physical memory address of the next dTD to be processed */
+
+ /* Word 1: qTQ Token */
+ volatile uint32_t : 3;
+ volatile uint32_t xact_err : 1;
+ volatile uint32_t : 1;
+ volatile uint32_t buffer_err : 1;
+ volatile uint32_t halted : 1;
+ volatile uint32_t active : 1;
+ volatile uint32_t : 2;
+ volatile uint32_t iso_mult_override : 2; /* This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. */
+ volatile uint32_t : 3;
+ volatile uint32_t int_on_complete : 1;
+ volatile uint32_t total_bytes : 15;
+ volatile uint32_t : 0;
+
+ /* Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page */
+ volatile uint32_t buffer[5];
+
+ /*------------- DCD Area -------------*/
+ volatile uint16_t expected_bytes;
+ volatile uint8_t reserved[2];
+} dcd_qtd_t;
+
+/* Queue Head */
+typedef struct {
+ /* Word 0: Capabilities and Characteristics */
+
+ volatile uint32_t : 15; /* Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. */
+ volatile uint32_t int_on_setup : 1; /* Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. */
+ volatile uint32_t max_packet_size : 11; /* This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) */
+ volatile uint32_t : 2;
+ volatile uint32_t zero_length_termination : 1; /* This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. */
+ volatile uint32_t iso_mult : 2;
+ volatile uint32_t : 0;
+
+ /* Word 1: Current qTD Pointer */
+ volatile uint32_t qtd_addr;
+
+ /* Word 2-9: Transfer Overlay */
+ volatile dcd_qtd_t qtd_overlay;
+
+ /* Word 10-11: Setup request (control OUT only) */
+ volatile struct usb_setup_packet setup_request;
+
+ /*--------------------------------------------------------------------
+ * Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes
+ * thus there are 16 bytes padding free that we can make use of.
+ *--------------------------------------------------------------------
+ */
+ volatile uint8_t reserved[16];
+} dcd_qhd_t;
+
+typedef struct {
+ dcd_qhd_t qhd[CONFIG_USBDEV_EP_NUM * 2];
+ dcd_qtd_t qtd[CONFIG_USBDEV_EP_NUM * 2 * QTD_COUNT_EACH_ENDPOINT];
+} dcd_data_t;
+
+/* Endpoint state */
+struct chipidea_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 *xfer_buf;
+ uint32_t xfer_len;
+ uint32_t actual_xfer_len;
+};
+
+/* Driver state */
+struct chipidea_udc {
+ dcd_data_t *dcd_data;
+ bool is_suspend;
+ struct chipidea_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
+ struct chipidea_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
+} g_chipidea_udc[CONFIG_USBDEV_MAX_BUS];
+
+static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data0;
+#if CONFIG_USBDEV_MAX_BUS == 2
+static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data1;
+#endif
+
+static dcd_data_t *g_dcd_data[CONFIG_USBDEV_MAX_BUS] = {
+ &_dcd_data0,
+#if CONFIG_USBDEV_MAX_BUS == 2
+ &_dcd_data1
+#endif
+};
+
+/* Index to bit position in register */
+static inline uint8_t ep_idx2bit(uint8_t ep_idx)
+{
+ return ep_idx / 2 + ((ep_idx % 2) ? 16 : 0);
+}
+
+static void __chipidea_bus_reset(CHIPIDEA_TypeDef *ptr)
+{
+ /* The reset value for all endpoint types is the control endpoint. If one endpoint
+ * direction is enabled and the paired endpoint of opposite direction is disabled, then the
+ * endpoint type of the unused direction must be changed from the control type to any other
+ * type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior
+ * for the data PID tracking on the active endpoint.
+ */
+
+ for (uint32_t i = 1; i < CONFIG_USBDEV_EP_NUM; i++) {
+ ptr->ENDPTCTRL[i] = USB_ENDPTCTRL_TXT_SET(USB_ENDPOINT_TYPE_BULK) | USB_ENDPTCTRL_RXT_SET(USB_ENDPOINT_TYPE_BULK);
+ }
+
+ /* Clear All Registers */
+ ptr->ENDPTNAK = ptr->ENDPTNAK;
+ ptr->ENDPTNAKEN = 0;
+ ptr->USBSTS = ptr->USBSTS;
+ ptr->ENDPTSETUPSTAT = ptr->ENDPTSETUPSTAT;
+ ptr->ENDPTCOMPLETE = ptr->ENDPTCOMPLETE;
+
+ while (ptr->ENDPTPRIME) {
+ }
+ ptr->ENDPTFLUSH = 0xFFFFFFFF;
+ while (ptr->ENDPTFLUSH) {
+ }
+}
+
+static void chipidea_init(CHIPIDEA_TypeDef *ptr)
+{
+ /* Reset controller */
+ ptr->USBCMD |= USB_USBCMD_RST_MASK;
+ while (USB_USBCMD_RST_GET(ptr->USBCMD)) {
+ }
+
+ /* Set mode to device, must be set immediately after reset */
+ ptr->USBMODE &= ~USB_USBMODE_CM_MASK;
+ ptr->USBMODE |= USB_USBMODE_CM_SET(2);
+
+ /* Disable setup lockout, please refer to "Control Endpoint Operation" section in RM. */
+ ptr->USBMODE &= ~USB_USBMODE_SLOM_MASK;
+
+ /* Set the endian */
+ ptr->USBMODE &= ~USB_USBMODE_ES_MASK;
+
+ /* Set parallel interface signal */
+ ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
+
+ /* Set parallel transceiver width */
+ ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
+
+ /* Set usb forced to full speed mode */
+ //ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK;
+
+ /* Not use interrupt threshold. */
+ ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
+
+ /* Enable VBUS discharge */
+ ptr->OTGSC |= USB_OTGSC_VD_MASK;
+}
+
+static void chipidea_deinit(CHIPIDEA_TypeDef *ptr)
+{
+ /* Stop */
+ ptr->USBCMD &= ~USB_USBCMD_RS_MASK;
+
+ /* Reset controller */
+ ptr->USBCMD |= USB_USBCMD_RST_MASK;
+ while (USB_USBCMD_RST_GET(ptr->USBCMD)) {
+ }
+
+ /* Reset endpoint list address register */
+ ptr->ENDPTLISTADDR = 0;
+
+ /* Reset status register */
+ ptr->USBSTS = ptr->USBSTS;
+
+ /* Reset interrupt enable register */
+ ptr->USBINTR = 0;
+}
+
+/*---------------------------------------------------------------------
+ * Endpoint API
+ *---------------------------------------------------------------------
+ */
+static void __chipidea_edpt_open(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr, uint8_t ep_type)
+{
+ uint8_t const epnum = ep_addr & 0x0f;
+ uint8_t const dir = (ep_addr & 0x80) >> 7;
+
+ /* Enable EP Control */
+ uint32_t temp = ptr->ENDPTCTRL[epnum];
+ temp &= ~((0x03 << 2) << (dir ? 16 : 0));
+ temp |= ((ep_type << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0);
+ ptr->ENDPTCTRL[epnum] = temp;
+}
+
+static void chipidea_edpt_xfer(CHIPIDEA_TypeDef *ptr, uint8_t ep_idx)
+{
+ uint32_t offset = ep_idx / 2 + ((ep_idx % 2) ? 16 : 0);
+
+ /* Start transfer */
+ ptr->ENDPTPRIME = 1 << offset;
+}
+
+static void chipidea_edpt_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
+{
+ uint8_t const epnum = ep_addr & 0x0f;
+ uint8_t const dir = (ep_addr & 0x80) >> 7;
+
+ ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0);
+}
+
+static void chipidea_edpt_clear_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
+{
+ uint8_t const epnum = ep_addr & 0x0f;
+ uint8_t const dir = (ep_addr & 0x80) >> 7;
+
+ /* data toggle also need to be reset */
+ ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << (dir ? 16 : 0);
+ ptr->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << (dir ? 16 : 0));
+}
+
+static bool chipidea_edpt_check_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
+{
+ uint8_t const epnum = ep_addr & 0x0f;
+ uint8_t const dir = (ep_addr & 0x80) >> 7;
+
+ return (ptr->ENDPTCTRL[epnum] & (ENDPTCTRL_STALL << (dir ? 16 : 0))) ? true : false;
+}
+
+static void chipidea_edpt_close(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
+{
+ uint8_t const epnum = ep_addr & 0x0f;
+ uint8_t const dir = (ep_addr & 0x80) >> 7;
+
+ uint32_t primebit = CHIPIDEA_BITSMASK(1, epnum) << (dir ? 16 : 0);
+
+ /* Flush the endpoint to stop a transfer. */
+ do {
+ /* Set the corresponding bit(s) in the ENDPTFLUSH register */
+ ptr->ENDPTFLUSH |= primebit;
+
+ /* Wait until all bits in the ENDPTFLUSH register are cleared. */
+ while (0U != (ptr->ENDPTFLUSH & primebit)) {
+ }
+ /*
+ * Read the ENDPTSTAT register to ensure that for all endpoints
+ * commanded to be flushed, that the corresponding bits
+ * are now cleared.
+ */
+ } while (0U != (ptr->ENDPTSTAT & primebit));
+
+ /* Disable the endpoint */
+ ptr->ENDPTCTRL[epnum] &= ~((ENDPTCTRL_TYPE | ENDPTCTRL_ENABLE | ENDPTCTRL_STALL) << (dir ? 16 : 0));
+ ptr->ENDPTCTRL[epnum] |= (USB_ENDPOINT_TYPE_BULK << 2) << (dir ? 16 : 0);
+}
+
+/* Initialize qtd */
+static void usb_qtd_init(dcd_qtd_t *p_qtd, void *data_ptr, uint16_t total_bytes)
+{
+ memset(p_qtd, 0, sizeof(dcd_qtd_t));
+
+ p_qtd->next = 1;
+ p_qtd->active = 1;
+ p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes;
+
+ if (data_ptr != NULL) {
+ p_qtd->buffer[0] = (uint32_t)data_ptr;
+ for (uint8_t i = 1; i < 5; i++) {
+ p_qtd->buffer[i] |= ((p_qtd->buffer[i - 1]) & 0xFFFFF000UL) + 4096U;
+ }
+ }
+}
+
+static dcd_qhd_t *chipidea_qhd_get(uint8_t busid, uint8_t ep_idx)
+{
+ dcd_data_t *dcd_data;
+
+ dcd_data = g_chipidea_udc[busid].dcd_data;
+ return &dcd_data->qhd[ep_idx];
+}
+
+static dcd_qtd_t *chipidea_qtd_get(uint8_t busid, uint8_t ep_idx)
+{
+ dcd_data_t *dcd_data;
+
+ dcd_data = g_chipidea_udc[busid].dcd_data;
+ return &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT];
+}
+
+static void chipidea_bus_reset(uint8_t busid, uint16_t ep0_max_packet_size)
+{
+ dcd_data_t *dcd_data;
+
+ dcd_data = g_chipidea_udc[busid].dcd_data;
+ __chipidea_bus_reset(USB_OTG_DEV);
+
+ /* Queue Head & Queue TD */
+ memset(dcd_data, 0, sizeof(dcd_data_t));
+
+ /* Set up Control Endpoints (0 OUT, 1 IN) */
+ dcd_data->qhd[0].zero_length_termination = dcd_data->qhd[1].zero_length_termination = 1;
+ dcd_data->qhd[0].max_packet_size = dcd_data->qhd[1].max_packet_size = ep0_max_packet_size;
+ dcd_data->qhd[0].qtd_overlay.next = dcd_data->qhd[1].qtd_overlay.next = 1;
+
+ /* OUT only */
+ dcd_data->qhd[0].int_on_setup = 1;
+}
+
+static void chipidea_edpt_open(uint8_t busid, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
+{
+ uint8_t const epnum = ep_addr & 0x0f;
+ uint8_t const dir = (ep_addr & 0x80) >> 7;
+ uint8_t const ep_idx = 2 * epnum + dir;
+ dcd_data_t *dcd_data;
+ dcd_qhd_t *p_qhd;
+
+ /* Prepare Queue Head */
+ dcd_data = g_chipidea_udc[busid].dcd_data;
+ p_qhd = &dcd_data->qhd[ep_idx];
+ memset(p_qhd, 0, sizeof(dcd_qhd_t));
+
+ p_qhd->zero_length_termination = 1;
+ p_qhd->max_packet_size = ep_mps & 0x7FFu;
+ p_qhd->qtd_overlay.next = 1;
+ if (ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ p_qhd->iso_mult = ((ep_mps >> 11u) & 0x3u) + 1u;
+ }
+
+ __chipidea_edpt_open(USB_OTG_DEV, ep_addr, ep_type);
+}
+
+static bool chipidea_start_xfer(uint8_t busid, uint8_t ep_addr, uint8_t *buffer, uint32_t total_bytes)
+{
+ uint8_t const epnum = ep_addr & 0x0f;
+ uint8_t const dir = (ep_addr & 0x80) >> 7;
+ uint8_t const ep_idx = 2 * epnum + dir;
+ uint8_t qtd_num;
+ uint8_t i;
+ uint32_t xfer_len;
+ dcd_qhd_t *p_qhd;
+ dcd_qtd_t *p_qtd;
+ dcd_qtd_t *first_p_qtd = NULL;
+ dcd_qtd_t *prev_p_qtd = NULL;
+ dcd_data_t *dcd_data;
+
+ dcd_data = g_chipidea_udc[busid].dcd_data;
+
+ if (epnum == 0) {
+ /* follows UM Setup packet handling using setup lockout mechanism
+ * wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
+ */
+ while (USB_OTG_DEV->ENDPTSETUPSTAT & CHIPIDEA_BITSMASK(1, 0)) {
+ }
+ }
+
+ qtd_num = (total_bytes + 0x3fff) / 0x4000;
+ if (qtd_num > QTD_COUNT_EACH_ENDPOINT) {
+ return false;
+ }
+
+ if (buffer != NULL) {
+ buffer = (uint8_t *)buffer;
+ }
+ p_qhd = &dcd_data->qhd[ep_idx];
+ i = 0;
+ do {
+ p_qtd = &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT + i];
+ i++;
+
+ if (total_bytes > 0x4000) {
+ xfer_len = 0x4000;
+ total_bytes -= 0x4000;
+ } else {
+ xfer_len = total_bytes;
+ total_bytes = 0;
+ }
+
+ usb_qtd_init(p_qtd, (void *)buffer, xfer_len);
+ if (total_bytes == 0) {
+ p_qtd->int_on_complete = true;
+ }
+ buffer += xfer_len;
+
+ if (prev_p_qtd) {
+ prev_p_qtd->next = (uint32_t)p_qtd;
+ } else {
+ first_p_qtd = p_qtd;
+ }
+ prev_p_qtd = p_qtd;
+ } while (total_bytes > 0);
+
+ p_qhd->qtd_overlay.next = (uint32_t)first_p_qtd; /* link qtd to qhd */
+
+ chipidea_edpt_xfer(USB_OTG_DEV, ep_idx);
+
+ return true;
+}
+
+__WEAK void usb_dc_low_level_init(uint8_t busid)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(uint8_t busid)
+{
+}
+
+int usb_dc_init(uint8_t busid)
+{
+ uint32_t int_mask;
+ int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_SLE_MASK |
+ USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK);
+
+ usb_dc_low_level_init(busid);
+
+ memset(&g_chipidea_udc[busid], 0, sizeof(struct chipidea_udc));
+ g_chipidea_udc[busid].dcd_data = g_dcd_data[busid];
+ memset(g_chipidea_udc[busid].dcd_data, 0, sizeof(dcd_data_t));
+
+ chipidea_init(USB_OTG_DEV);
+
+ /* Set endpoint list address */
+ USB_OTG_DEV->ENDPTLISTADDR = ((uint32_t)g_chipidea_udc[busid].dcd_data->qhd) & USB_ENDPTLISTADDR_EPBASE_MASK;
+
+ /* Clear status */
+ USB_OTG_DEV->USBSTS = USB_OTG_DEV->USBSTS;
+
+ /* Enable interrupt mask */
+ USB_OTG_DEV->USBINTR |= int_mask;
+
+ /* Connect by enabling internal pull-up resistor on D+/D- */
+ USB_OTG_DEV->USBCMD |= USB_USBCMD_RS_MASK;
+ return 0;
+}
+
+int usb_dc_deinit(uint8_t busid)
+{
+ chipidea_deinit(USB_OTG_DEV);
+
+ for (uint32_t i = 0; i < CONFIG_USBDEV_EP_NUM; i++) {
+ chipidea_edpt_close(USB_OTG_DEV, (i | 0x80));
+ chipidea_edpt_close(USB_OTG_DEV, (i | 0x00));
+ }
+
+ usb_dc_low_level_deinit(busid);
+ return 0;
+}
+
+int usbd_set_address(uint8_t busid, const uint8_t addr)
+{
+ USB_OTG_DEV->DEVICEADDR = USB_DEVICEADDR_USBADR_SET(addr) | USB_DEVICEADDR_USBADRA_MASK;
+ return 0;
+}
+
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ if (!USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) {
+ return -1;
+ }
+
+ USB_OTG_DEV->PORTSC1 |= USB_PORTSC1_FPR_MASK;
+ while (USB_OTG_DEV->PORTSC1 & USB_PORTSC1_FPR_MASK) {
+ }
+
+ return 0;
+}
+
+uint8_t usbd_get_port_speed(uint8_t busid)
+{
+ uint8_t speed;
+
+ speed = USB_PORTSC1_PSPD_GET(USB_OTG_DEV->PORTSC1);
+
+ if (speed == 0x00) {
+ return USB_SPEED_FULL;
+ }
+ if (speed == 0x01) {
+ return USB_SPEED_LOW;
+ }
+ if (speed == 0x02) {
+ return USB_SPEED_HIGH;
+ }
+
+ return 0;
+}
+
+int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
+
+ /* Must not exceed max endpoint number */
+ if (ep_idx >= CONFIG_USBDEV_EP_NUM) {
+ return -1;
+ }
+
+ chipidea_edpt_open(busid, ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), ep->wMaxPacketSize);
+
+ if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
+ g_chipidea_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_chipidea_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = true;
+ } else {
+ g_chipidea_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_chipidea_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = true;
+ }
+
+ return 0;
+}
+
+int usbd_ep_close(uint8_t busid, const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = false;
+ } else {
+ g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = false;
+ }
+
+ chipidea_edpt_close(USB_OTG_DEV, ep);
+
+ return 0;
+}
+
+int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
+{
+ chipidea_edpt_stall(USB_OTG_DEV, ep);
+ return 0;
+}
+
+int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
+{
+ chipidea_edpt_clear_stall(USB_OTG_DEV, ep);
+ return 0;
+}
+
+int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
+{
+ *stalled = chipidea_edpt_check_stall(USB_OTG_DEV, ep);
+ 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_chipidea_udc[busid].in_ep[ep_idx].ep_enable) {
+ return -2;
+ }
+
+ g_chipidea_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_chipidea_udc[busid].in_ep[ep_idx].xfer_len = data_len;
+ g_chipidea_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
+
+ chipidea_start_xfer(busid, ep, (uint8_t *)data, 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_chipidea_udc[busid].out_ep[ep_idx].ep_enable) {
+ return -2;
+ }
+
+ g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_chipidea_udc[busid].out_ep[ep_idx].xfer_len = data_len;
+ g_chipidea_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
+
+ chipidea_start_xfer(busid, ep, data, data_len);
+
+ return 0;
+}
+
+void USBD_IRQHandler(uint8_t busid)
+{
+ uint32_t int_status;
+ uint32_t transfer_len;
+ bool ep_cb_req;
+
+ /* Acknowledge handled interrupt */
+ int_status = USB_OTG_DEV->USBSTS;
+ int_status &= USB_OTG_DEV->USBINTR;
+ USB_OTG_DEV->USBSTS = int_status;
+
+ if (int_status & intr_error) {
+ USB_LOG_ERR("usbd intr error!\r\n");
+ }
+
+ if (int_status & intr_reset) {
+ g_chipidea_udc[busid].is_suspend = false;
+ memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
+ memset(g_chipidea_udc[busid].out_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
+ usbd_event_reset_handler(busid);
+ chipidea_bus_reset(busid, 64);
+ }
+
+ if (int_status & intr_suspend) {
+ if (USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) {
+ /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */
+ if (USB_DEVICEADDR_USBADR_GET(USB_OTG_DEV->DEVICEADDR)) {
+ g_chipidea_udc[busid].is_suspend = true;
+ usbd_event_suspend_handler(busid);
+ }
+ } else {
+ }
+ }
+
+ if (int_status & intr_port_change) {
+ if (!USB_PORTSC1_CCS_GET(USB_OTG_DEV->PORTSC1)) {
+ usbd_event_disconnect_handler(busid);
+ } else {
+ if (g_chipidea_udc[busid].is_suspend) {
+ g_chipidea_udc[busid].is_suspend = false;
+ usbd_event_resume_handler(busid);
+ }
+ usbd_event_connect_handler(busid);
+ }
+ }
+
+ if (int_status & intr_usb) {
+ uint32_t const edpt_complete = USB_OTG_DEV->ENDPTCOMPLETE;
+ USB_OTG_DEV->ENDPTCOMPLETE = edpt_complete;
+ uint32_t edpt_setup_status = USB_OTG_DEV->ENDPTSETUPSTAT;
+
+ if (edpt_setup_status) {
+ /*------------- Set up Received -------------*/
+ USB_OTG_DEV->ENDPTSETUPSTAT = edpt_setup_status;
+ dcd_qhd_t *qhd0 = chipidea_qhd_get(busid, 0);
+ usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request);
+ }
+
+ if (edpt_complete) {
+ for (uint8_t ep_idx = 0; ep_idx < (CONFIG_USBDEV_EP_NUM * 2); ep_idx++) {
+ if (edpt_complete & (1 << ep_idx2bit(ep_idx))) {
+ transfer_len = 0;
+ ep_cb_req = true;
+
+ /* Failed QTD also get ENDPTCOMPLETE set */
+ dcd_qtd_t *p_qtd = chipidea_qtd_get(busid, ep_idx);
+ while (1) {
+ if (p_qtd->halted || p_qtd->xact_err || p_qtd->buffer_err) {
+ USB_LOG_ERR("usbd transfer error!\r\n");
+ ep_cb_req = false;
+ break;
+ } else if (p_qtd->active) {
+ ep_cb_req = false;
+ break;
+ } else {
+ transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes;
+ }
+
+ if (p_qtd->next == 1) {
+ break;
+ } else {
+ p_qtd = (dcd_qtd_t *)p_qtd->next;
+ }
+ }
+
+ if (ep_cb_req) {
+ uint8_t const ep_addr = (ep_idx / 2) | ((ep_idx & 0x01) ? 0x80 : 0);
+ if (ep_addr & 0x80) {
+ usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len);
+ } else {
+ usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len);
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c b/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c
new file mode 100644
index 0000000000..29bb2d292c
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c
@@ -0,0 +1,94 @@
+#include "usbd_core.h"
+#include "fsl_common.h"
+
+/*! @brief USB controller ID */
+typedef enum _usb_controller_index {
+ kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
+ kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
+ to be used in the future. */
+ kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
+ kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U */
+} usb_controller_index_t;
+
+#define USB_DEVICE_CONFIG_EHCI 1
+
+/* USB PHY condfiguration */
+#define BOARD_USB_PHY_D_CAL (0x04U)
+#define BOARD_USB_PHY_TXCAL45DP (0x07U)
+#define BOARD_USB_PHY_TXCAL45DM (0x07U)
+#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */
+
+#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
+#include "usb_phy.h"
+#endif
+
+#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U))
+void USB1_HS_IRQHandler(void)
+{
+ extern void USBD_IRQHandler(uint8_t busid);
+ USBD_IRQHandler(0);
+}
+#endif
+
+void USB_ClockInit(void)
+{
+#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
+ usb_phy_config_struct_t phyConfig = {
+ BOARD_USB_PHY_D_CAL,
+ BOARD_USB_PHY_TXCAL45DP,
+ BOARD_USB_PHY_TXCAL45DM,
+ };
+#endif
+#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
+ SPC0->ACTIVE_VDELAY = 0x0500;
+ /* Change the power DCDC to 1.8v (By deafult, DCDC is 1.8V), CORELDO to 1.1v (By deafult, CORELDO is 1.0V) */
+ SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK;
+ SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) |
+ SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u);
+ /* Wait until it is done */
+ while (SPC0->SC & SPC_SC_BUSY_MASK)
+ ;
+ if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) {
+ SCG0->TRIM_LOCK = 0x5a5a0001U;
+ SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK;
+ /* wait LDO ready */
+ while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK))
+ ;
+ }
+ SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK;
+ SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK);
+ /* xtal = 20 ~ 30MHz */
+ SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT);
+ SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK;
+ while (1) {
+ if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) {
+ break;
+ }
+ }
+ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK;
+ CLOCK_EnableClock(kCLOCK_UsbHs);
+ CLOCK_EnableClock(kCLOCK_UsbHsPhy);
+ CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U);
+ CLOCK_EnableUsbhsClock();
+ USB_EhciPhyInit(kUSB_ControllerEhci0, BOARD_XTAL0_CLK_HZ, &phyConfig);
+#endif
+#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
+ CLOCK_AttachClk(kCLK_48M_to_USB0);
+ CLOCK_EnableClock(kCLOCK_Usb0Ram);
+ CLOCK_EnableClock(kCLOCK_Usb0Fs);
+ CLOCK_EnableUsbfsClock();
+#endif
+}
+
+void usb_dc_low_level_init(uint8_t busid)
+{
+ USB_ClockInit();
+ /* Install isr, set priority, and enable IRQ. */
+ NVIC_SetPriority((IRQn_Type)USB1_HS_IRQn, 3);
+ EnableIRQ((IRQn_Type)USB1_HS_IRQn);
+}
+
+void usb_dc_low_level_deinit(uint8_t busid)
+{
+ DisableIRQ((IRQn_Type)USB1_HS_IRQn);
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/dwc2/README.md b/components/drivers/usb/cherryusb/port/dwc2/README.md
index 2111008946..faf9ab5a1a 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/README.md
+++ b/components/drivers/usb/cherryusb/port/dwc2/README.md
@@ -1,5 +1,7 @@
# Note
+If you are using more than one port, all ip parameters must be the same(like fifo num, endpoint num, dma support and so on), otherwise give up using multi ports.
+
## Support Chip List
## STM32
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c b/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c
index 9dee5c1d98..ce951623d1 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c
@@ -93,7 +93,7 @@
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
#endif
-#define USBD_BASE (g_usbdev_bus[0].reg_base)
+#define USBD_BASE (g_usbdev_bus[busid].reg_base)
#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE))
#define USB_OTG_DEV ((DWC2_DeviceTypeDef *)(USBD_BASE + USB_OTG_DEVICE_BASE))
@@ -119,9 +119,9 @@ USB_NOCACHE_RAM_SECTION struct dwc2_udc {
__attribute__((aligned(32))) struct usb_setup_packet setup;
struct dwc2_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
struct dwc2_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
-} g_dwc2_udc;
+} g_dwc2_udc[CONFIG_USBHOST_MAX_BUS];
-static inline int dwc2_reset(void)
+static inline int dwc2_reset(uint8_t busid)
{
volatile uint32_t count = 0U;
@@ -145,7 +145,7 @@ static inline int dwc2_reset(void)
return 0;
}
-static inline int dwc2_core_init(void)
+static inline int dwc2_core_init(uint8_t busid)
{
int ret;
#if defined(CONFIG_USB_HS)
@@ -156,18 +156,18 @@ static inline int dwc2_core_init(void)
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* Reset after a PHY select */
- ret = dwc2_reset();
+ ret = dwc2_reset(busid);
#else
/* Select FS Embedded PHY */
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
/* Reset after a PHY select */
- ret = dwc2_reset();
+ ret = dwc2_reset(busid);
#endif
return ret;
}
-static inline void dwc2_set_mode(uint8_t mode)
+static inline void dwc2_set_mode(uint8_t busid, uint8_t mode)
{
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
@@ -176,12 +176,22 @@ static inline void dwc2_set_mode(uint8_t mode)
} else if (mode == USB_OTG_MODE_DEVICE) {
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
}
+
+ usbd_dwc2_delay_ms(50);
}
-static inline int dwc2_flush_rxfifo(void)
+static inline int dwc2_flush_rxfifo(uint8_t busid)
{
- volatile uint32_t count = 0;
+ volatile uint32_t count = 0U;
+ /* Wait for AHB master IDLE state. */
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+ count = 0;
USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
do {
@@ -193,10 +203,18 @@ static inline int dwc2_flush_rxfifo(void)
return 0;
}
-static inline int dwc2_flush_txfifo(uint32_t num)
+static inline int dwc2_flush_txfifo(uint8_t busid, uint32_t num)
{
volatile uint32_t count = 0U;
+ /* Wait for AHB master IDLE state. */
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+ count = 0;
USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
do {
@@ -208,7 +226,7 @@ static inline int dwc2_flush_txfifo(uint32_t num)
return 0;
}
-static void dwc2_set_turnaroundtime(uint32_t hclk, uint8_t speed)
+static void dwc2_set_turnaroundtime(uint8_t busid, uint32_t hclk, uint8_t speed)
{
uint32_t UsbTrd;
@@ -261,7 +279,7 @@ static void dwc2_set_turnaroundtime(uint32_t hclk, uint8_t speed)
USB_OTG_GLB->GUSBCFG |= (uint32_t)((UsbTrd << USB_OTG_GUSBCFG_TRDT_Pos) & USB_OTG_GUSBCFG_TRDT);
}
-static void dwc2_set_txfifo(uint8_t fifo, uint16_t size)
+static void dwc2_set_txfifo(uint8_t busid, uint8_t fifo, uint16_t size)
{
uint8_t i;
uint32_t tx_offset;
@@ -293,7 +311,7 @@ static void dwc2_set_txfifo(uint8_t fifo, uint16_t size)
USB_LOG_INFO("fifo%d size:%04x, offset:%04x\r\n", fifo, size, tx_offset);
}
-static uint8_t dwc2_get_devspeed(void)
+static uint8_t dwc2_get_devspeed(uint8_t busid)
{
uint8_t speed;
uint32_t DevEnumSpeed = USB_OTG_DEV->DSTS & USB_OTG_DSTS_ENUMSPD;
@@ -310,7 +328,7 @@ static uint8_t dwc2_get_devspeed(void)
return speed;
}
-static void dwc2_ep0_start_read_setup(uint8_t *psetup)
+static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup)
{
USB_OTG_OUTEP(0U)->DOEPTSIZ = 0U;
USB_OTG_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
@@ -324,7 +342,7 @@ static void dwc2_ep0_start_read_setup(uint8_t *psetup)
#endif
}
-void dwc2_ep_write(uint8_t ep_idx, uint8_t *src, uint16_t len)
+void dwc2_ep_write(uint8_t busid, uint8_t ep_idx, uint8_t *src, uint16_t len)
{
uint32_t *pSrc = (uint32_t *)src;
uint32_t count32b, i;
@@ -336,7 +354,7 @@ void dwc2_ep_write(uint8_t ep_idx, uint8_t *src, uint16_t len)
}
}
-void dwc2_ep_read(uint8_t *dest, uint16_t len)
+void dwc2_ep_read(uint8_t busid, uint8_t *dest, uint16_t len)
{
uint32_t *pDest = (uint32_t *)dest;
uint32_t i;
@@ -348,33 +366,33 @@ void dwc2_ep_read(uint8_t *dest, uint16_t len)
}
}
-static void dwc2_tx_fifo_empty_procecss(uint8_t ep_idx)
+static void dwc2_tx_fifo_empty_procecss(uint8_t busid, uint8_t ep_idx)
{
uint32_t len;
uint32_t len32b;
uint32_t fifoemptymsk;
- len = g_dwc2_udc.in_ep[ep_idx].xfer_len - g_dwc2_udc.in_ep[ep_idx].actual_xfer_len;
- if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps) {
- len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
+ len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len;
+ if (len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) {
+ len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps;
}
len32b = (len + 3U) / 4U;
while (((USB_OTG_INEP(ep_idx)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
- (g_dwc2_udc.in_ep[ep_idx].actual_xfer_len < g_dwc2_udc.in_ep[ep_idx].xfer_len) && (g_dwc2_udc.in_ep[ep_idx].xfer_len != 0U)) {
+ (g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len < g_dwc2_udc[busid].in_ep[ep_idx].xfer_len) && (g_dwc2_udc[busid].in_ep[ep_idx].xfer_len != 0U)) {
/* Write the FIFO */
- len = g_dwc2_udc.in_ep[ep_idx].xfer_len - g_dwc2_udc.in_ep[ep_idx].actual_xfer_len;
- if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps) {
- len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
+ len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len;
+ if (len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) {
+ len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps;
}
- dwc2_ep_write(ep_idx, g_dwc2_udc.in_ep[ep_idx].xfer_buf, len);
- g_dwc2_udc.in_ep[ep_idx].xfer_buf += len;
- g_dwc2_udc.in_ep[ep_idx].actual_xfer_len += len;
+ dwc2_ep_write(busid, ep_idx, g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf, len);
+ g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf += len;
+ g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len += len;
}
- if (g_dwc2_udc.in_ep[ep_idx].xfer_len <= g_dwc2_udc.in_ep[ep_idx].actual_xfer_len) {
+ if (g_dwc2_udc[busid].in_ep[ep_idx].xfer_len <= g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len) {
fifoemptymsk = (uint32_t)(0x1UL << (ep_idx & 0x0f));
USB_OTG_DEV->DIEPEMPMSK &= ~fifoemptymsk;
}
@@ -384,7 +402,7 @@ static void dwc2_tx_fifo_empty_procecss(uint8_t ep_idx)
* @brief dwc2_get_glb_intstatus: return the global USB interrupt status
* @retval status
*/
-static inline uint32_t dwc2_get_glb_intstatus(void)
+static inline uint32_t dwc2_get_glb_intstatus(uint8_t busid)
{
uint32_t tmpreg;
@@ -398,7 +416,7 @@ static inline uint32_t dwc2_get_glb_intstatus(void)
* @brief dwc2_get_outeps_intstatus: return the USB device OUT endpoints interrupt status
* @retval status
*/
-static inline uint32_t dwc2_get_outeps_intstatus(void)
+static inline uint32_t dwc2_get_outeps_intstatus(uint8_t busid)
{
uint32_t tmpreg;
@@ -412,7 +430,7 @@ static inline uint32_t dwc2_get_outeps_intstatus(void)
* @brief dwc2_get_ineps_intstatus: return the USB device IN endpoints interrupt status
* @retval status
*/
-static inline uint32_t dwc2_get_ineps_intstatus(void)
+static inline uint32_t dwc2_get_ineps_intstatus(uint8_t busid)
{
uint32_t tmpreg;
@@ -428,12 +446,13 @@ static inline uint32_t dwc2_get_ineps_intstatus(void)
* This parameter can be a value from 0 to 15
* @retval Device OUT EP Interrupt register
*/
-static inline uint32_t dwc2_get_outep_intstatus(uint8_t epnum)
+static inline uint32_t dwc2_get_outep_intstatus(uint8_t busid, uint8_t epnum)
{
uint32_t tmpreg;
tmpreg = USB_OTG_OUTEP((uint32_t)epnum)->DOEPINT;
- tmpreg &= USB_OTG_DEV->DOEPMSK;
+ USB_OTG_OUTEP((uint32_t)epnum)->DOEPINT = tmpreg;
+ tmpreg = tmpreg & USB_OTG_DEV->DOEPMSK;
return tmpreg;
}
@@ -444,26 +463,21 @@ static inline uint32_t dwc2_get_outep_intstatus(uint8_t epnum)
* This parameter can be a value from 0 to 15
* @retval Device IN EP Interrupt register
*/
-static inline uint32_t dwc2_get_inep_intstatus(uint8_t epnum)
+static inline uint32_t dwc2_get_inep_intstatus(uint8_t busid, uint8_t epnum)
{
uint32_t tmpreg, msk, emp;
msk = USB_OTG_DEV->DIEPMSK;
emp = USB_OTG_DEV->DIEPEMPMSK;
msk |= ((emp >> (epnum & 0x07)) & 0x1U) << 7;
- tmpreg = USB_OTG_INEP((uint32_t)epnum)->DIEPINT & msk;
+
+ tmpreg = USB_OTG_INEP((uint32_t)epnum)->DIEPINT;
+ USB_OTG_INEP((uint32_t)epnum)->DIEPINT = tmpreg;
+ tmpreg = tmpreg & msk;
return tmpreg;
}
-__WEAK void usb_dc_low_level_init(void)
-{
-}
-
-__WEAK void usb_dc_low_level_deinit(void)
-{
-}
-
int usb_dc_init(uint8_t busid)
{
int ret;
@@ -473,9 +487,9 @@ int usb_dc_init(uint8_t busid)
uint8_t endpoints;
uint32_t fifo_num;
- memset(&g_dwc2_udc, 0, sizeof(struct dwc2_udc));
+ memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
- usb_dc_low_level_init();
+ usb_dc_low_level_init(busid);
/*
Full-Speed PHY Interface Type (FSPhyType)
@@ -526,14 +540,10 @@ int usb_dc_init(uint8_t busid)
/* This is vendor register */
USB_OTG_GLB->GCCFG = usbd_get_dwc2_gccfg_conf(USBD_BASE);
- ret = dwc2_core_init();
+ ret = dwc2_core_init(busid);
/* Force Device Mode*/
- dwc2_set_mode(USB_OTG_MODE_DEVICE);
-
- /* B-peripheral session valid override enable */
- // USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
- // USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
+ dwc2_set_mode(busid, USB_OTG_MODE_DEVICE);
for (uint8_t i = 0U; i < 15U; i++) {
USB_OTG_GLB->DIEPTXF[i] = 0U;
@@ -567,6 +577,7 @@ int usb_dc_init(uint8_t busid)
/* Enable interrupts matching to the Device mode ONLY */
USB_OTG_GLB->GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM |
USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT |
+ USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM |
USB_OTG_GINTMSK_IISOIXFRM | USB_OTG_GINTMSK_PXFRM_IISOOXFRM;
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
@@ -590,10 +601,10 @@ int usb_dc_init(uint8_t busid)
USB_OTG_GLB->GRXFSIZ = (CONFIG_USB_DWC2_RXALL_FIFO_SIZE);
- dwc2_set_txfifo(0, CONFIG_USB_DWC2_TX0_FIFO_SIZE);
- dwc2_set_txfifo(1, CONFIG_USB_DWC2_TX1_FIFO_SIZE);
- dwc2_set_txfifo(2, CONFIG_USB_DWC2_TX2_FIFO_SIZE);
- dwc2_set_txfifo(3, CONFIG_USB_DWC2_TX3_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 0, CONFIG_USB_DWC2_TX0_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 1, CONFIG_USB_DWC2_TX1_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 2, CONFIG_USB_DWC2_TX2_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 3, CONFIG_USB_DWC2_TX3_FIFO_SIZE);
fifo_num = CONFIG_USB_DWC2_RXALL_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX0_FIFO_SIZE;
@@ -601,23 +612,23 @@ int usb_dc_init(uint8_t busid)
fifo_num += CONFIG_USB_DWC2_TX2_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX3_FIFO_SIZE;
#if CONFIG_USBDEV_EP_NUM > 4
- dwc2_set_txfifo(4, CONFIG_USB_DWC2_TX4_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 4, CONFIG_USB_DWC2_TX4_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX4_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 5
- dwc2_set_txfifo(5, CONFIG_USB_DWC2_TX5_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 5, CONFIG_USB_DWC2_TX5_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX5_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 6
- dwc2_set_txfifo(6, CONFIG_USB_DWC2_TX6_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 6, CONFIG_USB_DWC2_TX6_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX6_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 7
- dwc2_set_txfifo(7, CONFIG_USB_DWC2_TX7_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 7, CONFIG_USB_DWC2_TX7_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX7_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 8
- dwc2_set_txfifo(8, CONFIG_USB_DWC2_TX8_FIFO_SIZE);
+ dwc2_set_txfifo(busid, 8, CONFIG_USB_DWC2_TX8_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX8_FIFO_SIZE;
#endif
@@ -634,8 +645,8 @@ int usb_dc_init(uint8_t busid)
}
}
- ret = dwc2_flush_txfifo(0x10U);
- ret = dwc2_flush_rxfifo();
+ ret = dwc2_flush_txfifo(busid, 0x10U);
+ ret = dwc2_flush_rxfifo(busid);
USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_SDIS;
@@ -660,10 +671,10 @@ int usb_dc_deinit(uint8_t busid)
USB_OTG_DEV->DAINTMSK = 0U;
/* Flush the FIFO */
- dwc2_flush_txfifo(0x10U);
- dwc2_flush_rxfifo();
+ dwc2_flush_txfifo(busid, 0x10U);
+ dwc2_flush_rxfifo(busid);
- usb_dc_low_level_deinit();
+ usb_dc_low_level_deinit(busid);
return 0;
}
@@ -674,6 +685,17 @@ int usbd_set_address(uint8_t busid, const uint8_t addr)
return 0;
}
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ if (!(USB_OTG_DEV->DSTS & USB_OTG_DSTS_SUSPSTS)) {
+ return -1;
+ }
+ USB_OTG_DEV->DCTL |= USB_OTG_DCTL_RWUSIG;
+ usbd_dwc2_delay_ms(10);
+ USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_RWUSIG;
+ return 0;
+}
+
uint8_t usbd_get_port_speed(uint8_t busid)
{
uint8_t speed;
@@ -701,8 +723,8 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
}
if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
- g_dwc2_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
- g_dwc2_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_dwc2_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx));
@@ -724,8 +746,8 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
return -2;
}
- g_dwc2_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
- g_dwc2_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
+ g_dwc2_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
+ g_dwc2_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx);
@@ -735,7 +757,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
USB_OTG_DIEPCTL_USBAEP;
}
- dwc2_flush_txfifo(ep_idx);
+ dwc2_flush_txfifo(busid, ep_idx);
}
return 0;
}
@@ -806,7 +828,7 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
}
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
if (ep_idx == 0) {
- dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
+ dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
#endif
return 0;
@@ -818,14 +840,14 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
if (USB_EP_DIR_IS_OUT(ep)) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
- if ((g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
- (g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
+ if ((g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
+ (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
}
} else {
USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
- if ((g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
- (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
+ if ((g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
+ (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
}
}
@@ -834,8 +856,20 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
if (USB_EP_DIR_IS_OUT(ep)) {
+ if(USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
} else {
+ if(USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
}
return 0;
}
@@ -860,9 +894,9 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
return -4;
}
- g_dwc2_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
- g_dwc2_udc.in_ep[ep_idx].xfer_len = data_len;
- g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = 0;
+ g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = data_len;
+ g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
@@ -874,20 +908,20 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
}
if (ep_idx == 0) {
- if (data_len > g_dwc2_udc.in_ep[ep_idx].ep_mps) {
- data_len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
+ if (data_len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) {
+ data_len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps;
}
- g_dwc2_udc.in_ep[ep_idx].xfer_len = data_len;
+ g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = data_len;
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len);
} else {
- pktcnt = (uint16_t)((data_len + g_dwc2_udc.in_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.in_ep[ep_idx].ep_mps);
+ pktcnt = (uint16_t)((data_len + g_dwc2_udc[busid].in_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc[busid].in_ep[ep_idx].ep_mps);
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len);
}
- if (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ if (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
@@ -933,28 +967,28 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
return -4;
}
- g_dwc2_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
- g_dwc2_udc.out_ep[ep_idx].xfer_len = data_len;
- g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = 0;
+ g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data;
+ g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = data_len;
+ g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
if (data_len == 0) {
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
- USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc.out_ep[ep_idx].ep_mps);
+ USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc[busid].out_ep[ep_idx].ep_mps);
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
return 0;
}
if (ep_idx == 0) {
- if (data_len > g_dwc2_udc.out_ep[ep_idx].ep_mps) {
- data_len = g_dwc2_udc.out_ep[ep_idx].ep_mps;
+ if (data_len > g_dwc2_udc[busid].out_ep[ep_idx].ep_mps) {
+ data_len = g_dwc2_udc[busid].out_ep[ep_idx].ep_mps;
}
- g_dwc2_udc.out_ep[ep_idx].xfer_len = data_len;
+ g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = data_len;
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len);
} else {
- pktcnt = (uint16_t)((data_len + g_dwc2_udc.out_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.out_ep[ep_idx].ep_mps);
+ pktcnt = (uint16_t)((data_len + g_dwc2_udc[busid].out_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc[busid].out_ep[ep_idx].ep_mps);
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len);
@@ -963,7 +997,7 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
#endif
- if (g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
+ if (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
@@ -979,7 +1013,7 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
void USBD_IRQHandler(uint8_t busid)
{
uint32_t gint_status, temp, ep_idx, ep_intr, epint, read_count, daintmask;
- gint_status = dwc2_get_glb_intstatus();
+ gint_status = dwc2_get_glb_intstatus(busid);
if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_DEVICE) {
/* Avoid spurious interrupt */
@@ -998,12 +1032,12 @@ void USBD_IRQHandler(uint8_t busid)
if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
if (read_count != 0) {
- dwc2_ep_read(g_dwc2_udc.out_ep[ep_idx].xfer_buf, read_count);
- g_dwc2_udc.out_ep[ep_idx].xfer_buf += read_count;
+ dwc2_ep_read(busid, g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, read_count);
+ g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf += read_count;
}
} else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) {
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
- dwc2_ep_read((uint8_t *)&g_dwc2_udc.setup, read_count);
+ dwc2_ep_read(busid, (uint8_t *)&g_dwc2_udc[busid].setup, read_count);
} else {
/* ... */
}
@@ -1012,32 +1046,30 @@ void USBD_IRQHandler(uint8_t busid)
#endif
if (gint_status & USB_OTG_GINTSTS_OEPINT) {
ep_idx = 0;
- ep_intr = dwc2_get_outeps_intstatus();
+ ep_intr = dwc2_get_outeps_intstatus(busid);
while (ep_intr != 0U) {
if ((ep_intr & 0x1U) != 0U) {
- epint = dwc2_get_outep_intstatus(ep_idx);
- uint32_t DoepintReg = USB_OTG_OUTEP(ep_idx)->DOEPINT;
- USB_OTG_OUTEP(ep_idx)->DOEPINT = DoepintReg;
+ epint = dwc2_get_outep_intstatus(busid, ep_idx);
if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) {
if (ep_idx == 0) {
- if (g_dwc2_udc.out_ep[ep_idx].xfer_len == 0) {
+ if (g_dwc2_udc[busid].out_ep[ep_idx].xfer_len == 0) {
/* Out status, start reading setup */
- dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
+ dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
} else {
- g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = g_dwc2_udc.out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
- g_dwc2_udc.out_ep[ep_idx].xfer_len = 0;
- usbd_event_ep_out_complete_handler(0, 0x00, g_dwc2_udc.out_ep[ep_idx].actual_xfer_len);
+ g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
+ g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
+ usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
}
} else {
- g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = g_dwc2_udc.out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
- g_dwc2_udc.out_ep[ep_idx].xfer_len = 0;
- usbd_event_ep_out_complete_handler(0, ep_idx, g_dwc2_udc.out_ep[ep_idx].actual_xfer_len);
+ g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
+ g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
+ usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
}
}
if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) {
- usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_dwc2_udc.setup);
+ usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
}
ep_intr >>= 1U;
@@ -1046,34 +1078,32 @@ void USBD_IRQHandler(uint8_t busid)
}
if (gint_status & USB_OTG_GINTSTS_IEPINT) {
ep_idx = 0U;
- ep_intr = dwc2_get_ineps_intstatus();
+ ep_intr = dwc2_get_ineps_intstatus(busid);
while (ep_intr != 0U) {
if ((ep_intr & 0x1U) != 0U) {
- epint = dwc2_get_inep_intstatus(ep_idx);
- uint32_t DiepintReg = USB_OTG_INEP(ep_idx)->DIEPINT;
- USB_OTG_INEP(ep_idx)->DIEPINT = DiepintReg;
+ epint = dwc2_get_inep_intstatus(busid, ep_idx);
if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) {
if (ep_idx == 0) {
- g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = g_dwc2_udc.in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
- g_dwc2_udc.in_ep[ep_idx].xfer_len = 0;
- usbd_event_ep_in_complete_handler(0, 0x80, g_dwc2_udc.in_ep[ep_idx].actual_xfer_len);
+ g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
+ g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(busid, 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len);
- if (g_dwc2_udc.setup.wLength && ((g_dwc2_udc.setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
+ if (g_dwc2_udc[busid].setup.wLength && ((g_dwc2_udc[busid].setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
/* In status, start reading setup */
- dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
- } else if (g_dwc2_udc.setup.wLength == 0) {
+ dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
+ } else if (g_dwc2_udc[busid].setup.wLength == 0) {
/* In status, start reading setup */
- dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
+ dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
} else {
- g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = g_dwc2_udc.in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
- g_dwc2_udc.in_ep[ep_idx].xfer_len = 0;
- usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_dwc2_udc.in_ep[ep_idx].actual_xfer_len);
+ g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
+ g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = 0;
+ usbd_event_ep_in_complete_handler(busid, ep_idx | 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len);
}
}
if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) {
- dwc2_tx_fifo_empty_procecss(ep_idx);
+ dwc2_tx_fifo_empty_procecss(busid, ep_idx);
}
}
ep_intr >>= 1U;
@@ -1084,8 +1114,8 @@ void USBD_IRQHandler(uint8_t busid)
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBRST;
USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_RWUSIG;
- dwc2_flush_txfifo(0x10U);
- dwc2_flush_rxfifo();
+ dwc2_flush_txfifo(busid, 0x10U);
+ dwc2_flush_rxfifo(busid);
for (uint8_t i = 0U; i < CONFIG_USBDEV_EP_NUM; i++) {
if (i == 0U) {
@@ -1116,14 +1146,14 @@ void USBD_IRQHandler(uint8_t busid)
USB_OTG_DEV->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
- memset(&g_dwc2_udc, 0, sizeof(struct dwc2_udc));
- usbd_event_reset_handler(0);
+ memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
+ usbd_event_reset_handler(busid);
/* Start reading setup */
- dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
+ dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
if (gint_status & USB_OTG_GINTSTS_ENUMDNE) {
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_ENUMDNE;
- dwc2_set_turnaroundtime(SystemCoreClock, dwc2_get_devspeed());
+ dwc2_set_turnaroundtime(busid, SystemCoreClock, dwc2_get_devspeed(busid));
USB_OTG_DEV->DCTL |= USB_OTG_DCTL_CGINAK;
}
@@ -1132,7 +1162,7 @@ void USBD_IRQHandler(uint8_t busid)
daintmask >>= 16;
for (ep_idx = 1; ep_idx < CONFIG_USBDEV_EP_NUM; ep_idx++) {
- if ((BIT(ep_idx) & ~daintmask) || (g_dwc2_udc.out_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
+ if ((BIT(ep_idx) & ~daintmask) || (g_dwc2_udc[busid].out_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
continue;
if (!(USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_USBAEP))
continue;
@@ -1154,7 +1184,7 @@ void USBD_IRQHandler(uint8_t busid)
daintmask >>= 16;
for (ep_idx = 1; ep_idx < CONFIG_USBDEV_EP_NUM; ep_idx++) {
- if (((BIT(ep_idx) & ~daintmask)) || (g_dwc2_udc.in_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
+ if (((BIT(ep_idx) & ~daintmask)) || (g_dwc2_udc[busid].in_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
continue;
if (!(USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP))
@@ -1176,9 +1206,11 @@ void USBD_IRQHandler(uint8_t busid)
}
if (gint_status & USB_OTG_GINTSTS_USBSUSP) {
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBSUSP;
+ usbd_event_suspend_handler(busid);
}
if (gint_status & USB_OTG_GINTSTS_WKUINT) {
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_WKUINT;
+ usbd_event_resume_handler(busid);
}
if (gint_status & USB_OTG_GINTSTS_OTGINT) {
temp = USB_OTG_GLB->GOTGINT;
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h
index c3bd75d664..5f9b5f90bf 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h
@@ -1716,6 +1716,9 @@ typedef struct
#define USB_UNMASK_HALT_HC_INT(chnum) (USB_OTG_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM)
#define CLEAR_HC_INT(chnum, __INTERRUPT__) (USB_OTG_HC(chnum)->HCINT = (__INTERRUPT__))
+void usb_dc_low_level_init(uint8_t busid);
+void usb_dc_low_level_deinit(uint8_t busid);
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base);
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base);
+void usbd_dwc2_delay_ms(uint8_t ms);
#endif
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c
index d9c26261a2..137b1d8704 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c
@@ -12,7 +12,7 @@
* usbx->gccfg_bit.pwrdown = TRUE;
* usbx->gccfg_bit.avalidsesen = TRUE;
* usbx->gccfg_bit.bvalidsesen = TRUE;
- *
+ *
*/
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
@@ -49,4 +49,9 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
return ((1 << 16) | (1 << 21));
#endif
#endif
+}
+
+void usbd_dwc2_delay_ms(uint8_t ms)
+{
+ /* implement later */
}
\ No newline at end of file
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 8c63234e02..76abb19ea4 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c
@@ -8,13 +8,19 @@
#include "esp_intr_alloc.h"
#include "esp_private/usb_phy.h"
#include "soc/periph_defs.h"
+#include "freertos/FreeRTOS.h"
#include "usbd_core.h"
#include "usbh_core.h"
#ifdef CONFIG_IDF_TARGET_ESP32S2
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
+#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
#elif CONFIG_IDF_TARGET_ESP32S3
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ
+#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
+#elif CONFIG_IDF_TARGET_ESP32P4
+#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ
+#define DEFAULT_USB_INTR_SOURCE ETS_USB_OTG_INTR_SOURCE
#else
#define DEFAULT_CPU_FREQ_MHZ 160
#endif
@@ -29,7 +35,7 @@ static void usb_dc_interrupt_cb(void *arg_pv)
USBD_IRQHandler(0);
}
-void usb_dc_low_level_init(void)
+void usb_dc_low_level_init(uint8_t busid)
{
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
@@ -44,15 +50,15 @@ void usb_dc_low_level_init(void)
}
// TODO: Check when to enable interrupt
- ret = esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LEVEL2, usb_dc_interrupt_cb, 0, &s_interrupt_handle);
+ ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_dc_interrupt_cb, 0, &s_interrupt_handle);
if (ret != ESP_OK) {
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
return;
}
- USB_LOG_INFO("cherryusb, version: 0x%06x\r\n", CHERRYUSB_VERSION);
+ USB_LOG_INFO("cherryusb, version: "CHERRYUSB_VERSION_STR"\r\n");
}
-void usb_dc_low_level_deinit(void)
+void usb_dc_low_level_deinit(uint8_t busid)
{
if (s_interrupt_handle) {
esp_intr_free(s_interrupt_handle);
@@ -94,12 +100,12 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
}
// TODO: Check when to enable interrupt
- ret = esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LEVEL2, usb_hc_interrupt_cb, 0, &s_interrupt_handle);
+ ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_hc_interrupt_cb, 0, &s_interrupt_handle);
if (ret != ESP_OK) {
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
return;
}
- USB_LOG_INFO("cherryusb, version: 0x%06x\r\n", CHERRYUSB_VERSION);
+ USB_LOG_INFO("cherryusb, version: "CHERRYUSB_VERSION_STR"\r\n");
}
void usb_hc_low_level_deinit(struct usbh_bus *bus)
@@ -118,3 +124,8 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
{
return 0;
}
+
+void usbd_dwc2_delay_ms(uint8_t ms)
+{
+ vTaskDelay(pdMS_TO_TICKS(ms));
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c
index bdc0d68095..7121ac9dbd 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c
@@ -10,7 +10,7 @@
/* you can find this config in function:usb_core_init, file:drv_usb_core.c, for example:
*
* usb_regs->gr->GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN;
- *
+ *
*/
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
@@ -29,4 +29,9 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
#else
return ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21));
#endif
+}
+
+void usbd_dwc2_delay_ms(uint8_t ms)
+{
+ /* implement later */
}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c
index 9bebe6df52..431b5db5bf 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c
@@ -24,3 +24,8 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL;
return 0;
}
+
+void usbd_dwc2_delay_ms(uint8_t ms)
+{
+ /* implement later */
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c
new file mode 100644
index 0000000000..de10352b2e
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c
@@ -0,0 +1,157 @@
+/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include
+#include
+#include "usbd_core.h"
+#include "usbh_core.h"
+
+#define DEFAULT_USB_HCLK_FREQ_MHZ 200
+
+uint32_t SystemCoreClock = (DEFAULT_USB_HCLK_FREQ_MHZ * 1000 * 1000);
+uintptr_t g_usb_otg0_base = (uintptr_t)0x91500000UL;
+uintptr_t g_usb_otg1_base = (uintptr_t)0x91540000UL;
+
+static void sysctl_reset_hw_done(volatile uint32_t *reset_reg, uint8_t reset_bit, uint8_t done_bit)
+{
+ *reset_reg |= (1 << done_bit); /* clear done bit */
+ rt_thread_mdelay(1);
+
+ *reset_reg |= (1 << reset_bit); /* set reset bit */
+ rt_thread_mdelay(1);
+ /* check done bit */
+ while (*reset_reg & (1 << done_bit) == 0)
+ ;
+}
+
+#define USB_IDPULLUP0 (1 << 4)
+#define USB_DMPULLDOWN0 (1 << 8)
+#define USB_DPPULLDOWN0 (1 << 9)
+
+#ifdef PKG_CHERRYUSB_HOST
+static void usb_hc_interrupt_cb(int irq, void *arg_pv)
+{
+ extern void USBH_IRQHandler(uint8_t busid);
+ USBH_IRQHandler((uint8_t)(uintptr_t)arg_pv);
+}
+
+void usb_hc_low_level_init(struct usbh_bus *bus)
+{
+ uint32_t *hs_reg;
+ uint32_t usb_ctl3;
+
+ if (bus->hcd.hcd_id == 0) {
+ sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28);
+
+ hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
+ usb_ctl3 = *hs_reg | USB_IDPULLUP0;
+
+ *hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0);
+
+ rt_iounmap(hs_reg);
+
+ rt_hw_interrupt_install(173, usb_hc_interrupt_cb, NULL, "usbh0");
+ rt_hw_interrupt_umask(173);
+
+ } else {
+ sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29);
+
+ hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
+ usb_ctl3 = *hs_reg | USB_IDPULLUP0;
+
+ *hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0);
+
+ rt_iounmap(hs_reg);
+
+ rt_hw_interrupt_install(174, usb_hc_interrupt_cb, 1, "usbh1");
+ rt_hw_interrupt_umask(174);
+ }
+}
+
+void usb_hc_low_level_deinit(struct usbh_bus *bus)
+{
+ if (bus->hcd.hcd_id == 0) {
+ rt_hw_interrupt_mask(173);
+ } else {
+ rt_hw_interrupt_mask(174);
+ }
+}
+
+uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
+{
+ return 0;
+}
+#endif
+
+#ifdef PKG_CHERRYUSB_DEVICE
+static void usb_dc_interrupt_cb(int irq, void *arg_pv)
+{
+ extern void USBD_IRQHandler(uint8_t busid);
+ USBD_IRQHandler(0);
+}
+
+#ifdef CHERRYUSB_DEVICE_USING_USB0
+void usb_dc_low_level_init(uint8_t busid)
+{
+ sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28);
+ uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
+ *hs_reg = 0x37;
+ rt_iounmap(hs_reg);
+
+ rt_hw_interrupt_install(173, usb_dc_interrupt_cb, NULL, "usbd");
+ rt_hw_interrupt_umask(173);
+}
+
+void usb_dc_low_level_deinit(uint8_t busid)
+{
+ rt_hw_interrupt_mask(173);
+}
+#else
+void usb_dc_low_level_init(uint8_t busid)
+{
+ sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29);
+ uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
+ *hs_reg = 0x37;
+ rt_iounmap(hs_reg);
+
+ rt_hw_interrupt_install(174, usb_dc_interrupt_cb, NULL, "usbd");
+ rt_hw_interrupt_umask(174);
+}
+
+void usb_dc_low_level_deinit(uint8_t busid)
+{
+ rt_hw_interrupt_mask(174);
+}
+#endif
+uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
+{
+ return 0;
+}
+
+void usbd_dwc2_delay_ms(uint8_t ms)
+{
+ /* implement later */
+}
+#endif
\ No newline at end of file
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 94293d29b7..f73dc5e952 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
@@ -13,9 +13,11 @@
* USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
* USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
* USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
- *
+ *
*/
+extern void HAL_Delay(uint32_t Delay);
+
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
/**
* @brief USB_HS_PHY_Registers
@@ -201,3 +203,8 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
#endif
#endif
}
+
+void usbd_dwc2_delay_ms(uint8_t ms)
+{
+ HAL_Delay(ms);
+}
\ No newline at end of file
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 ddcbaf2802..3171f60ea3 100644
--- a/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c
+++ b/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c
@@ -114,12 +114,22 @@ static inline void dwc2_set_mode(struct usbh_bus *bus, uint8_t mode)
} else if (mode == USB_OTG_MODE_DEVICE) {
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
}
+
+ usb_osal_msleep(50);
}
static inline int dwc2_flush_rxfifo(struct usbh_bus *bus)
{
- volatile uint32_t count = 0;
+ volatile uint32_t count = 0U;
+ /* Wait for AHB master IDLE state. */
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+ count = 0;
USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
do {
@@ -135,6 +145,14 @@ static inline int dwc2_flush_txfifo(struct usbh_bus *bus, uint32_t num)
{
volatile uint32_t count = 0U;
+ /* Wait for AHB master IDLE state. */
+ do {
+ if (++count > 200000U) {
+ return -1;
+ }
+ } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+ count = 0;
USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
do {
@@ -424,10 +442,12 @@ static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_u
__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
{
+ (void)bus;
}
__WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus)
{
+ (void)bus;
}
int usb_hc_init(struct usbh_bus *bus)
@@ -627,6 +647,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u
case HUB_PORT_FEATURE_C_SUSPEND:
break;
case HUB_PORT_FEATURE_POWER:
+ dwc2_drivebus(bus, 0);
break;
case HUB_PORT_FEATURE_C_CONNECTION:
g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 0;
@@ -652,7 +673,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u
case HUB_PORT_FEATURE_SUSPEND:
break;
case HUB_PORT_FEATURE_POWER:
- USB_OTG_HPRT &= ~USB_OTG_HPRT_PPWR;
+ dwc2_drivebus(bus, 1);
break;
case HUB_PORT_FEATURE_RESET:
usbh_reset_port(bus, port);
diff --git a/components/drivers/usb/cherryusb/port/ehci/README.md b/components/drivers/usb/cherryusb/port/ehci/README.md
index 48b9a2b6eb..8160c65d37 100644
--- a/components/drivers/usb/cherryusb/port/ehci/README.md
+++ b/components/drivers/usb/cherryusb/port/ehci/README.md
@@ -22,6 +22,17 @@
- d13x, d21x
+### NXP
+
+Modify USB_NOCACHE_RAM_SECTION
+
+```
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".NonCacheable")))
+```
+
+- IMRT10XX/IMRT11XX
+- MCXN9XX/MCXN236
+
### Intel
- Intel 6 Series Chipset and Intel C200 Series Chipset
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_ehci_priv.h b/components/drivers/usb/cherryusb/port/ehci/usb_ehci_priv.h
deleted file mode 100644
index ba1d3510f7..0000000000
--- a/components/drivers/usb/cherryusb/port/ehci/usb_ehci_priv.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2022, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef _USB_EHCI_PRIV_H
-#define _USB_EHCI_PRIV_H
-
-#include "usbh_core.h"
-#include "usbh_hub.h"
-#include "usb_hc_ehci.h"
-
-#define EHCI_HCCR ((struct ehci_hccr *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET))
-#define EHCI_HCOR ((struct ehci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET + g_ehci_hcd[bus->hcd.hcd_id].hcor_offset))
-
-#define EHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x1F)
-#define EHCI_ADDR2QH(x) ((struct ehci_qh_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
-#define EHCI_ADDR2QTD(x) ((struct ehci_qtd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
-#define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
-
-#ifndef CONFIG_USB_EHCI_QH_NUM
-#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
-#endif
-#ifndef CONFIG_USB_EHCI_QTD_NUM
-#define CONFIG_USB_EHCI_QTD_NUM 3
-#endif
-#ifndef CONFIG_USB_EHCI_ITD_NUM
-#define CONFIG_USB_EHCI_ITD_NUM 5
-#endif
-#ifndef CONFIG_USB_EHCI_ISO_NUM
-#define CONFIG_USB_EHCI_ISO_NUM 4
-#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;
- uint32_t length;
-} __attribute__((aligned(32)));
-
-struct ehci_qh_hw {
- struct ehci_qh hw;
- struct ehci_qtd_hw qtd_pool[CONFIG_USB_EHCI_QTD_NUM];
- uint32_t first_qtd;
- struct usbh_urb *urb;
- usb_osal_sem_t waitsem;
- uint8_t remove_in_iaad;
-} __attribute__((aligned(32)));
-
-struct ehci_itd_hw {
- struct ehci_itd hw;
- struct usbh_urb *urb;
- uint16_t start_frame;
- uint8_t mf_unmask;
- uint8_t mf_valid;
- uint32_t pkt_idx[8];
-} __attribute__((aligned(32)));
-
-struct ehci_iso_hw
-{
- struct ehci_itd_hw itd_pool[CONFIG_USB_EHCI_ITD_NUM];
- uint32_t itd_num;
-};
-
-struct ehci_hcd {
- bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM];
- bool ehci_iso_used[CONFIG_USB_EHCI_ISO_NUM];
- bool ppc; /* Port Power Control */
- bool has_tt; /* if use tt instead of Companion Controller */
- uint8_t n_cc; /* Number of Companion Controller */
- uint8_t n_pcc; /* Number of ports supported per companion host controller */
- uint8_t n_ports;
- uint8_t hcor_offset;
-};
-
-extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS];
-extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)];
-
-int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb);
-void ehci_kill_iso_urb(struct usbh_bus *bus, struct usbh_urb *urb);
-void ehci_scan_isochronous_list(struct usbh_bus *bus);
-
-#endif
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_ehci_reg.h b/components/drivers/usb/cherryusb/port/ehci/usb_ehci_reg.h
new file mode 100644
index 0000000000..741eef64bb
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_ehci_reg.h
@@ -0,0 +1,393 @@
+/****************************************************************************
+ * include/nuttx/usb/ehci.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+/*
+ * Copyright 2022 sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef __INCLUDE_NUTTX_USB_EHCI_H
+#define __INCLUDE_NUTTX_USB_EHCI_H
+
+#define EHCI_FULL_SPEED (0) /* Full-Speed (12Mbs) */
+#define EHCI_LOW_SPEED (1) /* Low-Speed (1.5Mbs) */
+#define EHCI_HIGH_SPEED (2) /* High-Speed (480 Mb/s) */
+
+/* Host Controller Capability Register Bit Definitions **********************/
+
+/* Structural Parameters. Paragraph 2.2.3 */
+
+#define EHCI_HCSPARAMS_NPORTS_SHIFT (0) /* Bit 0-3: Number of physical downstream ports */
+#define EHCI_HCSPARAMS_NPORTS_MASK (15 << EHCI_HCSPARAMS_NPORTS_SHIFT)
+#define EHCI_HCSPARAMS_PPC (1 << 4) /* Bit 4: Port Power Control */
+#define EHCI_HCSPARAMS_PRR (1 << 7) /* Bit 7: Port Routing Rules */
+#define EHCI_HCSPARAMS_NPCC_SHIFT (8) /* Bit 8-11: Number of Ports per Companion Controller */
+#define EHCI_HCSPARAMS_NPCC_MASK (15 << EHCI_HCSPARAMS_NPCC_SHIFT)
+#define EHCI_HCSPARAMS_NCC_SHIFT (12) /* Bit 12-15: Number of Companion Controllers */
+#define EHCI_HCSPARAMS_NCC_MASK (15 << EHCI_HCSPARAMS_NCC_SHIFT)
+#define EHCI_HCSPARAMS_PIND (1 << 16) /* Bit 16: Port Indicators */
+#define EHCI_HCSPARAMS_DBGPORT_SHIFT (20) /* Bit 20-23: Debug Port Number */
+#define EHCI_HCSPARAMS_DBGPORT_MASK (15 << EHCI_HCSPARAMS_DBGPORT_SHIFT)
+
+/* Capability Parameters. Paragraph 2.2.4 */
+
+#define EHCI_HCCPARAMS_64BIT (1 << 0) /* Bit 0: 64-bit Addressing Capability */
+#define EHCI_HCCPARAMS_PFLF (1 << 1) /* Bit 1: Programmable Frame List Flag */
+#define EHCI_HCCPARAMS_ASPC (1 << 2) /* Bit 2: Asynchronous Schedule Park Capability */
+#define EHCI_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */
+#define EHCI_HCCPARAMS_IST_MASK (15 << EHCI_HCCPARAMS_IST_SHIFT)
+#define EHCI_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */
+#define EHCI_HCCPARAMS_EECP_MASK (0xff << EHCI_HCCPARAMS_EECP_SHIFT)
+
+/* Host Controller Operational Register Bit Definitions *********************/
+
+/* USB Command. Paragraph 2.3.1 */
+
+#define EHCI_USBCMD_RUN (1 << 0) /* Bit 0: Run/Stop */
+#define EHCI_USBCMD_HCRESET (1 << 1) /* Bit 1: Host Controller Reset */
+#define EHCI_USBCMD_FLSIZE_SHIFT (2) /* Bits 2-3: Frame List Size */
+#define EHCI_USBCMD_FLSIZE_MASK (3 << EHCI_USBCMD_FLSIZE_SHIFT)
+#define EHCI_USBCMD_FLSIZE_1024 (0 << EHCI_USBCMD_FLSIZE_SHIFT) /* 1024 elements (4096 bytes) */
+#define EHCI_USBCMD_FLSIZE_512 (1 << EHCI_USBCMD_FLSIZE_SHIFT) /* 512 elements (2048 bytes) */
+#define EHCI_USBCMD_FLSIZE_256 (2 << EHCI_USBCMD_FLSIZE_SHIFT) /* 256 elements (1024 bytes) */
+#define EHCI_USBCMD_PSEN (1 << 4) /* Bit 4: Periodic Schedule Enable */
+#define EHCI_USBCMD_ASEN (1 << 5) /* Bit 5: Asynchronous Schedule Enable */
+#define EHCI_USBCMD_IAAD (1 << 6) /* Bit 6: Interrupt on Async Advance Doorbell */
+#define EHCI_USBCMD_LRESET (1 << 7) /* Bit 7: Light Host Controller Reset */
+#define EHCI_USBCMD_ASYNC_PARKCNT_SHIFT (8) /* Bits 8-9: Asynchronous Schedule Park Mode Count */
+#define EHCI_USBCMD_ASYNC_PARKCNT_MASK (3 << EHCI_USBCMD_ASYNC_PARKCNT_SHIFT)
+#define EHCI_USBCMD_ASYNC_PARK (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */
+#define EHCI_USBCMD_ITHRE_SHIFT (16) /* Bits 16-23: Interrupt Threshold Control */
+#define EHCI_USBCMD_ITHRE_MASK (0xff << EHCI_USBCMD_ITHRE_SHIFT)
+#define EHCI_USBCMD_ITHRE_1MF (0x01 << EHCI_USBCMD_ITHRE_SHIFT) /* 1 micro-frame */
+#define EHCI_USBCMD_ITHRE_2MF (0x02 << EHCI_USBCMD_ITHRE_SHIFT) /* 2 micro-frames */
+#define EHCI_USBCMD_ITHRE_4MF (0x04 << EHCI_USBCMD_ITHRE_SHIFT) /* 4 micro-frames */
+#define EHCI_USBCMD_ITHRE_8MF (0x08 << EHCI_USBCMD_ITHRE_SHIFT) /* 8 micro-frames (default, 1 ms) */
+#define EHCI_USBCMD_ITHRE_16MF (0x10 << EHCI_USBCMD_ITHRE_SHIFT) /* 16 micro-frames (2 ms) */
+#define EHCI_USBCMD_ITHRE_32MF (0x20 << EHCI_USBCMD_ITHRE_SHIFT) /* 32 micro-frames (4 ms) */
+#define EHCI_USBCMD_ITHRE_64MF (0x40 << EHCI_USBCMD_ITHRE_SHIFT) /* 64 micro-frames (8 ms) */
+
+/* USB Status. Paragraph 2.3.2 */
+
+#define EHCI_USBSTS_INT (1 << 0) /* Bit 0: USB Interrupt */
+#define EHCI_USBSTS_ERR (1 << 1) /* Bit 1: USB Error Interrupt */
+#define EHCI_USBSTS_PCD (1 << 2) /* Bit 2: Port Change Detect */
+#define EHCI_USBSTS_FLR (1 << 3) /* Bit 3: Frame List Rollover */
+#define EHCI_USBSTS_FATAL (1 << 4) /* Bit 4: Host System Error */
+#define EHCI_USBSTS_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */
+#define EHCI_USBSTS_HALTED (1 << 12) /* Bit 12: HC Halted */
+#define EHCI_USBSTS_RECLAM (1 << 13) /* Bit 13: Reclamation */
+#define EHCI_USBSTS_PSS (1 << 14) /* Bit 14: Periodic Schedule Status */
+#define EHCI_USBSTS_ASS (1 << 15) /* Bit 15: Asynchronous Schedule Status */
+ /* Bits 16-31: Reserved */
+
+/* USB Interrupt Enable. Paragraph 2.3.3 */
+
+#define EHCI_USBIE_INT (1 << 0) /* Bit 0: USB Interrupt */
+#define EHCI_USBIE_ERR (1 << 1) /* Bit 1: USB Error Interrupt */
+#define EHCI_USBIE_PCD (1 << 2) /* Bit 2: Port Change Detect */
+#define EHCI_USBIE_FLROLL (1 << 3) /* Bit 3: Frame List Rollover */
+#define EHCI_USBIE_FATAL (1 << 4) /* Bit 4: Host System Error */
+#define EHCI_USBIE_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */
+#define EHCI_USBIE_ALLINTS (0x3f) /* Bits 0-5: All interrupts */
+
+/* USB Frame Index. Paragraph 2.3.4 */
+
+#define EHCI_FRINDEX_MASK (0x3fff) /* Bits 0-13: Frame index */
+
+/* 4G Segment Selector.
+ * Paragraph 2.3.5, Bits[64:32] of data structure addresses
+ */
+
+/* Frame List Base Address. Paragraph 2.3.6 */
+#define EHCI_PERIODICLISTBASE_MASK (0xfffff000) /* Bits 12-31: Base Address (Low) */
+
+/* Next Asynchronous List Address. Paragraph 2.3.7 */
+
+#define EHCI_ASYNCLISTADDR_MASK (0xffffffe0) /* Bits 5-31: Link Pointer Low (LPL) */
+
+/* Configured Flag Register. Paragraph 2.3.8 */
+
+#define EHCI_CONFIGFLAG (1 << 0) /* Bit 0: Configure Flag */
+
+/* Port Status/Control, Port 1-n. Paragraph 2.3.9 */
+
+#define EHCI_PORTSC_CCS (1 << 0) /* Bit 0: Current Connect Status */
+#define EHCI_PORTSC_CSC (1 << 1) /* Bit 1: Connect Status Change */
+#define EHCI_PORTSC_PE (1 << 2) /* Bit 2: Port Enable */
+#define EHCI_PORTSC_PEC (1 << 3) /* Bit 3: Port Enable/Disable Change */
+#define EHCI_PORTSC_OCA (1 << 4) /* Bit 4: Over-current Active */
+#define EHCI_PORTSC_OCC (1 << 5) /* Bit 5: Over-current Change */
+#define EHCI_PORTSC_RESUME (1 << 6) /* Bit 6: Force Port Resume */
+#define EHCI_PORTSC_SUSPEND (1 << 7) /* Bit 7: Suspend */
+#define EHCI_PORTSC_RESET (1 << 8) /* Bit 8: Port Reset */
+#define EHCI_PORTSC_LSTATUS_SHIFT (10) /* Bits 10-11: Line Status */
+#define EHCI_PORTSC_LSTATUS_MASK (3 << EHCI_PORTSC_LSTATUS_SHIFT)
+#define EHCI_PORTSC_LSTATUS_SE0 (0 << EHCI_PORTSC_LSTATUS_SHIFT) /* SE0 Not Low-speed device, perform EHCI reset */
+#define EHCI_PORTSC_LSTATUS_KSTATE (1 << EHCI_PORTSC_LSTATUS_SHIFT) /* K-state Low-speed device, release ownership of port */
+#define EHCI_PORTSC_LSTATUS_JSTATE (2 << EHCI_PORTSC_LSTATUS_SHIFT) /* J-state Not Low-speed device, perform EHCI reset */
+#define EHCI_PORTSC_PP (1 << 12) /* Bit 12: Port Power */
+#define EHCI_PORTSC_OWNER (1 << 13) /* Bit 13: Port Owner */
+#define EHCI_PORTSC_PIC_SHIFT (14) /* Bits 14-15: Port Indicator Control */
+#define EHCI_PORTSC_PIC_MASK (3 << EHCI_PORTSC_PIC_SHIFT)
+#define EHCI_PORTSC_PIC_OFF (0 << EHCI_PORTSC_PIC_SHIFT) /* Port indicators are off */
+#define EHCI_PORTSC_PIC_AMBER (1 << EHCI_PORTSC_PIC_SHIFT) /* Amber */
+#define EHCI_PORTSC_PIC_GREEN (2 << EHCI_PORTSC_PIC_SHIFT) /* Green */
+#define EHCI_PORTSC_PTC_SHIFT (16) /* Bits 16-19: Port Test Control */
+#define EHCI_PORTSC_PTC_MASK (15 << EHCI_PORTSC_PTC_SHIFT)
+#define EHCI_PORTSC_PTC_DISABLED (0 << EHCI_PORTSC_PTC_SHIFT) /* Test mode not enabled */
+#define EHCI_PORTSC_PTC_JSTATE (1 << EHCI_PORTSC_PTC_SHIFT) /* Test J_STATE */
+#define EHCI_PORTSC_PTC_KSTATE (2 << EHCI_PORTSC_PTC_SHIFT) /* Test K_STATE */
+#define EHCI_PORTSC_PTC_SE0NAK (3 << EHCI_PORTSC_PTC_SHIFT) /* Test SE0_NAK */
+#define EHCI_PORTSC_PTC_PACKET (4 << EHCI_PORTSC_PTC_SHIFT) /* Test Packet */
+#define EHCI_PORTSC_PTC_ENABLE (5 << EHCI_PORTSC_PTC_SHIFT) /* Test FORCE_ENABLE */
+#define EHCI_PORTSC_WKCCNTE (1 << 20) /* Bit 20: Wake on Connect Enable */
+#define EHCI_PORTSC_WKDSCNNTE (1 << 21) /* Bit 21: Wake on Disconnect Enable */
+#define EHCI_PORTSC_WKOCE (1 << 22) /* Bit 22: Wake on Over-current Enable */
+ /* Bits 23-31: Reserved */
+
+#define EHCI_PORTSC_ALLINTS (EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | \
+ EHCI_PORTSC_OCC | EHCI_PORTSC_RESUME)
+
+/* Queue Head. Paragraph 3.6 */
+
+/* Queue Head Horizontal Link Pointer: Queue Head DWord 0. Table 3-19 */
+
+#define QH_HLP_END 0x1
+
+#define QH_HLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) /* Isochronous Transfer Descriptor */
+#define QH_HLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) /* Queue Head */
+#define QH_HLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) /* Split Transaction Isochronous Transfer Descriptor */
+#define QH_HLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) /* Frame Span Traversal Node */
+
+/* Endpoint Characteristics: Queue Head DWord 1. Table 3-19 */
+
+#define QH_EPCHAR_DEVADDR_SHIFT (0) /* Bitx 0-6: Device Address */
+#define QH_EPCHAR_DEVADDR_MASK (0x7f << QH_EPCHAR_DEVADDR_SHIFT)
+#define QH_EPCHAR_I (1 << 7) /* Bit 7: Inactivate on Next Transaction */
+#define QH_EPCHAR_ENDPT_SHIFT (8) /* Bitx 8-11: Endpoint Number */
+#define QH_EPCHAR_ENDPT_MASK (15 << QH_EPCHAR_ENDPT_SHIFT)
+#define QH_EPCHAR_EPS_SHIFT (12) /* Bitx 12-13: Endpoint Speed */
+#define QH_EPCHAR_EPS_MASK (3 << QH_EPCHAR_EPS_SHIFT)
+#define QH_EPCHAR_EPS_FULL (0 << QH_EPCHAR_EPS_SHIFT) /* Full-Speed (12Mbs) */
+#define QH_EPCHAR_EPS_LOW (1 << QH_EPCHAR_EPS_SHIFT) /* Low-Speed (1.5Mbs) */
+#define QH_EPCHAR_EPS_HIGH (2 << QH_EPCHAR_EPS_SHIFT) /* High-Speed (480 Mb/s) */
+#define QH_EPCHAR_DTC (1 << 14) /* Bit 14: Data Toggle Control */
+#define QH_EPCHAR_H (1 << 15) /* Bit 15: Head of Reclamation List Flag */
+#define QH_EPCHAR_MAXPKT_SHIFT (16) /* Bitx 16-26: Maximum Packet Length */
+#define QH_EPCHAR_MAXPKT_MASK (0x7ff << QH_EPCHAR_MAXPKT_SHIFT)
+#define QH_EPCHAR_C (1 << 27) /* Bit 27: Control Endpoint Flag */
+#define QH_EPCHAR_RL_SHIFT (28) /* Bitx 28-31: Nak Count Reload */
+#define QH_EPCHAR_RL_MASK (15 << QH_EPCHAR_RL_SHIFT)
+
+/* Endpoint Capabilities: Queue Head DWord 2. Table 3-20 */
+
+#define QH_EPCAPS_SSMASK_SHIFT (0) /* Bitx 0-7: Interrupt Schedule Mask (Frame S-mask) */
+#define QH_EPCAPS_SSMASK_MASK (0xff << QH_EPCAPS_SSMASK_SHIFT)
+#define QH_EPCAPS_SSMASK(n) ((n) << QH_EPCAPS_SSMASK_SHIFT)
+#define QH_EPCAPS_SCMASK_SHIFT (8) /* Bitx 8-15: Split Completion Mask (Frame C-Mask) */
+#define QH_EPCAPS_SCMASK_MASK (0xff << QH_EPCAPS_SCMASK_SHIFT)
+#define QH_EPCAPS_SCMASK(n) ((n) << QH_EPCAPS_SCMASK_SHIFT)
+#define QH_EPCAPS_HUBADDR_SHIFT (16) /* Bitx 16-22: Hub Address */
+#define QH_EPCAPS_HUBADDR_MASK (0x7f << QH_EPCAPS_HUBADDR_SHIFT)
+#define QH_EPCAPS_HUBADDR(n) ((n) << QH_EPCAPS_HUBADDR_SHIFT)
+#define QH_EPCAPS_PORT_SHIFT (23) /* Bit 23-29: Port Number */
+#define QH_EPCAPS_PORT_MASK (0x7f << QH_EPCAPS_PORT_SHIFT)
+#define QH_EPCAPS_PORT(n) ((n) << QH_EPCAPS_PORT_SHIFT)
+#define QH_EPCAPS_MULT_SHIFT (30) /* Bit 30-31: High-Bandwidth Pipe Multiplier */
+#define QH_EPCAPS_MULT_MASK (3 << QH_EPCAPS_MULT_SHIFT)
+#define QH_EPCAPS_MULT(n) ((n) << QH_EPCAPS_MULT_SHIFT)
+
+/* qTD Token. Paragraph 3.5.3 */
+
+#define QTD_LIST_END 1
+
+#define QTD_TOKEN_STATUS_SHIFT (0) /* Bits 0-7: Status */
+#define QTD_TOKEN_STATUS_MASK (0xff << QTD_TOKEN_STATUS_SHIFT)
+#define QTD_TOKEN_STATUS_PINGSTATE (1 << 0) /* Bit 0 Ping State */
+#define QTD_TOKEN_STATUS_ERR (1 << 0) /* Bit 0 Error */
+#define QTD_TOKEN_STATUS_SPLITXSTATE (1 << 1) /* Bit 1 Split Transaction State */
+#define QTD_TOKEN_STATUS_MMF (1 << 2) /* Bit 2 Missed Micro-Frame */
+#define QTD_TOKEN_STATUS_XACTERR (1 << 3) /* Bit 3 Transaction Error */
+#define QTD_TOKEN_STATUS_BABBLE (1 << 4) /* Bit 4 Babble Detected */
+#define QTD_TOKEN_STATUS_DBERR (1 << 5) /* Bit 5 Data Buffer Error */
+#define QTD_TOKEN_STATUS_HALTED (1 << 6) /* Bit 6 Halted */
+#define QTD_TOKEN_STATUS_ACTIVE (1 << 7) /* Bit 7 Active */
+#define QTD_TOKEN_STATUS_ERRORS (0x78 << QTD_TOKEN_STATUS_SHIFT)
+#define QTD_TOKEN_PID_SHIFT (8) /* Bits 8-9: PID Code */
+#define QTD_TOKEN_PID_MASK (3 << QTD_TOKEN_PID_SHIFT)
+#define QTD_TOKEN_PID_OUT (0 << QTD_TOKEN_PID_SHIFT) /* OUT Token generates token (E1H) */
+#define QTD_TOKEN_PID_IN (1 << QTD_TOKEN_PID_SHIFT) /* IN Token generates token (69H) */
+#define QTD_TOKEN_PID_SETUP (2 << QTD_TOKEN_PID_SHIFT) /* SETUP Token generates token (2DH) */
+#define QTD_TOKEN_CERR_SHIFT (10) /* Bits 10-11: Error Counter */
+#define QTD_TOKEN_CERR_MASK (3 << QTD_TOKEN_CERR_SHIFT)
+#define QTD_TOKEN_CPAGE_SHIFT (12) /* Bits 12-14: Current Page */
+#define QTD_TOKEN_CPAGE_MASK (7 << QTD_TOKEN_CPAGE_SHIFT)
+#define QTD_TOKEN_IOC (1 << 15) /* Bit 15: Interrupt On Complete */
+#define QTD_TOKEN_NBYTES_SHIFT (16) /* Bits 16-30: Total Bytes to Transfer */
+#define QTD_TOKEN_NBYTES_MASK (0x7fff << QTD_TOKEN_NBYTES_SHIFT)
+#define QTD_TOKEN_TOGGLE (1 << 31) /* Bit 31: Data Toggle */
+
+/* Isochronous (High-Speed) Transfer Descriptor (iTD). Paragraph 3.3 */
+
+/* iTD Next Link Pointer. Paragraph 3.3.1 */
+
+#define ITD_NLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0)
+#define ITD_NLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2)
+#define ITD_NLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4)
+#define ITD_NLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6)
+
+/* iTD Transaction Status and Control List. Paragraph 3.3.2 */
+#define ITD_TSCL_XOFFS_SHIFT (0) /* Bits 0-11: Transaction X offset */
+#define ITD_TSCL_XOFFS_MASK (0xfff << ITD_TSCL_XOFFS_SHIFT)
+#define ITD_TSCL_PG_SHIFT (12) /* Bits 12-14: Page select */
+#define ITD_TSCL_PG_MASK (7 << ITD_TSCL_PG_SHIFT)
+#define ITD_TSCL_IOC (1 << 15) /* Bit 15: Interrupt On Comp */
+#define ITD_TSCL_LENGTH_SHIFT (16) /* Bits 16-27: Transaction length */
+#define ITD_TSCL_LENGTH_MASK (0xfff << ITD_TSCL_LENGTH_SHIFT)
+#define ITD_TSCL_STATUS_SHIFT (28) /* Bits 28-31: Transaction status */
+#define ITD_TSCL_STATUS_MASK (15 << ITD_TSCL_STATUS_SHIFT)
+#define ITD_TSCL_STATUS_XACTERR (1 << 28) /* Bit 28: Transaction error */
+#define ITD_TSCL_STATUS_BABBLE (1 << 29) /* Bit 29: Babble Detected */
+#define ITD_TSCL_STATUS_DBERROR (1 << 30) /* Bit 30: Data Buffer Error */
+#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 31: Active error */
+
+/* iTD Buffer Page Pointer List. Paragraph 3.3.4 */
+
+/* iTD Buffer Pointer Page 0. Table 3-4 */
+
+#define ITD_BUFPTR0_DEVADDR_SHIFT (0) /* Bits 0-6: Device Address */
+#define ITD_BUFPTR0_DEVADDR_MASK (0x7f << ITD_BUFPTR0_DEVADDR_SHIFT)
+#define ITD_BUFPTR0_ENDPT_SHIFT (8) /* Bits 8-11: Endpoint Number */
+#define ITD_BUFPTR0_ENDPT_MASK (15 << ITD_BUFPTR0_ENDPT_SHIFT)
+
+/* iTD Buffer Pointer Page 1. Table 3-5 */
+
+#define ITD_BUFPTR1_MAXPKT_SHIFT (0) /* Bits 0-10: Maximum Packet Size */
+#define ITD_BUFPTR1_MAXPKT_MASK (0x7ff << ITD_BUFPTR1_MAXPKT_SHIFT)
+#define ITD_BUFPTR1_DIRIN (1 << 11) /* Bit 11: Direction 1=IN */
+#define ITD_BUFPTR1_DIROUT (0) /* Bit 11: Direction 0=OUT */
+
+/* iTD Buffer Pointer Page 2. Table 3-6 */
+
+#define ITD_BUFPTR2_MULTI_SHIFT (0) /* Bits 0-1: Multi */
+#define ITD_BUFPTR2_MULTI_MASK (3 << ITD_BUFPTR2_MULTI_SHIFT)
+#define ITD_BUFPTR2_MULTI_1 (1 << ITD_BUFPTR2_MULTI_SHIFT) /* One transaction per micro-frame */
+#define ITD_BUFPTR2_MULTI_2 (2 << ITD_BUFPTR2_MULTI_SHIFT) /* Two transactions per micro-frame */
+#define ITD_BUFPTR2_MULTI_3 (3 << ITD_BUFPTR2_MULTI_SHIFT) /* Three transactions per micro-frame */
+
+/* Registers ****************************************************************/
+
+/* Host Controller Capability Registers.
+ * This register block must be positioned at a well known address.
+ */
+
+struct ehci_hccr {
+ volatile uint8_t caplength; /* 0x00: Capability Register Length */
+ volatile uint8_t reserved; /* 0x01: reserved */
+ volatile uint16_t hciversion; /* 0x02: Interface Version Number */
+ volatile uint32_t hcsparams; /* 0x04: Structural Parameters */
+ volatile uint32_t hccparams; /* 0x08: Capability Parameters */
+ volatile uint8_t hcspportroute[8]; /* 0x0c: Companion Port Route Description */
+};
+
+/* Host Controller Operational Registers.
+ * This register block is positioned at an offset of 'caplength' from the
+ * beginning of the Host Controller Capability Registers.
+ */
+
+struct ehci_hcor {
+ volatile uint32_t usbcmd; /* 0x00: USB Command */
+ volatile uint32_t usbsts; /* 0x04: USB Status */
+ volatile uint32_t usbintr; /* 0x08: USB Interrupt Enable */
+ volatile uint32_t frindex; /* 0x0c: USB Frame Index */
+ volatile uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */
+ volatile uint32_t periodiclistbase; /* 0x14: Frame List Base Address */
+ volatile uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */
+#ifndef CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
+ uint32_t reserved[9];
+#endif
+ volatile uint32_t configflag; /* 0x40: Configured Flag Register */
+ volatile uint32_t portsc[15]; /* 0x44: Port Status/Control */
+};
+
+/* USB2 Debug Port Register Interface.
+ * This register block is normally found via the PCI capabalities.
+ * In non-PCI implementions, you need apriori information about the
+ * location of these registers.
+ */
+
+struct ehci_debug {
+ uint32_t psc; /* 0x00: Debug Port Control/Status Register */
+ uint32_t pids; /* 0x04: Debug USB PIDs Register */
+ uint32_t data[2]; /* 0x08: Debug Data buffer Registers */
+ uint32_t addr; /* 0x10: Device Address Register */
+};
+
+/* Data Structures **********************************************************/
+
+/* Queue Element Transfer Descriptor (qTD). Paragraph 3.5 */
+
+struct ehci_qtd {
+ uint32_t next_qtd; /* 0x00-0x03: Next qTD Pointer */
+ uint32_t alt_next_qtd; /* 0x04-0x07: Alternate Next qTD Pointer */
+ uint32_t token; /* 0x08-0x0b: qTD Token */
+ uint32_t bpl[5]; /* 0x0c-0x1c: Buffer Page Pointer List */
+};
+
+#define SIZEOF_EHCI_QTD (32) /* 8*sizeof(uint32_t) */
+
+/* Queue Head. Paragraph 3.6 */
+
+struct ehci_qh {
+ uint32_t hlp; /* 0x00-0x03: Queue Head Horizontal Link Pointer */
+ uint32_t epchar; /* 0x04-0x07: Endpoint Characteristics */
+ uint32_t epcap; /* 0x08-0x0b: Endpoint Capabilities */
+ uint32_t curr_qtd; /* 0x0c-0x0f: Current qTD Pointer */
+ struct ehci_qtd overlay; /* 0x10-0x2c: Transfer overlay */
+};
+
+#define SIZEOF_EHCI_QH (48) /* 4*sizeof(uint32_t) + 32 */
+
+/* Isochronous (High-Speed) Transfer Descriptor (iTD).
+ * Paragraph 3.3. Must be aligned to 32-byte boundaries.
+ */
+
+struct ehci_itd {
+ uint32_t nlp; /* 0x00-0x03: Next link pointer */
+ uint32_t tscl[8]; /* 0x04-0x23: Transaction Status and Control List */
+ uint32_t bpl[7]; /* 0x24-0x3c: Buffer Page Pointer List */
+};
+
+#define SIZEOF_EHCI_ITD (64) /* 16*sizeof(uint32_t) */
+
+/* Split Transaction Isochronous Transfer Descriptor (siTD). Paragraph 3.4 */
+
+struct ehci_sitd {
+ uint32_t nlp; /* 0x00-0x03: Next link pointer */
+ uint32_t epchar; /* 0x04-0x07: Endpoint and Transaction Translator Characteristics */
+ uint32_t mfsc; /* 0x08-0x0b: Micro-frame Schedule Control */
+ uint32_t tsc; /* 0x0c-0x0f: Transfer Status and Control */
+ uint32_t bpl[2]; /* 0x10-0x17: Buffer Pointer List */
+ uint32_t blp; /* 0x18-0x1b: Back link pointer */
+};
+
+#define SIZEOF_EHCI_SITD (28) /* 7*sizeof(uint32_t) */
+
+#endif /* __INCLUDE_NUTTX_USB_EHCI_H */
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c b/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c
index 5445b535ae..9fc87c39b7 100644
--- a/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c
@@ -8,7 +8,7 @@
#include
#include
#include "usbh_core.h"
-#include "usb_ehci_priv.h"
+#include "usb_hc_ehci.h"
extern void USBH_IRQHandler(uint8_t busid);
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c b/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c
index f616f2cf0b..1772400849 100644
--- a/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c
@@ -82,6 +82,8 @@ uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
return 0;
}
+#if !defined(USBH_USE_CUSTOM_ISR) || !USBH_USE_CUSTOM_ISR
+
extern void USBH_IRQHandler(uint8_t busid);
void isr_usbh0(void)
@@ -97,3 +99,5 @@ void isr_usbh1(void)
}
SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1)
#endif
+
+#endif
diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_glue_mcx.c b/components/drivers/usb/cherryusb/port/ehci/usb_glue_mcx.c
new file mode 100644
index 0000000000..7f8f4bf554
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_glue_mcx.c
@@ -0,0 +1,151 @@
+#include "usbh_core.h"
+#include "fsl_common.h"
+#include "usb_chipidea_reg.h"
+
+#define USB_DEVICE_CONFIG_EHCI 1
+
+/*! @brief USB controller ID */
+typedef enum _usb_controller_index
+{
+ kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
+ kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
+ to be used in the future. */
+ kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
+ kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U */
+} usb_controller_index_t;
+
+/* USB PHY condfiguration */
+#define BOARD_USB_PHY_D_CAL (0x04U)
+#define BOARD_USB_PHY_TXCAL45DP (0x07U)
+#define BOARD_USB_PHY_TXCAL45DM (0x07U)
+#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */
+
+#if !defined(CONFIG_USB_EHCI_NXP)
+#error "mcx ehci must config CONFIG_USB_EHCI_NXP"
+#endif
+
+#if !defined(CONFIG_USB_EHCI_HCCR_OFFSET) || CONFIG_USB_EHCI_HCCR_OFFSET != 0x100
+#error "mcx ehci must config CONFIG_USB_EHCI_HCCR_OFFSET to 0x100"
+#endif
+
+#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
+#include "usb_phy.h"
+#endif
+
+#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U))
+void USB1_HS_IRQHandler(void)
+{
+ extern void USBH_IRQHandler(uint8_t busid);
+ USBH_IRQHandler(0);
+}
+#endif
+
+void USB_ClockInit(void)
+{
+#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
+ usb_phy_config_struct_t phyConfig = {
+ BOARD_USB_PHY_D_CAL,
+ BOARD_USB_PHY_TXCAL45DP,
+ BOARD_USB_PHY_TXCAL45DM,
+ };
+#endif
+#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
+ SPC0->ACTIVE_VDELAY = 0x0500;
+ /* Change the power DCDC to 1.8v (By deafult, DCDC is 1.8V), CORELDO to 1.1v (By deafult, CORELDO is 1.0V) */
+ SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK;
+ SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) |
+ SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u);
+ /* Wait until it is done */
+ while (SPC0->SC & SPC_SC_BUSY_MASK)
+ ;
+ if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) {
+ SCG0->TRIM_LOCK = 0x5a5a0001U;
+ SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK;
+ /* wait LDO ready */
+ while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK))
+ ;
+ }
+ SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK;
+ SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK);
+ /* xtal = 20 ~ 30MHz */
+ SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT);
+ SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK;
+ while (1) {
+ if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) {
+ break;
+ }
+ }
+ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK;
+ CLOCK_EnableClock(kCLOCK_UsbHs);
+ CLOCK_EnableClock(kCLOCK_UsbHsPhy);
+ CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U);
+ CLOCK_EnableUsbhsClock();
+ USB_EhciPhyInit(kUSB_ControllerEhci0, BOARD_XTAL0_CLK_HZ, &phyConfig);
+#endif
+#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
+ CLOCK_AttachClk(kCLK_48M_to_USB0);
+ CLOCK_EnableClock(kCLOCK_Usb0Ram);
+ CLOCK_EnableClock(kCLOCK_Usb0Fs);
+ CLOCK_EnableUsbfsClock();
+#endif
+}
+
+static void usb_host_mode_init(CHIPIDEA_TypeDef *ptr)
+{
+ /* Set mode to host, must be set immediately after reset */
+ ptr->USBMODE &= ~USB_USBMODE_CM_MASK;
+ ptr->USBMODE |= USB_USBMODE_CM_SET(3);
+
+ /* Set the endian */
+ ptr->USBMODE &= ~USB_USBMODE_ES_MASK;
+
+ /* Set parallel interface signal */
+ ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
+
+ /* Set parallel transceiver width */
+ ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
+
+ /* Not use interrupt threshold. */
+ ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
+}
+
+void usb_hc_low_level_init(struct usbh_bus *bus)
+{
+ USB_ClockInit();
+ /* Install isr, set priority, and enable IRQ. */
+ NVIC_SetPriority((IRQn_Type)USB1_HS_IRQn, 3);
+ EnableIRQ((IRQn_Type)USB1_HS_IRQn);
+}
+
+void usb_hc_low_level2_init(struct usbh_bus *bus)
+{
+ usb_host_mode_init((CHIPIDEA_TypeDef *)(bus->hcd.reg_base));
+}
+
+void usb_hc_low_level_deinit(struct usbh_bus *bus)
+{
+ DisableIRQ((IRQn_Type)USB1_HS_IRQn);
+}
+
+uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
+{
+ (void)port;
+ uint8_t speed;
+
+ CHIPIDEA_TypeDef *ptr = (CHIPIDEA_TypeDef *)bus->hcd.reg_base;
+
+ speed = USB_PORTSC1_PSPD_GET(ptr->PORTSC1);
+
+ if (speed == 0x00) {
+ return USB_SPEED_FULL;
+ }
+ if (speed == 0x01) {
+ return USB_SPEED_LOW;
+ }
+ if (speed == 0x02) {
+ USB_EhcihostPhyDisconnectDetectCmd(kUSB_ControllerEhci0, 1);
+ return USB_SPEED_HIGH;
+ }
+
+ return 0;
+}
\ No newline at end of file
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 d8370120a4..8b9caba419 100644
--- a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c
@@ -3,9 +3,9 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
-#include "usb_ehci_priv.h"
+#include "usb_hc_ehci.h"
#ifdef CONFIG_USB_EHCI_WITH_OHCI
-#include "usb_ohci_priv.h"
+#include "usb_hc_ohci.h"
#endif
#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
@@ -167,6 +167,7 @@ static void ehci_qh_fill(struct ehci_qh_hw *qh,
switch (speed) {
case USB_SPEED_LOW:
epchar |= QH_EPCHAR_EPS_LOW;
+ __attribute__((fallthrough));
case USB_SPEED_FULL:
if (ep_type == USB_ENDPOINT_TYPE_CONTROL) {
epchar |= QH_EPCHAR_C; /* for TT */
@@ -379,7 +380,7 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_bus *bus, struct usbh_u
urb->hport->parent->hub_addr,
urb->hport->port);
- while (buflen >= 0) {
+ while (1) {
qtd = &qh->qtd_pool[qtd_num];
if (buflen > 0x4000) {
@@ -480,7 +481,7 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_bus *bus, struct usbh_u
urb->hport->parent->hub_addr,
urb->hport->port);
- while (buflen >= 0) {
+ while (1) {
qtd = &qh->qtd_pool[qtd_num];
if (buflen > 0x4000) {
@@ -583,6 +584,8 @@ static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, st
{
struct ehci_qtd_hw *qtd;
+ (void)bus;
+
ehci_qh_remove(qhead, qh);
qtd = EHCI_ADDR2QTD(qh->first_qtd);
@@ -655,6 +658,8 @@ static void ehci_kill_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct
{
struct ehci_qtd_hw *qtd;
+ (void)bus;
+
ehci_qh_remove(qhead, qh);
qtd = EHCI_ADDR2QTD(qh->first_qtd);
@@ -697,14 +702,17 @@ static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
{
+ (void)bus;
}
__WEAK void usb_hc_low_level2_init(struct usbh_bus *bus)
{
+ (void)bus;
}
__WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus)
{
+ (void)bus;
}
int usb_hc_init(struct usbh_bus *bus)
@@ -777,6 +785,8 @@ int usb_hc_init(struct usbh_bus *bus)
g_ehci_hcd[bus->hcd.hcd_id].n_cc,
g_ehci_hcd[bus->hcd.hcd_id].n_pcc);
+ EHCI_HCOR->usbcmd &= ~EHCI_USBCMD_RUN;
+ usb_osal_msleep(2);
EHCI_HCOR->usbcmd |= EHCI_USBCMD_HCRESET;
while (EHCI_HCOR->usbcmd & EHCI_USBCMD_HCRESET) {
usb_osal_msleep(1);
@@ -830,6 +840,7 @@ int usb_hc_init(struct usbh_bus *bus)
for (uint8_t port = 0; port < g_ehci_hcd[bus->hcd.hcd_id].n_ports; port++) {
regval = EHCI_HCOR->portsc[port];
regval |= EHCI_PORTSC_PP;
+ regval &= ~(EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | EHCI_PORTSC_OCC);
EHCI_HCOR->portsc[port] = regval;
}
}
@@ -872,7 +883,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
regval &= ~EHCI_USBCMD_RUN;
EHCI_HCOR->usbcmd = regval;
- while ((EHCI_HCOR->usbsts & (EHCI_USBSTS_PSS | EHCI_USBSTS_ASS))) {
+ while ((EHCI_HCOR->usbsts & (EHCI_USBSTS_PSS | EHCI_USBSTS_ASS)) || ((EHCI_HCOR->usbsts & EHCI_USBSTS_HALTED) == 0)) {
usb_osal_msleep(1);
timeout++;
if (timeout > 100) {
@@ -893,6 +904,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
#endif
EHCI_HCOR->usbsts = EHCI_HCOR->usbsts;
+ EHCI_HCOR->usbcmd |= EHCI_USBCMD_HCRESET;
for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
qh = &ehci_qh_pool[bus->hcd.hcd_id][index];
@@ -1098,7 +1110,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u
if (temp & EHCI_PORTSC_RESET) {
status |= (1 << HUB_PORT_FEATURE_RESET);
}
- if (temp & EHCI_PORTSC_PP) {
+ if (temp & EHCI_PORTSC_PP || !(EHCI_HCCR->hcsparams & EHCI_HCSPARAMS_PPC)) {
status |= (1 << HUB_PORT_FEATURE_POWER);
}
memcpy(buf, &status, 4);
@@ -1341,6 +1353,11 @@ void USBH_IRQHandler(uint8_t busid)
if (portsc & EHCI_PORTSC_CSC) {
if ((portsc & EHCI_PORTSC_CCS) == EHCI_PORTSC_CCS) {
} else {
+#if defined(CONFIG_USB_EHCI_NXP)
+ /* kUSB_ControllerEhci0 and kUSB_ControllerEhci1*/
+ extern void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable);
+ USB_EhcihostPhyDisconnectDetectCmd(2 + busid, 0);
+#endif
for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
g_ehci_hcd[bus->hcd.hcd_id].ehci_qh_used[index] = false;
}
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 7f3febc23f..714128bc46 100644
--- a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h
+++ b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h
@@ -1,375 +1,84 @@
/*
- * Copyright 2020 The Apache Software Foundation
- * Copyright 2022 sakumisu
- *
+ * Copyright (c) 2022, sakumisu
+ *
* SPDX-License-Identifier: Apache-2.0
*/
-#ifndef USB_HC_EHCI_H
-#define USB_HC_EHCI_H
+#ifndef _USB_EHCI_PRIV_H
+#define _USB_EHCI_PRIV_H
-#define EHCI_FULL_SPEED (0) /* Full-Speed (12Mbs) */
-#define EHCI_LOW_SPEED (1) /* Low-Speed (1.5Mbs) */
-#define EHCI_HIGH_SPEED (2) /* High-Speed (480 Mb/s) */
+#include "usbh_core.h"
+#include "usbh_hub.h"
+#include "usb_ehci_reg.h"
-/* Host Controller Capability Register Bit Definitions **********************/
+#define EHCI_HCCR ((struct ehci_hccr *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET))
+#define EHCI_HCOR ((struct ehci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET + g_ehci_hcd[bus->hcd.hcd_id].hcor_offset))
-/* Structural Parameters. Paragraph 2.2.3 */
+#define EHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x1F)
+#define EHCI_ADDR2QH(x) ((struct ehci_qh_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
+#define EHCI_ADDR2QTD(x) ((struct ehci_qtd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
+#define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
-#define EHCI_HCSPARAMS_NPORTS_SHIFT (0) /* Bit 0-3: Number of physical downstream ports */
-#define EHCI_HCSPARAMS_NPORTS_MASK (15 << EHCI_HCSPARAMS_NPORTS_SHIFT)
-#define EHCI_HCSPARAMS_PPC (1 << 4) /* Bit 4: Port Power Control */
-#define EHCI_HCSPARAMS_PRR (1 << 7) /* Bit 7: Port Routing Rules */
-#define EHCI_HCSPARAMS_NPCC_SHIFT (8) /* Bit 8-11: Number of Ports per Companion Controller */
-#define EHCI_HCSPARAMS_NPCC_MASK (15 << EHCI_HCSPARAMS_NPCC_SHIFT)
-#define EHCI_HCSPARAMS_NCC_SHIFT (12) /* Bit 12-15: Number of Companion Controllers */
-#define EHCI_HCSPARAMS_NCC_MASK (15 << EHCI_HCSPARAMS_NCC_SHIFT)
-#define EHCI_HCSPARAMS_PIND (1 << 16) /* Bit 16: Port Indicators */
-#define EHCI_HCSPARAMS_DBGPORT_SHIFT (20) /* Bit 20-23: Debug Port Number */
-#define EHCI_HCSPARAMS_DBGPORT_MASK (15 << EHCI_HCSPARAMS_DBGPORT_SHIFT)
-
-/* Capability Parameters. Paragraph 2.2.4 */
-
-#define EHCI_HCCPARAMS_64BIT (1 << 0) /* Bit 0: 64-bit Addressing Capability */
-#define EHCI_HCCPARAMS_PFLF (1 << 1) /* Bit 1: Programmable Frame List Flag */
-#define EHCI_HCCPARAMS_ASPC (1 << 2) /* Bit 2: Asynchronous Schedule Park Capability */
-#define EHCI_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */
-#define EHCI_HCCPARAMS_IST_MASK (15 << EHCI_HCCPARAMS_IST_SHIFT)
-#define EHCI_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */
-#define EHCI_HCCPARAMS_EECP_MASK (0xff << EHCI_HCCPARAMS_EECP_SHIFT)
-
-/* Host Controller Operational Register Bit Definitions *********************/
-
-/* USB Command. Paragraph 2.3.1 */
-
-#define EHCI_USBCMD_RUN (1 << 0) /* Bit 0: Run/Stop */
-#define EHCI_USBCMD_HCRESET (1 << 1) /* Bit 1: Host Controller Reset */
-#define EHCI_USBCMD_FLSIZE_SHIFT (2) /* Bits 2-3: Frame List Size */
-#define EHCI_USBCMD_FLSIZE_MASK (3 << EHCI_USBCMD_FLSIZE_SHIFT)
-#define EHCI_USBCMD_FLSIZE_1024 (0 << EHCI_USBCMD_FLSIZE_SHIFT) /* 1024 elements (4096 bytes) */
-#define EHCI_USBCMD_FLSIZE_512 (1 << EHCI_USBCMD_FLSIZE_SHIFT) /* 512 elements (2048 bytes) */
-#define EHCI_USBCMD_FLSIZE_256 (2 << EHCI_USBCMD_FLSIZE_SHIFT) /* 256 elements (1024 bytes) */
-#define EHCI_USBCMD_PSEN (1 << 4) /* Bit 4: Periodic Schedule Enable */
-#define EHCI_USBCMD_ASEN (1 << 5) /* Bit 5: Asynchronous Schedule Enable */
-#define EHCI_USBCMD_IAAD (1 << 6) /* Bit 6: Interrupt on Async Advance Doorbell */
-#define EHCI_USBCMD_LRESET (1 << 7) /* Bit 7: Light Host Controller Reset */
-#define EHCI_USBCMD_ASYNC_PARKCNT_SHIFT (8) /* Bits 8-9: Asynchronous Schedule Park Mode Count */
-#define EHCI_USBCMD_ASYNC_PARKCNT_MASK (3 << EHCI_USBCMD_ASYNC_PARKCNT_SHIFT)
-#define EHCI_USBCMD_ASYNC_PARK (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */
-#define EHCI_USBCMD_ITHRE_SHIFT (16) /* Bits 16-23: Interrupt Threshold Control */
-#define EHCI_USBCMD_ITHRE_MASK (0xff << EHCI_USBCMD_ITHRE_SHIFT)
-#define EHCI_USBCMD_ITHRE_1MF (0x01 << EHCI_USBCMD_ITHRE_SHIFT) /* 1 micro-frame */
-#define EHCI_USBCMD_ITHRE_2MF (0x02 << EHCI_USBCMD_ITHRE_SHIFT) /* 2 micro-frames */
-#define EHCI_USBCMD_ITHRE_4MF (0x04 << EHCI_USBCMD_ITHRE_SHIFT) /* 4 micro-frames */
-#define EHCI_USBCMD_ITHRE_8MF (0x08 << EHCI_USBCMD_ITHRE_SHIFT) /* 8 micro-frames (default, 1 ms) */
-#define EHCI_USBCMD_ITHRE_16MF (0x10 << EHCI_USBCMD_ITHRE_SHIFT) /* 16 micro-frames (2 ms) */
-#define EHCI_USBCMD_ITHRE_32MF (0x20 << EHCI_USBCMD_ITHRE_SHIFT) /* 32 micro-frames (4 ms) */
-#define EHCI_USBCMD_ITHRE_64MF (0x40 << EHCI_USBCMD_ITHRE_SHIFT) /* 64 micro-frames (8 ms) */
-
-/* USB Status. Paragraph 2.3.2 */
-
-#define EHCI_USBSTS_INT (1 << 0) /* Bit 0: USB Interrupt */
-#define EHCI_USBSTS_ERR (1 << 1) /* Bit 1: USB Error Interrupt */
-#define EHCI_USBSTS_PCD (1 << 2) /* Bit 2: Port Change Detect */
-#define EHCI_USBSTS_FLR (1 << 3) /* Bit 3: Frame List Rollover */
-#define EHCI_USBSTS_FATAL (1 << 4) /* Bit 4: Host System Error */
-#define EHCI_USBSTS_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */
-#define EHCI_USBSTS_HALTED (1 << 12) /* Bit 12: HC Halted */
-#define EHCI_USBSTS_RECLAM (1 << 13) /* Bit 13: Reclamation */
-#define EHCI_USBSTS_PSS (1 << 14) /* Bit 14: Periodic Schedule Status */
-#define EHCI_USBSTS_ASS (1 << 15) /* Bit 15: Asynchronous Schedule Status */
- /* Bits 16-31: Reserved */
-
-/* USB Interrupt Enable. Paragraph 2.3.3 */
-
-#define EHCI_USBIE_INT (1 << 0) /* Bit 0: USB Interrupt */
-#define EHCI_USBIE_ERR (1 << 1) /* Bit 1: USB Error Interrupt */
-#define EHCI_USBIE_PCD (1 << 2) /* Bit 2: Port Change Detect */
-#define EHCI_USBIE_FLROLL (1 << 3) /* Bit 3: Frame List Rollover */
-#define EHCI_USBIE_FATAL (1 << 4) /* Bit 4: Host System Error */
-#define EHCI_USBIE_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */
-#define EHCI_USBIE_ALLINTS (0x3f) /* Bits 0-5: All interrupts */
-
-/* USB Frame Index. Paragraph 2.3.4 */
-
-#define EHCI_FRINDEX_MASK (0x3fff) /* Bits 0-13: Frame index */
-
-/* 4G Segment Selector.
- * Paragraph 2.3.5, Bits[64:32] of data structure addresses
- */
-
-/* Frame List Base Address. Paragraph 2.3.6 */
-#define EHCI_PERIODICLISTBASE_MASK (0xfffff000) /* Bits 12-31: Base Address (Low) */
-
-/* Next Asynchronous List Address. Paragraph 2.3.7 */
-
-#define EHCI_ASYNCLISTADDR_MASK (0xffffffe0) /* Bits 5-31: Link Pointer Low (LPL) */
-
-/* Configured Flag Register. Paragraph 2.3.8 */
-
-#define EHCI_CONFIGFLAG (1 << 0) /* Bit 0: Configure Flag */
-
-/* Port Status/Control, Port 1-n. Paragraph 2.3.9 */
-
-#define EHCI_PORTSC_CCS (1 << 0) /* Bit 0: Current Connect Status */
-#define EHCI_PORTSC_CSC (1 << 1) /* Bit 1: Connect Status Change */
-#define EHCI_PORTSC_PE (1 << 2) /* Bit 2: Port Enable */
-#define EHCI_PORTSC_PEC (1 << 3) /* Bit 3: Port Enable/Disable Change */
-#define EHCI_PORTSC_OCA (1 << 4) /* Bit 4: Over-current Active */
-#define EHCI_PORTSC_OCC (1 << 5) /* Bit 5: Over-current Change */
-#define EHCI_PORTSC_RESUME (1 << 6) /* Bit 6: Force Port Resume */
-#define EHCI_PORTSC_SUSPEND (1 << 7) /* Bit 7: Suspend */
-#define EHCI_PORTSC_RESET (1 << 8) /* Bit 8: Port Reset */
-#define EHCI_PORTSC_LSTATUS_SHIFT (10) /* Bits 10-11: Line Status */
-#define EHCI_PORTSC_LSTATUS_MASK (3 << EHCI_PORTSC_LSTATUS_SHIFT)
-#define EHCI_PORTSC_LSTATUS_SE0 (0 << EHCI_PORTSC_LSTATUS_SHIFT) /* SE0 Not Low-speed device, perform EHCI reset */
-#define EHCI_PORTSC_LSTATUS_KSTATE (1 << EHCI_PORTSC_LSTATUS_SHIFT) /* K-state Low-speed device, release ownership of port */
-#define EHCI_PORTSC_LSTATUS_JSTATE (2 << EHCI_PORTSC_LSTATUS_SHIFT) /* J-state Not Low-speed device, perform EHCI reset */
-#define EHCI_PORTSC_PP (1 << 12) /* Bit 12: Port Power */
-#define EHCI_PORTSC_OWNER (1 << 13) /* Bit 13: Port Owner */
-#define EHCI_PORTSC_PIC_SHIFT (14) /* Bits 14-15: Port Indicator Control */
-#define EHCI_PORTSC_PIC_MASK (3 << EHCI_PORTSC_PIC_SHIFT)
-#define EHCI_PORTSC_PIC_OFF (0 << EHCI_PORTSC_PIC_SHIFT) /* Port indicators are off */
-#define EHCI_PORTSC_PIC_AMBER (1 << EHCI_PORTSC_PIC_SHIFT) /* Amber */
-#define EHCI_PORTSC_PIC_GREEN (2 << EHCI_PORTSC_PIC_SHIFT) /* Green */
-#define EHCI_PORTSC_PTC_SHIFT (16) /* Bits 16-19: Port Test Control */
-#define EHCI_PORTSC_PTC_MASK (15 << EHCI_PORTSC_PTC_SHIFT)
-#define EHCI_PORTSC_PTC_DISABLED (0 << EHCI_PORTSC_PTC_SHIFT) /* Test mode not enabled */
-#define EHCI_PORTSC_PTC_JSTATE (1 << EHCI_PORTSC_PTC_SHIFT) /* Test J_STATE */
-#define EHCI_PORTSC_PTC_KSTATE (2 << EHCI_PORTSC_PTC_SHIFT) /* Test K_STATE */
-#define EHCI_PORTSC_PTC_SE0NAK (3 << EHCI_PORTSC_PTC_SHIFT) /* Test SE0_NAK */
-#define EHCI_PORTSC_PTC_PACKET (4 << EHCI_PORTSC_PTC_SHIFT) /* Test Packet */
-#define EHCI_PORTSC_PTC_ENABLE (5 << EHCI_PORTSC_PTC_SHIFT) /* Test FORCE_ENABLE */
-#define EHCI_PORTSC_WKCCNTE (1 << 20) /* Bit 20: Wake on Connect Enable */
-#define EHCI_PORTSC_WKDSCNNTE (1 << 21) /* Bit 21: Wake on Disconnect Enable */
-#define EHCI_PORTSC_WKOCE (1 << 22) /* Bit 22: Wake on Over-current Enable */
- /* Bits 23-31: Reserved */
-
-#define EHCI_PORTSC_ALLINTS (EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | \
- EHCI_PORTSC_OCC | EHCI_PORTSC_RESUME)
-
-/* Queue Head. Paragraph 3.6 */
-
-/* Queue Head Horizontal Link Pointer: Queue Head DWord 0. Table 3-19 */
-
-#define QH_HLP_END 0x1
-
-#define QH_HLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) /* Isochronous Transfer Descriptor */
-#define QH_HLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) /* Queue Head */
-#define QH_HLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) /* Split Transaction Isochronous Transfer Descriptor */
-#define QH_HLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) /* Frame Span Traversal Node */
-
-/* Endpoint Characteristics: Queue Head DWord 1. Table 3-19 */
-
-#define QH_EPCHAR_DEVADDR_SHIFT (0) /* Bitx 0-6: Device Address */
-#define QH_EPCHAR_DEVADDR_MASK (0x7f << QH_EPCHAR_DEVADDR_SHIFT)
-#define QH_EPCHAR_I (1 << 7) /* Bit 7: Inactivate on Next Transaction */
-#define QH_EPCHAR_ENDPT_SHIFT (8) /* Bitx 8-11: Endpoint Number */
-#define QH_EPCHAR_ENDPT_MASK (15 << QH_EPCHAR_ENDPT_SHIFT)
-#define QH_EPCHAR_EPS_SHIFT (12) /* Bitx 12-13: Endpoint Speed */
-#define QH_EPCHAR_EPS_MASK (3 << QH_EPCHAR_EPS_SHIFT)
-#define QH_EPCHAR_EPS_FULL (0 << QH_EPCHAR_EPS_SHIFT) /* Full-Speed (12Mbs) */
-#define QH_EPCHAR_EPS_LOW (1 << QH_EPCHAR_EPS_SHIFT) /* Low-Speed (1.5Mbs) */
-#define QH_EPCHAR_EPS_HIGH (2 << QH_EPCHAR_EPS_SHIFT) /* High-Speed (480 Mb/s) */
-#define QH_EPCHAR_DTC (1 << 14) /* Bit 14: Data Toggle Control */
-#define QH_EPCHAR_H (1 << 15) /* Bit 15: Head of Reclamation List Flag */
-#define QH_EPCHAR_MAXPKT_SHIFT (16) /* Bitx 16-26: Maximum Packet Length */
-#define QH_EPCHAR_MAXPKT_MASK (0x7ff << QH_EPCHAR_MAXPKT_SHIFT)
-#define QH_EPCHAR_C (1 << 27) /* Bit 27: Control Endpoint Flag */
-#define QH_EPCHAR_RL_SHIFT (28) /* Bitx 28-31: Nak Count Reload */
-#define QH_EPCHAR_RL_MASK (15 << QH_EPCHAR_RL_SHIFT)
-
-/* Endpoint Capabilities: Queue Head DWord 2. Table 3-20 */
-
-#define QH_EPCAPS_SSMASK_SHIFT (0) /* Bitx 0-7: Interrupt Schedule Mask (Frame S-mask) */
-#define QH_EPCAPS_SSMASK_MASK (0xff << QH_EPCAPS_SSMASK_SHIFT)
-#define QH_EPCAPS_SSMASK(n) ((n) << QH_EPCAPS_SSMASK_SHIFT)
-#define QH_EPCAPS_SCMASK_SHIFT (8) /* Bitx 8-15: Split Completion Mask (Frame C-Mask) */
-#define QH_EPCAPS_SCMASK_MASK (0xff << QH_EPCAPS_SCMASK_SHIFT)
-#define QH_EPCAPS_SCMASK(n) ((n) << QH_EPCAPS_SCMASK_SHIFT)
-#define QH_EPCAPS_HUBADDR_SHIFT (16) /* Bitx 16-22: Hub Address */
-#define QH_EPCAPS_HUBADDR_MASK (0x7f << QH_EPCAPS_HUBADDR_SHIFT)
-#define QH_EPCAPS_HUBADDR(n) ((n) << QH_EPCAPS_HUBADDR_SHIFT)
-#define QH_EPCAPS_PORT_SHIFT (23) /* Bit 23-29: Port Number */
-#define QH_EPCAPS_PORT_MASK (0x7f << QH_EPCAPS_PORT_SHIFT)
-#define QH_EPCAPS_PORT(n) ((n) << QH_EPCAPS_PORT_SHIFT)
-#define QH_EPCAPS_MULT_SHIFT (30) /* Bit 30-31: High-Bandwidth Pipe Multiplier */
-#define QH_EPCAPS_MULT_MASK (3 << QH_EPCAPS_MULT_SHIFT)
-#define QH_EPCAPS_MULT(n) ((n) << QH_EPCAPS_MULT_SHIFT)
-
-/* qTD Token. Paragraph 3.5.3 */
-
-#define QTD_LIST_END 1
-
-#define QTD_TOKEN_STATUS_SHIFT (0) /* Bits 0-7: Status */
-#define QTD_TOKEN_STATUS_MASK (0xff << QTD_TOKEN_STATUS_SHIFT)
-#define QTD_TOKEN_STATUS_PINGSTATE (1 << 0) /* Bit 0 Ping State */
-#define QTD_TOKEN_STATUS_ERR (1 << 0) /* Bit 0 Error */
-#define QTD_TOKEN_STATUS_SPLITXSTATE (1 << 1) /* Bit 1 Split Transaction State */
-#define QTD_TOKEN_STATUS_MMF (1 << 2) /* Bit 2 Missed Micro-Frame */
-#define QTD_TOKEN_STATUS_XACTERR (1 << 3) /* Bit 3 Transaction Error */
-#define QTD_TOKEN_STATUS_BABBLE (1 << 4) /* Bit 4 Babble Detected */
-#define QTD_TOKEN_STATUS_DBERR (1 << 5) /* Bit 5 Data Buffer Error */
-#define QTD_TOKEN_STATUS_HALTED (1 << 6) /* Bit 6 Halted */
-#define QTD_TOKEN_STATUS_ACTIVE (1 << 7) /* Bit 7 Active */
-#define QTD_TOKEN_STATUS_ERRORS (0x78 << QTD_TOKEN_STATUS_SHIFT)
-#define QTD_TOKEN_PID_SHIFT (8) /* Bits 8-9: PID Code */
-#define QTD_TOKEN_PID_MASK (3 << QTD_TOKEN_PID_SHIFT)
-#define QTD_TOKEN_PID_OUT (0 << QTD_TOKEN_PID_SHIFT) /* OUT Token generates token (E1H) */
-#define QTD_TOKEN_PID_IN (1 << QTD_TOKEN_PID_SHIFT) /* IN Token generates token (69H) */
-#define QTD_TOKEN_PID_SETUP (2 << QTD_TOKEN_PID_SHIFT) /* SETUP Token generates token (2DH) */
-#define QTD_TOKEN_CERR_SHIFT (10) /* Bits 10-11: Error Counter */
-#define QTD_TOKEN_CERR_MASK (3 << QTD_TOKEN_CERR_SHIFT)
-#define QTD_TOKEN_CPAGE_SHIFT (12) /* Bits 12-14: Current Page */
-#define QTD_TOKEN_CPAGE_MASK (7 << QTD_TOKEN_CPAGE_SHIFT)
-#define QTD_TOKEN_IOC (1 << 15) /* Bit 15: Interrupt On Complete */
-#define QTD_TOKEN_NBYTES_SHIFT (16) /* Bits 16-30: Total Bytes to Transfer */
-#define QTD_TOKEN_NBYTES_MASK (0x7fff << QTD_TOKEN_NBYTES_SHIFT)
-#define QTD_TOKEN_TOGGLE (1 << 31) /* Bit 31: Data Toggle */
-
-/* Isochronous (High-Speed) Transfer Descriptor (iTD). Paragraph 3.3 */
-
-/* iTD Next Link Pointer. Paragraph 3.3.1 */
-
-#define ITD_NLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0)
-#define ITD_NLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2)
-#define ITD_NLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4)
-#define ITD_NLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6)
-
-/* iTD Transaction Status and Control List. Paragraph 3.3.2 */
-#define ITD_TSCL_XOFFS_SHIFT (0) /* Bits 0-11: Transaction X offset */
-#define ITD_TSCL_XOFFS_MASK (0xfff << ITD_TSCL_XOFFS_SHIFT)
-#define ITD_TSCL_PG_SHIFT (12) /* Bits 12-14: Page select */
-#define ITD_TSCL_PG_MASK (7 << ITD_TSCL_PG_SHIFT)
-#define ITD_TSCL_IOC (1 << 15) /* Bit 15: Interrupt On Comp */
-#define ITD_TSCL_LENGTH_SHIFT (16) /* Bits 16-27: Transaction length */
-#define ITD_TSCL_LENGTH_MASK (0xfff << ITD_TSCL_LENGTH_SHIFT)
-#define ITD_TSCL_STATUS_SHIFT (28) /* Bits 28-31: Transaction status */
-#define ITD_TSCL_STATUS_MASK (15 << ITD_TSCL_STATUS_SHIFT)
-#define ITD_TSCL_STATUS_XACTERR (1 << 28) /* Bit 28: Transaction error */
-#define ITD_TSCL_STATUS_BABBLE (1 << 29) /* Bit 29: Babble Detected */
-#define ITD_TSCL_STATUS_DBERROR (1 << 30) /* Bit 30: Data Buffer Error */
-#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 31: Active error */
-
-/* iTD Buffer Page Pointer List. Paragraph 3.3.4 */
-
-/* iTD Buffer Pointer Page 0. Table 3-4 */
-
-#define ITD_BUFPTR0_DEVADDR_SHIFT (0) /* Bits 0-6: Device Address */
-#define ITD_BUFPTR0_DEVADDR_MASK (0x7f << ITD_BUFPTR0_DEVADDR_SHIFT)
-#define ITD_BUFPTR0_ENDPT_SHIFT (8) /* Bits 8-11: Endpoint Number */
-#define ITD_BUFPTR0_ENDPT_MASK (15 << ITD_BUFPTR0_ENDPT_SHIFT)
-
-/* iTD Buffer Pointer Page 1. Table 3-5 */
-
-#define ITD_BUFPTR1_MAXPKT_SHIFT (0) /* Bits 0-10: Maximum Packet Size */
-#define ITD_BUFPTR1_MAXPKT_MASK (0x7ff << ITD_BUFPTR1_MAXPKT_SHIFT)
-#define ITD_BUFPTR1_DIRIN (1 << 11) /* Bit 11: Direction 1=IN */
-#define ITD_BUFPTR1_DIROUT (0) /* Bit 11: Direction 0=OUT */
-
-/* iTD Buffer Pointer Page 2. Table 3-6 */
-
-#define ITD_BUFPTR2_MULTI_SHIFT (0) /* Bits 0-1: Multi */
-#define ITD_BUFPTR2_MULTI_MASK (3 << ITD_BUFPTR2_MULTI_SHIFT)
-#define ITD_BUFPTR2_MULTI_1 (1 << ITD_BUFPTR2_MULTI_SHIFT) /* One transaction per micro-frame */
-#define ITD_BUFPTR2_MULTI_2 (2 << ITD_BUFPTR2_MULTI_SHIFT) /* Two transactions per micro-frame */
-#define ITD_BUFPTR2_MULTI_3 (3 << ITD_BUFPTR2_MULTI_SHIFT) /* Three transactions per micro-frame */
-
-/* Registers ****************************************************************/
-
-/* Host Controller Capability Registers.
- * This register block must be positioned at a well known address.
- */
-
-struct ehci_hccr {
- volatile uint8_t caplength; /* 0x00: Capability Register Length */
- volatile uint8_t reserved; /* 0x01: reserved */
- volatile uint16_t hciversion; /* 0x02: Interface Version Number */
- volatile uint32_t hcsparams; /* 0x04: Structural Parameters */
- volatile uint32_t hccparams; /* 0x08: Capability Parameters */
- volatile uint8_t hcspportroute[8]; /* 0x0c: Companion Port Route Description */
-};
-
-/* Host Controller Operational Registers.
- * This register block is positioned at an offset of 'caplength' from the
- * beginning of the Host Controller Capability Registers.
- */
-
-struct ehci_hcor {
- volatile uint32_t usbcmd; /* 0x00: USB Command */
- volatile uint32_t usbsts; /* 0x04: USB Status */
- volatile uint32_t usbintr; /* 0x08: USB Interrupt Enable */
- volatile uint32_t frindex; /* 0x0c: USB Frame Index */
- volatile uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */
- volatile uint32_t periodiclistbase; /* 0x14: Frame List Base Address */
- volatile uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */
-#ifndef CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
- uint32_t reserved[9];
+#ifndef CONFIG_USB_EHCI_QH_NUM
+#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
#endif
- volatile uint32_t configflag; /* 0x40: Configured Flag Register */
- volatile uint32_t portsc[15]; /* 0x44: Port Status/Control */
+#ifndef CONFIG_USB_EHCI_QTD_NUM
+#define CONFIG_USB_EHCI_QTD_NUM 3
+#endif
+#ifndef CONFIG_USB_EHCI_ITD_NUM
+#define CONFIG_USB_EHCI_ITD_NUM 5
+#endif
+#ifndef CONFIG_USB_EHCI_ISO_NUM
+#define CONFIG_USB_EHCI_ISO_NUM 4
+#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;
+ uint32_t length;
+} __attribute__((aligned(32)));
+
+struct ehci_qh_hw {
+ struct ehci_qh hw;
+ struct ehci_qtd_hw qtd_pool[CONFIG_USB_EHCI_QTD_NUM];
+ uint32_t first_qtd;
+ struct usbh_urb *urb;
+ usb_osal_sem_t waitsem;
+ uint8_t remove_in_iaad;
+} __attribute__((aligned(32)));
+
+struct ehci_itd_hw {
+ struct ehci_itd hw;
+ struct usbh_urb *urb;
+ uint16_t start_frame;
+ uint8_t mf_unmask;
+ uint8_t mf_valid;
+ uint32_t pkt_idx[8];
+} __attribute__((aligned(32)));
+
+struct ehci_iso_hw
+{
+ struct ehci_itd_hw itd_pool[CONFIG_USB_EHCI_ITD_NUM];
+ uint32_t itd_num;
};
-/* USB2 Debug Port Register Interface.
- * This register block is normally found via the PCI capabalities.
- * In non-PCI implementions, you need apriori information about the
- * location of these registers.
- */
-
-struct ehci_debug {
- uint32_t psc; /* 0x00: Debug Port Control/Status Register */
- uint32_t pids; /* 0x04: Debug USB PIDs Register */
- uint32_t data[2]; /* 0x08: Debug Data buffer Registers */
- uint32_t addr; /* 0x10: Device Address Register */
+struct ehci_hcd {
+ bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM];
+ bool ehci_iso_used[CONFIG_USB_EHCI_ISO_NUM];
+ bool ppc; /* Port Power Control */
+ bool has_tt; /* if use tt instead of Companion Controller */
+ uint8_t n_cc; /* Number of Companion Controller */
+ uint8_t n_pcc; /* Number of ports supported per companion host controller */
+ uint8_t n_ports;
+ uint8_t hcor_offset;
};
-/* Data Structures **********************************************************/
+extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS];
+extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)];
-/* Queue Element Transfer Descriptor (qTD). Paragraph 3.5 */
+int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb);
+void ehci_kill_iso_urb(struct usbh_bus *bus, struct usbh_urb *urb);
+void ehci_scan_isochronous_list(struct usbh_bus *bus);
-struct ehci_qtd {
- uint32_t next_qtd; /* 0x00-0x03: Next qTD Pointer */
- uint32_t alt_next_qtd; /* 0x04-0x07: Alternate Next qTD Pointer */
- uint32_t token; /* 0x08-0x0b: qTD Token */
- uint32_t bpl[5]; /* 0x0c-0x1c: Buffer Page Pointer List */
-};
-
-#define SIZEOF_EHCI_QTD (32) /* 8*sizeof(uint32_t) */
-
-/* Queue Head. Paragraph 3.6 */
-
-struct ehci_qh {
- uint32_t hlp; /* 0x00-0x03: Queue Head Horizontal Link Pointer */
- uint32_t epchar; /* 0x04-0x07: Endpoint Characteristics */
- uint32_t epcap; /* 0x08-0x0b: Endpoint Capabilities */
- uint32_t curr_qtd; /* 0x0c-0x0f: Current qTD Pointer */
- struct ehci_qtd overlay; /* 0x10-0x2c: Transfer overlay */
-};
-
-#define SIZEOF_EHCI_QH (48) /* 4*sizeof(uint32_t) + 32 */
-
-/* Isochronous (High-Speed) Transfer Descriptor (iTD).
- * Paragraph 3.3. Must be aligned to 32-byte boundaries.
- */
-
-struct ehci_itd {
- uint32_t nlp; /* 0x00-0x03: Next link pointer */
- uint32_t tscl[8]; /* 0x04-0x23: Transaction Status and Control List */
- uint32_t bpl[7]; /* 0x24-0x3c: Buffer Page Pointer List */
-};
-
-#define SIZEOF_EHCI_ITD (64) /* 16*sizeof(uint32_t) */
-
-/* Split Transaction Isochronous Transfer Descriptor (siTD). Paragraph 3.4 */
-
-struct ehci_sitd {
- uint32_t nlp; /* 0x00-0x03: Next link pointer */
- uint32_t epchar; /* 0x04-0x07: Endpoint and Transaction Translator Characteristics */
- uint32_t mfsc; /* 0x08-0x0b: Micro-frame Schedule Control */
- uint32_t tsc; /* 0x0c-0x0f: Transfer Status and Control */
- uint32_t bpl[2]; /* 0x10-0x17: Buffer Pointer List */
- uint32_t blp; /* 0x18-0x1b: Back link pointer */
-};
-
-#define SIZEOF_EHCI_SITD (28) /* 7*sizeof(uint32_t) */
-
-#endif /* USB_HC_EHCI_H */
+#endif
diff --git a/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c b/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c
index b3bfb5c4cb..b2dd9cca4d 100644
--- a/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c
+++ b/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c
@@ -117,6 +117,11 @@ 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;
@@ -255,8 +260,20 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
if (USB_EP_DIR_IS_OUT(ep)) {
+ if (PCD_GET_EP_RX_STATUS(USB, ep_idx) & USB_EP_RX_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
} else {
+ if (PCD_GET_EP_TX_STATUS(USB, ep_idx) & USB_EP_TX_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
}
return 0;
}
diff --git a/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c b/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c
index 31ad5b72ac..625c8b11fb 100644
--- a/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c
+++ b/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c
@@ -39,6 +39,7 @@ struct hpm_ep_state {
/* Driver state */
struct hpm_udc {
usb_device_handle_t *handle;
+ bool is_suspend;
struct hpm_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
struct hpm_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
} g_hpm_udc[CONFIG_USBDEV_MAX_BUS];
@@ -91,7 +92,7 @@ int usb_dc_init(uint8_t busid)
}
uint32_t int_mask;
- int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK |
+ int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_SLE_MASK |
USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK);
usb_device_init(g_hpm_udc[busid].handle, int_mask);
@@ -116,6 +117,23 @@ int usbd_set_address(uint8_t busid, const uint8_t addr)
return 0;
}
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ USB_Type *ptr;
+
+ ptr = g_hpm_udc[busid].handle->regs;
+
+ if (!usb_get_suspend_status(ptr)) {
+ return -1;
+ }
+
+ usb_force_port_resume(ptr);
+ while (ptr->PORTSC1 & USB_PORTSC1_FPR_MASK) {
+ }
+
+ return 0;
+}
+
uint8_t usbd_get_port_speed(uint8_t busid)
{
uint8_t speed;
@@ -259,6 +277,7 @@ void USBD_IRQHandler(uint8_t busid)
}
if (int_status & intr_reset) {
+ g_hpm_udc[busid].is_suspend = false;
memset(g_hpm_udc[busid].in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS);
memset(g_hpm_udc[busid].out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS);
usbd_event_reset_handler(busid);
@@ -267,10 +286,12 @@ void USBD_IRQHandler(uint8_t busid)
if (int_status & intr_suspend) {
if (usb_device_get_suspend_status(handle)) {
- usbd_event_suspend_handler(busid);
/* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */
if (usb_device_get_address(handle)) {
+ g_hpm_udc[busid].is_suspend = true;
+ usbd_event_suspend_handler(busid);
}
+ } else {
}
}
@@ -278,6 +299,10 @@ void USBD_IRQHandler(uint8_t busid)
if (!usb_device_get_port_ccs(handle)) {
usbd_event_disconnect_handler(busid);
} else {
+ if (g_hpm_udc[busid].is_suspend) {
+ g_hpm_udc[busid].is_suspend = false;
+ usbd_event_resume_handler(busid);
+ }
usbd_event_connect_handler(busid);
}
}
@@ -314,7 +339,7 @@ void USBD_IRQHandler(uint8_t busid)
transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes;
}
- if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID){
+ if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID) {
break;
} else {
p_qtd = (dcd_qtd_t *)p_qtd->next;
@@ -335,6 +360,8 @@ void USBD_IRQHandler(uint8_t busid)
}
}
+#if !defined(USBD_USE_CUSTOM_ISR) || !USBD_USE_CUSTOM_ISR
+
void isr_usbd0(void)
{
USBD_IRQHandler(_dcd_busid[0]);
@@ -347,4 +374,6 @@ void isr_usbd1(void)
USBD_IRQHandler(_dcd_busid[1]);
}
SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbd1)
-#endif
\ No newline at end of file
+#endif
+
+#endif
diff --git a/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c b/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c
index d66ec39edc..845e583b59 100644
--- a/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c
+++ b/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c
@@ -273,7 +273,7 @@ int usb_dc_init(uint8_t busid)
}
/* Enable USB interrupts */
- HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET;
+ HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET | USB_IE_SUSPND | USB_IE_RESUME;
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0;
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
@@ -296,6 +296,14 @@ int usbd_set_address(uint8_t busid, const uint8_t addr)
return 0;
}
+int usbd_set_remote_wakeup(uint8_t busid)
+{
+ HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_RESUME;
+ usbd_musb_delay_ms(10);
+ HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_RESUME;
+ return 0;
+}
+
uint8_t usbd_get_port_speed(uint8_t busid)
{
uint8_t speed = USB_SPEED_UNKNOWN;
@@ -501,6 +509,26 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint8_t old_ep_idx;
+
+ old_ep_idx = musb_get_active_ep();
+ musb_set_active_ep(ep_idx);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ if(HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
+ } else {
+ if(HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_STALL) {
+ *stalled = 1;
+ } else {
+ *stalled = 0;
+ }
+ }
+ musb_set_active_ep(old_ep_idx);
return 0;
}
@@ -706,9 +734,11 @@ void USBD_IRQHandler(uint8_t busid)
}
if (is & USB_IS_RESUME) {
+ usbd_event_resume_handler(0);
}
if (is & USB_IS_SUSPEND) {
+ usbd_event_suspend_handler(0);
}
txis &= HWREGH(USB_BASE + MUSB_TXIE_OFFSET);
diff --git a/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c b/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c
index 7eb987f9c2..2af1e361da 100644
--- a/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c
+++ b/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c
@@ -277,6 +277,11 @@ void usb_dc_low_level_deinit(void)
sys_drv_dev_clk_pwr_up(CLK_PWR_ID_USB_1, CLK_PWR_CTRL_PWR_DOWN);
}
+void usbd_musb_delay_ms(uint8_t ms)
+{
+ /* implement later */
+}
+
extern void USBH_IRQHandler(uint8_t busid);
void USBH_IRQ(void)
diff --git a/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c b/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c
index adfc293c39..b1a8f8eb2e 100644
--- a/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c
+++ b/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c
@@ -50,4 +50,9 @@ uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg)
uint32_t usb_get_musb_ram_size(void)
{
return 4096;
-}
\ No newline at end of file
+}
+
+void usbd_musb_delay_ms(uint8_t ms)
+{
+ /* implement later */
+}
diff --git a/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c b/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c
index 433923048f..706a60c791 100644
--- a/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c
+++ b/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c
@@ -56,4 +56,9 @@ uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg)
uint32_t usb_get_musb_ram_size(void)
{
return 8192;
-}
\ No newline at end of file
+}
+
+void usbd_musb_delay_ms(uint8_t ms)
+{
+ /* implement later */
+}
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 b5d7e36cec..39c787f8ab 100644
--- a/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c
+++ b/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c
@@ -475,10 +475,12 @@ static void musb_pipe_free(struct musb_pipe *pipe)
__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
{
+ (void)bus;
}
__WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus)
{
+ (void)bus;
}
int usb_hc_init(struct usbh_bus *bus)
@@ -653,6 +655,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u
}
}
+ status |= (1 << HUB_PORT_FEATURE_POWER);
memcpy(buf, &status, 4);
break;
default:
diff --git a/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h b/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h
index 885bdd4a27..17765372d7 100644
--- a/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h
+++ b/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h
@@ -3882,5 +3882,6 @@ struct musb_fifo_cfg {
uint8_t usbd_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg);
uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg);
uint32_t usb_get_musb_ram_size(void);
+void usbd_musb_delay_ms(uint8_t ms);
#endif
diff --git a/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c b/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c
index b3d658290c..fda180909d 100644
--- a/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c
+++ b/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c
@@ -3,8 +3,8 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
-#include "usb_ohci_priv.h"
-#include "usb_ehci_priv.h"
+#include "usb_hc_ohci.h"
+#include "usb_hc_ehci.h"
int ohci_init(struct usbh_bus *bus)
{
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 030350e5cc..68815d9d19 100644
--- a/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h
+++ b/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h
@@ -1,484 +1,24 @@
-/****************************************************************************
- * include/nuttx/usb/ohci.h
+/*
+ * Copyright (c) 2024, sakumisu
*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership. The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __INCLUDE_NUTTX_USB_OHCI_H
-#define __INCLUDE_NUTTX_USB_OHCI_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Register offsets *********************************************************/
-
-/* Control and status registers (section 7.1) */
-
-#define OHCI_HCIREV_OFFSET 0x0000 /* HcRevision: Version of HCI specification */
-#define OHCI_CTRL_OFFSET 0x0004 /* HcControl: HC control */
-#define OHCI_CMDST_OFFSET 0x0008 /* HcCommandStatus: HC command status */
-#define OHCI_INTST_OFFSET 0x000c /* HcInterruptStatus: HC interrupt status */
-#define OHCI_INTEN_OFFSET 0x0010 /* HcInterruptEnable: HC interrupt enable */
-#define OHCI_INTDIS_OFFSET 0x0014 /* HcInterruptDisable: HC interrupt disable */
-
-/* Memory pointer registers (section 7.2) */
-
-#define OHCI_HCCA_OFFSET 0x0018 /* HcHCCA: HC communication area */
-#define OHCI_PERED_OFFSET 0x001c /* HcPeriodCurrentED: Current isoc or int endpoint desc */
-#define OHCI_CTRLHEADED_OFFSET 0x0020 /* HcControlHeadED: First EP desc in the control list */
-#define OHCI_CTRLED_OFFSET 0x0024 /* HcControlCurrentED: Current EP desc in the control list */
-#define OHCI_BULKHEADED_OFFSET 0x0028 /* HcBulkHeadED: First EP desc in the bulk list */
-#define OHCI_BULKED_OFFSET 0x002c /* HcBulkCurrentED: Current EP desc in the bulk list */
-#define OHCI_DONEHEAD_OFFSET 0x0030 /* HcDoneHead: Last transfer desc added to DONE queue */
-
-/* Frame counter registers (section 7.3) */
-
-#define OHCI_FMINT_OFFSET 0x0034 /* HcFmInterval: Bit time interval that would not cause overrun */
-#define OHCI_FMREM_OFFSET 0x0038 /* HcFmRemaining: Bit time remaining in current frame */
-#define OHCI_FMNO_OFFSET 0x003c /* HcFmNumber: Frame number counter */
-#define OHCI_PERSTART_OFFSET 0x0040 /* HcPeriodicStart: Time to start processing periodic list */
-
-/* Root hub registers (section 7.4) */
-
-#define OHCI_LSTHRES_OFFSET 0x0044 /* HcLSThreshold: Commit to transfer threshold */
-#define OHCI_RHDESCA_OFFSET 0x0048 /* HcRhDescriptorA: Describes root hub (part A) */
-#define OHCI_RHDESCB_OFFSET 0x004c /* HcRhDescriptorB: Describes root hub (part B) */
-#define OHCI_RHSTATUS_OFFSET 0x0050 /* HcRhStatus: Root hub status */
-
-#define OHCI_MAX_RHPORT 15 /* Maximum number of OHCI root hub ports */
-
-#define OHCI_RHPORTST_OFFSET(n) (0x0054 + (((n) - 1) << 2))
-#define OHCI_RHPORTST1_OFFSET 0x0054 /* HcRhPort1Status: Root hub port status 1 */
-#define OHCI_RHPORTST2_OFFSET 0x0058 /* HcRhPort2Status: Root hub port status 2 */
-#define OHCI_RHPORTST3_OFFSET 0x005c /* HcRhPort3Status: Root hub port status 3 */
-#define OHCI_RHPORTST4_OFFSET 0x0060 /* HcRhPort4Status: Root hub port status 4 */
-#define OHCI_RHPORTST5_OFFSET 0x0064 /* HcRhPort5Status: Root hub port status 5 */
-#define OHCI_RHPORTST6_OFFSET 0x0068 /* HcRhPort6Status: Root hub port status 6 */
-#define OHCI_RHPORTST7_OFFSET 0x006c /* HcRhPort7Status: Root hub port status 7 */
-#define OHCI_RHPORTST8_OFFSET 0x0070 /* HcRhPort8Status: Root hub port status 8 */
-#define OHCI_RHPORTST9_OFFSET 0x0074 /* HcRhPort9Status: Root hub port status 9 */
-#define OHCI_RHPORTST10_OFFSET 0x0078 /* HcRhPort10Status: Root hub port status 10 */
-#define OHCI_RHPORTST11_OFFSET 0x007c /* HcRhPort11Status: Root hub port status 11 */
-#define OHCI_RHPORTST12_OFFSET 0x0080 /* HcRhPort12Status: Root hub port status 12 */
-#define OHCI_RHPORTST13_OFFSET 0x0084 /* HcRhPort13Status: Root hub port status 13 */
-#define OHCI_RHPORTST14_OFFSET 0x0088 /* HcRhPort14Status: Root hub port status 14 */
-#define OHCI_RHPORTST15_OFFSET 0x008c /* HcRhPort15Status: Root hub port status 15 */
-
-/* Register bit definitions *************************************************/
-
-/* HcRevision: Version of HCI specification (7.1.1) */
-
-#define OHCI_HCIREV_SHIFT (0) /* Bits 0-7: HCI spec version (BCD) */
-#define OHCI_HCIREV_MASK (0xff << OHCI_HCIREV_SHIFT)
-
-/* HcControl: HC control (7.1.2) */
-
-#define OHCI_CTRL_CBSR (3 << 0) /* Bit 0: Control/bulk service ratio */
-#define OHCI_CTRL_PLE (1 << 2) /* Bit 1: Periodic list enable */
-#define OHCI_CTRL_IE (1 << 3) /* Bit 2: Isochronous enable */
-#define OHCI_CTRL_CLE (1 << 4) /* Bit 3: Control list enable */
-#define OHCI_CTRL_BLE (1 << 5) /* Bit 4: Bulk list enable */
-#define OHCI_CTRL_HCFS_SHIFT (6) /* Bits 6-7: Host controller functional state */
-#define OHCI_CTRL_HCFS_MASK (3 << OHCI_CTRL_HCFS_SHIFT)
-# define OHCI_CTRL_HCFS_RESET (0 << OHCI_CTRL_HCFS_SHIFT)
-# define OHCI_CTRL_HCFS_RESUME (1 << OHCI_CTRL_HCFS_SHIFT)
-# define OHCI_CTRL_HCFS_OPER (2 << OHCI_CTRL_HCFS_SHIFT)
-# define OHCI_CTRL_HCFS_SUSPEND (3 << OHCI_CTRL_HCFS_SHIFT)
-#define OHCI_CTRL_IR (1 << 8) /* Bit 8: Interrupt routing */
-#define OHCI_CTRL_RWC (1 << 9) /* Bit 9: Remote wakeup connected */
-#define OHCI_CTRL_RWE (1 << 10) /* Bit 10: Remote wakeup enable */
- /* Bits 11-31: Reserved */
-
-/* HcCommandStatus: HC command status (7.1.3) */
-
-#define OHCI_CMDST_HCR (1 << 0) /* Bit 0: Host controller reset */
-#define OHCI_CMDST_CLF (1 << 1) /* Bit 1: Control list filled */
-#define OHCI_CMDST_BLF (1 << 2) /* Bit 2: Bulk list filled */
-#define OHCI_CMDST_OCR (1 << 3) /* Bit 3: Ownership change request */
- /* Bits 4-15: Reserved */
-#define OHCI_CMDST_SOC (3 << 16) /* Bit 16: Scheduling overrun count */
- /* Bits 17-31: Reserved */
-
-/* HcInterruptStatus: HC interrupt status (7.1.4),
- * HcInterruptEnable: HC interrupt enable (7.1.5), and
- * HcInterruptDisable: HC interrupt disable (7.1.6)
+ * SPDX-License-Identifier: Apache-2.0
*/
+#ifndef _USB_OHCI_PRIV_H
+#define _USB_OHCI_PRIV_H
-#define OHCI_INT_SO (1 << 0) /* Bit 0: Scheduling overrun */
-#define OHCI_INT_WDH (1 << 1) /* Bit 1: Writeback done head */
-#define OHCI_INT_SF (1 << 2) /* Bit 2: Start of frame */
-#define OHCI_INT_RD (1 << 3) /* Bit 3: Resume detected */
-#define OHCI_INT_UE (1 << 4) /* Bit 4: Unrecoverable error */
-#define OHCI_INT_FNO (1 << 5) /* Bit 5: Frame number overflow */
-#define OHCI_INT_RHSC (1 << 6) /* Bit 6: Root hub status change */
- /* Bits 7-29: Reserved */
-#define OHCI_INT_OC (1 << 30) /* Bit 30: Ownership change */
-#define OHCI_INT_MIE (1 << 31) /* Bit 31: Master interrupt enable
- * (Enable/disable only) */
+#include "usbh_core.h"
+#include "usbh_hub.h"
+#include "usb_ohci_reg.h"
-/* HcHCCA: HC communication area (7.2.1):
- *
- * 32-bits aligned to 256 byte boundary.
- */
+#define OHCI_HCOR ((struct ohci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_OHCI_HCOR_OFFSET))
-/* HcPeriodCurrentED: Current isoc or int endpoint desc (7.2.2),
- * HcControlHeadED: First EP desc in the control list (7.2.3),
- * HcControlCurrentED: Current EP desc in the control list (7.2.4),
- * HcBulkHeadED: First EP desc in the bulk list (7.2.5),
- * HcBulkCurrentED: Current EP desc in the bulk list (7.2.6), and
- * HcDoneHead: Last transfer desc added to DONE queue (7.2.7):
- *
- * All 32-bits aligned to an 8-byte boundary
- */
+int ohci_init(struct usbh_bus *bus);
+int ohci_deinit(struct usbh_bus *bus);
+uint16_t ohci_get_frame_number(struct usbh_bus *bus);
+int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf);
+int ohci_submit_urb(struct usbh_urb *urb);
+int ohci_kill_urb(struct usbh_urb *urb);
-/* HcFmInterval: Bit time interval that would not cause overrun (7.3.1) */
+void OHCI_IRQHandler(uint8_t busid);
-#define OHCI_FMINT_FI_SHIFT (0) /* Bits 0-13: Frame interval */
-#define OHCI_FMINT_FI_MASK (0x3fff << OHCI_FMINT_FI_SHIFT)
- /* Bits 14-15: Reserved */
-#define OHCI_FMINT_FSMPS_SHIFT (16) /* Bits 16-30: FS largest packet data */
-#define OHCI_FMINT_FSMPS_MASK (0x7fff << OHCI_FMINT_FSMPS_SHIFT)
-#define OHCI_FMINT_FIT (1 << 31) /* Bit 31: Frame interval toggle */
-
-/* HcFmRemaining: Bit time remaining in current frame (7.3.2) */
-
-#define OHCI_FMREM_FR_SHIFT (0) /* Bits 0-13: Frame remaining */
-#define OHCI_FMREM_FR_MASK (0x3fff << OHCI_FMREM_FR_SHIFT)
- /* Bits 16-30: Reserved */
-#define OHCI_FMINT_FRT (1 << 31) /* Bit 31: Frame remaining toggle */
-
-/* HcFmNumber: Frame number counter (7.3.3) */
-
-#define OHCI_FMNO_FI_SHIFT (0) /* Bits 0-15: Frame number */
-#define OHCI_FMNO_FI_MASK (0xffff << OHCI_FMINT_FI_SHIFT)
- /* Bits 16-31: Reserved */
-
-/* HcPeriodicStart: Time to start processing periodic list (7.3.4) */
-
-#define OHCI_PERSTART_SHIFT (0) /* Bits 0-13: Periodic start */
-#define OHCI_PERSTART_MASK (0x3fff << OHCI_PERSTART_SHIFT)
- /* Bits 14-31: Reserved */
-
-/* HcLSThreshold: Commit to transfer threshold (7.3.5) */
-
-#define OHCI_LSTHRES_SHIFT (0) /* Bits 0-11: LS threshold */
-#define OHCI_LSTHRES_MASK (0x0fff << OHCI_PERSTART_SHIFT)
- /* Bits 12-31: Reserved */
-
-/* HcRhDescriptorN: Describes root hub (part A) (7.4.1) */
-
-#define OHCI_RHDESCA_NDP_SHIFT (0) /* Bits 0-7: Number downstream ports */
-#define OHCI_RHDESCA_NDP_MASK (0xff << OHCI_RHDESCA_NDP_SHIFT)
-#define OHCI_RHDESCA_PSM (1 << 8) /* Bit 8: Power switching mode */
-#define OHCI_RHDESCA_NPS (1 << 9) /* Bit 9: No power switching */
-#define OHCI_RHDESCA_DT (1 << 10) /* Bit 10: Device type */
-#define OHCI_RHDESCA_OCPM (1 << 11) /* Bit 11: Over current protection mode */
-#define OHCI_RHDESCA_NOCP (1 << 12) /* Bit 12: No over current protection */
- /* Bits 13-23: Reserved */
-#define OHCI_RHDESCA_POTPGT_SHIFT (24) /* Bits 24-31: Power on to power good time */
-#define OHCI_RHDESCA_POTPGT_MASK (0xff << OHCI_RHDESCA_POTPGT_SHIFT)
-
-/* HcRhDescriptorB: Describes root hub (part B) (7.4.2) */
-
-#define OHCI_RHDESCB_DR_SHIFT (0) /* Bits 0-15: Device removable */
-#define OHCI_RHDESCB_DR_MASK (0xffff << OHCI_RHDESCB_DR_SHIFT)
-# define OHCI_RHDESCB_ATTACHED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n)))
-#define OHCI_RHDESCB_PPCM_SHIFT (16) /* Bits 16-31: Port power control mask */
-#define OHCI_RHDESCB_PPCM_MASK (0xffff << OHCI_RHDESCB_PPCM_SHIFT)
-# define OHCI_RHDESCB_POWERED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n)))
-
-/* HcRhStatus: Root hub status (7.4.3) */
-
-#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status (read)*/
-#define OHCI_RHSTATUS_CGP (1 << 0) /* Bit 0: Clear global power (write)*/
-#define OHCI_RHSTATUS_OCI (1 << 1) /* Bit 1: Over current indicator */
- /* Bits 2-14: Reserved */
-#define OHCI_RHSTATUS_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */
-#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change (read) */
-#define OHCI_RHSTATUS_SGP (1 << 16) /* Bit 16: Set global power (write) */
-#define OHCI_RHSTATUS_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */
- /* Bits 18-30: Reserved */
-#define OHCI_RHSTATUS_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */
-
-/* HcRhPortStatus: Root hub port status (7.4.4) */
-
-#define OHCI_RHPORTST_CCS (1 << 0) /* Bit 0: Current connect status */
-#define OHCI_RHPORTST_PES (1 << 1) /* Bit 1: Port enable status */
-#define OHCI_RHPORTST_PSS (1 << 2) /* Bit 2: Port suspend status */
-#define OHCI_RHPORTST_POCI (1 << 3) /* Bit 3: Port over current indicator */
-#define OHCI_RHPORTST_PRS (1 << 4) /* Bit 4: Port reset status */
- /* Bits 5-7: Reserved */
-#define OHCI_RHPORTST_PPS (1 << 8) /* Bit 8: Port power status */
-#define OHCI_RHPORTST_LSDA (1 << 9) /* Bit 9: Low speed device attached */
- /* Bits 10-15: Reserved */
-#define OHCI_RHPORTST_CSC (1 << 16) /* Bit 16: Connect status change */
-#define OHCI_RHPORTST_PESC (1 << 17) /* Bit 17: Port enable status change */
-#define OHCI_RHPORTST_PSSC (1 << 18) /* Bit 18: Port suspend status change */
-#define OHCI_RHPORTST_OCIC (1 << 19) /* Bit 19: Port over current indicator change */
-#define OHCI_RHPORTST_PRSC (1 << 20) /* Bit 20: Port reset status change */
- /* Bits 21-31: Reserved */
-
-/* Transfer Descriptors *****************************************************/
-
-/* Endpoint Descriptor Offsets (4.2.1) */
-
-#define ED_CONTROL_OFFSET (0x00) /* ED status/control bits */
-#define ED_TAILP_OFFSET (0x04) /* TD Queue Tail Pointer (TailP) */
-#define ED_HEADP_OFFSET (0x08) /* TD Queue Head Pointer (HeadP) */
-#define ED_NEXTED_OFFSET (0x0c) /* Next Endpoint Descriptor (NextED) */
-
-/* Endpoint Descriptor Bit Definitions (4.2.2) */
-
-#define ED_CONTROL_FA_SHIFT (0) /* Bits 0-6: Function Address */
-#define ED_CONTROL_FA_MASK (0x7f << ED_CONTROL_FA_SHIFT)
-#define ED_CONTROL_EN_SHIFT (7) /* Bits 7-10: Endpoint number */
-#define ED_CONTROL_EN_MASK (15 << ED_CONTROL_EN_SHIFT)
-#define ED_CONTROL_D_SHIFT (11) /* Bits 11-12: Direction */
-#define ED_CONTROL_D_MASK (3 << ED_CONTROL_D_SHIFT)
-# define ED_CONTROL_D_TD1 (0 << ED_CONTROL_D_SHIFT) /* Get direction from TD */
-# define ED_CONTROL_D_OUT (1 << ED_CONTROL_D_SHIFT) /* OUT */
-# define ED_CONTROL_D_IN (2 << ED_CONTROL_D_SHIFT) /* IN */
-# define ED_CONTROL_D_TD2 (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */
-
-#define ED_CONTROL_S (1 << 13) /* Bit 13: Speed (low) */
-#define ED_CONTROL_K (1 << 14) /* Bit 14: Skip */
-#define ED_CONTROL_F (1 << 15) /* Bit 15: Format (isochronous) */
-#define ED_CONTROL_MPS_SHIFT (16) /* Bits 16-26: Maximum packet size */
-#define ED_CONTROL_MPS_MASK (0x7ff << ED_CONTROL_MPS_SHIFT)
-
-#define ED_HEADP_ADDR_SHIFT (0)
-#define ED_HEADP_ADDR_MASK 0xfffffff0
-#define ED_HEADP_H (1 << 0) /* Bit 0: Halted */
-#define ED_HEADP_C (1 << 1) /* Bit 1: Toggle carry */
-
-/* General Transfer Descriptor Offsets (4.3.1) */
-
-#define GTD_STATUS_OFFSET (0x00) /* TD status bits */
-#define GTD_CBP_OFFSET (0x04) /* Current Buffer Pointer (CBP) */
-#define GTD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */
-#define GTD_BE_OFFSET (0x0c) /* Buffer End (BE) */
-
-/* General Transfer Descriptor Bit Definitions */
-
- /* Bits 0-17: Reserved */
-
-#define GTD_STATUS_R (1 << 18) /* Bit 18: Buffer rounding */
-#define GTD_STATUS_DP_SHIFT (19) /* Bits 19-20: Direction/PID */
-#define GTD_STATUS_DP_MASK (3 << GTD_STATUS_DP_SHIFT)
-# define GTD_STATUS_DP_SETUP (0 << GTD_STATUS_DP_SHIFT) /* To endpoint */
-# define GTD_STATUS_DP_OUT (1 << GTD_STATUS_DP_SHIFT) /* To endpoint */
-# define GTD_STATUS_DP_IN (2 << GTD_STATUS_DP_SHIFT) /* From endpoint */
-
-#define GTD_STATUS_DI_SHIFT (21) /* Bits 21-23: Delay input */
-#define GTD_STATUS_DI_MASK (7 << GTD_STATUS_DI_SHIFT)
-#define GTD_STATUS_T_SHIFT (24) /* Bits 24-25: Data Toggle */
-#define GTD_STATUS_T_MASK (3 << GTD_STATUS_T_SHIFT)
-# define GTD_STATUS_T_TOGGLE (0 << GTD_STATUS_T_SHIFT)
-# define GTD_STATUS_T_DATA0 (2 << GTD_STATUS_T_SHIFT)
-# define GTD_STATUS_T_DATA1 (3 << GTD_STATUS_T_SHIFT)
-#define GTD_STATUS_EC_SHIFT (26) /* Bits 26-27: Error count */
-#define GTD_STATUS_EC_MASK (3 << GTD_STATUS_EC_SHIFT)
-#define GTD_STATUS_CC_SHIFT (28) /* Bits 28-31: Condition code */
-#define GTD_STATUS_CC_MASK (15 << GTD_STATUS_CC_SHIFT)
-
-/* Isochronous Transfer Descriptor Offsets (4.3.2) */
-
-#define ITD_STATUS_OFFSET (0x00) /* TD status bits */
-#define ITD_BP0_OFFSET (0x04) /* Buffer page 0 (BP0) */
-#define ITD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */
-#define ITD_BE_OFFSET (0x0c) /* Buffer End (BE) */
-
-#define ITD_NPSW (8)
-#define ITD_PSW0_OFFSET (0x10) /* Offset0/PSW0 */
-#define ITD_PSW1_OFFSET (0x12) /* Offset1/PSW1 */
-#define ITD_PSW2_OFFSET (0x14) /* Offset2/PSW2 */
-#define ITD_PSW3_OFFSET (0x16) /* Offset3/PSW3 */
-#define ITD_PSW4_OFFSET (0x18) /* Offset4/PSW4 */
-#define ITD_PSW5_OFFSET (0x1a) /* Offset5/PSW5 */
-#define ITD_PSW6_OFFSET (0x1c) /* Offset6/PSW6 */
-#define ITD_PSW7_OFFSET (0x1e) /* Offset7/PSW7 */
-
-/* Condition codes (Table 4-7) */
-
-#define TD_CC_NOERROR 0x00
-#define TD_CC_CRC 0x01
-#define TD_CC_BITSTUFFING 0x02
-#define TD_CC_DATATOGGLEMISMATCH 0x03
-#define TD_CC_STALL 0x04
-#define TD_CC_DEVNOTRESPONDING 0x05
-#define TD_CC_PIDCHECKFAILURE 0x06
-#define TD_CC_UNEXPECTEDPID 0x07
-#define TD_CC_DATAOVERRUN 0x08
-#define TD_CC_DATAUNDERRUN 0x09
-#define TD_CC_BUFFEROVERRUN 0x0c
-#define TD_CC_BUFFERUNDERRUN 0x0d
-#define TD_CC_NOTACCESSED 0x0f
-
-#define TD_CC_USER 0x10 /* For use by OHCI drivers */
-
-/* Host Controller Communications Area Format (4.4.1) ***********************/
-
-/* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */
-
-#define HCCA_INTTBL_OFFSET (0x00)
-#define HCCA_INTTBL_WSIZE (32)
-#define HCCA_INTTBL_BSIZE (HCCA_INTTBL_WSIZE * 4)
-
-/* HccaFrameNumber: Current frame number */
-
-#define HCCA_FMNO_OFFSET (0x80)
-#define HCCA_FMNO_BSIZE (2)
-
-/* HccaPad1: Zero when frame no. updated */
-
-#define HCCA_PAD1_OFFSET (0x82)
-#define HCCA_PAD1_BSIZE (2)
-
-/* HccaDoneHead: When the HC reaches the end of a frame and its deferred
- * interrupt register is 0, it writes the current value of its HcDoneHead to
- * this location and generates an interrupt.
- *
- * The LSB of HCCADoneHead may be set to 1 to indicate that an unmasked
- * HcInterruptStatus was set when HccaDoneHead was written.
- */
-
-#define HCCA_DONEHEAD_OFFSET (0x84)
-#define HCCA_DONEHEAD_BSIZE (4)
-
-#define HCCA_DONEHEAD_MASK 0xfffffffe
-#define HCCA_DONEHEAD_INTSTA (1 << 0)
-
-/* 0x88: 116 bytes reserved */
-
-#define HCCA_RESERVED_OFFSET (0x88)
-#define HCCA_RESERVED_BSIZE (116)
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-struct ohci_hcor
-{
- volatile uint32_t hcrevision; /* 0x00 */
- volatile uint32_t hccontrol; /* 0x04 */
- volatile uint32_t hccmdsts; /* 0x08 */
- volatile uint32_t hcintsts; /* 0x0c */
- volatile uint32_t hcinten; /* 0x10 */
- volatile uint32_t hcintdis; /* 0x14 */
- volatile uint32_t hchcca; /* 0x18 */
- volatile uint32_t hcperiodcurrented; /* 0x1c */
- volatile uint32_t hccontrolheaded; /* 0x20 */
- volatile uint32_t hccontrolcurrented; /* 0x24 */
- volatile uint32_t hcbulkheaded; /* 0x28 */
- volatile uint32_t hcbulkcurrented; /* 0x2c */
- volatile uint32_t hcdonehead; /* 0x30 */
- volatile uint32_t hcfminterval; /* 0x34 */
- volatile uint32_t hcfmremaining; /* 0x38 */
- volatile uint32_t hcfmnumber; /* 0x3c */
- volatile uint32_t hcperiodicstart; /* 0x40 */
- volatile uint32_t hclsthreshold; /* 0x44 */
- volatile uint32_t hcrhdescriptora; /* 0x48 */
- volatile uint32_t hcrhdescriptorb; /* 0x4c */
- volatile uint32_t hcrhsts; /* 0x50 */
- volatile uint32_t hcrhportsts[15]; /* 0x54 */
-};
-
-/* Endpoint Descriptor Offsets (4.2.1) */
-
-struct ohci_ed_s
-{
- volatile uint32_t ctrl; /* ED status/control bits */
- volatile uint32_t tailp; /* TD Queue Tail Pointer (TailP) */
- volatile uint32_t headp; /* TD Queue Head Pointer (HeadP) */
- volatile uint32_t nexted; /* Next Endpoint Descriptor (NextED) */
-};
-
-/* General Transfer Descriptor (4.3.1) */
-
-struct ohci_gtd_s
-{
- volatile uint32_t ctrl; /* TD status/control bits */
- volatile uint32_t cbp; /* Current Buffer Pointer (CBP) */
- volatile uint32_t nexttd; /* Next TD (NextTD) */
- volatile uint32_t be; /* Buffer End (BE) */
-};
-
-/* Isochronous Transfer Descriptor Offsets (4.3.2) */
-
-struct ohci_itd_s
-{
- volatile uint32_t ctrl; /* TD status/control bits */
- volatile uint32_t bp0; /* Buffer page 0 (BP0 */
- volatile uint32_t nexttd; /* Next TD (NextTD) */
- volatile uint32_t be; /* Buffer End (BE) */
- volatile uint16_t psw[ITD_NPSW]; /* Offset/PSW */
-};
-
-/* Host Controller Communications Area Format (4.4.1) */
-
-struct ohci_hcca_s
-{
- /* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */
-
- volatile uint32_t inttbl[HCCA_INTTBL_WSIZE];
-
- /* HccaFrameNumber: Current frame number and
- * HccaPad1: Zero when frame no. updated
- */
-
- volatile uint16_t fmno;
- volatile uint16_t pad1;
-
- /* HccaDoneHead: When the HC reaches the end of a frame and its deferred
- * interrupt register is 0, it writes the current value of its HcDoneHead
- * to this location and generates an interrupt.
- */
-
- volatile uint32_t donehead;
- volatile uint8_t reserved[HCCA_RESERVED_BSIZE];
- volatile uint32_t extra;
-} __attribute__((aligned(256)));
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_NUTTX_USB_OHCI_H */
+#endif
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/ohci/usb_ohci_priv.h b/components/drivers/usb/cherryusb/port/ohci/usb_ohci_priv.h
deleted file mode 100644
index 4404dc253e..0000000000
--- a/components/drivers/usb/cherryusb/port/ohci/usb_ohci_priv.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#ifndef _USB_OHCI_PRIV_H
-#define _USB_OHCI_PRIV_H
-
-#include "usbh_core.h"
-#include "usbh_hub.h"
-#include "usb_hc_ohci.h"
-
-#define OHCI_HCOR ((struct ohci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_OHCI_HCOR_OFFSET))
-
-int ohci_init(struct usbh_bus *bus);
-int ohci_deinit(struct usbh_bus *bus);
-uint16_t ohci_get_frame_number(struct usbh_bus *bus);
-int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf);
-int ohci_submit_urb(struct usbh_urb *urb);
-int ohci_kill_urb(struct usbh_urb *urb);
-
-void OHCI_IRQHandler(uint8_t busid);
-
-#endif
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/ohci/usb_ohci_reg.h b/components/drivers/usb/cherryusb/port/ohci/usb_ohci_reg.h
new file mode 100644
index 0000000000..030350e5cc
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/ohci/usb_ohci_reg.h
@@ -0,0 +1,484 @@
+/****************************************************************************
+ * include/nuttx/usb/ohci.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_USB_OHCI_H
+#define __INCLUDE_NUTTX_USB_OHCI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register offsets *********************************************************/
+
+/* Control and status registers (section 7.1) */
+
+#define OHCI_HCIREV_OFFSET 0x0000 /* HcRevision: Version of HCI specification */
+#define OHCI_CTRL_OFFSET 0x0004 /* HcControl: HC control */
+#define OHCI_CMDST_OFFSET 0x0008 /* HcCommandStatus: HC command status */
+#define OHCI_INTST_OFFSET 0x000c /* HcInterruptStatus: HC interrupt status */
+#define OHCI_INTEN_OFFSET 0x0010 /* HcInterruptEnable: HC interrupt enable */
+#define OHCI_INTDIS_OFFSET 0x0014 /* HcInterruptDisable: HC interrupt disable */
+
+/* Memory pointer registers (section 7.2) */
+
+#define OHCI_HCCA_OFFSET 0x0018 /* HcHCCA: HC communication area */
+#define OHCI_PERED_OFFSET 0x001c /* HcPeriodCurrentED: Current isoc or int endpoint desc */
+#define OHCI_CTRLHEADED_OFFSET 0x0020 /* HcControlHeadED: First EP desc in the control list */
+#define OHCI_CTRLED_OFFSET 0x0024 /* HcControlCurrentED: Current EP desc in the control list */
+#define OHCI_BULKHEADED_OFFSET 0x0028 /* HcBulkHeadED: First EP desc in the bulk list */
+#define OHCI_BULKED_OFFSET 0x002c /* HcBulkCurrentED: Current EP desc in the bulk list */
+#define OHCI_DONEHEAD_OFFSET 0x0030 /* HcDoneHead: Last transfer desc added to DONE queue */
+
+/* Frame counter registers (section 7.3) */
+
+#define OHCI_FMINT_OFFSET 0x0034 /* HcFmInterval: Bit time interval that would not cause overrun */
+#define OHCI_FMREM_OFFSET 0x0038 /* HcFmRemaining: Bit time remaining in current frame */
+#define OHCI_FMNO_OFFSET 0x003c /* HcFmNumber: Frame number counter */
+#define OHCI_PERSTART_OFFSET 0x0040 /* HcPeriodicStart: Time to start processing periodic list */
+
+/* Root hub registers (section 7.4) */
+
+#define OHCI_LSTHRES_OFFSET 0x0044 /* HcLSThreshold: Commit to transfer threshold */
+#define OHCI_RHDESCA_OFFSET 0x0048 /* HcRhDescriptorA: Describes root hub (part A) */
+#define OHCI_RHDESCB_OFFSET 0x004c /* HcRhDescriptorB: Describes root hub (part B) */
+#define OHCI_RHSTATUS_OFFSET 0x0050 /* HcRhStatus: Root hub status */
+
+#define OHCI_MAX_RHPORT 15 /* Maximum number of OHCI root hub ports */
+
+#define OHCI_RHPORTST_OFFSET(n) (0x0054 + (((n) - 1) << 2))
+#define OHCI_RHPORTST1_OFFSET 0x0054 /* HcRhPort1Status: Root hub port status 1 */
+#define OHCI_RHPORTST2_OFFSET 0x0058 /* HcRhPort2Status: Root hub port status 2 */
+#define OHCI_RHPORTST3_OFFSET 0x005c /* HcRhPort3Status: Root hub port status 3 */
+#define OHCI_RHPORTST4_OFFSET 0x0060 /* HcRhPort4Status: Root hub port status 4 */
+#define OHCI_RHPORTST5_OFFSET 0x0064 /* HcRhPort5Status: Root hub port status 5 */
+#define OHCI_RHPORTST6_OFFSET 0x0068 /* HcRhPort6Status: Root hub port status 6 */
+#define OHCI_RHPORTST7_OFFSET 0x006c /* HcRhPort7Status: Root hub port status 7 */
+#define OHCI_RHPORTST8_OFFSET 0x0070 /* HcRhPort8Status: Root hub port status 8 */
+#define OHCI_RHPORTST9_OFFSET 0x0074 /* HcRhPort9Status: Root hub port status 9 */
+#define OHCI_RHPORTST10_OFFSET 0x0078 /* HcRhPort10Status: Root hub port status 10 */
+#define OHCI_RHPORTST11_OFFSET 0x007c /* HcRhPort11Status: Root hub port status 11 */
+#define OHCI_RHPORTST12_OFFSET 0x0080 /* HcRhPort12Status: Root hub port status 12 */
+#define OHCI_RHPORTST13_OFFSET 0x0084 /* HcRhPort13Status: Root hub port status 13 */
+#define OHCI_RHPORTST14_OFFSET 0x0088 /* HcRhPort14Status: Root hub port status 14 */
+#define OHCI_RHPORTST15_OFFSET 0x008c /* HcRhPort15Status: Root hub port status 15 */
+
+/* Register bit definitions *************************************************/
+
+/* HcRevision: Version of HCI specification (7.1.1) */
+
+#define OHCI_HCIREV_SHIFT (0) /* Bits 0-7: HCI spec version (BCD) */
+#define OHCI_HCIREV_MASK (0xff << OHCI_HCIREV_SHIFT)
+
+/* HcControl: HC control (7.1.2) */
+
+#define OHCI_CTRL_CBSR (3 << 0) /* Bit 0: Control/bulk service ratio */
+#define OHCI_CTRL_PLE (1 << 2) /* Bit 1: Periodic list enable */
+#define OHCI_CTRL_IE (1 << 3) /* Bit 2: Isochronous enable */
+#define OHCI_CTRL_CLE (1 << 4) /* Bit 3: Control list enable */
+#define OHCI_CTRL_BLE (1 << 5) /* Bit 4: Bulk list enable */
+#define OHCI_CTRL_HCFS_SHIFT (6) /* Bits 6-7: Host controller functional state */
+#define OHCI_CTRL_HCFS_MASK (3 << OHCI_CTRL_HCFS_SHIFT)
+# define OHCI_CTRL_HCFS_RESET (0 << OHCI_CTRL_HCFS_SHIFT)
+# define OHCI_CTRL_HCFS_RESUME (1 << OHCI_CTRL_HCFS_SHIFT)
+# define OHCI_CTRL_HCFS_OPER (2 << OHCI_CTRL_HCFS_SHIFT)
+# define OHCI_CTRL_HCFS_SUSPEND (3 << OHCI_CTRL_HCFS_SHIFT)
+#define OHCI_CTRL_IR (1 << 8) /* Bit 8: Interrupt routing */
+#define OHCI_CTRL_RWC (1 << 9) /* Bit 9: Remote wakeup connected */
+#define OHCI_CTRL_RWE (1 << 10) /* Bit 10: Remote wakeup enable */
+ /* Bits 11-31: Reserved */
+
+/* HcCommandStatus: HC command status (7.1.3) */
+
+#define OHCI_CMDST_HCR (1 << 0) /* Bit 0: Host controller reset */
+#define OHCI_CMDST_CLF (1 << 1) /* Bit 1: Control list filled */
+#define OHCI_CMDST_BLF (1 << 2) /* Bit 2: Bulk list filled */
+#define OHCI_CMDST_OCR (1 << 3) /* Bit 3: Ownership change request */
+ /* Bits 4-15: Reserved */
+#define OHCI_CMDST_SOC (3 << 16) /* Bit 16: Scheduling overrun count */
+ /* Bits 17-31: Reserved */
+
+/* HcInterruptStatus: HC interrupt status (7.1.4),
+ * HcInterruptEnable: HC interrupt enable (7.1.5), and
+ * HcInterruptDisable: HC interrupt disable (7.1.6)
+ */
+
+#define OHCI_INT_SO (1 << 0) /* Bit 0: Scheduling overrun */
+#define OHCI_INT_WDH (1 << 1) /* Bit 1: Writeback done head */
+#define OHCI_INT_SF (1 << 2) /* Bit 2: Start of frame */
+#define OHCI_INT_RD (1 << 3) /* Bit 3: Resume detected */
+#define OHCI_INT_UE (1 << 4) /* Bit 4: Unrecoverable error */
+#define OHCI_INT_FNO (1 << 5) /* Bit 5: Frame number overflow */
+#define OHCI_INT_RHSC (1 << 6) /* Bit 6: Root hub status change */
+ /* Bits 7-29: Reserved */
+#define OHCI_INT_OC (1 << 30) /* Bit 30: Ownership change */
+#define OHCI_INT_MIE (1 << 31) /* Bit 31: Master interrupt enable
+ * (Enable/disable only) */
+
+/* HcHCCA: HC communication area (7.2.1):
+ *
+ * 32-bits aligned to 256 byte boundary.
+ */
+
+/* HcPeriodCurrentED: Current isoc or int endpoint desc (7.2.2),
+ * HcControlHeadED: First EP desc in the control list (7.2.3),
+ * HcControlCurrentED: Current EP desc in the control list (7.2.4),
+ * HcBulkHeadED: First EP desc in the bulk list (7.2.5),
+ * HcBulkCurrentED: Current EP desc in the bulk list (7.2.6), and
+ * HcDoneHead: Last transfer desc added to DONE queue (7.2.7):
+ *
+ * All 32-bits aligned to an 8-byte boundary
+ */
+
+/* HcFmInterval: Bit time interval that would not cause overrun (7.3.1) */
+
+#define OHCI_FMINT_FI_SHIFT (0) /* Bits 0-13: Frame interval */
+#define OHCI_FMINT_FI_MASK (0x3fff << OHCI_FMINT_FI_SHIFT)
+ /* Bits 14-15: Reserved */
+#define OHCI_FMINT_FSMPS_SHIFT (16) /* Bits 16-30: FS largest packet data */
+#define OHCI_FMINT_FSMPS_MASK (0x7fff << OHCI_FMINT_FSMPS_SHIFT)
+#define OHCI_FMINT_FIT (1 << 31) /* Bit 31: Frame interval toggle */
+
+/* HcFmRemaining: Bit time remaining in current frame (7.3.2) */
+
+#define OHCI_FMREM_FR_SHIFT (0) /* Bits 0-13: Frame remaining */
+#define OHCI_FMREM_FR_MASK (0x3fff << OHCI_FMREM_FR_SHIFT)
+ /* Bits 16-30: Reserved */
+#define OHCI_FMINT_FRT (1 << 31) /* Bit 31: Frame remaining toggle */
+
+/* HcFmNumber: Frame number counter (7.3.3) */
+
+#define OHCI_FMNO_FI_SHIFT (0) /* Bits 0-15: Frame number */
+#define OHCI_FMNO_FI_MASK (0xffff << OHCI_FMINT_FI_SHIFT)
+ /* Bits 16-31: Reserved */
+
+/* HcPeriodicStart: Time to start processing periodic list (7.3.4) */
+
+#define OHCI_PERSTART_SHIFT (0) /* Bits 0-13: Periodic start */
+#define OHCI_PERSTART_MASK (0x3fff << OHCI_PERSTART_SHIFT)
+ /* Bits 14-31: Reserved */
+
+/* HcLSThreshold: Commit to transfer threshold (7.3.5) */
+
+#define OHCI_LSTHRES_SHIFT (0) /* Bits 0-11: LS threshold */
+#define OHCI_LSTHRES_MASK (0x0fff << OHCI_PERSTART_SHIFT)
+ /* Bits 12-31: Reserved */
+
+/* HcRhDescriptorN: Describes root hub (part A) (7.4.1) */
+
+#define OHCI_RHDESCA_NDP_SHIFT (0) /* Bits 0-7: Number downstream ports */
+#define OHCI_RHDESCA_NDP_MASK (0xff << OHCI_RHDESCA_NDP_SHIFT)
+#define OHCI_RHDESCA_PSM (1 << 8) /* Bit 8: Power switching mode */
+#define OHCI_RHDESCA_NPS (1 << 9) /* Bit 9: No power switching */
+#define OHCI_RHDESCA_DT (1 << 10) /* Bit 10: Device type */
+#define OHCI_RHDESCA_OCPM (1 << 11) /* Bit 11: Over current protection mode */
+#define OHCI_RHDESCA_NOCP (1 << 12) /* Bit 12: No over current protection */
+ /* Bits 13-23: Reserved */
+#define OHCI_RHDESCA_POTPGT_SHIFT (24) /* Bits 24-31: Power on to power good time */
+#define OHCI_RHDESCA_POTPGT_MASK (0xff << OHCI_RHDESCA_POTPGT_SHIFT)
+
+/* HcRhDescriptorB: Describes root hub (part B) (7.4.2) */
+
+#define OHCI_RHDESCB_DR_SHIFT (0) /* Bits 0-15: Device removable */
+#define OHCI_RHDESCB_DR_MASK (0xffff << OHCI_RHDESCB_DR_SHIFT)
+# define OHCI_RHDESCB_ATTACHED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n)))
+#define OHCI_RHDESCB_PPCM_SHIFT (16) /* Bits 16-31: Port power control mask */
+#define OHCI_RHDESCB_PPCM_MASK (0xffff << OHCI_RHDESCB_PPCM_SHIFT)
+# define OHCI_RHDESCB_POWERED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n)))
+
+/* HcRhStatus: Root hub status (7.4.3) */
+
+#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status (read)*/
+#define OHCI_RHSTATUS_CGP (1 << 0) /* Bit 0: Clear global power (write)*/
+#define OHCI_RHSTATUS_OCI (1 << 1) /* Bit 1: Over current indicator */
+ /* Bits 2-14: Reserved */
+#define OHCI_RHSTATUS_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */
+#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change (read) */
+#define OHCI_RHSTATUS_SGP (1 << 16) /* Bit 16: Set global power (write) */
+#define OHCI_RHSTATUS_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */
+ /* Bits 18-30: Reserved */
+#define OHCI_RHSTATUS_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */
+
+/* HcRhPortStatus: Root hub port status (7.4.4) */
+
+#define OHCI_RHPORTST_CCS (1 << 0) /* Bit 0: Current connect status */
+#define OHCI_RHPORTST_PES (1 << 1) /* Bit 1: Port enable status */
+#define OHCI_RHPORTST_PSS (1 << 2) /* Bit 2: Port suspend status */
+#define OHCI_RHPORTST_POCI (1 << 3) /* Bit 3: Port over current indicator */
+#define OHCI_RHPORTST_PRS (1 << 4) /* Bit 4: Port reset status */
+ /* Bits 5-7: Reserved */
+#define OHCI_RHPORTST_PPS (1 << 8) /* Bit 8: Port power status */
+#define OHCI_RHPORTST_LSDA (1 << 9) /* Bit 9: Low speed device attached */
+ /* Bits 10-15: Reserved */
+#define OHCI_RHPORTST_CSC (1 << 16) /* Bit 16: Connect status change */
+#define OHCI_RHPORTST_PESC (1 << 17) /* Bit 17: Port enable status change */
+#define OHCI_RHPORTST_PSSC (1 << 18) /* Bit 18: Port suspend status change */
+#define OHCI_RHPORTST_OCIC (1 << 19) /* Bit 19: Port over current indicator change */
+#define OHCI_RHPORTST_PRSC (1 << 20) /* Bit 20: Port reset status change */
+ /* Bits 21-31: Reserved */
+
+/* Transfer Descriptors *****************************************************/
+
+/* Endpoint Descriptor Offsets (4.2.1) */
+
+#define ED_CONTROL_OFFSET (0x00) /* ED status/control bits */
+#define ED_TAILP_OFFSET (0x04) /* TD Queue Tail Pointer (TailP) */
+#define ED_HEADP_OFFSET (0x08) /* TD Queue Head Pointer (HeadP) */
+#define ED_NEXTED_OFFSET (0x0c) /* Next Endpoint Descriptor (NextED) */
+
+/* Endpoint Descriptor Bit Definitions (4.2.2) */
+
+#define ED_CONTROL_FA_SHIFT (0) /* Bits 0-6: Function Address */
+#define ED_CONTROL_FA_MASK (0x7f << ED_CONTROL_FA_SHIFT)
+#define ED_CONTROL_EN_SHIFT (7) /* Bits 7-10: Endpoint number */
+#define ED_CONTROL_EN_MASK (15 << ED_CONTROL_EN_SHIFT)
+#define ED_CONTROL_D_SHIFT (11) /* Bits 11-12: Direction */
+#define ED_CONTROL_D_MASK (3 << ED_CONTROL_D_SHIFT)
+# define ED_CONTROL_D_TD1 (0 << ED_CONTROL_D_SHIFT) /* Get direction from TD */
+# define ED_CONTROL_D_OUT (1 << ED_CONTROL_D_SHIFT) /* OUT */
+# define ED_CONTROL_D_IN (2 << ED_CONTROL_D_SHIFT) /* IN */
+# define ED_CONTROL_D_TD2 (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */
+
+#define ED_CONTROL_S (1 << 13) /* Bit 13: Speed (low) */
+#define ED_CONTROL_K (1 << 14) /* Bit 14: Skip */
+#define ED_CONTROL_F (1 << 15) /* Bit 15: Format (isochronous) */
+#define ED_CONTROL_MPS_SHIFT (16) /* Bits 16-26: Maximum packet size */
+#define ED_CONTROL_MPS_MASK (0x7ff << ED_CONTROL_MPS_SHIFT)
+
+#define ED_HEADP_ADDR_SHIFT (0)
+#define ED_HEADP_ADDR_MASK 0xfffffff0
+#define ED_HEADP_H (1 << 0) /* Bit 0: Halted */
+#define ED_HEADP_C (1 << 1) /* Bit 1: Toggle carry */
+
+/* General Transfer Descriptor Offsets (4.3.1) */
+
+#define GTD_STATUS_OFFSET (0x00) /* TD status bits */
+#define GTD_CBP_OFFSET (0x04) /* Current Buffer Pointer (CBP) */
+#define GTD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */
+#define GTD_BE_OFFSET (0x0c) /* Buffer End (BE) */
+
+/* General Transfer Descriptor Bit Definitions */
+
+ /* Bits 0-17: Reserved */
+
+#define GTD_STATUS_R (1 << 18) /* Bit 18: Buffer rounding */
+#define GTD_STATUS_DP_SHIFT (19) /* Bits 19-20: Direction/PID */
+#define GTD_STATUS_DP_MASK (3 << GTD_STATUS_DP_SHIFT)
+# define GTD_STATUS_DP_SETUP (0 << GTD_STATUS_DP_SHIFT) /* To endpoint */
+# define GTD_STATUS_DP_OUT (1 << GTD_STATUS_DP_SHIFT) /* To endpoint */
+# define GTD_STATUS_DP_IN (2 << GTD_STATUS_DP_SHIFT) /* From endpoint */
+
+#define GTD_STATUS_DI_SHIFT (21) /* Bits 21-23: Delay input */
+#define GTD_STATUS_DI_MASK (7 << GTD_STATUS_DI_SHIFT)
+#define GTD_STATUS_T_SHIFT (24) /* Bits 24-25: Data Toggle */
+#define GTD_STATUS_T_MASK (3 << GTD_STATUS_T_SHIFT)
+# define GTD_STATUS_T_TOGGLE (0 << GTD_STATUS_T_SHIFT)
+# define GTD_STATUS_T_DATA0 (2 << GTD_STATUS_T_SHIFT)
+# define GTD_STATUS_T_DATA1 (3 << GTD_STATUS_T_SHIFT)
+#define GTD_STATUS_EC_SHIFT (26) /* Bits 26-27: Error count */
+#define GTD_STATUS_EC_MASK (3 << GTD_STATUS_EC_SHIFT)
+#define GTD_STATUS_CC_SHIFT (28) /* Bits 28-31: Condition code */
+#define GTD_STATUS_CC_MASK (15 << GTD_STATUS_CC_SHIFT)
+
+/* Isochronous Transfer Descriptor Offsets (4.3.2) */
+
+#define ITD_STATUS_OFFSET (0x00) /* TD status bits */
+#define ITD_BP0_OFFSET (0x04) /* Buffer page 0 (BP0) */
+#define ITD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */
+#define ITD_BE_OFFSET (0x0c) /* Buffer End (BE) */
+
+#define ITD_NPSW (8)
+#define ITD_PSW0_OFFSET (0x10) /* Offset0/PSW0 */
+#define ITD_PSW1_OFFSET (0x12) /* Offset1/PSW1 */
+#define ITD_PSW2_OFFSET (0x14) /* Offset2/PSW2 */
+#define ITD_PSW3_OFFSET (0x16) /* Offset3/PSW3 */
+#define ITD_PSW4_OFFSET (0x18) /* Offset4/PSW4 */
+#define ITD_PSW5_OFFSET (0x1a) /* Offset5/PSW5 */
+#define ITD_PSW6_OFFSET (0x1c) /* Offset6/PSW6 */
+#define ITD_PSW7_OFFSET (0x1e) /* Offset7/PSW7 */
+
+/* Condition codes (Table 4-7) */
+
+#define TD_CC_NOERROR 0x00
+#define TD_CC_CRC 0x01
+#define TD_CC_BITSTUFFING 0x02
+#define TD_CC_DATATOGGLEMISMATCH 0x03
+#define TD_CC_STALL 0x04
+#define TD_CC_DEVNOTRESPONDING 0x05
+#define TD_CC_PIDCHECKFAILURE 0x06
+#define TD_CC_UNEXPECTEDPID 0x07
+#define TD_CC_DATAOVERRUN 0x08
+#define TD_CC_DATAUNDERRUN 0x09
+#define TD_CC_BUFFEROVERRUN 0x0c
+#define TD_CC_BUFFERUNDERRUN 0x0d
+#define TD_CC_NOTACCESSED 0x0f
+
+#define TD_CC_USER 0x10 /* For use by OHCI drivers */
+
+/* Host Controller Communications Area Format (4.4.1) ***********************/
+
+/* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */
+
+#define HCCA_INTTBL_OFFSET (0x00)
+#define HCCA_INTTBL_WSIZE (32)
+#define HCCA_INTTBL_BSIZE (HCCA_INTTBL_WSIZE * 4)
+
+/* HccaFrameNumber: Current frame number */
+
+#define HCCA_FMNO_OFFSET (0x80)
+#define HCCA_FMNO_BSIZE (2)
+
+/* HccaPad1: Zero when frame no. updated */
+
+#define HCCA_PAD1_OFFSET (0x82)
+#define HCCA_PAD1_BSIZE (2)
+
+/* HccaDoneHead: When the HC reaches the end of a frame and its deferred
+ * interrupt register is 0, it writes the current value of its HcDoneHead to
+ * this location and generates an interrupt.
+ *
+ * The LSB of HCCADoneHead may be set to 1 to indicate that an unmasked
+ * HcInterruptStatus was set when HccaDoneHead was written.
+ */
+
+#define HCCA_DONEHEAD_OFFSET (0x84)
+#define HCCA_DONEHEAD_BSIZE (4)
+
+#define HCCA_DONEHEAD_MASK 0xfffffffe
+#define HCCA_DONEHEAD_INTSTA (1 << 0)
+
+/* 0x88: 116 bytes reserved */
+
+#define HCCA_RESERVED_OFFSET (0x88)
+#define HCCA_RESERVED_BSIZE (116)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ohci_hcor
+{
+ volatile uint32_t hcrevision; /* 0x00 */
+ volatile uint32_t hccontrol; /* 0x04 */
+ volatile uint32_t hccmdsts; /* 0x08 */
+ volatile uint32_t hcintsts; /* 0x0c */
+ volatile uint32_t hcinten; /* 0x10 */
+ volatile uint32_t hcintdis; /* 0x14 */
+ volatile uint32_t hchcca; /* 0x18 */
+ volatile uint32_t hcperiodcurrented; /* 0x1c */
+ volatile uint32_t hccontrolheaded; /* 0x20 */
+ volatile uint32_t hccontrolcurrented; /* 0x24 */
+ volatile uint32_t hcbulkheaded; /* 0x28 */
+ volatile uint32_t hcbulkcurrented; /* 0x2c */
+ volatile uint32_t hcdonehead; /* 0x30 */
+ volatile uint32_t hcfminterval; /* 0x34 */
+ volatile uint32_t hcfmremaining; /* 0x38 */
+ volatile uint32_t hcfmnumber; /* 0x3c */
+ volatile uint32_t hcperiodicstart; /* 0x40 */
+ volatile uint32_t hclsthreshold; /* 0x44 */
+ volatile uint32_t hcrhdescriptora; /* 0x48 */
+ volatile uint32_t hcrhdescriptorb; /* 0x4c */
+ volatile uint32_t hcrhsts; /* 0x50 */
+ volatile uint32_t hcrhportsts[15]; /* 0x54 */
+};
+
+/* Endpoint Descriptor Offsets (4.2.1) */
+
+struct ohci_ed_s
+{
+ volatile uint32_t ctrl; /* ED status/control bits */
+ volatile uint32_t tailp; /* TD Queue Tail Pointer (TailP) */
+ volatile uint32_t headp; /* TD Queue Head Pointer (HeadP) */
+ volatile uint32_t nexted; /* Next Endpoint Descriptor (NextED) */
+};
+
+/* General Transfer Descriptor (4.3.1) */
+
+struct ohci_gtd_s
+{
+ volatile uint32_t ctrl; /* TD status/control bits */
+ volatile uint32_t cbp; /* Current Buffer Pointer (CBP) */
+ volatile uint32_t nexttd; /* Next TD (NextTD) */
+ volatile uint32_t be; /* Buffer End (BE) */
+};
+
+/* Isochronous Transfer Descriptor Offsets (4.3.2) */
+
+struct ohci_itd_s
+{
+ volatile uint32_t ctrl; /* TD status/control bits */
+ volatile uint32_t bp0; /* Buffer page 0 (BP0 */
+ volatile uint32_t nexttd; /* Next TD (NextTD) */
+ volatile uint32_t be; /* Buffer End (BE) */
+ volatile uint16_t psw[ITD_NPSW]; /* Offset/PSW */
+};
+
+/* Host Controller Communications Area Format (4.4.1) */
+
+struct ohci_hcca_s
+{
+ /* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */
+
+ volatile uint32_t inttbl[HCCA_INTTBL_WSIZE];
+
+ /* HccaFrameNumber: Current frame number and
+ * HccaPad1: Zero when frame no. updated
+ */
+
+ volatile uint16_t fmno;
+ volatile uint16_t pad1;
+
+ /* HccaDoneHead: When the HC reaches the end of a frame and its deferred
+ * interrupt register is 0, it writes the current value of its HcDoneHead
+ * to this location and generates an interrupt.
+ */
+
+ volatile uint32_t donehead;
+ volatile uint8_t reserved[HCCA_RESERVED_BSIZE];
+ volatile uint32_t extra;
+} __attribute__((aligned(256)));
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_USB_OHCI_H */
diff --git a/components/drivers/usb/cherryusb/port/xhci/phytium/README.md b/components/drivers/usb/cherryusb/port/xhci/phytium/README.md
new file mode 100644
index 0000000000..4eb67580e4
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/xhci/phytium/README.md
@@ -0,0 +1,70 @@
+# USB 3.0 Host 控制器 (XHCI)
+
+- Phytium PI 和 Phyium E2000 系列开发板提供符合 XHCI 1.1 规范的 USB 3.0 Host 控制器, 其它 Phytium 系列平台可以通过 PCIe 扩展卡获得 XHCI 控制器
+- 相关的使用例程可以在 Phytium PI(飞腾派)、E2000 D/Q Demo 板以及 D2000 和后续平台上运行,例程包括
+
+---------------------------------------------
+
+- FreeRTOS
+
+- - 1. [XHCI 平台控制器使用鼠标/键盘/U盘功能](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_platform/README.md)
+- - 2. [XHCI PCIe控制器使用鼠标/键盘/U盘功能](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_pcie/README.md)
+- - 3. [LVGL 中使用 XHCI 平台控制器连接的鼠标/键盘/U盘](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/blob/master/example/peripheral/media/lvgl_indev/README.md)
+
+---------------------------------------------
+
+- RT-Thread
+
+- - 1. [XHCI 平台控制器识别鼠标/键盘/U盘](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md)
+
+---------------------------------------------
+
+- Standalone 裸机
+
+- - 暂不支持
+
+---------------------------------------------
+
+- XHCI 的驱动功能以静态库的方式提供,仅限在 Phytium 系列 CPU 平台使用,
+
+- - libxhci_a64.a : AARCH64 驱动库
+- - libxhci_a32_hardfp.a : AARCH32 驱动库,使用硬浮点
+- - libxhci_a32_softfp.a : AARCH32 驱动库,使用软浮点
+
+需要获取源代码请联系 `opensource_embedded@phytium.com.cn` 获取,如需移植运行到非 Phytium 系列 CPU 平台请提前联系`opensource_embedded@phytium.com.cn`获得允许
+
+# USB 3.0 Host Controller (XHCI)
+
+- The Phytium PI and Phytium E2000 series development boards provide USB 3.0 Host controllers that conform to the XHCI 1.1 specification. Other Phytium series platforms can obtain XHCI controllers through PCIe expansion cards.
+- Related example routines can be run on Phytium PI (Fetion Pi), E2000 D/Q Demo boards, and D2000 and later platforms. Examples include:
+
+---------------------------------------------
+
+- FreeRTOS
+
+ - 1. [XHCI platform controller for mouse/keyboard/USB drive functions](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_platform/README.md)
+ - 2. [XHCI PCIe controller for mouse/keyboard/USB drive functions](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_pcie/README.md)
+ - 3. [Using XHCI platform controller-connected mouse/keyboard/USB drive in LVGL](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/blob/master/example/peripheral/media/lvgl_indev/README.md)
+
+---------------------------------------------
+
+- RT-Thread
+
+ - 1. [XHCI platform controller recognizing mouse/keyboard/USB drive](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md)
+
+---------------------------------------------
+
+- Standalone (Bare Metal)
+
+ - Not supported yet
+
+---------------------------------------------
+
+- This XHCI driver functionality is provided as a static library and is only available for Phytium series CPU platforms.
+
+ - - `libxhci_a64.a` : Driver library for AARCH64
+ - - `libxhci_a32_hardfp.a` : Driver library for AARCH32, using hard floating point
+ - - `libxhci_a32_softfp.a` : Driver library for AARCH32, using soft floating point
+
+- To obtain the source code, please contact `opensource_embedded@phytium.com.cn`.
+- For porting to non-Phytium CPU platforms, shall contact `opensource_embedded@phytium.com.cn` in advance for permission.
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_config.h b/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_config.h
new file mode 100644
index 0000000000..460d12410b
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_config.h
@@ -0,0 +1,289 @@
+/*
+ * Copyright : (C) 2024 Phytium Information Technology, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Modify History:
+ * Ver Who Date Changes
+ * ----- ------ -------- --------------------------------------
+ * 1.0 zhugengyu 2024/6/26 first commit
+ */
+#ifndef CHERRYUSB_CONFIG_H
+#define CHERRYUSB_CONFIG_H
+
+#include "rtthread.h"
+
+/* ================ USB common Configuration ================ */
+
+#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)
+
+void *xhci_mem_malloc(size_t align, size_t size);
+void xhci_mem_free(void *ptr);
+
+#define XHCI_DCACHE_FLUSH (1 << 0)
+#define XHCI_DCACHE_INVALIDATE (1 << 1)
+void xhci_dcache_sync(void *ptr, size_t len, uint32_t flags);
+
+unsigned long usb_hc_get_register_base(uint32_t id);
+
+#define usb_malloc(size) xhci_mem_malloc(sizeof(int), size)
+#define usb_free(ptr) xhci_mem_free(ptr)
+
+#ifndef CONFIG_USB_DBG_LEVEL
+#if defined(CONFIG_LOG_ERROR)
+#define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR
+#elif defined(CONFIG_LOG_WARN)
+#define CONFIG_USB_DBG_LEVEL USB_DBG_WARNING
+#elif defined(CONFIG_LOG_INFO)
+#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
+#elif defined(CONFIG_LOG_DEBUG) || defined(CONFIG_LOG_VERBOS)
+#define CONFIG_USB_DBG_LEVEL USB_DBG_LOG
+#else
+#define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR
+#endif
+#endif
+
+/* Enable print with color */
+#define CONFIG_USB_PRINTF_COLOR_ENABLE
+
+/* data align size when use dma */
+#ifndef CONFIG_USB_ALIGN_SIZE
+#define CONFIG_USB_ALIGN_SIZE 4
+#endif
+
+/* attribute data into no cache ram */
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
+
+/* ================= USB Device Stack Configuration ================ */
+
+/* Ep0 in and out transfer buffer */
+#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
+#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512
+#endif
+
+/* Setup packet log for debug */
+// #define CONFIG_USBDEV_SETUP_LOG_PRINT
+
+/* Send ep0 in data from user buffer instead of copying into ep0 reqdata
+ * Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE
+*/
+// #define CONFIG_USBDEV_EP0_INDATA_NO_COPY
+
+/* Check if the input descriptor is correct */
+// #define CONFIG_USBDEV_DESC_CHECK
+
+/* Enable test mode */
+// #define CONFIG_USBDEV_TEST_MODE
+
+#ifndef CONFIG_USBDEV_MSC_MAX_LUN
+#define CONFIG_USBDEV_MSC_MAX_LUN 1
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_MAX_BUFSIZE
+#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 512
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
+#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
+#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
+#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
+#endif
+
+// #define CONFIG_USBDEV_MSC_THREAD
+
+#ifndef CONFIG_USBDEV_MSC_PRIO
+#define CONFIG_USBDEV_MSC_PRIO 4
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_STACKSIZE
+#define CONFIG_USBDEV_MSC_STACKSIZE 2048
+#endif
+
+#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
+#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
+#endif
+
+/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/
+#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
+#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
+#endif
+
+#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
+#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff
+#endif
+
+#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC
+#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
+#endif
+
+#define CONFIG_USBDEV_RNDIS_USING_LWIP
+
+/* ================ USB HOST Stack Configuration ================== */
+
+#define CONFIG_USBHOST_MAX_RHPORTS 8
+#define CONFIG_USBHOST_MAX_EXTHUBS 4
+#define CONFIG_USBHOST_MAX_EHPORTS 8
+#define CONFIG_USBHOST_MAX_INTERFACES 8
+#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
+#define CONFIG_USBHOST_MAX_ENDPOINTS 8
+
+#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
+#define CONFIG_USBHOST_MAX_HID_CLASS 4
+#define CONFIG_USBHOST_MAX_MSC_CLASS 2
+#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
+#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
+
+#define CONFIG_USBHOST_DEV_NAMELEN 16
+
+#ifndef CONFIG_USBHOST_PSC_PRIO
+#define CONFIG_USBHOST_PSC_PRIO 0
+#endif
+#ifndef CONFIG_USBHOST_PSC_STACKSIZE
+#define CONFIG_USBHOST_PSC_STACKSIZE 8192
+#endif
+
+//#define CONFIG_USBHOST_GET_STRING_DESC
+
+// #define CONFIG_USBHOST_MSOS_ENABLE
+#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE
+#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00
+#endif
+
+/* Ep0 max transfer buffer */
+#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
+#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
+#endif
+
+#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
+#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
+#endif
+
+#ifndef CONFIG_USBHOST_MSC_TIMEOUT
+#define CONFIG_USBHOST_MSC_TIMEOUT 0xffffffff
+#endif
+
+#ifndef CONFIG_INPUT_MOUSE_WHEEL
+#define CONFIG_INPUT_MOUSE_WHEEL
+#endif
+
+/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
+ * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
+ */
+#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE
+#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048)
+#endif
+
+/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
+#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE
+#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048)
+#endif
+
+/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
+ * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
+ */
+#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE
+#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048)
+#endif
+/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
+#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE
+#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048)
+#endif
+
+/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
+ * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
+ */
+#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE
+#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048)
+#endif
+/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
+#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE
+#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048)
+#endif
+
+/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
+ * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
+ */
+#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE
+#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048)
+#endif
+/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
+#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE
+#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048)
+#endif
+
+#define CONFIG_USBHOST_BLUETOOTH_HCI_H4
+// #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG
+
+#ifndef CONFIG_USBHOST_BLUETOOTH_TX_SIZE
+#define CONFIG_USBHOST_BLUETOOTH_TX_SIZE 2048
+#endif
+#ifndef CONFIG_USBHOST_BLUETOOTH_RX_SIZE
+#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048
+#endif
+
+/* ================ USB Device Port Configuration ================*/
+
+#ifndef CONFIG_USBDEV_MAX_BUS
+#define CONFIG_USBDEV_MAX_BUS 2 // for now, bus num must be 1 except hpm ip
+#endif
+
+#ifndef CONFIG_USBDEV_EP_NUM
+#define CONFIG_USBDEV_EP_NUM 8
+#endif
+
+/* ---------------- FSDEV Configuration ---------------- */
+//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
+
+/* ---------------- DWC2 Configuration ---------------- */
+// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
+// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
+// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4)
+// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
+// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
+// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4)
+// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4)
+// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
+// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
+// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
+
+/* ---------------- MUSB Configuration ---------------- */
+// #define CONFIG_USB_MUSB_SUNXI
+
+/* ================ USB Host Port Configuration ==================*/
+#ifndef CONFIG_USBHOST_MAX_BUS
+#define CONFIG_USBHOST_MAX_BUS 2
+#endif
+
+#ifndef CONFIG_USBHOST_PIPE_NUM
+#define CONFIG_USBHOST_PIPE_NUM 10
+#endif
+
+/* ---------------- EHCI Configuration ---------------- */
+
+#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0)
+#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
+#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
+#define CONFIG_USB_EHCI_QTD_NUM 3
+#define CONFIG_USB_EHCI_ITD_NUM 20
+// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
+// #define CONFIG_USB_EHCI_CONFIGFLAG
+// #define CONFIG_USB_EHCI_ISO
+// #define CONFIG_USB_EHCI_WITH_OHCI
+
+/* ---------------- OHCI Configuration ---------------- */
+#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0)
+
+/* ---------------- XHCI Configuration ---------------- */
+#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
+
+#ifndef CONFIG_USB_XHCI_ENABLE_SOFT_ISR
+#define CONFIG_USB_XHCI_ENABLE_SOFT_ISR 0
+#endif
+
+#endif
diff --git a/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium.c b/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium.c
new file mode 100644
index 0000000000..1f72f313b8
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright : (C) 2024 Phytium Information Technology, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Modify History:
+ * Ver Who Date Changes
+ * ----- ------ -------- --------------------------------------
+ * 1.0 zhugengyu 2024/6/26 first commit
+ */
+#include "rtthread.h"
+#include "usbh_core.h"
+
+#include "usb_config.h"
+
+void usb_hc_setup_xhci_interrupt(uint32_t id);
+void usb_hc_revoke_xhci_interrupt(uint32_t id);
+
+void *xhci_mem_malloc(size_t align, size_t size)
+{
+ void *result = rt_malloc_align(size, align);
+
+ if (result)
+ {
+ memset(result, 0U, size);
+ }
+
+ return result;
+}
+
+void xhci_mem_free(void *ptr)
+{
+ if (NULL != ptr)
+ {
+ rt_free(ptr);
+ }
+}
+
+void xhci_dcache_sync(void *ptr, size_t len, uint32_t flags)
+{
+ if (flags & XHCI_DCACHE_FLUSH)
+ {
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, ptr, len);
+ }
+ else if (flags & XHCI_DCACHE_INVALIDATE)
+ {
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, ptr, len);
+ }
+}
+
+void usb_assert(const char *filename, int linenum)
+{
+ rt_assert_handler("", filename, linenum);
+}
+
+void usb_hc_low_level_init(struct usbh_bus *bus)
+{
+ /* platform XHCI controller */
+ usb_hc_setup_xhci_interrupt(bus->busid);
+}
+
+void usb_hc_low_level_deinit(struct usbh_bus *bus)
+{
+ usb_hc_revoke_xhci_interrupt(bus->busid);
+}
\ No newline at end of file
diff --git a/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c b/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c
new file mode 100644
index 0000000000..5847eefc8c
--- /dev/null
+++ b/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright : (C) 2024 Phytium Information Technology, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Modify History:
+ * Ver Who Date Changes
+ * ----- ------ -------- --------------------------------------
+ * 1.0 zhugengyu 2024/6/26 first commit
+ */
+#include "rtthread.h"
+#include "interrupt.h"
+
+#include "fparameters.h"
+
+void USBH_IRQHandler(uint8_t busid);
+
+static void usb_hc_xhci_interrupt_handler(int irqno, void *param)
+{
+ if (irqno == FUSB3_0_IRQ_NUM) {
+ USBH_IRQHandler(FUSB3_ID_0);
+ } else if (irqno == FUSB3_1_IRQ_NUM) {
+ USBH_IRQHandler(FUSB3_ID_1);
+ }
+}
+
+void usb_hc_setup_xhci_interrupt(uint32_t id)
+{
+ uint32_t irq_num = (id == FUSB3_ID_0) ? FUSB3_0_IRQ_NUM : FUSB3_1_IRQ_NUM;
+ rt_hw_interrupt_set_priority(irq_num, 0xd0);
+ rt_hw_interrupt_install(irq_num, usb_hc_xhci_interrupt_handler,
+ NULL, "xhci");
+ rt_hw_interrupt_umask(irq_num);
+}
+
+void usb_hc_revoke_xhci_interrupt(uint32_t id)
+{
+ uint32_t irq_num = (id == FUSB3_ID_0) ? FUSB3_0_IRQ_NUM : FUSB3_1_IRQ_NUM;
+
+ rt_hw_interrupt_mask(irq_num);
+}
+
+unsigned long usb_hc_get_register_base(uint32_t id)
+{
+ if (FUSB3_ID_0 == id)
+ return FUSB3_0_BASE_ADDR + FUSB3_XHCI_OFFSET;
+ else
+ return FUSB3_1_BASE_ADDR + FUSB3_XHCI_OFFSET;
+}
\ No newline at end of file