Update cherryusb to v1.3.1 (#9122)

* fix(hpmicro): remove duplicate usb variable

* update(cherryusb): update to v1.3.1
This commit is contained in:
sakumisu
2024-06-30 08:01:51 +08:00
committed by GitHub
parent c018a3e3fd
commit cc853de5f3
74 changed files with 7278 additions and 2731 deletions
@@ -111,12 +111,6 @@ SECTIONS
KEEP (*(.fini))
. = ALIGN(8);
/* section information for usbh class */
. = ALIGN(8);
__usbh_class_info_start__ = .;
KEEP(*(.usbh_class_info))
__usbh_class_info_end__ = .;
/*********************************************
*
* RT-Thread related sections - Start
+13 -7
View File
@@ -36,12 +36,16 @@ if RT_USING_CHERRYUSB
bool "dwc2_at"
config RT_CHERRYUSB_DEVICE_DWC2_GD
bool "dwc2_gd"
config RT_CHERRYUSB_DEVICE_DWC2_HC
bool "dwc2_hc"
config RT_CHERRYUSB_DEVICE_DWC2_CUSTOM
bool "dwc2_custom"
config RT_CHERRYUSB_DEVICE_MUSB_STANDARD
bool "musb_standard"
config RT_CHERRYUSB_DEVICE_MUSB_ES
bool "musb_es"
config RT_CHERRYUSB_DEVICE_MUSB_SUNXI
bool "musb_sunxi"
config RT_CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config RT_CHERRYUSB_DEVICE_BL
@@ -170,10 +174,12 @@ if RT_USING_CHERRYUSB
bool "dwc2_esp"
config RT_CHERRYUSB_HOST_DWC2_CUSTOM
bool "dwc2_custom"
config RT_CHERRYUSB_HOST_MUSB_STANDARD
bool "musb_standard"
config RT_CHERRYUSB_HOST_MUSB_ES
bool "musb_es"
config RT_CHERRYUSB_HOST_MUSB_SUNXI
bool "musb_sunxi"
config RT_CHERRYUSB_HOST_MUSB_BK
bool "musb_bk"
config RT_CHERRYUSB_HOST_MUSB_CUSTOM
bool "musb_custom"
config RT_CHERRYUSB_HOST_PUSB2
@@ -242,7 +248,7 @@ if RT_USING_CHERRYUSB
prompt "Enable usb asix driver"
select RT_USING_LWIP
select RT_USING_LWIP212
select CONFIG_USBHOST_PLATFORM_CDC_ASIX
select CONFIG_USBHOST_PLATFORM_ASIX
default n
config RT_CHERRYUSB_HOST_RTL8152
@@ -250,7 +256,7 @@ if RT_USING_CHERRYUSB
prompt "Enable usb rtl8152 driver"
select RT_USING_LWIP
select RT_USING_LWIP212
select CONFIG_USBHOST_PLATFORM_CDC_RTL8152
select CONFIG_USBHOST_PLATFORM_RTL8152
default n
config RT_CHERRYUSB_HOST_FTDI
@@ -285,7 +291,7 @@ if RT_USING_CHERRYUSB
config CONFIG_USBHOST_PLATFORM_ASIX
bool
config CONFIG_USBHOST_PLATFORM_RTL152
config CONFIG_USBHOST_PLATFORM_RTL8152
bool
config CHERRYUSB_HOST_TEMPLATE
@@ -36,12 +36,16 @@ if CHERRYUSB
bool "dwc2_at"
config CHERRYUSB_DEVICE_DWC2_GD
bool "dwc2_gd"
config CHERRYUSB_DEVICE_DWC2_HC
bool "dwc2_hc"
config CHERRYUSB_DEVICE_DWC2_CUSTOM
bool "dwc2_custom"
config CHERRYUSB_DEVICE_MUSB_STANDARD
bool "musb_standard"
config CHERRYUSB_DEVICE_MUSB_ES
bool "musb_es"
config CHERRYUSB_DEVICE_MUSB_SUNXI
bool "musb_sunxi"
config CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_DEVICE_BL
@@ -168,12 +172,16 @@ if CHERRYUSB
bool "dwc2_st"
config CHERRYUSB_HOST_DWC2_ESP
bool "dwc2_esp"
config CHERRYUSB_HOST_DWC2_HC
bool "dwc2_hc"
config CHERRYUSB_HOST_DWC2_CUSTOM
bool "dwc2_custom"
config CHERRYUSB_HOST_MUSB_STANDARD
bool "musb_standard"
config CHERRYUSB_HOST_MUSB_ES
bool "musb_es"
config CHERRYUSB_HOST_MUSB_SUNXI
bool "musb_sunxi"
config CHERRYUSB_HOST_MUSB_BK
bool "musb_bk"
config CHERRYUSB_HOST_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_HOST_PUSB2
@@ -274,7 +282,7 @@ if CHERRYUSB
config USBHOST_PLATFORM_ASIX
bool
config USBHOST_PLATFORM_RTL152
config USBHOST_PLATFORM_RTL8152
bool
config CHERRYUSB_HOST_TEMPLATE
@@ -295,7 +303,7 @@ if CHERRYUSB
depends on CHERRYUSB_HOST_HID
config TEST_USBH_MSC
int
prompt "demo for test msc, do not enable because it has used dfs instead"
prompt "demo for test msc"
default 0
depends on CHERRYUSB_HOST_MSC
endif
+21 -16
View File
@@ -94,8 +94,8 @@ CherryUSB Host Stack has the following functions
- Support Communication Device Class (CDC_ACM, CDC_ECM)
- Support Human Interface Device (HID)
- Support Mass Storage Class (MSC)
- Support USB Video CLASS (commercial charge)
- Support USB Audio CLASS (commercial charge)
- Support USB Video CLASS (UVC1.0、UVC1.5)
- Support USB Audio CLASS (UAC1.0)
- Support Remote NDIS (RNDIS)
- Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm)
- Support Vendor class
@@ -115,7 +115,7 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2):
|usbh_hid.c | ~1000 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~3700 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~3100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~3900 | 4096 + 2 * 2048 | sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_rndis.c | ~3900 | 4096 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2500 | 2 * 1514 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_bluetooth.c | ~2300 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
@@ -148,7 +148,7 @@ Only standard and commercial USB IP are listed.
| OHCI(intel) | none | OHCI | × |
| EHCI(intel) | none | EHCI | √ |
| XHCI(intel) | none | XHCI | √ |
| UHCI(intel) | none | UHCI | × |
| UHCI(intel) | none | UHCI | × |
| DWC2(synopsys) | DWC2 | DWC2 | √ |
| MUSB(mentor) | MUSB | MUSB | √ |
| FOTG210(faraday)| FOTG210 | EHCI | √ |
@@ -173,17 +173,22 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|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 |
|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 |
|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 |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|<= v0.10.2 | No more updated |
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
|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 |
|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 |
|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 |
|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 |
## Commercial Support
Refer to https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html.
## Contact
@@ -193,4 +198,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
Thanks to the following companies for their support (in no particular order).
<img src="docs/assets/bouffalolab.jpg" width="100" height="100"/> <img src="docs/assets/hpmicro.jpg" width="100" height="100" /> <img src="docs/assets/eastsoft.jpg" width="100" height="100" /> <img src="docs/assets/rtthread.jpg" width="100" height="100" /> <img src="docs/assets/sophgo.jpg" width="100" height="100" /> <img src="docs/assets/phytium.jpg" width="100" height="100" /> <img src="docs/assets/thead.jpg" width="100" height="100" /> <img src="docs/assets/nuvoton.jpg" width="100" height="100" /> <img src="docs/assets/artinchip.jpg" width="100" height="100" />
<img src="docs/assets/bouffalolab.jpg" width="100" height="100"/> <img src="docs/assets/hpmicro.jpg" width="100" height="100" /> <img src="docs/assets/eastsoft.jpg" width="100" height="100" /> <img src="docs/assets/rtthread.jpg" width="100" height="100" /> <img src="docs/assets/sophgo.jpg" width="100" height="100" /> <img src="docs/assets/phytium.jpg" width="100" height="100" /> <img src="docs/assets/thead.jpg" width="100" height="100" /> <img src="docs/assets/nuvoton.jpg" width="100" height="100" /> <img src="docs/assets/artinchip.jpg" width="100" height="100" /> <img src="docs/assets/bekencorp.jpg" width="100" height="100" />
+22 -17
View File
@@ -94,8 +94,8 @@ CherryUSB Host 协议栈当前实现以下功能:
- 支持 Communication Device Class (CDC_ACM, CDC_ECM)
- 支持 Human Interface Device (HID)
- 支持 Mass Storage Class (MSC)
- Support USB Video CLASS(商业收费)
- Support USB Audio CLASS(商业收费)
- Support USB Video CLASS (UVC1.0、UVC1.5)
- Support USB Audio CLASS (UAC1.0)
- 支持 Remote NDIS (RNDIS)
- 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能)
- 支持 Vendor 类 class
@@ -115,7 +115,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2):
|usbh_hid.c | ~1000 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~3700 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~3100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~3900 | 4096 + 2 * 2048 | sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_rndis.c | ~3900 | 4096 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2500 | 2 * 1514 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_bluetooth.c | ~2300 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
@@ -148,7 +148,7 @@ x 受以下宏影响:
| OHCI(intel) | none | OHCI | × |
| EHCI(intel) | none | EHCI | √ |
| XHCI(intel) | none | XHCI | √ |
| UHCI(intel) | none | UHCI | × |
| UHCI(intel) | none | UHCI | × |
| DWC2(synopsys) | DWC2 | DWC2 | √ |
| MUSB(mentor) | MUSB | MUSB | √ |
| FOTG210(faraday)| FOTG210 | EHCI | √ |
@@ -174,19 +174,24 @@ CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|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 |
|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 |
|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 |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|<= v0.10.2 | No more updated |
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
|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 |
|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 |
|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 |
|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 |
## Contact
## 商业支持
参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html。
## 联系
CherryUSB QQ 群:642693751
CherryUSB 微信群:与我联系后邀请加入
@@ -195,4 +200,4 @@ CherryUSB 微信群:与我联系后邀请加入
感谢以下企业支持(顺序不分先后)。
<img src="docs/assets/bouffalolab.jpg" width="100" height="100"/> <img src="docs/assets/hpmicro.jpg" width="100" height="100" /> <img src="docs/assets/eastsoft.jpg" width="100" height="100" /> <img src="docs/assets/rtthread.jpg" width="100" height="100" /> <img src="docs/assets/sophgo.jpg" width="100" height="100" /> <img src="docs/assets/phytium.jpg" width="100" height="100" /> <img src="docs/assets/thead.jpg" width="100" height="100" /> <img src="docs/assets/nuvoton.jpg" width="100" height="100" /> <img src="docs/assets/artinchip.jpg" width="100" height="100" />
<img src="docs/assets/bouffalolab.jpg" width="100" height="100"/> <img src="docs/assets/hpmicro.jpg" width="100" height="100" /> <img src="docs/assets/eastsoft.jpg" width="100" height="100" /> <img src="docs/assets/rtthread.jpg" width="100" height="100" /> <img src="docs/assets/sophgo.jpg" width="100" height="100" /> <img src="docs/assets/phytium.jpg" width="100" height="100" /> <img src="docs/assets/thead.jpg" width="100" height="100" /> <img src="docs/assets/nuvoton.jpg" width="100" height="100" /> <img src="docs/assets/artinchip.jpg" width="100" height="100" /> <img src="docs/assets/bekencorp.jpg" width="100" height="100" />
+16 -3
View File
@@ -40,13 +40,20 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_GD']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
src += Glob('port/dwc2/usb_glue_gd.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_HC']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
src += Glob('port/dwc2/usb_glue_hc.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_CUSTOM']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_STANDARD']):
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_ES']):
src += Glob('port/musb/usb_dc_musb.c')
src += Glob('port/musb/usb_glue_es.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_SUNXI']):
src += Glob('port/musb/usb_dc_musb.c')
src += Glob('port/musb/usb_glue_sunxi.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_BK']):
src += Glob('port/musb/usb_dc_musb.c')
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_BL']):
@@ -151,9 +158,15 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
src += Glob('port/dwc2/usb_hc_dwc2.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_STANDARD']):
src += Glob('port/musb/usb_hc_musb.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_ES']):
src += Glob('port/musb/usb_hc_musb.c')
src += Glob('port/musb/usb_glue_es.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_SUNXI']):
src += Glob('port/musb/usb_hc_musb.c')
src += Glob('port/musb/usb_glue_sunxi.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_BK']):
src += Glob('port/musb/usb_hc_musb.c')
src += Glob('port/musb/usb_glue_bk.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_CUSTOM']):
src += Glob('port/musb/usb_hc_musb.c')
@@ -197,8 +210,8 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
if GetDepend('RT_CHERRYUSB_HOST_CDC_ECM') \
or GetDepend('RT_CHERRYUSB_HOST_CDC_RNDIS') \
or GetDepend('RT_CHERRYUSB_HOST_CDC_NCM') \
or GetDepend('RT_CHERRYUSB_HOST_CDC_ASIX') \
or GetDepend('RT_CHERRYUSB_HOST_CDC_RTL8152'):
or GetDepend('RT_CHERRYUSB_HOST_ASIX') \
or GetDepend('RT_CHERRYUSB_HOST_RTL8152'):
src += Glob('platform/rtthread/usbh_lwip.c')
src += Glob('platform/rtthread/usb_msh.c')
+1 -1
View File
@@ -1,5 +1,5 @@
VERSION_MAJOR = 1
VERSION_MINOR = 3
PATCHLEVEL = 0
PATCHLEVEL = 1
VERSION_TWEAK = 0
EXTRAVERSION = 0
@@ -71,26 +71,39 @@ if(CONFIG_CHERRYUSB_DEVICE)
endif()
if(DEFINED CONFIG_CHERRYUSB_DEVICE_DCD)
if("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "dwc2_st")
if("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "fsdev")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/fsdev/usb_dc_fsdev.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "dwc2_st")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_dc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_st.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "dwc2_esp")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_dc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_esp.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "dwc2_aic")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_dc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_aic.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "dwc2_at")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_dc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_at.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "fsdev")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/fsdev/usb_dc_fsdev.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "dwc2_gd")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_dc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_gd.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "dwc2_hc")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_dc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_hc.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "musb_es")
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_es.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "musb_sunxi")
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_sunxi.c)
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 "hpm")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpm/usb_dc_hpm.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "bl")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/bouffalolab/usb_dc_bl.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "musb")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "aic")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic_ll.c)
endif()
endif()
@@ -223,8 +236,18 @@ if(CONFIG_CHERRYUSB_HOST)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "dwc2_esp")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_hc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_esp.c)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "musb")
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "dwc2_hc")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_hc_dwc2.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/dwc2/usb_glue_hc.c)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "musb_es")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_es.c)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "musb_sunxi")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_sunxi.c)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "musb_bk")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
endif()
endif()
@@ -6,8 +6,8 @@
#ifndef CHERRYUSB_CONFIG_H
#define CHERRYUSB_CONFIG_H
#define CHERRYUSB_VERSION 0x010300
#define CHERRYUSB_VERSION_STR "v1.3.0"
#define CHERRYUSB_VERSION 0x010301
#define CHERRYUSB_VERSION_STR "v1.3.1"
/* ================ USB common Configuration ================ */
@@ -168,6 +168,17 @@
#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.
*/
@@ -203,7 +214,11 @@
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
/* ---------------- DWC2 Configuration ---------------- */
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
*/
// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
/* IN Endpoints Max packet Size / 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)
@@ -57,7 +57,7 @@ static void usbh_audio_class_free(struct usbh_audio *audio_class)
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq)
{
struct usb_setup_packet *setup = audio_class->hport->setup;
struct usb_setup_packet *setup;
struct usb_endpoint_descriptor *ep_desc;
uint8_t mult;
uint16_t mps;
@@ -65,6 +65,11 @@ int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t s
uint8_t intf = 0xff;
uint8_t altsetting = 1;
if (!audio_class || !audio_class->hport) {
return -USB_ERR_INVAL;
}
setup = audio_class->hport->setup;
if (audio_class->is_opened) {
return 0;
}
@@ -129,12 +134,17 @@ freq_found:
int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
{
struct usb_setup_packet *setup = audio_class->hport->setup;
struct usb_setup_packet *setup;
struct usb_endpoint_descriptor *ep_desc;
int ret;
uint8_t intf = 0xff;
uint8_t altsetting = 1;
if (!audio_class || !audio_class->hport) {
return -USB_ERR_INVAL;
}
setup = audio_class->hport->setup;
for (size_t i = 0; i < audio_class->module_num; i++) {
if (strcmp(name, audio_class->module[i].name) == 0) {
intf = audio_class->module[i].data_intf;
@@ -172,12 +182,17 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume)
{
struct usb_setup_packet *setup = audio_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
uint8_t intf = 0xff;
uint8_t feature_id = 0xff;
uint16_t volume_hex;
if (!audio_class || !audio_class->hport) {
return -USB_ERR_INVAL;
}
setup = audio_class->hport->setup;
for (size_t i = 0; i < audio_class->module_num; i++) {
if (strcmp(name, audio_class->module[i].name) == 0) {
intf = audio_class->ctrl_intf;
@@ -205,11 +220,16 @@ int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint
int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute)
{
struct usb_setup_packet *setup = audio_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
uint8_t intf = 0xff;
uint8_t feature_id = 0xff;
if (!audio_class || !audio_class->hport) {
return -USB_ERR_INVAL;
}
setup = audio_class->hport->setup;
for (size_t i = 0; i < audio_class->module_num; i++) {
if (strcmp(name, audio_class->module[i].name) == 0) {
intf = audio_class->ctrl_intf;
@@ -367,9 +387,9 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq_num = desc->bSamFreqType;
for (uint8_t j = 0; j < desc->bSamFreqType; j++) {
audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq[j] = (uint32_t)(p[10 + j] << 16) |
(uint32_t)(p[9 + j] << 8) |
(uint32_t)(p[8 + j] << 0);
audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq[j] = (uint32_t)(p[10 + j * 3] << 16) |
(uint32_t)(p[9 + j * 3] << 8) |
(uint32_t)(p[8 + j * 3] << 0);
}
if (cur_alt_setting == (hport->config.intf[intf + 1].altsetting_num - 1)) {
format_offset++;
@@ -588,7 +588,7 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype */\
str_idx, /* Device's MAC string index */\
DBVAL_BE(eth_statistics), /* Ethernet statistics (bitmap) */\
WBVAL(wMaxPacketSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
WBVAL(wMaxSegmentSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
WBVAL(wNumberMCFilters), /* wNumberMCFilters: the number of multicast filters */\
bNumberPowerFilters, /* bNumberPowerFilters: the number of wakeup power filters */\
0x07, /* bLength */ \
@@ -167,7 +167,7 @@ void usbd_cdc_ecm_start_read_next(void)
{
g_cdc_ecm_rx_data_length = 0;
g_cdc_ecm_rx_data_buffer = NULL;
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, g_cdc_ecm_rx_buffer, usbd_get_ep_mps(busid, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, g_cdc_ecm_rx_buffer, usbd_get_ep_mps(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
}
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
@@ -183,7 +183,7 @@ struct pbuf *usbd_cdc_ecm_eth_rx(void)
usbd_cdc_ecm_start_read_next();
return NULL;
}
memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
usb_memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
p->len = g_cdc_ecm_rx_data_length;
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_data_length);
@@ -206,13 +206,11 @@ int usbd_cdc_ecm_eth_tx(struct pbuf *p)
buffer = g_cdc_ecm_tx_buffer;
for (q = p; q != NULL; q = q->next) {
memcpy(buffer, q->payload, q->len);
usb_memcpy(buffer, q->payload, q->len);
buffer += q->len;
}
g_cdc_ecm_tx_data_length = p->tot_len;
return usbd_cdc_ecm_start_write(g_cdc_ecm_tx_buffer, g_cdc_ecm_tx_data_length);
return usbd_cdc_ecm_start_write(g_cdc_ecm_tx_buffer, p->tot_len);
}
#endif
@@ -244,4 +242,4 @@ 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)
{
}
}
@@ -44,7 +44,12 @@ static void usbh_cdc_acm_class_free(struct usbh_cdc_acm *cdc_acm_class)
int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
{
struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
struct usb_setup_packet *setup;
if (!cdc_acm_class || !cdc_acm_class->hport) {
return -USB_ERR_INVAL;
}
setup = cdc_acm_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_SET_LINE_CODING;
@@ -59,9 +64,14 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
{
struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!cdc_acm_class || !cdc_acm_class->hport) {
return -USB_ERR_INVAL;
}
setup = cdc_acm_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_GET_LINE_CODING;
setup->wValue = 0;
@@ -78,7 +88,12 @@ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts)
{
struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
struct usb_setup_packet *setup;
if (!cdc_acm_class || !cdc_acm_class->hport) {
return -USB_ERR_INVAL;
}
setup = cdc_acm_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE;
@@ -32,7 +32,12 @@ static struct usbh_cdc_ecm g_cdc_ecm_class;
static int usbh_cdc_ecm_set_eth_packet_filter(struct usbh_cdc_ecm *cdc_ecm_class, uint16_t filter_value)
{
struct usb_setup_packet *setup = cdc_ecm_class->hport->setup;
struct usb_setup_packet *setup;
if (!cdc_ecm_class || !cdc_ecm_class->hport) {
return -USB_ERR_INVAL;
}
setup = cdc_ecm_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_SET_ETHERNET_PACKET_FILTER;
@@ -188,7 +193,7 @@ get_mac:
}
USB_LOG_INFO("Set CDC ECM packet filter:%04x\r\n", CONFIG_USBHOST_CDC_ECM_PKT_FILTER);
memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register CDC ECM Class:%s\r\n", hport->config.intf[intf].devname);
@@ -246,30 +251,33 @@ find_class:
usb_osal_msleep(100);
goto find_class;
}
usb_osal_msleep(128);
}
g_cdc_ecm_rx_length = 0;
while (1) {
usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkin_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkin, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_length], CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkin_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkin, g_cdc_ecm_rx_buffer, CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_cdc_ecm_class.bulkin_urb);
if (ret < 0) {
goto find_class;
}
g_cdc_ecm_rx_length += g_cdc_ecm_class.bulkin_urb.actual_length;
g_cdc_ecm_rx_length = g_cdc_ecm_class.bulkin_urb.actual_length;
if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize)) {
/* A transfer is complete because last packet is a short packet.
* Short packet is not zero, match g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize).
* Short packet is zero, check if g_cdc_ecm_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 512 < 1514.
* This case is always true
*/
if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize) ||
(g_cdc_ecm_class.bulkin_urb.actual_length < CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE)) {
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_length);
usbh_cdc_ecm_eth_input(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length);
g_cdc_ecm_rx_length = 0;
} else {
/* read continue util read short packet */
if (g_cdc_ecm_rx_length > CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE) {
USB_LOG_ERR("Rx packet is overflow\r\n");
g_cdc_ecm_rx_length = 0;
}
/* There's no way to run here. */
}
}
// clang-format off
@@ -279,16 +287,17 @@ delete:
// clang-format on
}
int usbh_cdc_ecm_eth_output(uint8_t *buf, uint32_t buflen)
uint8_t *usbh_cdc_ecm_get_eth_txbuf(void)
{
uint8_t *buffer = g_cdc_ecm_tx_buffer;
return g_cdc_ecm_tx_buffer;
}
int usbh_cdc_ecm_eth_output(uint32_t buflen)
{
if (g_cdc_ecm_class.connect_status == false) {
return -USB_ERR_NOTCONN;
}
memcpy(buffer, buf, buflen);
USB_LOG_DBG("txlen:%d\r\n", buflen);
usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, buflen, USB_OSAL_WAITING_FOREVER, NULL, NULL);
@@ -38,7 +38,8 @@ int usbh_cdc_ecm_get_connect_status(struct usbh_cdc_ecm *cdc_ecm_class);
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class);
void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class);
int usbh_cdc_ecm_eth_output(uint8_t *buf, uint32_t buflen);
uint8_t *usbh_cdc_ecm_get_eth_txbuf(void);
int usbh_cdc_ecm_eth_output(uint32_t buflen);
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ecm_rx_thread(void *argument);
@@ -33,9 +33,14 @@ static struct usbh_cdc_ncm g_cdc_ncm_class;
static int usbh_cdc_ncm_get_ntb_parameters(struct usbh_cdc_ncm *cdc_ncm_class, struct cdc_ncm_ntb_parameters *param)
{
struct usb_setup_packet *setup = cdc_ncm_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!cdc_ncm_class || !cdc_ncm_class->hport) {
return -USB_ERR_INVAL;
}
setup = cdc_ncm_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_GET_NTB_PARAMETERS;
setup->wValue = 0;
@@ -206,7 +211,7 @@ get_mac:
}
}
memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register CDC NCM Class:%s\r\n", hport->config.intf[intf].devname);
@@ -248,6 +253,11 @@ void usbh_cdc_ncm_rx_thread(void *argument)
{
uint32_t g_cdc_ncm_rx_length;
int ret;
#if CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE <= (16 * 1024)
uint32_t transfer_size = CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE;
#else
uint32_t transfer_size = (16 * 1024);
#endif
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
// clang-format off
@@ -268,7 +278,7 @@ find_class:
g_cdc_ncm_rx_length = 0;
while (1) {
usbh_bulk_urb_fill(&g_cdc_ncm_class.bulkin_urb, g_cdc_ncm_class.hport, g_cdc_ncm_class.bulkin, &g_cdc_ncm_rx_buffer[g_cdc_ncm_rx_length], (CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
usbh_bulk_urb_fill(&g_cdc_ncm_class.bulkin_urb, g_cdc_ncm_class.hport, g_cdc_ncm_class.bulkin, &g_cdc_ncm_rx_buffer[g_cdc_ncm_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_cdc_ncm_class.bulkin_urb);
if (ret < 0) {
goto find_class;
@@ -276,7 +286,12 @@ find_class:
g_cdc_ncm_rx_length += g_cdc_ncm_class.bulkin_urb.actual_length;
if (g_cdc_ncm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize)) {
/* A transfer is complete because last packet is a short packet.
* Short packet is not zero, match g_cdc_ncm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize).
* Short packet is zero, check if g_cdc_ncm_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 1024 < 2048.
*/
if ((g_cdc_ncm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize)) ||
(g_cdc_ncm_class.bulkin_urb.actual_length < transfer_size)) {
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ncm_rx_length);
struct cdc_ncm_nth16 *nth16 = (struct cdc_ncm_nth16 *)&g_cdc_ncm_rx_buffer[0];
@@ -309,11 +324,15 @@ find_class:
}
g_cdc_ncm_rx_length = 0;
} else {
if (g_cdc_ncm_rx_length > CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) {
USB_LOG_ERR("Rx packet is overflow\r\n");
g_cdc_ncm_rx_length = 0;
#if CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE <= (16 * 1024)
if (g_cdc_ncm_rx_length == CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) {
#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");
while (1) {
}
}
}
}
@@ -324,9 +343,13 @@ delete:
// clang-format on
}
int usbh_cdc_ncm_eth_output(uint8_t *buf, uint32_t buflen)
uint8_t *usbh_cdc_ncm_get_eth_txbuf(void)
{
return &g_cdc_ncm_tx_buffer[16];
}
int usbh_cdc_ncm_eth_output(uint32_t buflen)
{
uint8_t *buffer;
struct cdc_ncm_ndp16_datagram *ndp16_datagram;
if (g_cdc_ncm_class.connect_status == false) {
@@ -355,9 +378,6 @@ int usbh_cdc_ncm_eth_output(uint8_t *buf, uint32_t buflen)
ndp16_datagram->wDatagramIndex = 0;
ndp16_datagram->wDatagramLength = 0;
buffer = &g_cdc_ncm_tx_buffer[16];
memcpy(buffer, buf, buflen);
USB_LOG_DBG("txlen:%d\r\n", nth16->wBlockLength);
usbh_bulk_urb_fill(&g_cdc_ncm_class.bulkout_urb, g_cdc_ncm_class.hport, g_cdc_ncm_class.bulkout, g_cdc_ncm_tx_buffer, nth16->wBlockLength, USB_OSAL_WAITING_FOREVER, NULL, NULL);
@@ -42,7 +42,8 @@ int usbh_cdc_ncm_get_connect_status(struct usbh_cdc_ncm *cdc_ncm_class);
void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class);
void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class);
int usbh_cdc_ncm_eth_output(uint8_t *buf, uint32_t buflen);
uint8_t *usbh_cdc_ncm_get_eth_txbuf(void);
int usbh_cdc_ncm_eth_output(uint32_t buflen);
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ncm_rx_thread(void *argument);
@@ -44,9 +44,14 @@ static void usbh_hid_class_free(struct usbh_hid *hid_class)
static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer)
{
struct usb_setup_packet *setup = hid_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
}
setup = hid_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = HID_DESCRIPTOR_TYPE_HID_REPORT << 8;
@@ -63,7 +68,12 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b
int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration)
{
struct usb_setup_packet *setup = hid_class->hport->setup;
struct usb_setup_packet *setup;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
}
setup = hid_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_SET_IDLE;
@@ -76,9 +86,14 @@ int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t dur
int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
{
struct usb_setup_packet *setup = hid_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
}
setup = hid_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_GET_IDLE;
setup->wValue = 0;
@@ -95,7 +110,12 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
int usbh_hid_set_protocol(struct usbh_hid *hid_class, uint8_t protocol)
{
struct usb_setup_packet *setup = hid_class->hport->setup;
struct usb_setup_packet *setup;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
}
setup = hid_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_SET_PROTOCOL;
@@ -108,7 +128,12 @@ int usbh_hid_set_protocol(struct usbh_hid *hid_class, uint8_t protocol)
int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen)
{
struct usb_setup_packet *setup = hid_class->hport->setup;
struct usb_setup_packet *setup;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
}
setup = hid_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_SET_REPORT;
@@ -121,7 +146,12 @@ 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 = hid_class->hport->setup;
struct usb_setup_packet *setup;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
}
setup = hid_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_GET_REPORT;
@@ -27,13 +27,6 @@ extern void usbh_hubport_release(struct usbh_hubport *hport);
static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
#ifdef CONFIG_USBHOST_XHCI
struct usbh_hubport *usbh_get_roothub_port(unsigned int port)
{
return &roothub.child[port - 1];
}
#endif
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
static struct usbh_hub g_hub_class[CONFIG_USBHOST_MAX_EXTHUBS];
static uint32_t g_devinuse = 0;
@@ -373,8 +366,6 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
hub->connected = true;
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hub->index);
usb_slist_add_tail(&hub->bus->hub_list, &hub->list);
USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname);
hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
@@ -412,7 +403,6 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
if (hport->config.intf[intf].devname[0] != '\0') {
USB_LOG_INFO("Unregister HUB Class:%s\r\n", hport->config.intf[intf].devname);
usb_slist_remove(&hub->bus->hub_list, &hub->list);
}
usbh_hub_class_free(hub);
@@ -421,18 +411,6 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
#endif
static void usbh_hubport_enumerate_thread(void *argument)
{
struct usbh_hubport *child = (struct usbh_hubport *)argument;
if (usbh_enumerate(child) < 0) {
/** release child sources */
usbh_hubport_release(child);
USB_LOG_ERR("Port %u enumerate fail\r\n", child->port);
}
usb_osal_thread_delete(NULL);
}
static void usbh_hub_events(struct usbh_hub *hub)
{
struct usbh_hubport *child;
@@ -444,13 +422,16 @@ static void usbh_hub_events(struct usbh_hub *hub)
uint16_t feat;
uint8_t speed;
int ret;
size_t flags;
if (!hub->connected) {
return;
}
flags = usb_osal_enter_critical_section();
portchange_index = hub->int_buffer[0];
hub->int_buffer[0] &= ~portchange_index;
usb_osal_leave_critical_section(flags);
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index);
@@ -562,25 +543,9 @@ static void usbh_hub_events(struct usbh_hub *hub)
speed = USB_SPEED_HIGH;
} else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
speed = USB_SPEED_LOW;
}
#ifdef CONFIG_USBHOST_XHCI
else {
extern uint8_t usbh_get_port_speed(struct usbh_hub * hub, const uint8_t port);
/* USB3.0 speed cannot get from portstatus, checkout port speed instead */
uint8_t super_speed = usbh_get_port_speed(hub, port + 1);
if (super_speed > USB_SPEED_HIGH) {
/* assert that when using USB 3.0 ports, attached device must also be USB 3.0 speed */
speed = super_speed;
} else {
speed = USB_SPEED_FULL;
}
}
#else
else {
} else {
speed = USB_SPEED_FULL;
}
#endif
child = &hub->child[port];
/** release child sources first */
@@ -596,8 +561,11 @@ static void usbh_hub_events(struct usbh_hub *hub)
USB_LOG_INFO("New %s device on Bus %u, Hub %u, Port %u connected\r\n", speed_table[speed], hub->bus->busid, hub->index, port + 1);
/* create disposable thread to enumerate device on current hport, do not block hub thread */
usb_osal_thread_create("usbh_enum", CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hubport_enumerate_thread, (void *)child);
if (usbh_enumerate(child) < 0) {
/** release child sources */
usbh_hubport_release(child);
USB_LOG_ERR("Port %u enumerate fail\r\n", child->port);
}
} else {
child = &hub->child[port];
/** release child sources */
@@ -648,6 +616,17 @@ void usbh_hub_thread_wakeup(struct usbh_hub *hub)
int usbh_hub_initialize(struct usbh_bus *bus)
{
char thread_name[32] = { 0 };
struct usbh_hub *hub;
hub = &bus->hcd.roothub;
hub->connected = true;
hub->index = 1;
hub->is_roothub = true;
hub->parent = NULL;
hub->hub_addr = 1;
hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
hub->int_buffer = bus->hcd.roothub_intbuf;
hub->bus = bus;
bus->hub_mq = usb_osal_mq_create(7);
if (bus->hub_mq == NULL) {
@@ -666,21 +645,17 @@ int usbh_hub_initialize(struct usbh_bus *bus)
int usbh_hub_deinitialize(struct usbh_bus *bus)
{
usb_slist_t *hub_list;
struct usbh_hubport *hport;
struct usbh_hub *hub;
size_t flags;
flags = usb_osal_enter_critical_section();
usb_slist_for_each(hub_list, &bus->hub_list)
{
struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
hub = &bus->hcd.roothub;
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
usbh_hubport_release(hport);
}
usbh_hubport_release(hport);
}
usb_hc_deinit(bus);
@@ -13,6 +13,8 @@
#define DEV_FORMAT "/dev/sd%c"
#define MSC_INQUIRY_TIMEOUT 500
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[64];
static struct usbh_msc g_msc_class[CONFIG_USBHOST_MAX_MSC_CLASS];
@@ -46,7 +48,12 @@ static void usbh_msc_class_free(struct usbh_msc *msc_class)
static int usbh_msc_get_maxlun(struct usbh_msc *msc_class, uint8_t *buffer)
{
struct usb_setup_packet *setup = msc_class->hport->setup;
struct usb_setup_packet *setup;
if (!msc_class || !msc_class->hport) {
return -USB_ERR_INVAL;
}
setup = msc_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = MSC_REQUEST_GET_MAX_LUN;
@@ -113,14 +120,14 @@ static inline int usbh_msc_bulk_out_transfer(struct usbh_msc *msc_class, uint8_t
return ret;
}
static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, struct CSW *csw, uint8_t *buffer)
static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, struct CSW *csw, uint8_t *buffer, uint32_t timeout)
{
int nbytes;
usbh_msc_cbw_dump(cbw);
/* Send the CBW */
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, timeout);
if (nbytes < 0) {
USB_LOG_ERR("cbw transfer error\r\n");
goto __err_exit;
@@ -128,16 +135,16 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
if (cbw->dDataLength != 0) {
if (cbw->CB[0] == SCSI_CMD_WRITE10) {
nbytes = usbh_msc_bulk_out_transfer(msc_class, buffer, cbw->dDataLength, CONFIG_USBHOST_MSC_TIMEOUT);
nbytes = usbh_msc_bulk_out_transfer(msc_class, buffer, cbw->dDataLength, timeout);
} else if (cbw->CB[0] == SCSI_CMD_READCAPACITY10) {
nbytes = usbh_msc_bulk_in_transfer(msc_class, buffer, cbw->dDataLength, CONFIG_USBHOST_MSC_TIMEOUT);
nbytes = usbh_msc_bulk_in_transfer(msc_class, buffer, cbw->dDataLength, timeout);
if (nbytes >= 0) {
/* Save the capacity information */
msc_class->blocknum = GET_BE32(&buffer[0]) + 1;
msc_class->blocksize = GET_BE32(&buffer[4]);
}
} else {
nbytes = usbh_msc_bulk_in_transfer(msc_class, buffer, cbw->dDataLength, CONFIG_USBHOST_MSC_TIMEOUT);
nbytes = usbh_msc_bulk_in_transfer(msc_class, buffer, cbw->dDataLength, timeout);
}
if (nbytes < 0) {
@@ -148,7 +155,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
/* Receive the CSW */
memset(csw, 0, USB_SIZEOF_MSC_CSW);
nbytes = usbh_msc_bulk_in_transfer(msc_class, (uint8_t *)csw, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
nbytes = usbh_msc_bulk_in_transfer(msc_class, (uint8_t *)csw, USB_SIZEOF_MSC_CSW, timeout);
if (nbytes < 0) {
USB_LOG_ERR("csw transfer error\r\n");
goto __err_exit;
@@ -182,7 +189,7 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
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);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL, MSC_INQUIRY_TIMEOUT);
}
static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
@@ -200,7 +207,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);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT);
}
static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
@@ -218,7 +225,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);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT);
}
static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
@@ -235,7 +242,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);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT);
}
static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message)
@@ -247,7 +254,7 @@ static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t
memcpy(g_msc_buf, message, 31);
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL);
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL, MSC_INQUIRY_TIMEOUT);
}
static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
@@ -380,7 +387,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);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (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)
@@ -400,7 +407,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);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
}
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
+72 -27
View File
@@ -14,10 +14,9 @@
#define DEV_FORMAT "/dev/asix"
static struct usbh_asix g_asix_class;
#define CONFIG_USBHOST_ASIX_ETH_MAX_SIZE (1514U + 8)
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_rx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_tx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_rx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_tx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_inttx_buffer[16];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_buf[32];
@@ -56,9 +55,14 @@ static int usbh_asix_read_cmd(struct usbh_asix *asix_class,
void *data,
uint16_t size)
{
struct usb_setup_packet *setup = asix_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!asix_class || !asix_class->hport) {
return -USB_ERR_INVAL;
}
setup = asix_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = cmd;
setup->wValue = value;
@@ -81,7 +85,12 @@ static int usbh_asix_write_cmd(struct usbh_asix *asix_class,
void *data,
uint16_t size)
{
struct usb_setup_packet *setup = asix_class->hport->setup;
struct usb_setup_packet *setup;
if (!asix_class || !asix_class->hport) {
return -USB_ERR_INVAL;
}
setup = asix_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = cmd;
@@ -263,6 +272,15 @@ static int usbh_asix_write_gpio(struct usbh_asix *asix_class, uint16_t value, in
static void usbh_asix_set_multicast(struct usbh_asix *asix_class)
{
uint16_t rx_ctl = AX_DEFAULT_RX_CTL | AX_RX_CTL_AM;
#if CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE == 4096
rx_ctl |= AX_RX_CTL_MFB_4096;
#elif CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE == 8192
rx_ctl |= AX_RX_CTL_MFB_8192;
#elif CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE == 16384
rx_ctl |= AX_RX_CTL_MFB_16384;
#else
rx_ctl |= AX_RX_CTL_MFB_2048;
#endif
const uint8_t multi_filter[] = { 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x40 };
usbh_asix_write_cmd(asix_class, AX_CMD_WRITE_MULTI_FILTER, 0, 0, (uint8_t *)multi_filter, AX_MCAST_FILTER_SIZE);
@@ -589,7 +607,7 @@ static int usbh_asix_connect(struct usbh_hubport *hport, uint8_t intf)
USB_LOG_INFO("Init %s done\r\n", asix_class->name);
memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register ASIX Class:%s\r\n", hport->config.intf[intf].devname);
usbh_asix_run(asix_class);
@@ -655,6 +673,12 @@ void usbh_asix_rx_thread(void *argument)
int ret;
uint16_t len;
uint16_t len_crc;
uint32_t data_offset;
#if CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE <= (16 * 1024)
uint32_t transfer_size = CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE;
#else
uint32_t transfer_size = (16 * 1024);
#endif
USB_LOG_INFO("Create asix rx thread\r\n");
// clang-format off
@@ -671,11 +695,12 @@ find_class:
usb_osal_msleep(100);
goto find_class;
}
usb_osal_msleep(128);
}
g_asix_rx_length = 0;
while (1) {
usbh_bulk_urb_fill(&g_asix_class.bulkin_urb, g_asix_class.hport, g_asix_class.bulkin, &g_asix_rx_buffer[g_asix_rx_length], CONFIG_USBHOST_ASIX_ETH_MAX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
usbh_bulk_urb_fill(&g_asix_class.bulkin_urb, g_asix_class.hport, g_asix_class.bulkin, &g_asix_rx_buffer[g_asix_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_asix_class.bulkin_urb);
if (ret < 0) {
goto find_class;
@@ -683,24 +708,43 @@ find_class:
g_asix_rx_length += g_asix_class.bulkin_urb.actual_length;
if (g_asix_rx_length % USB_GET_MAXPACKETSIZE(g_asix_class.bulkin->wMaxPacketSize)) {
len = ((uint16_t)g_asix_rx_buffer[0] | ((uint16_t)(g_asix_rx_buffer[1]) << 8)) & 0x7ff;
len_crc = g_asix_rx_buffer[2] | ((uint16_t)(g_asix_rx_buffer[3]) << 8);
if (len != (~len_crc & 0x7ff)) {
USB_LOG_ERR("asix rx header error\r\n");
continue;
}
/* A transfer is complete because last packet is a short packet.
* Short packet is not zero, match g_asix_rx_length % USB_GET_MAXPACKETSIZE(g_asix_class.bulkin->wMaxPacketSize).
* Short packet is zero, check if g_asix_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 1024 < 2048.
*/
if (g_asix_rx_length % USB_GET_MAXPACKETSIZE(g_asix_class.bulkin->wMaxPacketSize) ||
(g_asix_class.bulkin_urb.actual_length < transfer_size)) {
USB_LOG_DBG("rxlen:%d\r\n", g_asix_rx_length);
uint8_t *buf = (uint8_t *)&g_asix_rx_buffer[4];
usbh_asix_eth_input(buf, len);
g_asix_rx_length = 0;
data_offset = 0;
while (g_asix_rx_length > 0) {
len = ((uint16_t)g_asix_rx_buffer[data_offset + 0] | ((uint16_t)(g_asix_rx_buffer[data_offset + 1]) << 8)) & 0x7ff;
len_crc = g_asix_rx_buffer[data_offset + 2] | ((uint16_t)(g_asix_rx_buffer[data_offset + 3]) << 8);
if (len != (~len_crc & 0x7ff)) {
USB_LOG_ERR("rx header error\r\n");
g_asix_rx_length = 0;
continue;
}
uint8_t *buf = (uint8_t *)&g_asix_rx_buffer[data_offset + 4];
usbh_asix_eth_input(buf, len);
g_asix_rx_length -= (len + 4);
data_offset += (len + 4);
if (g_asix_rx_length < 4) {
g_asix_rx_length = 0;
}
}
} else {
if (g_asix_rx_length > CONFIG_USBHOST_ASIX_ETH_MAX_SIZE) {
USB_LOG_ERR("Rx packet is overflow\r\n");
g_asix_rx_length = 0;
#if CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE <= (16 * 1024)
if (g_asix_rx_length == CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE) {
#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");
while (1) {
}
}
}
}
@@ -711,18 +755,19 @@ delete:
// clang-format on
}
int usbh_asix_eth_output(uint8_t *buf, uint32_t buflen)
uint8_t *usbh_asix_get_eth_txbuf(void)
{
return &g_asix_tx_buffer[4];
}
int usbh_asix_eth_output(uint32_t buflen)
{
uint16_t actual_len;
uint8_t *buffer;
if (g_asix_class.connect_status == false) {
return -USB_ERR_NOTCONN;
}
buffer = &g_asix_tx_buffer[4];
memcpy(buffer, buf, buflen);
g_asix_tx_buffer[0] = buflen & 0xff;
g_asix_tx_buffer[1] = (buflen >> 8) & 0xff;
g_asix_tx_buffer[2] = ~g_asix_tx_buffer[0];
@@ -165,7 +165,8 @@ int usbh_asix_get_connect_status(struct usbh_asix *asix_class);
void usbh_asix_run(struct usbh_asix *asix_class);
void usbh_asix_stop(struct usbh_asix *asix_class);
int usbh_asix_eth_output(uint8_t *buf, uint32_t buflen);
uint8_t *usbh_asix_get_eth_txbuf(void);
int usbh_asix_eth_output(uint32_t buflen);
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_asix_rx_thread(void *argument);
@@ -946,9 +946,14 @@ static int usbh_rtl8152_read_regs(struct usbh_rtl8152 *rtl8152_class,
uint16_t size,
void *data)
{
struct usb_setup_packet *setup = rtl8152_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!rtl8152_class || !rtl8152_class->hport) {
return -USB_ERR_INVAL;
}
setup = rtl8152_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = RTL8152_REQ_GET_REGS;
setup->wValue = value;
@@ -970,7 +975,12 @@ static int usbh_rtl8152_write_regs(struct usbh_rtl8152 *rtl8152_class,
uint16_t size,
void *data)
{
struct usb_setup_packet *setup = rtl8152_class->hport->setup;
struct usb_setup_packet *setup;
if (!rtl8152_class || !rtl8152_class->hport) {
return -USB_ERR_INVAL;
}
setup = rtl8152_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = RTL8152_REQ_SET_REGS;
@@ -2080,7 +2090,7 @@ static int usbh_rtl8152_connect(struct usbh_hubport *hport, uint8_t intf)
}
}
memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register RTL8152 Class:%s\r\n", hport->config.intf[intf].devname);
@@ -2124,6 +2134,11 @@ void usbh_rtl8152_rx_thread(void *argument)
int ret;
uint16_t len;
uint16_t data_offset;
#if CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE <= (16 * 1024)
uint32_t transfer_size = CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE;
#else
uint32_t transfer_size = (16 * 1024);
#endif
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
// clang-format off
@@ -2154,7 +2169,7 @@ find_class:
g_rtl8152_rx_length = 0;
while (1) {
usbh_bulk_urb_fill(&g_rtl8152_class.bulkin_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkin, &g_rtl8152_rx_buffer[g_rtl8152_rx_length], (CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
usbh_bulk_urb_fill(&g_rtl8152_class.bulkin_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkin, &g_rtl8152_rx_buffer[g_rtl8152_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_rtl8152_class.bulkin_urb);
if (ret < 0) {
goto find_class;
@@ -2162,7 +2177,12 @@ find_class:
g_rtl8152_rx_length += g_rtl8152_class.bulkin_urb.actual_length;
if (g_rtl8152_rx_length % USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize)) {
/* A transfer is complete because last packet is a short packet.
* Short packet is not zero, match g_rtl8152_rx_length % USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize).
* Short packet is zero, check if g_rtl8152_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 1024 < 2048.
*/
if (g_rtl8152_rx_length % USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize) ||
(g_rtl8152_class.bulkin_urb.actual_length < transfer_size)) {
data_offset = 0;
USB_LOG_DBG("rxlen:%d\r\n", g_rtl8152_rx_length);
@@ -2185,9 +2205,14 @@ find_class:
}
}
} else {
if (g_rtl8152_rx_length > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) {
USB_LOG_ERR("Rx packet is overflow\r\n");
g_rtl8152_rx_length = 0;
#if CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE <= (16 * 1024)
if (g_rtl8152_rx_length == CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) {
#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");
while (1) {
}
}
}
}
@@ -2198,9 +2223,13 @@ delete:
// clang-format on
}
int usbh_rtl8152_eth_output(uint8_t *buf, uint32_t buflen)
uint8_t *usbh_rtl8152_get_eth_txbuf(void)
{
return (g_rtl8152_tx_buffer + sizeof(struct tx_desc));
}
int usbh_rtl8152_eth_output(uint32_t buflen)
{
uint8_t *buffer;
struct tx_desc *tx_desc;
if (g_rtl8152_class.connect_status == false) {
@@ -2211,9 +2240,6 @@ int usbh_rtl8152_eth_output(uint8_t *buf, uint32_t buflen)
tx_desc->opts1 = buflen | TX_FS | TX_LS;
tx_desc->opts2 = 0;
buffer = g_rtl8152_tx_buffer + sizeof(struct tx_desc);
memcpy(buffer, buf, buflen);
USB_LOG_DBG("txlen:%d\r\n", buflen + sizeof(struct tx_desc));
usbh_bulk_urb_fill(&g_rtl8152_class.bulkout_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkout, g_rtl8152_tx_buffer, buflen + sizeof(struct tx_desc), USB_OSAL_WAITING_FOREVER, NULL, NULL);
@@ -56,7 +56,8 @@ int usbh_rtl8152_get_connect_status(struct usbh_rtl8152 *rtl8152_class);
void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class);
void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class);
int usbh_rtl8152_eth_output(uint8_t *buf, uint32_t buflen);
uint8_t *usbh_rtl8152_get_eth_txbuf(void);
int usbh_rtl8152_eth_output(uint32_t buflen);
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_rtl8152_rx_thread(void *argument);
@@ -90,9 +90,14 @@ static int usbh_ch34x_get_baudrate_div(uint32_t baudrate, uint8_t *factor, uint8
static int usbh_ch34x_get_version(struct usbh_ch34x *ch34x_class)
{
struct usb_setup_packet *setup = ch34x_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!ch34x_class || !ch34x_class->hport) {
return -USB_ERR_INVAL;
}
setup = ch34x_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = CH34X_READ_VERSION;
setup->wValue = 0;
@@ -110,7 +115,12 @@ static int usbh_ch34x_get_version(struct usbh_ch34x *ch34x_class)
static int usbh_ch34x_flow_ctrl(struct usbh_ch34x *ch34x_class)
{
struct usb_setup_packet *setup = ch34x_class->hport->setup;
struct usb_setup_packet *setup;
if (!ch34x_class || !ch34x_class->hport) {
return -USB_ERR_INVAL;
}
setup = ch34x_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = CH34X_WRITE_REG;
@@ -123,12 +133,17 @@ static int usbh_ch34x_flow_ctrl(struct usbh_ch34x *ch34x_class)
int usbh_ch34x_set_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding)
{
struct usb_setup_packet *setup = ch34x_class->hport->setup;
struct usb_setup_packet *setup;
uint16_t reg_value = 0;
uint16_t value = 0;
uint8_t factor = 0;
uint8_t divisor = 0;
if (!ch34x_class || !ch34x_class->hport) {
return -USB_ERR_INVAL;
}
setup = ch34x_class->hport->setup;
memcpy((uint8_t *)&ch34x_class->line_coding, line_coding, sizeof(struct cdc_line_coding));
/* refer to https://github.com/WCHSoftGroup/ch341ser_linux/blob/main/driver/ch341.c */
@@ -197,7 +212,12 @@ int usbh_ch34x_get_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_c
int usbh_ch34x_set_line_state(struct usbh_ch34x *ch34x_class, bool dtr, bool rts)
{
struct usb_setup_packet *setup = ch34x_class->hport->setup;
struct usb_setup_packet *setup;
if (!ch34x_class || !ch34x_class->hport) {
return -USB_ERR_INVAL;
}
setup = ch34x_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = CH34X_MODEM_CTRL;
@@ -42,7 +42,12 @@ static void usbh_cp210x_class_free(struct usbh_cp210x *cp210x_class)
static int usbh_cp210x_enable(struct usbh_cp210x *cp210x_class)
{
struct usb_setup_packet *setup = cp210x_class->hport->setup;
struct usb_setup_packet *setup;
if (!cp210x_class || !cp210x_class->hport) {
return -USB_ERR_INVAL;
}
setup = cp210x_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CP210X_IFC_ENABLE;
@@ -55,7 +60,12 @@ static int usbh_cp210x_enable(struct usbh_cp210x *cp210x_class)
static int usbh_cp210x_set_flow(struct usbh_cp210x *cp210x_class)
{
struct usb_setup_packet *setup = cp210x_class->hport->setup;
struct usb_setup_packet *setup;
if (!cp210x_class || !cp210x_class->hport) {
return -USB_ERR_INVAL;
}
setup = cp210x_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CP210X_SET_FLOW;
@@ -70,7 +80,12 @@ static int usbh_cp210x_set_flow(struct usbh_cp210x *cp210x_class)
static int usbh_cp210x_set_chars(struct usbh_cp210x *cp210x_class)
{
struct usb_setup_packet *setup = cp210x_class->hport->setup;
struct usb_setup_packet *setup;
if (!cp210x_class || !cp210x_class->hport) {
return -USB_ERR_INVAL;
}
setup = cp210x_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CP210X_SET_CHARS;
@@ -87,7 +102,12 @@ static int usbh_cp210x_set_chars(struct usbh_cp210x *cp210x_class)
static int usbh_cp210x_set_baudrate(struct usbh_cp210x *cp210x_class, uint32_t baudrate)
{
struct usb_setup_packet *setup = cp210x_class->hport->setup;
struct usb_setup_packet *setup;
if (!cp210x_class || !cp210x_class->hport) {
return -USB_ERR_INVAL;
}
setup = cp210x_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CP210X_SET_BAUDRATE;
@@ -101,9 +121,14 @@ static int usbh_cp210x_set_baudrate(struct usbh_cp210x *cp210x_class, uint32_t b
static int usbh_cp210x_set_data_format(struct usbh_cp210x *cp210x_class, uint8_t databits, uint8_t parity, uint8_t stopbits)
{
struct usb_setup_packet *setup = cp210x_class->hport->setup;
struct usb_setup_packet *setup;
uint16_t value;
if (!cp210x_class || !cp210x_class->hport) {
return -USB_ERR_INVAL;
}
setup = cp210x_class->hport->setup;
value = ((databits & 0x0F) << 8) | ((parity & 0x0f) << 4) | ((stopbits & 0x03) << 0);
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -117,9 +142,14 @@ static int usbh_cp210x_set_data_format(struct usbh_cp210x *cp210x_class, uint8_t
static int usbh_cp210x_set_mhs(struct usbh_cp210x *cp210x_class, uint8_t dtr, uint8_t rts, uint8_t dtr_mask, uint8_t rts_mask)
{
struct usb_setup_packet *setup = cp210x_class->hport->setup;
struct usb_setup_packet *setup;
uint16_t value;
if (!cp210x_class || !cp210x_class->hport) {
return -USB_ERR_INVAL;
}
setup = cp210x_class->hport->setup;
value = ((dtr & 0x01) << 0) | ((rts & 0x01) << 1) | ((dtr_mask & 0x01) << 8) | ((rts_mask & 0x01) << 9);
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -71,7 +71,12 @@ static void usbh_ftdi_caculate_baudrate(uint32_t *itdf_divisor, uint32_t actual_
int usbh_ftdi_reset(struct usbh_ftdi *ftdi_class)
{
struct usb_setup_packet *setup = ftdi_class->hport->setup;
struct usb_setup_packet *setup;
if (!ftdi_class || !ftdi_class->hport) {
return -USB_ERR_INVAL;
}
setup = ftdi_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = SIO_RESET_REQUEST;
@@ -84,7 +89,12 @@ int usbh_ftdi_reset(struct usbh_ftdi *ftdi_class)
static int usbh_ftdi_set_modem(struct usbh_ftdi *ftdi_class, uint16_t value)
{
struct usb_setup_packet *setup = ftdi_class->hport->setup;
struct usb_setup_packet *setup;
if (!ftdi_class || !ftdi_class->hport) {
return -USB_ERR_INVAL;
}
setup = ftdi_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = SIO_SET_MODEM_CTRL_REQUEST;
@@ -97,11 +107,16 @@ static int usbh_ftdi_set_modem(struct usbh_ftdi *ftdi_class, uint16_t value)
static int usbh_ftdi_set_baudrate(struct usbh_ftdi *ftdi_class, uint32_t baudrate)
{
struct usb_setup_packet *setup = ftdi_class->hport->setup;
struct usb_setup_packet *setup;
uint32_t itdf_divisor;
uint16_t value;
uint8_t baudrate_high;
if (!ftdi_class || !ftdi_class->hport) {
return -USB_ERR_INVAL;
}
setup = ftdi_class->hport->setup;
usbh_ftdi_caculate_baudrate(&itdf_divisor, baudrate);
value = itdf_divisor & 0xFFFF;
baudrate_high = (itdf_divisor >> 16) & 0xff;
@@ -123,10 +138,15 @@ static int usbh_ftdi_set_data_format(struct usbh_ftdi *ftdi_class, uint8_t datab
* D11-D12 STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2
* D14 BREAK_OFF=0, BREAK_ON=1
**/
struct usb_setup_packet *setup;
uint16_t value;
uint16_t value = ((isbreak & 0x01) << 14) | ((stopbits & 0x03) << 11) | ((parity & 0x0f) << 8) | (databits & 0x0f);
if (!ftdi_class || !ftdi_class->hport) {
return -USB_ERR_INVAL;
}
setup = ftdi_class->hport->setup;
struct usb_setup_packet *setup = ftdi_class->hport->setup;
value = ((isbreak & 0x01) << 14) | ((stopbits & 0x03) << 11) | ((parity & 0x0f) << 8) | (databits & 0x0f);
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = SIO_SET_DATA_REQUEST;
@@ -139,7 +159,12 @@ static int usbh_ftdi_set_data_format(struct usbh_ftdi *ftdi_class, uint8_t datab
static int usbh_ftdi_set_latency_timer(struct usbh_ftdi *ftdi_class, uint16_t value)
{
struct usb_setup_packet *setup = ftdi_class->hport->setup;
struct usb_setup_packet *setup;
if (!ftdi_class || !ftdi_class->hport) {
return -USB_ERR_INVAL;
}
setup = ftdi_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = SIO_SET_LATENCY_TIMER_REQUEST;
@@ -152,7 +177,12 @@ static int usbh_ftdi_set_latency_timer(struct usbh_ftdi *ftdi_class, uint16_t va
static int usbh_ftdi_set_flow_ctrl(struct usbh_ftdi *ftdi_class, uint16_t value)
{
struct usb_setup_packet *setup = ftdi_class->hport->setup;
struct usb_setup_packet *setup;
if (!ftdi_class || !ftdi_class->hport) {
return -USB_ERR_INVAL;
}
setup = ftdi_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = SIO_SET_FLOW_CTRL_REQUEST;
@@ -165,9 +195,14 @@ static int usbh_ftdi_set_flow_ctrl(struct usbh_ftdi *ftdi_class, uint16_t value)
static int usbh_ftdi_read_modem_status(struct usbh_ftdi *ftdi_class)
{
struct usb_setup_packet *setup = ftdi_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!ftdi_class || !ftdi_class->hport) {
return -USB_ERR_INVAL;
}
setup = ftdi_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = SIO_POLL_MODEM_STATUS_REQUEST;
setup->wValue = 0x0000;
@@ -131,7 +131,12 @@ static int usbh_pl2303_do(struct usbh_pl2303 *pl2303_class,
uint8_t req_type, uint8_t request, uint16_t value, uint16_t index,
uint16_t length)
{
struct usb_setup_packet *setup = pl2303_class->hport->setup;
struct usb_setup_packet *setup;
if (!pl2303_class || !pl2303_class->hport) {
return -USB_ERR_INVAL;
}
setup = pl2303_class->hport->setup;
setup->bmRequestType = req_type;
setup->bRequest = request;
@@ -144,7 +149,12 @@ static int usbh_pl2303_do(struct usbh_pl2303 *pl2303_class,
int usbh_pl2303_set_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding)
{
struct usb_setup_packet *setup = pl2303_class->hport->setup;
struct usb_setup_packet *setup;
if (!pl2303_class || !pl2303_class->hport) {
return -USB_ERR_INVAL;
}
setup = pl2303_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_SET_LINE_CODING;
@@ -159,9 +169,14 @@ int usbh_pl2303_set_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_lin
int usbh_pl2303_get_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding)
{
struct usb_setup_packet *setup = pl2303_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!pl2303_class || !pl2303_class->hport) {
return -USB_ERR_INVAL;
}
setup = pl2303_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_GET_LINE_CODING;
setup->wValue = 0;
@@ -178,7 +193,12 @@ int usbh_pl2303_get_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_lin
int usbh_pl2303_set_line_state(struct usbh_pl2303 *pl2303_class, bool dtr, bool rts)
{
struct usb_setup_packet *setup = pl2303_class->hport->setup;
struct usb_setup_packet *setup;
if (!pl2303_class || !pl2303_class->hport) {
return -USB_ERR_INVAL;
}
setup = pl2303_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE;
@@ -806,14 +806,15 @@ struct video_still_probe_and_commit_controls {
struct video_cs_if_vc_header_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdVDC;
uint8_t bDescriptorSubType;
uint16_t bcdUVC;
uint16_t wTotalLength;
uint32_t dwClockFrequency;
uint8_t bInCollection;
uint8_t baInterfaceNr[];
} __PACKED;
#define VIDEO_SIZEOF_VC_HEADER_DESC(n) (11 + n)
#define VIDEO_SIZEOF_VC_HEADER_DESC(n) (12 + n)
struct video_cs_if_vc_input_terminal_descriptor {
uint8_t bLength;
@@ -860,6 +861,22 @@ struct video_cs_if_vc_output_terminal_descriptor {
#define VIDEO_SIZEOF_VC_OUTPUT_TERMINAL_DESC 9
struct video_cs_if_vc_extension_unit_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bUnitID;
uint8_t guidExtensionCode[16];
uint8_t bNumControls;
uint8_t bNrInPins;
// uint8_t baSourceID[];
uint8_t bControlSize;
// uint8_t bmControls[]
uint8_t iExtension;
} __PACKED;
#define VIDEO_SIZEOF_VC_EXTENSION_UNIT_DESC(p, n) (24 + p + n)
struct video_cs_ep_vc_ep_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
@@ -922,7 +939,7 @@ struct video_cs_if_vs_frame_uncompressed_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bFormatIndex;
uint8_t bFrameIndex;
uint8_t bmCapabilities;
uint16_t wWidth;
uint16_t wHeight;
@@ -931,10 +948,10 @@ struct video_cs_if_vs_frame_uncompressed_descriptor {
uint32_t dwMaxVideoFrameBufferSize;
uint32_t dwDefaultFrameInterval;
uint8_t bFrameIntervalType;
uint32_t dwFrameInterval;
uint32_t dwFrameInterval[];
} __PACKED;
#define VIDEO_SIZEOF_VS_FRAME_UNCOMPRESSED_DESC 30
#define VIDEO_SIZEOF_VS_FRAME_UNCOMPRESSED_DESC(n) (26 + 4 * (n))
struct video_cs_if_vs_format_mjpeg_descriptor {
uint8_t bLength;
@@ -956,7 +973,7 @@ struct video_cs_if_vs_frame_mjpeg_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bFormatIndex;
uint8_t bFrameIndex;
uint8_t bmCapabilities;
uint16_t wWidth;
uint16_t wHeight;
@@ -965,11 +982,48 @@ struct video_cs_if_vs_frame_mjpeg_descriptor {
uint32_t dwMaxVideoFrameBufferSize;
uint32_t dwDefaultFrameInterval;
uint8_t bFrameIntervalType;
uint32_t dwFrameInterval1;
uint32_t dwFrameInterval2;
uint32_t dwFrameInterval[];
} __PACKED;
#define VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(n) (26 + n)
#define VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(n) (26 + 4 * (n))
/* H264 Payload - 3.1.1. H264 Video Format Descriptor */
struct video_cs_if_vs_format_h26x_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bFormatIndex;
uint8_t bNumFrameDescriptors;
uint8_t guidFormat[16];
uint8_t bBitsPerPixel;
uint8_t bDefaultFrameIndex;
uint8_t bAspectRatioX;
uint8_t bAspectRatioY;
uint8_t bmInterfaceFlags;
uint8_t bCopyProtect;
uint8_t bVariableSize;
} __PACKED;
#define VIDEO_SIZEOF_VS_FORMAT_H264_DESC 28
/* H264 Payload - 3.1.2. H264 Video Frame Descriptor */
struct video_cs_if_vs_frame_h26x_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bFrameIndex;
uint8_t bmCapabilities;
uint16_t wWidth;
uint16_t wHeight;
uint32_t dwMinBitRate;
uint32_t dwMaxBitRate;
uint32_t dwDefaultFrameInterval;
uint8_t bFrameIntervalType;
uint32_t dwBytesPerLine;
uint32_t dwFrameInterval[];
} __PACKED;
#define VIDEO_SIZEOF_VS_FRAME_H264_DESC(n) (26 + 4 * (n))
struct video_cs_if_vs_colorformat_descriptor {
uint8_t bLength;
@@ -1041,74 +1095,145 @@ struct video_autoexposure_mode {
#define VIDEO_GUID_YUY2 0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
#define VIDEO_GUID_NV12 0x4E, 0x56, 0x31, 0x32, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
#define VIDEO_GUID_NV21 0x4E, 0x56, 0x32, 0x31, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
#define VIDEO_GUID_M420 0x4D, 0x34, 0x32, 0x30, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
#define VIDEO_GUID_I420 0x49, 0x34, 0x32, 0x30, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
#define VIDEO_GUID_H264 0x48, 0x32, 0x36, 0x34, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
#define VIDEO_VC_TERMINAL_LEN (13 + 18 + 12 + 9)
/*Length of template descriptor: 81 bytes*/
#define VIDEO_VC_DESCRIPTOR_LEN (8 + 9 + VIDEO_VC_TERMINAL_LEN + 7 + 5)
#define VIDEO_VC_NOEP_DESCRIPTOR_LEN (8 + 9 + VIDEO_VC_TERMINAL_LEN)
// clang-format off
#define VIDEO_VC_DESCRIPTOR_INIT(bFirstInterface, bNumEndpoints, bcdUVC, wTotalLength, dwClockFrequency, stridx) \
/* Interface Association Descriptor */ \
0x08, \
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, \
bFirstInterface, \
0x02, \
USB_DEVICE_CLASS_VIDEO, \
VIDEO_SC_VIDEO_INTERFACE_COLLECTION, \
0x00, \
0x00, \
/* VideoControl Interface Descriptor */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
0x00, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
bNumEndpoints, /* bNumEndpoints:1 endpoint (interrupt endpoint) */ \
USB_DEVICE_CLASS_VIDEO, /* bInterfaceClass : CC_VIDEO */ \
VIDEO_SC_VIDEOCONTROL, /* bInterfaceSubClass : SC_VIDEOCONTROL */ \
VIDEO_PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol : PC_PROTOCOL_UNDEFINED */ \
stridx, /* iInterface:Index to string descriptor that contains the string <Your Product Name> */ \
/*Class-specific VideoControl Interface Descriptor */ \
0x0d, /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
VIDEO_VC_HEADER_DESCRIPTOR_SUBTYPE, /* bDescriptorSubType : VC_HEADER subtype */ \
WBVAL(bcdUVC), /* bcdUVC : Revision of class specification that this device is based upon.*/ \
WBVAL(wTotalLength), /* wTotalLength */ \
DBVAL(dwClockFrequency), /* dwClockFrequency : 0x005b8d80 -> 6,000,000 == 6MHz*/ \
0x01, /* bInCollection : Number of streaming interfaces. */ \
(uint8_t)(bFirstInterface + 1), /* baInterfaceNr(0) : VideoStreaming interface 1 belongs to this VideoControl interface.*/ \
/* Input Terminal 1 -> Processing Unit 2 -> Output Terminal 3 */ \
0x12, \
0x24, \
VIDEO_VC_INPUT_TERMINAL_DESCRIPTOR_SUBTYPE, \
0x01, /* bTerminalID */ \
WBVAL(VIDEO_ITT_CAMERA), /* wTerminalType : 0x0201 Camera Sensor*/ \
0x00, /* bAssocTerminal */ \
0x00, /* iTerminal */ \
WBVAL(0x0000), /* wObjectiveFocalLengthMin */ \
WBVAL(0x0000), /* wObjectiveFocalLengthMax */ \
WBVAL(0x0000), /* wOcularFocalLength */ \
0x03, /* bControlSize */ \
0x00, 0x00, 0x00, /* bmControls */ \
0x0c, \
0x24, \
VIDEO_VC_PROCESSING_UNIT_DESCRIPTOR_SUBTYPE, \
0x02, /* bUnitID */ \
0x01, /* bSourceID */ \
0x00, 0x00, /* wMaxMultiplier */ \
0x02, /* bControlSize */ \
0x00, 0x00, /* bmControls */ \
0x00, /* iProcessing */ \
0x00, /* bmVideoStandards */ \
0x09, \
0x24, \
VIDEO_VC_OUTPUT_TERMINAL_DESCRIPTOR_SUBTYPE, \
0x03, /* bTerminalID */ \
WBVAL(VIDEO_TT_STREAMING), \
0x00, /* bAssocTerminal */ \
0x02, /* bSourceID */ \
0x00 /* iTerminal */
#define VIDEO_VC_DESCRIPTOR_INIT(bFirstInterface, bEndpointAddress, bcdUVC, wTotalLength, dwClockFrequency, stridx) \
/* Interface Association Descriptor */ \
0x08, \
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, \
bFirstInterface, \
0x02, \
USB_DEVICE_CLASS_VIDEO, \
VIDEO_SC_VIDEO_INTERFACE_COLLECTION, \
0x00, \
0x00, /* VideoControl Interface Descriptor */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
0x00, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
0x01, /* bNumEndpoints:1 endpoint (interrupt endpoint) */ \
USB_DEVICE_CLASS_VIDEO, /* bInterfaceClass : CC_VIDEO */ \
VIDEO_SC_VIDEOCONTROL, /* bInterfaceSubClass : SC_VIDEOCONTROL */ \
VIDEO_PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol : PC_PROTOCOL_UNDEFINED */ \
stridx, /* iInterface:Index to string descriptor that contains the string <Your Product Name> */ /*Class-specific VideoControl Interface Descriptor */ \
0x0d, /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
VIDEO_VC_HEADER_DESCRIPTOR_SUBTYPE, /* bDescriptorSubType : VC_HEADER subtype */ \
WBVAL(bcdUVC), /* bcdUVC : Revision of class specification that this device is based upon.*/ \
WBVAL(wTotalLength), /* wTotalLength */ \
DBVAL(dwClockFrequency), /* dwClockFrequency : 0x005b8d80 -> 6,000,000 == 6MHz*/ \
0x01, /* bInCollection : Number of streaming interfaces. */ \
(uint8_t)(bFirstInterface + 1), /* baInterfaceNr(0) : VideoStreaming interface 1 belongs to this VideoControl interface.*/ /* Input Terminal 1 -> Processing Unit 2 -> Output Terminal 3 */ \
0x12, \
0x24, \
VIDEO_VC_INPUT_TERMINAL_DESCRIPTOR_SUBTYPE, \
0x01, /* bTerminalID */ \
WBVAL(VIDEO_ITT_CAMERA), /* wTerminalType : 0x0201 Camera Sensor*/ \
0x00, /* bAssocTerminal */ \
0x00, /* iTerminal */ \
WBVAL(0x0000), /* wObjectiveFocalLengthMin */ \
WBVAL(0x0000), /* wObjectiveFocalLengthMax */ \
WBVAL(0x0000), /* wOcularFocalLength */ \
0x03, /* bControlSize */ \
0x00, 0x00, 0x00, /* bmControls */ \
0x0c, \
0x24, \
VIDEO_VC_PROCESSING_UNIT_DESCRIPTOR_SUBTYPE, \
0x02, /* bUnitID */ \
0x01, /* bSourceID */ \
0x00, 0x00, /* wMaxMultiplier */ \
0x02, /* bControlSize */ \
0x00, 0x00, /* bmControls */ \
0x00, /* iProcessing */ \
0x00, /* bmVideoStandards */ \
0x09, \
0x24, \
VIDEO_VC_OUTPUT_TERMINAL_DESCRIPTOR_SUBTYPE, \
0x03, /* bTerminalID */ \
WBVAL(VIDEO_TT_STREAMING), \
0x00, /* bAssocTerminal */ \
0x02, /* bSourceID */ \
0x00, /* iTerminal */ \
0x07, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
bEndpointAddress, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \
0x10, 0x00, /* wMaxPacketSize */ \
0x08, /* bInterval */ \
/* Class-specific VC Interrupt Endpoint Descriptor */ \
0x05, 0x25, 0x03, 0x10, 0x00
#define VIDEO_VC_NOEP_DESCRIPTOR_INIT(bFirstInterface, bEndpointAddress, bcdUVC, wTotalLength, dwClockFrequency, stridx) \
/* Interface Association Descriptor */ \
0x08, \
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, \
bFirstInterface, \
0x02, \
USB_DEVICE_CLASS_VIDEO, \
VIDEO_SC_VIDEO_INTERFACE_COLLECTION, \
0x00, \
0x00, /* VideoControl Interface Descriptor */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
0x00, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
0x00, /* bNumEndpoints:1 endpoint (interrupt endpoint) */ \
USB_DEVICE_CLASS_VIDEO, /* bInterfaceClass : CC_VIDEO */ \
VIDEO_SC_VIDEOCONTROL, /* bInterfaceSubClass : SC_VIDEOCONTROL */ \
VIDEO_PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol : PC_PROTOCOL_UNDEFINED */ \
stridx, /* iInterface:Index to string descriptor that contains the string <Your Product Name> */ /*Class-specific VideoControl Interface Descriptor */ \
0x0d, /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
VIDEO_VC_HEADER_DESCRIPTOR_SUBTYPE, /* bDescriptorSubType : VC_HEADER subtype */ \
WBVAL(bcdUVC), /* bcdUVC : Revision of class specification that this device is based upon.*/ \
WBVAL(wTotalLength), /* wTotalLength */ \
DBVAL(dwClockFrequency), /* dwClockFrequency : 0x005b8d80 -> 6,000,000 == 6MHz*/ \
0x01, /* bInCollection : Number of streaming interfaces. */ \
(uint8_t)(bFirstInterface + 1), /* baInterfaceNr(0) : VideoStreaming interface 1 belongs to this VideoControl interface.*/ /* Input Terminal 1 -> Processing Unit 2 -> Output Terminal 3 */ \
0x12, \
0x24, \
VIDEO_VC_INPUT_TERMINAL_DESCRIPTOR_SUBTYPE, \
0x01, /* bTerminalID */ \
WBVAL(VIDEO_ITT_CAMERA), /* wTerminalType : 0x0201 Camera Sensor*/ \
0x00, /* bAssocTerminal */ \
0x00, /* iTerminal */ \
WBVAL(0x0000), /* wObjectiveFocalLengthMin */ \
WBVAL(0x0000), /* wObjectiveFocalLengthMax */ \
WBVAL(0x0000), /* wOcularFocalLength */ \
0x03, /* bControlSize */ \
0x00, 0x00, 0x00, /* bmControls */ \
0x0c, \
0x24, \
VIDEO_VC_PROCESSING_UNIT_DESCRIPTOR_SUBTYPE, \
0x02, /* bUnitID */ \
0x01, /* bSourceID */ \
0x00, 0x00, /* wMaxMultiplier */ \
0x02, /* bControlSize */ \
0x00, 0x00, /* bmControls */ \
0x00, /* iProcessing */ \
0x00, /* bmVideoStandards */ \
0x09, \
0x24, \
VIDEO_VC_OUTPUT_TERMINAL_DESCRIPTOR_SUBTYPE, \
0x03, /* bTerminalID */ \
WBVAL(VIDEO_TT_STREAMING), \
0x00, /* bAssocTerminal */ \
0x02, /* bSourceID */ \
0x00 /* iTerminal */ \
#define VIDEO_VS_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bNumEndpoints) \
/* Video Streaming (VS) Interface Descriptor */ \
0x09, /* bLength */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType : INTERFACE */ \
bInterfaceNumber, /* bInterfaceNumber: Index of this interface */ \
bAlternateSetting, /* bAlternateSetting: Index of this alternate setting */ \
@@ -1118,21 +1243,37 @@ struct video_autoexposure_mode {
0x00, /* bInterfaceProtocol : PC_PROTOCOL_UNDEFINED */ \
0x00 /* iInterface : unused */
#define VIDEO_VS_HEADER_DESCRIPTOR_INIT(bNumFormats, wTotalLength, bEndpointAddress, ...) \
/*Class-specific VideoStream Header Descriptor (Input) */ \
0x0d + PP_NARG(__VA_ARGS__), \
0x24, \
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_SUBTYPE, \
bNumFormats, /* bNumFormats : One format descriptor follows. */ \
WBVAL(wTotalLength), \
bEndpointAddress, \
0x00, /* bmInfo : No dynamic format change supported. */ \
0x03, /* bTerminalLink : This VideoStreaming interface supplies terminal ID 2 (Output Terminal). */ \
0x00, /* bStillCaptureMethod : Device supports still image capture method 0. */ \
0x00, /* bTriggerSupport : Hardware trigger supported for still image capture */ \
0x00, /* bTriggerUsage : Hardware trigger should initiate a still image capture. */ \
PP_NARG(__VA_ARGS__), /* bControlSize : Size of the bmaControls field */ \
__VA_ARGS__ /* bmaControls : No VideoStreaming specific controls are supported.*/
#define VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(bNumFormats, wTotalLength, bEndpointAddress, ...) \
/*Class-specific VideoStream Header Descriptor (Input) */ \
0x0d + PP_NARG(__VA_ARGS__), \
0x24, \
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_SUBTYPE, \
bNumFormats, /* bNumFormats : One format descriptor follows. */ \
WBVAL(wTotalLength), \
bEndpointAddress, \
0x00, /* bmInfo : No dynamic format change supported. */ \
0x03, /* bTerminalLink : This VideoStreaming interface supplies terminal ID 2 (Output Terminal). */ \
0x00, /* bStillCaptureMethod : Device supports still image capture method 0. */ \
0x00, /* bTriggerSupport : Hardware trigger supported for still image capture */ \
0x00, /* bTriggerUsage : Hardware trigger should initiate a still image capture. */ \
0x01, /* bControlSize : Size of the bmaControls field */ \
__VA_ARGS__ /* bmaControls : No VideoStreaming specific controls are supported.*/
#define VIDEO_VS_OUTPUT_HEADER_DESCRIPTOR_INIT(bNumFormats, wTotalLength, bEndpointAddress, ...) \
/*Class-specific VideoStream Header Descriptor (Input) */ \
0x0d + PP_NARG(__VA_ARGS__), \
0x24, \
VIDEO_VS_OUTPUT_HEADER_DESCRIPTOR_SUBTYPE, \
bNumFormats, /* bNumFormats : One format descriptor follows. */ \
WBVAL(wTotalLength), \
bEndpointAddress, \
0x00, /* bmInfo : No dynamic format change supported. */ \
0x03, /* bTerminalLink : This VideoStreaming interface supplies terminal ID 2 (Output Terminal). */ \
0x00, /* bStillCaptureMethod : Device supports still image capture method 0. */ \
0x00, /* bTriggerSupport : Hardware trigger supported for still image capture */ \
0x00, /* bTriggerUsage : Hardware trigger should initiate a still image capture. */ \
PP_NARG(__VA_ARGS__), /* bControlSize : Size of the bmaControls field */ \
__VA_ARGS__ /* bmaControls : No VideoStreaming specific controls are supported.*/
#define VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_INIT(bFormatIndex, bNumFrameDescriptors, GUIDFormat) \
/*Payload Format(UNCOMPRESSED) Descriptor */ \
@@ -1142,7 +1283,7 @@ struct video_autoexposure_mode {
bFormatIndex, /* bFormatIndex : First (and only) format descriptor */ \
bNumFrameDescriptors, /* bNumFrameDescriptors : One frame descriptor for this format follows. */ \
GUIDFormat, /* GUID Format YUY2 {32595559-0000-0010-8000-00AA00389B71} */ \
0x0c, /* bBitsPerPixel : Number of bits per pixel used to specify color in the decoded video frame - 16 for yuy2*/ \
0x10, /* bBitsPerPixel : Number of bits per pixel used to specify color in the decoded video frame - 16 for yuy2*/ \
0x01, /* bDefaultFrameIndex : Default frame index is 1. */ \
0x00, /* bAspectRatioX : Non-interlaced stream not required. */ \
0x00, /* bAspectRatioY : Non-interlaced stream not required. */ \
@@ -1150,8 +1291,8 @@ struct video_autoexposure_mode {
0x00 /* bCopyProtect : No restrictions imposed on the duplication of this video stream. */
#define VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_INIT(bFrameIndex, wWidth, wHeight, dwMinBitRate, dwMaxBitRate, \
dwMaxVideoFrameBufferSize, dwDefaultFrameInterval, dwFrameInterval) \
0x1e, \
dwMaxVideoFrameBufferSize, dwDefaultFrameInterval, bFrameIntervalType, ...) \
0x1a + PP_NARG(__VA_ARGS__), \
0x24, \
VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_SUBTYPE, \
bFrameIndex, \
@@ -1161,13 +1302,13 @@ struct video_autoexposure_mode {
DBVAL(dwMinBitRate), \
DBVAL(dwMaxBitRate), \
DBVAL(dwMaxVideoFrameBufferSize), \
DBVAL(dwDefaultFrameInterval), \
0x01, \
DBVAL(dwFrameInterval)
dwDefaultFrameInterval, /* dwDefaultFrameInterval : 1,000,000 * 100ns -> 10 FPS */ \
bFrameIntervalType, /* bFrameIntervalType : Indicates how the frame interval can be programmed. 0: Continuous frame interval 1..255: The number of discrete frame */ \
__VA_ARGS__
#define VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(bFormatIndex, bNumFrameDescriptors) \
/*Payload Format(MJPEG) Descriptor */ \
0x0b, /* bLength */ \
0x0b, /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
0x06, /* bDescriptorSubType : VS_FORMAT_MJPEG subtype */ \
bFormatIndex, /* bFormatIndex : First (and only) format descriptor */ \
@@ -1181,7 +1322,7 @@ struct video_autoexposure_mode {
#define VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(bFrameIndex, wWidth, wHeight, dwMinBitRate, dwMaxBitRate, \
dwMaxVideoFrameBufferSize, dwDefaultFrameInterval, bFrameIntervalType, ...) \
0x1a + PP_NARG(__VA_ARGS__), /* bLength */ \
0x1a + PP_NARG(__VA_ARGS__), /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE, /* bDescriptorSubType : VS_FRAME_MJPEG */ \
bFrameIndex, /* bFrameIndex : First (and only) frame descriptor */ \
@@ -1194,5 +1335,46 @@ struct video_autoexposure_mode {
dwDefaultFrameInterval, /* dwDefaultFrameInterval : 1,000,000 * 100ns -> 10 FPS */ \
bFrameIntervalType, /* bFrameIntervalType : Indicates how the frame interval can be programmed. 0: Continuous frame interval 1..255: The number of discrete frame */ \
__VA_ARGS__
#define VIDEO_VS_FORMAT_H264_DESCRIPTOR_INIT(bFormatIndex, bNumFrameDescriptors) \
/*Payload Format(H.264) Descriptor */ \
0x1c, /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
VIDEO_VS_FORMAT_FRAME_BASED_DESCRIPTOR_SUBTYPE, /* bDescriptorSubType : VS_FORMAT_FRAME_BASED subtype */\
bFormatIndex, /* bFormatIndex : First (and only) format descriptor */ \
bNumFrameDescriptors, /* bNumFrameDescriptors : One frame descriptor for this format follows. */ \
VIDEO_GUID_H264, \
0x00, /* bmFlags : Uses fixed size samples.. */ \
0x01, /* bDefaultFrameIndex : Default frame index is 1. */ \
0x00, /* bAspectRatioX : Non-interlaced stream not required. */ \
0x00, /* bAspectRatioY : Non-interlaced stream not required. */ \
0x00, /* bmInterlaceFlags : Non-interlaced stream */ \
0x00, /* bCopyProtect : No restrictions imposed on the duplication of this video stream. */ \
0x00 /* Variable size: False */
#define VIDEO_VS_FRAME_H264_DESCRIPTOR_INIT(bFrameIndex, wWidth, wHeight, dwMinBitRate, dwMaxBitRate, \
dwDefaultFrameInterval, bFrameIntervalType, ...) \
0x1a + PP_NARG(__VA_ARGS__), /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
VIDEO_VS_FRAME_FRAME_BASED_DESCRIPTOR_SUBTYPE, /* bDescriptorSubType : VS_FRAME_BASED */ \
bFrameIndex, /* bFrameIndex : First (and only) frame descriptor */ \
0x00, /* bmCapabilities : Still images using capture method 0 are supported at this frame setting.D1: Fixed frame-rate. */ \
WBVAL(wWidth), /* wWidth (2bytes): Width of frame is 128 pixels. */ \
WBVAL(wHeight), /* wHeight (2bytes): Height of frame is 64 pixels. */ \
DBVAL(dwMinBitRate), /* dwMinBitRate (4bytes): Min bit rate in bits/s */ \
DBVAL(dwMaxBitRate), /* dwMaxBitRate (4bytes): Max bit rate in bits/s */ \
dwDefaultFrameInterval, /* dwDefaultFrameInterval : 1,000,000 * 100ns -> 10 FPS */ \
bFrameIntervalType, /* bFrameIntervalType : Indicates how the frame interval can be programmed. 0: Continuous frame interval 1..255: The number of discrete frame */ \
DBVAL(0x00), /* dwBytesPerLine (4bytes) */ \
__VA_ARGS__
#define VIDEO_VS_COLOR_MATCHING_DESCRIPTOR_INIT() \
0x06, /* bLength */ \
0x24, /* bDescriptorType : CS_INTERFACE */ \
VIDEO_VS_COLORFORMAT_DESCRIPTOR_SUBTYPE, /* bDescriptorSubType : VS_COLORFORMAT */ \
0x01, /* bColorPrimaries */ \
0x01, /* bTransferCharacteristics */ \
0x04 /* bMatrixCoefficients */
// clang-format on
#endif /*USB_VIDEO_H */
@@ -295,8 +295,7 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc
case VIDEO_PU_BRIGHTNESS_CONTROL:
switch (setup->bRequest) {
case VIDEO_REQUEST_SET_CUR: {
uint16_t wBrightness = (uint16_t)(*data)[1] << 8 | (uint16_t)(*data)[0];
USB_LOG_INFO("Video set brightness:%d\r\n", wBrightness);
//uint16_t wBrightness = (uint16_t)(*data)[1] << 8 | (uint16_t)(*data)[0];
} break;
case VIDEO_REQUEST_GET_CUR: {
uint16_t wBrightness = 0x0080;
@@ -762,7 +761,7 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface
return intf;
}
uint32_t usbd_video_mjpeg_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len)
uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len)
{
uint32_t packets;
uint32_t last_packet_size;
@@ -20,7 +20,7 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface
void usbd_video_open(uint8_t busid, uint8_t intf);
void usbd_video_close(uint8_t busid, uint8_t intf);
uint32_t usbd_video_mjpeg_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len);
uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len);
#ifdef __cplusplus
}
@@ -59,10 +59,15 @@ static void usbh_video_class_free(struct usbh_video *video_class)
int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
{
struct usb_setup_packet *setup = video_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
uint8_t retry;
if (!video_class || !video_class->hport) {
return -USB_ERR_INVAL;
}
setup = video_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = request;
setup->wValue = cs << 8;
@@ -91,9 +96,14 @@ int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf
int usbh_video_set(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
{
struct usb_setup_packet *setup = video_class->hport->setup;
struct usb_setup_packet *setup;
int ret;
if (!video_class || !video_class->hport) {
return -USB_ERR_INVAL;
}
setup = video_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = request;
setup->wValue = cs << 8;
@@ -136,7 +146,7 @@ int usbh_video_open(struct usbh_video *video_class,
uint16_t wHeight,
uint8_t altsetting)
{
struct usb_setup_packet *setup = video_class->hport->setup;
struct usb_setup_packet *setup;
struct usb_endpoint_descriptor *ep_desc;
uint8_t mult;
uint16_t mps;
@@ -146,6 +156,11 @@ int usbh_video_open(struct usbh_video *video_class,
uint8_t frameidx = 0;
uint8_t step;
if (!video_class || !video_class->hport) {
return -USB_ERR_INVAL;
}
setup = video_class->hport->setup;
if (video_class->is_opened) {
return 0;
}
@@ -265,9 +280,14 @@ errout:
int usbh_video_close(struct usbh_video *video_class)
{
struct usb_setup_packet *setup = video_class->hport->setup;
struct usb_setup_packet *setup;
int ret = 0;
if (!video_class || !video_class->hport) {
return -USB_ERR_INVAL;
}
setup = video_class->hport->setup;
USB_LOG_INFO("Close video device\r\n");
video_class->is_opened = false;
@@ -217,7 +217,7 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
case OID_GEN_MAXIMUM_FRAME_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
RNDIS_INQUIRY_PUT_LE32(0x05DC);
RNDIS_INQUIRY_PUT_LE32(0x05DC); /* mtu 1500 */
infomation_len = 4;
break;
case OID_GEN_VENDOR_ID:
@@ -255,7 +255,7 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
infomation_len = 4;
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
RNDIS_INQUIRY_PUT_LE32(CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE);
RNDIS_INQUIRY_PUT_LE32(0x0616); /* 1514 + 44 */
infomation_len = 4;
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
@@ -488,7 +488,7 @@ struct pbuf *usbd_rndis_eth_rx(void)
if (p == NULL) {
return NULL;
}
memcpy(p->payload, (uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
usb_memcpy(p->payload, (uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
p->len = g_rndis_rx_data_length;
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_data_length);
@@ -518,7 +518,7 @@ int usbd_rndis_eth_tx(struct pbuf *p)
buffer = (uint8_t *)(g_rndis_tx_buffer + sizeof(rndis_data_packet_t));
for (q = p; q != NULL; q = q->next) {
memcpy(buffer, q->payload, q->len);
usb_memcpy(buffer, q->payload, q->len);
buffer += q->len;
}
@@ -96,7 +96,7 @@ static int usbh_bluetooth_connect(struct usbh_hubport *hport, uint8_t intf)
}
USB_LOG_INFO("Bluetooth select altsetting 0\r\n");
#endif
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT);
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register Bluetooth Class:%s\r\n", hport->config.intf[intf].devname);
usbh_bluetooth_run(bluetooth_class);
return ret;
@@ -234,7 +234,12 @@ delete :
static int usbh_bluetooth_hci_cmd(uint8_t *buffer, uint32_t buflen)
{
struct usbh_bluetooth *bluetooth_class = &g_bluetooth_class;
struct usb_setup_packet *setup = bluetooth_class->hport->setup;
struct usb_setup_packet *setup;
if (!bluetooth_class || !bluetooth_class->hport) {
return -USB_ERR_INVAL;
}
setup = bluetooth_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = 0x00;
@@ -40,11 +40,16 @@ static int usbh_rndis_get_notification(struct usbh_rndis *rndis_class)
static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
{
struct usb_setup_packet *setup = rndis_class->hport->setup;
struct usb_setup_packet *setup;
int ret = 0;
rndis_initialize_msg_t *cmd;
rndis_initialize_cmplt_t *resp;
if (!rndis_class || !rndis_class->hport) {
return -USB_ERR_INVAL;
}
setup = rndis_class->hport->setup;
cmd = (rndis_initialize_msg_t *)g_rndis_buf;
cmd->MessageType = REMOTE_NDIS_INITIALIZE_MSG;
@@ -82,16 +87,26 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
return ret;
}
rndis_class->max_transfer_pkts = resp->MaxPacketsPerTransfer;
rndis_class->max_transfer_size = resp->MaxTransferSize;
USB_LOG_INFO("MaxPacketsPerTransfer:%d\r\n", resp->MaxPacketsPerTransfer);
USB_LOG_INFO("MaxTransferSize:%d\r\n", resp->MaxTransferSize);
return ret;
}
int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, uint32_t query_len, uint8_t *info, uint32_t *info_len)
{
struct usb_setup_packet *setup = rndis_class->hport->setup;
struct usb_setup_packet *setup;
int ret = 0;
rndis_query_msg_t *cmd;
rndis_query_cmplt_t *resp;
if (!rndis_class || !rndis_class->hport) {
return -USB_ERR_INVAL;
}
setup = rndis_class->hport->setup;
cmd = (rndis_query_msg_t *)g_rndis_buf;
cmd->MessageType = REMOTE_NDIS_QUERY_MSG;
@@ -138,11 +153,16 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid,
static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, uint8_t *info, uint32_t info_len)
{
struct usb_setup_packet *setup = rndis_class->hport->setup;
struct usb_setup_packet *setup;
int ret = 0;
rndis_set_msg_t *cmd;
rndis_set_cmplt_t *resp;
if (!rndis_class || !rndis_class->hport) {
return -USB_ERR_INVAL;
}
setup = rndis_class->hport->setup;
cmd = (rndis_set_msg_t *)g_rndis_buf;
cmd->MessageType = REMOTE_NDIS_SET_MSG;
@@ -205,11 +225,16 @@ int usbh_rndis_get_connect_status(struct usbh_rndis *rndis_class)
int usbh_rndis_keepalive(struct usbh_rndis *rndis_class)
{
struct usb_setup_packet *setup = rndis_class->hport->setup;
struct usb_setup_packet *setup;
int ret = 0;
rndis_keepalive_msg_t *cmd;
rndis_keepalive_cmplt_t *resp;
if (!rndis_class || !rndis_class->hport) {
return -USB_ERR_INVAL;
}
setup = rndis_class->hport->setup;
cmd = (rndis_keepalive_msg_t *)g_rndis_buf;
cmd->MessageType = REMOTE_NDIS_KEEPALIVE_MSG;
@@ -382,7 +407,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
rndis_class->mac[4],
rndis_class->mac[5]);
memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register RNDIS Class:%s\r\n", hport->config.intf[intf].devname);
usbh_rndis_run(rndis_class);
@@ -429,6 +454,11 @@ void usbh_rndis_rx_thread(void *argument)
uint32_t pmg_offset;
rndis_data_packet_t *pmsg;
rndis_data_packet_t temp;
#if CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE <= (16 * 1024)
uint32_t transfer_size = CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE;
#else
uint32_t transfer_size = (16 * 1024);
#endif
USB_LOG_INFO("Create rndis rx thread\r\n");
// clang-format off
@@ -445,17 +475,23 @@ find_class:
usb_osal_msleep(100);
goto find_class;
}
usb_osal_msleep(128);
}
g_rndis_rx_length = 0;
while (1) {
usbh_bulk_urb_fill(&g_rndis_class.bulkin_urb, g_rndis_class.hport, g_rndis_class.bulkin, g_rndis_rx_buffer, (CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
usbh_bulk_urb_fill(&g_rndis_class.bulkin_urb, g_rndis_class.hport, g_rndis_class.bulkin, &g_rndis_rx_buffer[g_rndis_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_rndis_class.bulkin_urb);
if (ret < 0) {
goto find_class;
}
g_rndis_rx_length += g_rndis_class.bulkin_urb.actual_length;
/* A transfer is complete because last packet is a short packet.
* Short packet is not zero, match g_rndis_rx_length % USB_GET_MAXPACKETSIZE(g_rndis_class.bulkin->wMaxPacketSize).
* Short packet cannot be zero.
*/
if (g_rndis_rx_length % USB_GET_MAXPACKETSIZE(g_rndis_class.bulkin->wMaxPacketSize)) {
pmg_offset = 0;
@@ -468,7 +504,7 @@ find_class:
/* Not word-aligned case */
if (pmg_offset & 0x3) {
memcpy(&temp, pmsg, sizeof(rndis_data_packet_t));
usb_memcpy(&temp, pmsg, sizeof(rndis_data_packet_t));
pmsg = &temp;
}
@@ -490,9 +526,14 @@ find_class:
}
}
} else {
if (g_rndis_rx_length > CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) {
USB_LOG_ERR("Rx packet is overflow\r\n");
g_rndis_rx_length = 0;
#if CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE <= (16 * 1024)
if (g_rndis_rx_length == CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) {
#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");
while (1) {
}
}
}
}
@@ -504,9 +545,13 @@ delete:
// clang-format on
}
int usbh_rndis_eth_output(uint8_t *buf, uint32_t buflen)
uint8_t *usbh_rndis_get_eth_txbuf(void)
{
return (g_rndis_tx_buffer + sizeof(rndis_data_packet_t));
}
int usbh_rndis_eth_output(uint32_t buflen)
{
uint8_t *buffer;
rndis_data_packet_t *hdr;
uint32_t len;
@@ -522,12 +567,9 @@ int usbh_rndis_eth_output(uint8_t *buf, uint32_t buflen)
hdr->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_generic_msg_t);
hdr->DataLength = buflen;
buffer = (uint8_t *)(g_rndis_tx_buffer + sizeof(rndis_data_packet_t));
memcpy(buffer, buf, buflen);
len = hdr->MessageLength;
/* if message length is the multiple of wMaxPacketSize, we should add a short packet to tell device transfer is over. */
if (!(hdr->MessageLength % g_rndis_class.bulkout->wMaxPacketSize)) {
if (!(len % g_rndis_class.bulkout->wMaxPacketSize)) {
len += 1;
}
@@ -22,6 +22,9 @@ struct usbh_rndis {
uint8_t minor;
uint32_t request_id;
uint32_t tx_offset;
uint32_t max_transfer_pkts; /* max packets in one transfer */
uint32_t max_transfer_size; /* max size in one transfer */
uint32_t link_speed;
bool connect_status;
@@ -40,7 +43,8 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class);
void usbh_rndis_run(struct usbh_rndis *rndis_class);
void usbh_rndis_stop(struct usbh_rndis *rndis_class);
int usbh_rndis_eth_output(uint8_t *buf, uint32_t buflen);
uint8_t *usbh_rndis_get_eth_txbuf(void);
int usbh_rndis_eth_output(uint32_t buflen);
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_rndis_rx_thread(void *argument);
@@ -34,6 +34,7 @@ struct usbh_iso_frame_packet {
* Structure containing the USB Urb configuration.
*/
struct usbh_urb {
usb_slist_t list;
void *hcpriv;
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *ep;
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USB_MEMCPY_H
#define USB_MEMCPY_H
#include <stdint.h>
#include <stddef.h>
#define ALIGN_UP_DWORD(x) ((uint32_t)(uintptr_t)(x) & (sizeof(uint32_t) - 1))
static inline void dword2array(char *addr, uint32_t w)
{
addr[0] = w;
addr[1] = w >> 8;
addr[2] = w >> 16;
addr[3] = w >> 24;
}
static inline void *usb_memcpy(void *s1, const void *s2, size_t n)
{
char *b1 = (char *)s1;
const char *b2 = (const char *)s2;
uint32_t *w1;
const uint32_t *w2;
if (ALIGN_UP_DWORD(b1) == ALIGN_UP_DWORD(b2)) {
while (ALIGN_UP_DWORD(b1) != 0 && n > 0) {
*b1++ = *b2++;
--n;
}
w1 = (uint32_t *)b1;
w2 = (const uint32_t *)b2;
while (n >= 4 * sizeof(uint32_t)) {
*w1++ = *w2++;
*w1++ = *w2++;
*w1++ = *w2++;
*w1++ = *w2++;
n -= 4 * sizeof(uint32_t);
}
while (n >= sizeof(uint32_t)) {
*w1++ = *w2++;
n -= sizeof(uint32_t);
}
b1 = (char *)w1;
b2 = (const char *)w2;
while (n--) {
*b1++ = *b2++;
}
} else {
while (n > 0 && ALIGN_UP_DWORD(b2) != 0) {
*b1++ = *b2++;
--n;
}
w2 = (const uint32_t *)b2;
while (n >= 4 * sizeof(uint32_t)) {
dword2array(b1, *w2++);
b1 += sizeof(uint32_t);
dword2array(b1, *w2++);
b1 += sizeof(uint32_t);
dword2array(b1, *w2++);
b1 += sizeof(uint32_t);
dword2array(b1, *w2++);
b1 += sizeof(uint32_t);
n -= 4 * sizeof(uint32_t);
}
while (n >= sizeof(uint32_t)) {
dword2array(b1, *w2++);
b1 += sizeof(uint32_t);
n -= sizeof(uint32_t);
}
b2 = (const char *)w2;
while (n--) {
*b1++ = *b2++;
}
}
return s1;
}
#endif
@@ -57,7 +57,7 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
#ifdef CONFIG_USBDEV_TEST_MODE
bool test_req;
#endif
struct usbd_interface *intf[8];
struct usbd_interface *intf[16];
uint8_t intf_offset;
struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM];
@@ -98,7 +98,7 @@ static bool is_device_configured(uint8_t busid)
*/
static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descriptor *ep)
{
USB_LOG_INFO("Open ep:0x%02x type:%u mps:%u\r\n",
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));
@@ -125,7 +125,7 @@ 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_INFO("Close ep:0x%02x type:%u\r\n",
USB_LOG_DBG("Close ep:0x%02x type:%u\r\n",
ep->bEndpointAddress,
USB_GET_ENDPOINT_TYPE(ep->bmAttributes));
@@ -177,8 +177,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
break;
case USB_DESCRIPTOR_TYPE_STRING:
if (index == USB_OSDESC_STRING_DESC_INDEX) {
USB_LOG_INFO("read MS OS 2.0 descriptor string\r\n");
if (!g_usbd_core[busid].descriptors->msosv1_descriptor) {
found = false;
break;
@@ -244,8 +242,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
break;
case USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE:
USB_LOG_INFO("read BOS descriptor string\r\n");
if (!g_usbd_core[busid].descriptors->bos_descriptor) {
found = false;
break;
@@ -283,8 +279,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
index = LO_BYTE(type_index);
if ((type == USB_DESCRIPTOR_TYPE_STRING) && (index == USB_OSDESC_STRING_DESC_INDEX)) {
USB_LOG_INFO("read MS OS 2.0 descriptor string\r\n");
if (!g_usbd_core[busid].msosv1_desc) {
return false;
}
@@ -295,8 +289,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
return true;
} else if (type == USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE) {
USB_LOG_INFO("read BOS descriptor string\r\n");
if (!g_usbd_core[busid].bos_desc) {
return false;
}
@@ -623,8 +615,6 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
case USB_REQUEST_GET_DESCRIPTOR:
if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */
USB_LOG_INFO("read hid report descriptor\r\n");
for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) {
struct usbd_interface *intf = g_usbd_core[busid].intf[i];
@@ -813,7 +803,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
if (setup->bRequest == g_usbd_core[busid].descriptors->msosv1_descriptor->vendor_code) {
switch (setup->wIndex) {
case 0x04:
USB_LOG_INFO("get Compat ID\r\n");
desclen = g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id[0] +
(g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id[1] << 8) +
(g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id[2] << 16) +
@@ -824,7 +813,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
*len = desclen;
return 0;
case 0x05:
USB_LOG_INFO("get Compat id properties\r\n");
desclen = g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue][0] +
(g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue][1] << 8) +
(g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue][2] << 16) +
@@ -843,8 +831,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
if (setup->bRequest == g_usbd_core[busid].descriptors->msosv2_descriptor->vendor_code) {
switch (setup->wIndex) {
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
desclen = g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id_len;
*data = (uint8_t *)g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id;
//memcpy(*data, g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id, desclen);
@@ -859,8 +845,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
if (setup->bRequest == g_usbd_core[busid].descriptors->webusb_url_descriptor->vendor_code) {
switch (setup->wIndex) {
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
USB_LOG_INFO("GET Webusb url Descriptor\r\n");
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);
@@ -877,7 +861,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
if (setup->bRequest == g_usbd_core[busid].msosv1_desc->vendor_code) {
switch (setup->wIndex) {
case 0x04:
USB_LOG_INFO("get Compat ID\r\n");
*data = (uint8_t *)g_usbd_core[busid].msosv1_desc->compat_id;
desclen = g_usbd_core[busid].msosv1_desc->compat_id[0] +
(g_usbd_core[busid].msosv1_desc->compat_id[1] << 8) +
@@ -887,7 +870,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
*len = desclen;
return 0;
case 0x05:
USB_LOG_INFO("get Compat id properties\r\n");
*data = (uint8_t *)g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue];
desclen = g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][0] +
(g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][1] << 8) +
@@ -905,7 +887,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
if (setup->bRequest == g_usbd_core[busid].msosv2_desc->vendor_code) {
switch (setup->wIndex) {
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
*data = (uint8_t *)g_usbd_core[busid].msosv2_desc->compat_id;
//memcpy(*data, g_usbd_core[busid].msosv2_desc->compat_id, g_usbd_core[busid].msosv2_desc->compat_id_len);
*len = g_usbd_core[busid].msosv2_desc->compat_id_len;
@@ -22,6 +22,7 @@ extern "C" {
#include "usb_list.h"
#include "usb_log.h"
#include "usb_dc.h"
#include "usb_memcpy.h"
enum usbd_event_type {
/* USB DCD IRQ */
+130 -100
View File
@@ -81,13 +81,9 @@ static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
static int usbh_free_devaddr(struct usbh_hubport *hport)
{
#ifndef CONFIG_USBHOST_XHCI
if (hport->dev_addr > 0) {
__usbh_free_devaddr(&hport->bus->devgen, hport->dev_addr);
}
#endif
hport->dev_addr = 0;
return 0;
}
@@ -398,23 +394,12 @@ int usbh_enumerate(struct usbh_hubport *hport)
/* Reconfigure EP0 with the correct maximum packet size */
ep->wMaxPacketSize = ep_mps;
#ifdef CONFIG_USBHOST_XHCI
extern int usbh_get_xhci_devaddr(usbh_pipe_t * pipe);
/* Assign a function address to the device connected to this port */
dev_addr = usbh_get_xhci_devaddr(hport->ep0);
if (dev_addr < 0) {
USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
goto errout;
}
#else
/* Assign a function address to the device connected to this port */
dev_addr = usbh_allocate_devaddr(&hport->bus->devgen);
if (dev_addr < 0) {
USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
goto errout;
}
#endif
/* Set the USB device address */
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -617,8 +602,6 @@ void usbh_hubport_release(struct usbh_hubport *hport)
static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base)
{
struct usbh_hub *hub;
memset(bus, 0, sizeof(struct usbh_bus));
bus->busid = busid;
bus->hcd.hcd_id = busid;
@@ -627,20 +610,6 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base
/* devaddr 1 is for roothub */
bus->devgen.next = 2;
usb_slist_init(&bus->hub_list);
hub = &bus->hcd.roothub;
hub->connected = true;
hub->index = 1;
hub->is_roothub = true;
hub->parent = NULL;
hub->hub_addr = 1;
hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
hub->int_buffer = bus->hcd.roothub_intbuf;
hub->bus = bus;
usb_slist_init(&bus->hub_list);
usb_slist_add_tail(&bus->hub_list, &hub->list);
usb_slist_add_tail(&g_bus_head, &bus->list);
}
@@ -684,7 +653,6 @@ int usbh_deinitialize(uint8_t busid)
usbh_hub_deinitialize(bus);
usb_slist_init(&bus->hub_list);
usb_slist_remove(&g_bus_head, &bus->list);
return 0;
@@ -757,24 +725,29 @@ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsett
return usbh_control_transfer(hport, setup, NULL);
}
void *usbh_find_class_instance(const char *devname)
static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devname)
{
struct usbh_hubport *hport;
usb_slist_t *hub_list;
usb_slist_t *bus_list;
struct usbh_hub *hub_next;
void *priv;
usb_slist_for_each(bus_list, &g_bus_head)
{
struct usbh_bus *bus = usb_slist_entry(bus_list, struct usbh_bus, list);
usb_slist_for_each(hub_list, &bus->hub_list)
{
struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
if (hport->connected) {
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
return hport->config.intf[itf].priv;
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
if (hport->connected) {
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
return hport->config.intf[itf].priv;
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
hub_next = hport->config.intf[itf].priv;
if (hub_next && hub_next->connected) {
priv = usbh_list_all_interface_name(hub_next, devname);
if (priv) {
return priv;
}
}
}
}
}
@@ -783,11 +756,101 @@ void *usbh_find_class_instance(const char *devname)
return NULL;
}
static void usbh_list_all_interface_driver(struct usbh_hub *hub)
{
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
if (hport->connected) {
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
for (uint8_t j = 0; j < hub->index; j++) {
USB_LOG_RAW("\t");
}
USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s\r\n",
hport->port,
hport->dev_addr,
itf,
hport->config.intf[itf].class_driver->driver_name);
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
hub_next = hport->config.intf[itf].priv;
if (hub_next && hub_next->connected) {
usbh_list_all_interface_driver(hub_next);
}
}
}
}
}
}
}
static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *hub)
{
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
if (hport->connected) {
USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
bus->busid,
hub->index,
hport->port,
hport->dev_addr,
hport->device_desc.idVendor,
hport->device_desc.idProduct);
usbh_print_hubport_info(hport);
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
hub_next = hport->config.intf[itf].priv;
if (hub_next && hub_next->connected) {
usbh_list_all_interface_desc(bus, hub_next);
}
}
}
}
}
}
}
void *usbh_find_class_instance(const char *devname)
{
usb_slist_t *bus_list;
struct usbh_hub *hub;
struct usbh_bus *bus;
void *priv;
size_t flags;
flags = usb_osal_enter_critical_section();
usb_slist_for_each(bus_list, &g_bus_head)
{
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
hub = &bus->hcd.roothub;
priv = usbh_list_all_interface_name(hub, devname);
if (priv) {
usb_osal_leave_critical_section(flags);
return priv;
}
}
usb_osal_leave_critical_section(flags);
return NULL;
}
int lsusb(int argc, char **argv)
{
usb_slist_t *hub_list;
usb_slist_t *bus_list;
struct usbh_hubport *hport;
struct usbh_hub *hub;
struct usbh_bus *bus;
size_t flags;
if (argc < 2) {
USB_LOG_RAW("Usage: lsusb [options]...\r\n");
@@ -810,69 +873,36 @@ int lsusb(int argc, char **argv)
return 0;
}
flags = usb_osal_enter_critical_section();
if (strcmp(argv[1], "-V") == 0) {
USB_LOG_RAW("CherryUSB Version %s\r\n", CHERRYUSB_VERSION_STR);
}
if (strcmp(argv[1], "-t") == 0) {
usb_slist_for_each(bus_list, &g_bus_head)
{
struct usbh_bus *bus = usb_slist_entry(bus_list, struct usbh_bus, list);
usb_slist_for_each(hub_list, &bus->hub_list)
{
struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
hub = &bus->hcd.roothub;
if (hub->is_roothub) {
USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
bus->busid,
hub->index,
hub->hub_desc.bNbrPorts);
} else {
USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, mounted on Hub %02u:Port %u\r\n",
bus->busid,
hub->index,
hub->hub_desc.bNbrPorts,
hub->parent->parent->index,
hub->parent->port);
}
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
if (hport->connected) {
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->driver_name) {
USB_LOG_RAW("\t|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s\r\n",
hport->port,
hport->dev_addr,
i,
hport->config.intf[i].class_driver->driver_name);
}
}
}
}
}
USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
bus->busid,
hub->index,
hub->hub_desc.bNbrPorts);
usbh_list_all_interface_driver(hub);
}
}
if (strcmp(argv[1], "-v") == 0) {
usb_slist_for_each(bus_list, &g_bus_head)
{
struct usbh_bus *bus = usb_slist_entry(bus_list, struct usbh_bus, list);
usb_slist_for_each(hub_list, &bus->hub_list)
{
struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
if (hport->connected) {
USB_LOG_RAW("Bus %u, Hub %02u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
bus->busid,
hub->index,
hport->port,
hport->dev_addr,
hport->device_desc.idVendor,
hport->device_desc.idProduct);
usbh_print_hubport_info(hport);
}
}
}
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
hub = &bus->hcd.roothub;
usbh_list_all_interface_desc(bus, hub);
}
}
usb_osal_leave_critical_section(flags);
return 0;
}
@@ -20,6 +20,7 @@
#include "usb_hc.h"
#include "usb_osal.h"
#include "usbh_hub.h"
#include "usb_memcpy.h"
#ifdef __cplusplus
extern "C" {
@@ -51,10 +52,10 @@ extern "C" {
ep = ep_desc; \
USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", \
ep_desc->bEndpointAddress, \
USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes), \
ep_desc->bmAttributes, \
USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize), \
ep_desc->bInterval, \
USB_GET_MULT(ep_desc->bmAttributes)); \
USB_GET_MULT(ep_desc->wMaxPacketSize)); \
} while (0)
struct usbh_class_info {
@@ -109,16 +110,12 @@ struct usbh_hubport {
struct usb_setup_packet *setup;
struct usbh_hub *parent;
struct usbh_bus *bus;
#ifdef CONFIG_USBHOST_XHCI
uint32_t protocol; /* port protocol, for xhci, some ports are USB2.0, others are USB3.0 */
#endif
struct usb_endpoint_descriptor ep0;
struct usbh_urb ep0_urb;
usb_osal_mutex_t mutex;
};
struct usbh_hub {
usb_slist_t list;
bool connected;
bool is_roothub;
uint8_t index;
@@ -159,7 +156,6 @@ struct usbh_bus {
struct usbh_devaddr_map devgen;
usb_osal_thread_t hub_thread;
usb_osal_mq_t hub_mq;
usb_slist_t hub_list;
};
static inline void usbh_control_urb_fill(struct usbh_urb *urb,
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because one or more lines are too long
@@ -194,11 +194,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
void usbd_audio_close(uint8_t busid, uint8_t intf)
{
if (intf == 1) {
rx_flag = 1;
ep_tx_busy_flag = false;
rx_flag = 0;
printf("CLOSE1\r\n");
} else {
tx_flag = 0;
ep_tx_busy_flag = false;
printf("CLOSE2\r\n");
}
}
@@ -275,7 +275,7 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
void usbd_audio_close(uint8_t busid, uint8_t intf)
{
if (intf == 1) {
rx_flag = 1;
rx_flag = 0;
USB_LOG_RAW("CLOSE1\r\n");
} else {
tx_flag = 0;
@@ -215,6 +215,7 @@ void cdc_ecm_lwip_init(void)
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, mac, 6);
netif->hwaddr[5] = ~netif->hwaddr[5]; /* device mac can't same as host. */
netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, cdc_ecm_if_init, netif_input);
netif_set_default(netif);
@@ -264,14 +265,14 @@ struct usbd_interface intf0;
struct usbd_interface intf1;
/* ecm only supports in linux, and you should input the following command
*
*
* sudo ifconfig enxaabbccddeeff up
* sudo dhcpclient enxaabbccddeeff
*/
void cdc_ecm_init(uint8_t busid, uint32_t reg_base)
{
cdc_ecm_lwip_init();
usbd_desc_register(busid, cdc_ecm_descriptor);
usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf0, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf1, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
@@ -143,7 +143,11 @@ static rt_err_t rt_usbd_rndis_control(rt_device_t dev, int cmd, void *args)
/* get mac address */
if (args)
rt_memcpy(args, mac, 6);
{
uint8_t *mac_dev = (uint8_t *)args;
rt_memcpy(mac_dev, mac, 6);
mac_dev[5] = ~mac_dev[5]; /* device mac can't same as host. */
}
else
return -RT_ERROR;
@@ -247,6 +251,7 @@ void rndis_lwip_init(void)
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, mac, 6);
netif->hwaddr[5] = ~netif->hwaddr[5]; /* device mac can't same as host. */
netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, rndisif_init, netif_input);
netif_set_default(netif);
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More