103 Commits

Author SHA1 Message Date
sakumisu
3336919e0d release v1.3.0 2024-05-22 18:51:41 +08:00
sakumisu
8b070570a7 fix(port/ehci): fix missing busid 2024-05-22 18:51:41 +08:00
sakumisu
af792eabab fix typo 2024-05-21 16:08:28 +08:00
sakumisu
3be08d16f7 update(port/dwc2): rename struct name to avoid duplicate definitions 2024-05-21 11:50:49 +08:00
sakumisu
5dafdcb895 fix warning 2024-05-21 10:10:31 +08:00
sakumisu
f24c37d3aa update(class/wireless/usbd_rndis): remove ununsed speed field 2024-05-20 18:15:01 +08:00
Zhihong Chen
a7a7afc6bb port: HPMicro: update usb_glue_hpm
- update usb_glue_hpm

Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2024-05-18 10:17:57 +08:00
sakumisu
66b893e64f update: add langid in string desc 2024-05-17 22:18:21 +08:00
sakumisu
3a3de9cb69 update: format log 2024-05-17 17:22:25 +08:00
sakumisu
13e4670f3d update: remove internal configs, you should get config from usb_config.h 2024-05-17 17:04:53 +08:00
sakumisu
1d9a36b61c update(docs): update rst 2024-05-17 17:03:50 +08:00
sakumisu
b1c81a92f5 fix warning 2024-05-16 20:47:37 +08:00
sakumisu
af92236cf4 refactor(core/usbd_core): process string internal, you can use like \"cherryusb\" now 2024-05-16 11:19:58 +08:00
sakumisu
0985a7e5fa fix(port/usb_hc_ehci): clear iaad status 2024-05-16 10:13:52 +08:00
sakumisu
8b805ee6d7 fix(dwc2): check those chips with 1.25KB fifo 2024-05-15 23:07:46 +08:00
sakumisu
5e6bd78f80 update(dwc2): change rx fifo to 1024/4 as default 2024-05-15 22:37:57 +08:00
sakumisu
f2133f5ca2 update(docs): update rst 2024-05-15 12:10:38 +08:00
sakumisu
9657585f1f update(core/usbh_core): remove ununsed urb memset 2024-05-15 09:57:21 +08:00
sakumisu
a225ee383b update(demo/midi): add read api 2024-05-14 21:34:50 +08:00
sakumisu
60747ce435 update(port/musb): add sunxi glue for check 2024-05-14 21:34:15 +08:00
sakumisu
490cac1a0f fix(class): change ifdef to if for LWIP_TCPIP_CORE_LOCKING_INPUT 2024-05-14 13:59:39 +08:00
sakumisu
207fb7b128 update(usbh_ncm/usbh_rndis): limit read size to 16K 2024-05-14 13:53:58 +08:00
sakumisu
d23a8a8d00 update: get mps by usbd_get_ep_mps 2024-05-14 11:33:11 +08:00
sakumisu
4243394225 fix(demo): remove duplicate macro 2024-05-14 11:32:56 +08:00
sakumisu
62c9c8b747 update(demo/usb_host): change eth name index 2024-05-12 20:50:29 +08:00
sakumisu
7b38b4b323 update(demo/usb_host): disable keep timer(no need) 2024-05-12 20:47:42 +08:00
sakumisu
e1aa49e086 fix typo 2024-05-12 20:47:34 +08:00
sakumisu
fabeebd4c5 fix(class/vendor/net/usbh_asix): fix write cmd param 2024-05-12 20:47:34 +08:00
sakumisu
58550b3ed5 update: rename ecm and asix eth macro name 2024-05-12 20:47:34 +08:00
sakumisu
363533be4c update(class/vendor/net/usbh_rtl8152): update eth rx/tx size 2024-05-12 20:47:34 +08:00
sakumisu
074662a50d fix(class/wireless/usbh_rndis): when last data is dummy byte, ignore it 2024-05-12 20:47:33 +08:00
sakumisu
532e05e293 fix nuttx timeout 2024-05-11 15:59:25 +08:00
sakumisu
b55d40e512 change CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE to 1580 default 2024-05-11 14:01:42 +08:00
Zhihong Chen
263a66ed9b port: HPMicro: update hpm usb deivce port file
- update hpm usb deivce port file

Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2024-05-10 12:27:54 +08:00
sakumisu
775ac135de bugfix by ccef9b92 2024-05-10 11:36:17 +08:00
sakumisu
aecae9434b add kconfig template 2024-05-10 10:12:48 +08:00
sakumisu
5a7042fe15 import aic dcd port 2024-05-10 10:12:42 +08:00
sakumisu
18c4454228 add nuttx osal 2024-05-09 10:45:27 +08:00
sakumisu
cd8b103a71 update rtt config check 2024-05-08 19:28:20 +08:00
sakumisu
8ecbd32483 remove qh with iaad 2024-05-08 17:17:57 +08:00
sakumisu
d0f79ff668 update host demo to support multi class 2024-05-05 13:34:36 +08:00
sakumisu
7272ccfc02 update company support 2024-05-05 12:12:00 +08:00
sakumisu
e081642c76 add pl2303 host driver 2024-05-05 11:38:25 +08:00
sakumisu
b51da4fbf9 remove ununsed code 2024-05-04 20:09:04 +08:00
sakumisu
97c5e37453 add check for rtt config 2024-05-04 15:49:54 +08:00
sakumisu
cdd308f3e8 fix typo 2024-05-04 15:48:45 +08:00
sakumisu
6db4fbba4c add check for hpm 2024-05-04 14:21:13 +08:00
sakumisu
102801e45c add comments for macros 2024-05-03 20:34:13 +08:00
sakumisu
0ceb7ef885 zero copy when enables LWIP_TCPIP_CORE_LOCKING_INPUT 2024-05-03 19:53:22 +08:00
sakumisu
ae5a9d1e57 check if eth rx packet is overflow 2024-05-03 19:19:17 +08:00
sakumisu
7ebcafe158 adjust code order 2024-05-03 18:57:09 +08:00
sakumisu
81cebaf78c add vendor serial into cmake 2024-05-03 18:55:12 +08:00
sakumisu
5fec929b93 support id table for multi vid pid 2024-05-03 18:54:36 +08:00
sakumisu
4bf0e126af move usbh_hubport_release api to core 2024-05-03 18:00:59 +08:00
sakumisu
ccef9b92cc bugfix for 183d49, add CONFIG_USBDEV_EP0_INDATA_NO_COPY 2024-05-03 14:07:26 +08:00
Zhihong Chen
9cb992bed7 add USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT and USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT macros
Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2024-04-30 20:05:57 +08:00
sakumisu
183d49efbd copy data into ep0 buffer at a unified location 2024-04-30 14:21:31 +08:00
sakumisu
8d18a8b6e5 change CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE to 2048 default 2024-04-30 14:10:17 +08:00
sakumisu
5f79fdc865 include ehci port path in cmake 2024-04-30 14:08:13 +08:00
sakumisu
2f5f2b906f add usbd_get_ep_mult api 2024-04-29 14:11:24 +08:00
sakumisu
0556ae199b add config for cdc ncm transfer size 2024-04-29 11:46:31 +08:00
sakumisu
2da4edf76b remove port param in usbd_get_port_speed 2024-04-29 11:35:29 +08:00
sakumisu
45e9a2fde8 add usbd_get_ep_mps api 2024-04-29 11:32:54 +08:00
sakumisu
5b72907f6d simplify code for get device qualifier desc 2024-04-29 11:29:52 +08:00
sakumisu
6abe6befa8 fix rndis msg when mss is larger than rndis rx size 2024-04-28 19:54:53 +08:00
sakumisu
7ee77b42ee check class_driver is null 2024-04-25 21:20:24 +08:00
sakumisu
404225ade4 change INFO to DBG 2024-04-25 21:17:56 +08:00
sakumisu
694b201ff7 move get speed before get device desc 2024-04-25 21:11:55 +08:00
sakumisu
23e2787a43 add user_data param in host class for users 2024-04-24 22:40:55 +08:00
sakumisu
a3302584ce remove dfu exe,use url instead 2024-04-24 22:27:52 +08:00
sakumisu
8625e4409e support speed get in when enables CONFIG_USBDEV_ADVANCE_DESC 2024-04-24 22:10:47 +08:00
sakumisu
190fb36c43 add hid host report api 2024-04-23 22:02:16 +08:00
sakumisu
a24d2bdc07 fix rndis send dummy 2024-04-23 21:30:59 +08:00
sakumisu
ceaf0923c5 fix caculate precision 2024-04-23 16:33:02 +08:00
sakumisu
2cb6c598c1 update missing license 2024-04-23 13:04:41 +08:00
sakumisu
4e6b0d0923 format code 2024-04-23 10:52:45 +08:00
sakumisu
017eb5560d fix missing busid 2024-04-19 13:03:54 +08:00
sakumisu
b97fc903c0 clear urb timeout after take sem, follow 76f58b93 2024-04-19 11:52:04 +08:00
sakumisu
81ddf9bded change ep0 buffer to 512 2024-04-18 22:06:20 +08:00
sakumisu
8995cf9568 move rndis config macros into template 2024-04-18 21:27:34 +08:00
sakumisu
76f58b93fe do not clear timeout in irq,urb init will sometime call irq before take sem 2024-04-18 21:11:36 +08:00
sakumisu
70c7f1ccbd use only one dhcp timer, delete timer when stop 2024-04-17 22:09:48 +08:00
sakumisu
29c72f3455 update msh cmd and scons 2024-04-16 22:18:25 +08:00
sakumisu
51b9640489 add missing license 2024-04-16 22:11:30 +08:00
sakumisu
32f96f4248 remove duplicate h7 config 2024-04-16 21:52:52 +08:00
sakumisu
e3886fe99d format comment 2024-04-16 21:48:11 +08:00
zhaofx4534
d8714d8169 enable bit21(VBUSSIG) in gd chips 2024-04-15 21:36:58 +08:00
sakumisu
9d5479e0c3 list all porting macros into template for use 2024-04-14 19:53:20 +08:00
sakumisu
ed8a3ceca3 add ifndef for test macros 2024-04-14 19:36:34 +08:00
sakumisu
3592794393 import bouffalo dcd 2024-04-14 19:35:48 +08:00
Zhihong Chen
4357a1d7d1 osal: freeRTOS: fix enter/exit critical
- fix enter/exit critical

Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2024-04-13 11:08:53 +08:00
sakumisu
c1cb6e397b move queue files 2024-04-11 10:14:43 +08:00
sakumisu
c8be4d6fd3 change INFO to RAW 2024-04-07 23:31:04 +08:00
sakumisu
725d635c76 add cherryrb and cherry pool 2024-04-07 23:30:51 +08:00
sakumisu
1eef5f3e35 add config index to select multi configs 2024-04-07 16:53:53 +08:00
sakumisu
1dd45e3e5a update rst for ld 2024-04-07 13:26:03 +08:00
sakumisu
8119a500b2 change CONFIG_USB_DWC2_ULPI_PHY to CONFIG_USB_HS, support stm32f723 2024-04-07 13:20:33 +08:00
sakumisu
c5f2ffa6f9 export ehci config macros 2024-04-07 13:17:01 +08:00
sakumisu
db10c62b59 read ehci hcor offset from hccr caplength 2024-04-06 20:19:53 +08:00
sakumisu
808cd454a3 init ohci for ehci 2024-04-04 16:43:05 +08:00
sakumisu
a41c66c2c3 change rt_ssize_t to ssize_t, compatible with older rtt version 2024-04-04 12:56:43 +08:00
sakumisu
6ef086a085 add check for dwc2 fifo with ep mps 2024-04-03 15:44:43 +08:00
sakumisu
5494b0e99a add check for wTotalLength 2024-04-03 11:27:28 +08:00
158 changed files with 7824 additions and 1213 deletions

304
Kconfig.cherryusb Normal file
View File

@@ -0,0 +1,304 @@
# Kconfig file for CherryUSB
menuconfig CHERRYUSB
bool "Using CherryUSB"
default n
if CHERRYUSB
menuconfig CHERRYUSB_DEVICE
bool "Enable usb device mode"
default n
if CHERRYUSB_DEVICE
choice
prompt "Select usb device speed"
default CHERRYUSB_DEVICE_SPEED_FS
config CHERRYUSB_DEVICE_SPEED_FS
bool "FS"
config CHERRYUSB_DEVICE_SPEED_HS
bool "HS"
config CHERRYUSB_DEVICE_SPEED_AUTO
bool "AUTO"
endchoice
choice
prompt "Select usb device ip, and some ip need config in usb_config.h, please check"
default CHERRYUSB_DEVICE_CUSTOM
config CHERRYUSB_DEVICE_CUSTOM
bool "CUSTOM (Implement it yourself)"
config CHERRYUSB_DEVICE_FSDEV
bool "fsdev"
config CHERRYUSB_DEVICE_DWC2_ST
bool "dwc2_st"
config CHERRYUSB_DEVICE_DWC2_ESP
bool "dwc2_esp"
config CHERRYUSB_DEVICE_DWC2_AT
bool "dwc2_at"
config CHERRYUSB_DEVICE_DWC2_GD
bool "dwc2_gd"
config CHERRYUSB_DEVICE_DWC2_CUSTOM
bool "dwc2_custom"
config CHERRYUSB_DEVICE_MUSB_STANDARD
bool "musb_standard"
config CHERRYUSB_DEVICE_MUSB_SUNXI
bool "musb_sunxi"
config CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_DEVICE_BL
bool "bouffalo"
config CHERRYUSB_DEVICE_HPM
bool "hpm"
config CHERRYUSB_DEVICE_AIC
bool "aic"
config CHERRYUSB_DEVICE_CH32
bool "ch32"
config CHERRYUSB_DEVICE_PUSB2
bool "pusb2"
endchoice
config CHERRYUSB_DEVICE_CDC_ACM
bool
prompt "Enable usb cdc acm device"
default n
config CHERRYUSB_DEVICE_HID
bool
prompt "Enable usb hid device"
default n
config CHERRYUSB_DEVICE_MSC
bool
prompt "Enable usb msc device"
default n
config CHERRYUSB_DEVICE_AUDIO
bool
prompt "Enable usb audio device"
default n
config CHERRYUSB_DEVICE_VIDEO
bool
prompt "Enable usb video device"
default n
config CHERRYUSB_DEVICE_CDC_RNDIS
bool
prompt "Enable usb cdc rndis device"
default n
config CHERRYUSB_DEVICE_CDC_ECM
bool
prompt "Enable usb cdc ecm device"
default n
config CHERRYUSB_DEVICE_CDC_NCM
bool
prompt "Enable usb cdc ncm device"
default n
config CHERRYUSB_DEVICE_DFU
bool
prompt "Enable usb dfu device"
default n
choice
prompt "Select usb device template"
default CHERRYUSB_DEVICE_TEMPLATE
config CHERRYUSB_DEVICE_TEMPLATE_NONE
bool "none (Implement it yourself)"
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
bool "cdc_acm"
config CHERRYUSB_DEVICE_TEMPLATE_MSC
bool "msc"
config CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
bool "hid_keyboard"
config CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
bool "hid_mouse"
config CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
bool "hid_custom"
config CHERRYUSB_DEVICE_TEMPLATE_VIDEO
bool "video"
config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
bool "audio_v1_mic_speaker_multichan"
config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
bool "audio_v2_mic_speaker_multichan"
config CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
bool "cdc_rndis"
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
bool "cdc_ecm"
config CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
bool "cdc_ncm"
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
bool "cdc_acm_msc"
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
bool "cdc_acm_msc_hid"
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
bool "winusbv1"
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
bool "winusbv2_cdc"
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
bool "winusbv2_hid"
endchoice
endif
menuconfig CHERRYUSB_HOST
bool "Enable usb host mode"
default n
if CHERRYUSB_HOST
choice
prompt "Select usb host ip, and some ip need config in usb_config.h, please check"
default CHERRYUSB_HOST_CUSTOM
config CHERRYUSB_HOST_CUSTOM
bool "CUSTOM (Implement it yourself)"
config CHERRYUSB_HOST_EHCI_BL
bool "ehci_bouffalo"
config CHERRYUSB_HOST_EHCI_HPM
bool "ehci_hpm"
config CHERRYUSB_HOST_EHCI_AIC
bool "ehci_aic"
config CHERRYUSB_HOST_EHCI_NUVOTON_NUC980
bool "ehci_nuvoton_nuc980"
config CHERRYUSB_HOST_EHCI_NUVOTON_MA35D0
bool "ehci_nuvoton_ma35d0"
config CHERRYUSB_HOST_EHCI_CUSTOM
bool "ehci_custom"
config CHERRYUSB_HOST_DWC2_ST
bool "dwc2_st"
config CHERRYUSB_HOST_DWC2_ESP
bool "dwc2_esp"
config CHERRYUSB_HOST_DWC2_CUSTOM
bool "dwc2_custom"
config CHERRYUSB_HOST_MUSB_STANDARD
bool "musb_standard"
config CHERRYUSB_HOST_MUSB_SUNXI
bool "musb_sunxi"
config CHERRYUSB_HOST_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_HOST_PUSB2
bool "pusb2"
config CHERRYUSB_HOST_XHCI
bool "xhci"
endchoice
config CHERRYUSB_HOST_CDC_ACM
bool
prompt "Enable usb cdc acm driver"
default n
config CHERRYUSB_HOST_HID
bool
prompt "Enable usb hid driver"
default n
config CHERRYUSB_HOST_MSC
bool
prompt "Enable usb msc driver"
default n
config CHERRYUSB_HOST_CDC_RNDIS
bool
prompt "Enable usb rndis driver"
default n
config CHERRYUSB_HOST_CDC_ECM
bool
prompt "Enable usb cdc ecm driver"
default n
config CHERRYUSB_HOST_CDC_NCM
bool
prompt "Enable usb cdc ncm driver"
default n
config CHERRYUSB_HOST_VIDEO
bool
prompt "Enable usb video driver, it is commercial charge"
default n
config CHERRYUSB_HOST_AUDIO
bool
prompt "Enable usb audio driver, it is commercial charge"
default n
config CHERRYUSB_HOST_BLUETOOTH
bool
prompt "Enable usb bluetooth driver"
default n
config CHERRYUSB_HOST_ASIX
bool
prompt "Enable usb asix driver"
default n
config CHERRYUSB_HOST_RTL8152
bool
prompt "Enable usb rtl8152 driver"
default n
config CHERRYUSB_HOST_FTDI
bool
prompt "Enable usb ftdi driver"
default n
config CHERRYUSB_HOST_CH34X
bool
prompt "Enable usb ch34x driver"
default n
config CHERRYUSB_HOST_CP210X
bool
prompt "Enable usb cp210x driver"
default n
config CHERRYUSB_HOST_TEMPLATE
bool
prompt "Use usb host template"
default n
if CHERRYUSB_HOST_TEMPLATE
config TEST_USBH_CDC_ACM
int
prompt "demo for test cdc acm"
default 0
depends on CHERRYUSB_HOST_CDC_ACM
config TEST_USBH_HID
int
prompt "demo for test hid"
default 0
depends on CHERRYUSB_HOST_HID
config TEST_USBH_MSC
int
prompt "demo for test msc, do not enable because it has used dfs instead"
default 0
depends on CHERRYUSB_HOST_MSC
config TEST_USBH_CDC_ECM
int
prompt "demo for test cdc ecm"
default 0
depends on CHERRYUSB_HOST_CDC_ECM
config TEST_USBH_CDC_NCM
int
prompt "demo for test cdc ncm"
default 0
depends on CHERRYUSB_HOST_CDC_NCM
config TEST_USBH_RNDIS
int
prompt "demo for test cdc rndis"
default 0
depends on CHERRYUSB_HOST_CDC_RNDIS
config TEST_USBH_ASIX
int
prompt "demo for test asix"
default 0
depends on CHERRYUSB_HOST_ASIX
config TEST_USBH_RTL8152
int
prompt "demo for test rtl8152"
default 0
depends on CHERRYUSB_HOST_RTL8152
endif
endif
endif

View File

@@ -191,7 +191,7 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|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 | dwc2/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | 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 |
@@ -200,4 +200,10 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
## Contact
CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
## Company Support
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" />

View File

@@ -190,7 +190,7 @@ CherryUSB 快速入门、USB 基本概念API 手册Class 基本概念和
|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 | dwc2/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | 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 |
@@ -200,4 +200,10 @@ CherryUSB 快速入门、USB 基本概念API 手册Class 基本概念和
## Contact
CherryUSB QQ 群:642693751
CherryUSB 微信群:与我联系后邀请加入
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" />

View File

@@ -26,13 +26,6 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
if GetDepend(['PKG_CHERRYUSB_DEVICE_HS']):
CPPDEFINES+=['CONFIG_USB_HS']
if GetDepend(['PKG_CHERRYUSB_DEVICE_BL']):
CPPDEFINES += ['CONFIG_CHERRYUSB']
if GetDepend(['PKG_CHERRYUSB_DEVICE_CH32']):
if GetDepend(['PKG_CHERRYUSB_DEVICE_HS']):
src += Glob('port/ch32/usb_dc_usbhs.c')
else:
src += Glob('port/ch32/usb_dc_usbfs.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_FSDEV']):
src += Glob('port/fsdev/usb_dc_fsdev.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_ST']):
@@ -44,25 +37,30 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_AT']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
src += Glob('port/dwc2/usb_glue_at.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_AIC']):
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_GD']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
src += Glob('port/dwc2/usb_glue_aic.c')
src += Glob('port/dwc2/usb_glue_gd.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_CUSTOM']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_STANDARD']):
src += Glob('port/musb/usb_dc_musb.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_SUNXI']):
src += Glob('port/musb/usb_dc_musb.c')
CPPDEFINES += ['CONFIG_USB_MUSB_SUNXI']
src += Glob('port/musb/usb_glue_sunxi.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM']):
src += Glob('port/musb/usb_dc_musb.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_BL']):
src += Glob('port/bouffalolab/usb_dc_bl.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_HPM']):
src += Glob('port/hpm/usb_dc_hpm.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_PUSB2']):
path += [cwd + '/port/pusb2/common']
path += [cwd + '/port/pusb2/fpusb2']
src += Glob('port/pusb2/fpusb2' + '/*.c')
src += Glob('port/pusb2/usb_dc_pusb2.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_AIC']):
src += Glob('port/aic/usb_dc_aic.c')
src += Glob('port/aic/usb_dc_aic_ll.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_CH32']):
if GetDepend(['PKG_CHERRYUSB_DEVICE_HS']):
src += Glob('port/ch32/usb_dc_usbhs.c')
else:
src += Glob('port/ch32/usb_dc_usbfs.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_CDC_ACM']):
src += Glob('class/cdc/usbd_cdc.c')
@@ -130,8 +128,11 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
src += Glob('port/ehci/usb_hc_ehci.c')
src += Glob('port/ehci/usb_glue_hpm.c')
if GetDepend(['PKG_CHERRYUSB_HOST_EHCI_AIC']):
path += [cwd + '/port/ehci']
path += [cwd + '/port/ohci']
src += Glob('port/ehci/usb_hc_ehci.c')
src += Glob('port/ehci/usb_glue_aic.c')
src += Glob('port/ohci/usb_hc_ohci.c')
if GetDepend(['PKG_CHERRYUSB_HOST_EHCI_NUVOTON_NUC980']):
src += Glob('port/ehci/usb_hc_ehci.c')
src += Glob('port/ehci/usb_glue_nuc980.c')
@@ -152,18 +153,9 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
src += Glob('port/musb/usb_hc_musb.c')
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_SUNXI']):
src += Glob('port/musb/usb_hc_musb.c')
CPPDEFINES += ['CONFIG_USB_MUSB_SUNXI']
src += Glob('port/musb/usb_glue_sunxi.c')
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_CUSTOM']):
src += Glob('port/musb/usb_hc_musb.c')
if GetDepend(['PKG_CHERRYUSB_HOST_XHCI']):
src += Glob('port/xhci/usb_hc_xhci.c')
src += Glob('port/xhci/xhci_dbg.c')
src += Glob('port/xhci/xhci.c')
if GetDepend(['PKG_CHERRYUSB_HOST_PUSB2']):
path += [cwd + '/port/pusb2/common']
path += [cwd + '/port/pusb2/fpusb2']
src += Glob('port/pusb2/fpusb2' + '/*.c')
src += Glob('port/pusb2/usb_hc_pusb2.c')
if GetDepend(['PKG_CHERRYUSB_HOST_CDC_ACM']):
src += Glob('class/cdc/usbh_cdc_acm.c')
@@ -193,12 +185,17 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
src += Glob('class/vendor/serial/usbh_ch34x.c')
if GetDepend(['PKG_CHERRYUSB_HOST_CP210X']):
src += Glob('class/vendor/serial/usbh_cp210x.c')
if GetDepend(['PKG_CHERRYUSB_HOST_PL2303']):
src += Glob('class/vendor/serial/usbh_pl2303.c')
if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']):
src += Glob('demo/usb_host.c')
if GetDepend('RT_USING_DFS'):
src += Glob('third_party/rt-thread-5.0/dfs_usbh_msc.c')
src += Glob('third_party/rt-thread-5.0/dfs_usbh_msc.c')
src += Glob('third_party/rt-thread-5.0/usb_msh.c')
src += Glob('third_party/rt-thread-5.0/usb_check.c')
group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES)

View File

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

View File

@@ -1,8 +1,8 @@
#
#
# Copyright (c) 2024, sakumisu
#
#
# SPDX-License-Identifier: Apache-2.0
#
#
# set(CONFIG_CHERRYUSB_DEVICE 1)
# set(CONFIG_CHERRYUSB_DEVICE_CDC 1)
@@ -26,14 +26,14 @@
# set(CONFIG_CHERRYUSB_HOST_HCD "ehci_xxx")
list(APPEND cherryusb_incs
${CMAKE_CURRENT_LIST_DIR}/common
${CMAKE_CURRENT_LIST_DIR}/core
${CMAKE_CURRENT_LIST_DIR}/class/hub
${CMAKE_CURRENT_LIST_DIR}/class/cdc
${CMAKE_CURRENT_LIST_DIR}/class/hid
${CMAKE_CURRENT_LIST_DIR}/class/msc
${CMAKE_CURRENT_LIST_DIR}/common
${CMAKE_CURRENT_LIST_DIR}/core
${CMAKE_CURRENT_LIST_DIR}/class/hub
${CMAKE_CURRENT_LIST_DIR}/class/cdc
${CMAKE_CURRENT_LIST_DIR}/class/hid
${CMAKE_CURRENT_LIST_DIR}/class/msc
${CMAKE_CURRENT_LIST_DIR}/class/audio
${CMAKE_CURRENT_LIST_DIR}/class/video
${CMAKE_CURRENT_LIST_DIR}/class/video
${CMAKE_CURRENT_LIST_DIR}/class/wireless
${CMAKE_CURRENT_LIST_DIR}/class/midi
${CMAKE_CURRENT_LIST_DIR}/class/vendor/net
@@ -87,6 +87,8 @@ if(CONFIG_CHERRYUSB_DEVICE)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/fsdev/usb_dc_fsdev.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)
endif()
@@ -127,6 +129,11 @@ if(CONFIG_CHERRYUSB_HOST)
endif()
if(CONFIG_CHERRYUSB_HOST_VIDEO)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/video/usbh_video.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/chry_pool.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/usbh_uvc_queue.c)
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb)
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool)
endif()
if(CONFIG_CHERRYUSB_HOST_AUDIO)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/audio/usbh_audio.c)
@@ -140,7 +147,7 @@ if(CONFIG_CHERRYUSB_HOST)
set(BLUETOOTH_PATH ${CMAKE_CURRENT_LIST_DIR}/third_party/zephyr_bluetooth-2.7.5)
list(APPEND cherryusb_srcs
${BLUETOOTH_PATH}/ble_hci_usbh.c
${BLUETOOTH_PATH}/ble_hci_usbh.c
${BLUETOOTH_PATH}/zephyr_bluetooth/examples/beacon/src/main.c
${BLUETOOTH_PATH}/zephyr_bluetooth/examples/central/src/main.c
${BLUETOOTH_PATH}/zephyr_bluetooth/examples/central_hr/src/main.c
@@ -177,20 +184,35 @@ if(CONFIG_CHERRYUSB_HOST)
if(CONFIG_CHERRYUSB_HOST_RTL8152)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/net/usbh_rtl8152.c)
endif()
if(CONFIG_CHERRYUSB_HOST_CH34X)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_ch34x.c)
endif()
if(CONFIG_CHERRYUSB_HOST_CP210X)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_cp210x.c)
endif()
if(CONFIG_CHERRYUSB_HOST_FTDI)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_ftdi.c)
endif()
if(CONFIG_CHERRYUSB_HOST_PL2303)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_pl2303.c)
endif()
if(DEFINED CONFIG_CHERRYUSB_HOST_HCD)
if("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_bouffalo")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_bouffalo.c)
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_hpm")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_hpm.c)
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_aic")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_aic.c)
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_nuvoton")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)

View File

@@ -6,8 +6,8 @@
#ifndef CHERRYUSB_CONFIG_H
#define CHERRYUSB_CONFIG_H
#define CHERRYUSB_VERSION 0x010200
#define CHERRYUSB_VERSION_STR "v1.2.0"
#define CHERRYUSB_VERSION 0x010300
#define CHERRYUSB_VERSION_STR "v1.3.0"
/* ================ USB common Configuration ================ */
@@ -33,14 +33,19 @@
/* ================= USB Device Stack Configuration ================ */
#define CONFIG_USBDEV_MAX_BUS 1 // for now, bus num must be 1 except hpm ip
/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
/* Ep0 in and out transfer buffer */
#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512
#endif
/* Setup packet log for debug */
// #define CONFIG_USBDEV_SETUP_LOG_PRINT
/* Send ep0 in data from user buffer instead of copying into ep0 reqdata
* Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE
*/
// #define CONFIG_USBDEV_EP0_INDATA_NO_COPY
/* Check if the input descriptor is correct */
// #define CONFIG_USBDEV_DESC_CHECK
@@ -81,8 +86,9 @@
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
#endif
/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/
#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1536
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
#endif
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
@@ -97,7 +103,6 @@
/* ================ USB HOST Stack Configuration ================== */
#define CONFIG_USBHOST_MAX_BUS 1
#define CONFIG_USBHOST_MAX_RHPORTS 1
#define CONFIG_USBHOST_MAX_EXTHUBS 1
#define CONFIG_USBHOST_MAX_EHPORTS 4
@@ -123,10 +128,14 @@
//#define CONFIG_USBHOST_GET_STRING_DESC
// #define CONFIG_USBHOST_MSOS_ENABLE
#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE
#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00
#endif
/* Ep0 max transfer buffer */
#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
#endif
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
@@ -136,6 +145,40 @@
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
#endif
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
*/
#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE
#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048)
#endif
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE
#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048)
#endif
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
*/
#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE
#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048)
#endif
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE
#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048)
#endif
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
*/
#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE
#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048)
#endif
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE
#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048)
#endif
#define CONFIG_USBHOST_BLUETOOTH_HCI_H4
// #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG
@@ -148,22 +191,71 @@
/* ================ USB Device Port Configuration ================*/
#ifndef CONFIG_USBDEV_MAX_BUS
#define CONFIG_USBDEV_MAX_BUS 1 // for now, bus num must be 1 except hpm ip
#endif
#ifndef CONFIG_USBDEV_EP_NUM
#define CONFIG_USBDEV_EP_NUM 8
#endif
/* ---------------- FSDEV Configuration ---------------- */
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
/* ---------------- DWC2 Configuration ---------------- */
// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4)
// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
/* ---------------- MUSB Configuration ---------------- */
// #define CONFIG_USB_MUSB_SUNXI
/* ================ USB Host Port Configuration ==================*/
#ifndef CONFIG_USBHOST_MAX_BUS
#define CONFIG_USBHOST_MAX_BUS 1
#endif
// #define CONFIG_USBHOST_PIPE_NUM 10
#ifndef CONFIG_USBHOST_PIPE_NUM
#define CONFIG_USBHOST_PIPE_NUM 10
#endif
/* ================ EHCI Configuration ================ */
/* ---------------- EHCI Configuration ---------------- */
#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0)
#define CONFIG_USB_EHCI_HCOR_OFFSET (0x10)
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
#define CONFIG_USB_EHCI_QTD_NUM 3
#define CONFIG_USB_EHCI_ITD_NUM 20
// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
// #define CONFIG_USB_EHCI_CONFIGFLAG
// #define CONFIG_USB_EHCI_PORT_POWER
// #define CONFIG_USB_EHCI_PRINT_HW_PARAM
// #define CONFIG_USB_EHCI_ISO
// #define CONFIG_USB_EHCI_WITH_OHCI
/* ---------------- OHCI Configuration ---------------- */
#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0)
/* ---------------- XHCI Configuration ---------------- */
#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
/* ---------------- DWC2 Configuration ---------------- */
/* largest non-periodic USB packet used / 4 */
// #define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
/* largest periodic USB packet used / 4 */
// #define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4)
/* ---------------- MUSB Configuration ---------------- */
// #define CONFIG_USB_MUSB_SUNXI
#endif

View File

@@ -236,27 +236,27 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_
void usbh_audio_list_module(struct usbh_audio *audio_class)
{
USB_LOG_INFO("============= Audio module information ===================\r\n");
USB_LOG_INFO("bcdADC :%04x\r\n", audio_class->bcdADC);
USB_LOG_INFO("Num of modules :%u\r\n", audio_class->module_num);
USB_LOG_INFO("Num of altsettings:%u\r\n", audio_class->num_of_intf_altsettings);
USB_LOG_RAW("bcdADC :%04x\r\n", audio_class->bcdADC);
USB_LOG_RAW("Num of modules :%u\r\n", audio_class->module_num);
USB_LOG_RAW("Num of altsettings:%u\r\n", audio_class->num_of_intf_altsettings);
for (uint8_t i = 0; i < audio_class->module_num; i++) {
USB_LOG_INFO(" module name :%s\r\n", audio_class->module[i].name);
USB_LOG_INFO(" module feature unit id :%d\r\n", audio_class->module[i].feature_unit_id);
USB_LOG_RAW(" module name :%s\r\n", audio_class->module[i].name);
USB_LOG_RAW(" module feature unit id :%d\r\n", audio_class->module[i].feature_unit_id);
for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) {
if (j == 0) {
USB_LOG_INFO(" Ingore altsetting 0\r\n");
USB_LOG_RAW(" Ingore altsetting 0\r\n");
continue;
}
USB_LOG_INFO(" Altsetting %u\r\n", j);
USB_LOG_INFO(" module channels :%u\r\n", audio_class->module[i].altsetting[j].channels);
//USB_LOG_INFO(" module format_type :%u\r\n",audio_class->module[i].altsetting[j].format_type);
USB_LOG_INFO(" module bitresolution :%u\r\n", audio_class->module[i].altsetting[j].bitresolution);
USB_LOG_INFO(" module sampfreq num :%u\r\n", audio_class->module[i].altsetting[j].sampfreq_num);
USB_LOG_RAW(" Altsetting %u\r\n", j);
USB_LOG_RAW(" module channels :%u\r\n", audio_class->module[i].altsetting[j].channels);
//USB_LOG_RAW(" module format_type :%u\r\n",audio_class->module[i].altsetting[j].format_type);
USB_LOG_RAW(" module bitresolution :%u\r\n", audio_class->module[i].altsetting[j].bitresolution);
USB_LOG_RAW(" module sampfreq num :%u\r\n", audio_class->module[i].altsetting[j].sampfreq_num);
for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) {
USB_LOG_INFO(" module sampfreq :%d hz\r\n", audio_class->module[i].altsetting[j].sampfreq[k]);
USB_LOG_RAW(" module sampfreq :%d hz\r\n", audio_class->module[i].altsetting[j].sampfreq[k]);
}
}
}
@@ -469,8 +469,7 @@ CLASS_INFO_DEFINE const struct usbh_class_info audio_ctrl_intf_class_info = {
.class = USB_DEVICE_CLASS_AUDIO,
.subclass = AUDIO_SUBCLASS_AUDIOCONTROL,
.protocol = 0x00,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &audio_ctrl_class_driver
};
@@ -479,7 +478,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info audio_streaming_intf_class_info =
.class = USB_DEVICE_CLASS_AUDIO,
.subclass = AUDIO_SUBCLASS_AUDIOSTREAMING,
.protocol = 0x00,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &audio_streaming_class_driver
};

View File

@@ -53,6 +53,8 @@ struct usbh_audio {
uint8_t num_of_intf_altsettings;
struct usbh_audio_module module[2];
uint8_t module_num;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -13,12 +13,6 @@
/* Describe EndPoints configuration */
static struct usbd_endpoint cdc_ecm_ep_data[3];
#ifdef CONFIG_USB_HS
#define CDC_ECM_MAX_PACKET_SIZE 512
#else
#define CDC_ECM_MAX_PACKET_SIZE 64
#endif
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16];
@@ -89,7 +83,7 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
switch (setup->bRequest) {
case CDC_REQUEST_SET_ETHERNET_PACKET_FILTER:
/* bit0 Promiscuous
/* bit0 Promiscuous
* bit1 ALL Multicast
* bit2 Directed
* bit3 Broadcast
@@ -119,7 +113,7 @@ void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
g_cdc_ecm_rx_data_buffer = NULL;
break;
case USBD_EVENT_CONFIGURED:
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], CDC_ECM_MAX_PACKET_SIZE);
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
break;
default:
@@ -131,17 +125,17 @@ void cdc_ecm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
g_cdc_ecm_rx_data_length += nbytes;
if (nbytes < CDC_ECM_MAX_PACKET_SIZE) {
if (nbytes < usbd_get_ep_mps(busid, ep)) {
g_cdc_ecm_rx_data_buffer = g_cdc_ecm_rx_buffer;
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
} else {
usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], CDC_ECM_MAX_PACKET_SIZE);
usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, ep));
}
}
void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
if ((nbytes % CDC_ECM_MAX_PACKET_SIZE) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(0, ep, NULL, 0);
} else {
@@ -173,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, CDC_ECM_MAX_PACKET_SIZE);
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));
}
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP

View File

@@ -249,8 +249,7 @@ CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = {
.class = USB_DEVICE_CLASS_CDC,
.subclass = CDC_ABSTRACT_CONTROL_MODEL,
.protocol = CDC_COMMON_PROTOCOL_AT_COMMANDS,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &cdc_acm_class_driver
};
@@ -259,7 +258,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = {
.class = USB_DEVICE_CLASS_CDC_DATA,
.subclass = 0x00,
.protocol = 0x00,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &cdc_data_class_driver
};

View File

@@ -25,6 +25,8 @@ struct usbh_cdc_acm {
uint8_t intf;
uint8_t minor;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -21,11 +21,11 @@
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
#define CONFIG_USBHOST_CDC_ECM_PKT_FILTER 0x000C
#define CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE 1514U
#define CONFIG_USBHOST_CDC_ECM_PKT_FILTER 0x000C
#define CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE 1514U
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_inttx_buffer[16];
static struct usbh_cdc_ecm g_cdc_ecm_class;
@@ -139,8 +139,8 @@ get_mac:
cdc_ecm_class->mac[4],
cdc_ecm_class->mac[5]);
if (cdc_ecm_class->max_segment_size > CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE) {
USB_LOG_ERR("CDC ECM Max Segment Size is overflow, default is %u, but now %u\r\n", CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE, cdc_ecm_class->max_segment_size);
if (cdc_ecm_class->max_segment_size > CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE) {
USB_LOG_ERR("CDC ECM Max Segment Size is overflow, default is %u, but now %u\r\n", CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE, cdc_ecm_class->max_segment_size);
} else {
USB_LOG_INFO("CDC ECM Max Segment Size:%u\r\n", cdc_ecm_class->max_segment_size);
}
@@ -176,7 +176,7 @@ get_mac:
}
}
/* bit0 Promiscuous
/* bit0 Promiscuous
* bit1 ALL Multicast
* bit2 Directed
* bit3 Broadcast
@@ -232,6 +232,11 @@ void usbh_cdc_ecm_rx_thread(void *argument)
int ret;
err_t err;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create cdc ecm rx thread\r\n");
@@ -253,7 +258,7 @@ find_class:
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], USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize), 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[g_cdc_ecm_rx_length], 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;
@@ -261,12 +266,16 @@ find_class:
g_cdc_ecm_rx_length += g_cdc_ecm_class.bulkin_urb.actual_length;
if (g_cdc_ecm_class.bulkin_urb.actual_length != USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize)) {
if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize)) {
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_length);
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_length, PBUF_POOL);
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_length, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = g_cdc_ecm_rx_buffer;
#else
memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length);
#endif
g_cdc_ecm_rx_length = 0;
err = netif->input(p, netif);
@@ -279,6 +288,10 @@ find_class:
}
} 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;
}
}
}
// clang-format off
@@ -333,7 +346,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info cdc_ecm_class_info = {
.class = USB_DEVICE_CLASS_CDC,
.subclass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL,
.protocol = CDC_COMMON_PROTOCOL_NONE,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &cdc_ecm_class_driver
};

View File

@@ -23,7 +23,7 @@ struct usbh_cdc_ecm {
uint8_t ctrl_intf; /* Control interface number */
uint8_t data_intf; /* Data interface number */
uint8_t minor;
uint8_t mac[6];
bool connect_status;
uint16_t max_segment_size;
@@ -32,6 +32,8 @@ struct usbh_cdc_ecm {
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -10,21 +10,21 @@
#define USB_DBG_TAG "usbh_cdc_ncm"
#include "usb_log.h"
#define DEV_FORMAT "/dev/cdc_ncm"
#define DEV_FORMAT "/dev/cdc_ncm"
/* general descriptor field offsets */
#define DESC_bLength 0 /** Length offset */
#define DESC_bDescriptorType 1 /** Descriptor type offset */
#define DESC_bDescriptorSubType 2 /** Descriptor subtype offset */
#define DESC_bLength 0 /** Length offset */
#define DESC_bDescriptorType 1 /** Descriptor type offset */
#define DESC_bDescriptorSubType 2 /** Descriptor subtype offset */
/* interface descriptor field offsets */
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_SEGSZE 1514U
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ncm_rx_buffer[2048];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ncm_tx_buffer[2048];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ncm_rx_buffer[CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ncm_tx_buffer[CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ncm_inttx_buffer[16];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ncm_buf[32];
@@ -250,6 +250,11 @@ void usbh_cdc_ncm_rx_thread(void *argument)
int ret;
err_t err;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
@@ -271,7 +276,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], USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize), 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], (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);
ret = usbh_submit_urb(&g_cdc_ncm_class.bulkin_urb);
if (ret < 0) {
goto find_class;
@@ -279,7 +284,7 @@ find_class:
g_cdc_ncm_rx_length += g_cdc_ncm_class.bulkin_urb.actual_length;
if (g_cdc_ncm_class.bulkin_urb.actual_length != USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize)) {
if (g_cdc_ncm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize)) {
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];
@@ -306,10 +311,13 @@ find_class:
if (ndp16_datagram->wDatagramIndex && ndp16_datagram->wDatagramLength) {
USB_LOG_DBG("ndp16_datagram index:%02x, length:%02x\r\n", ndp16_datagram->wDatagramIndex, ndp16_datagram->wDatagramLength);
p = pbuf_alloc(PBUF_RAW, ndp16_datagram->wDatagramLength, PBUF_POOL);
p = pbuf_alloc(PBUF_RAW, ndp16_datagram->wDatagramLength, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex];
#else
memcpy(p->payload, (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex], ndp16_datagram->wDatagramLength);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
@@ -323,6 +331,10 @@ 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;
}
}
}
// clang-format off
@@ -344,7 +356,7 @@ err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p)
}
struct cdc_ncm_nth16 *nth16 = (struct cdc_ncm_nth16 *)&g_cdc_ncm_tx_buffer[0];
nth16->dwSignature = CDC_NCM_NTH16_SIGNATURE;
nth16->wHeaderLength = 12;
nth16->wSequence = g_cdc_ncm_class.bulkout_sequence++;
@@ -402,7 +414,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info cdc_ncm_class_info = {
.class = USB_DEVICE_CLASS_CDC,
.subclass = CDC_NETWORK_CONTROL_MODEL,
.protocol = CDC_COMMON_PROTOCOL_NONE,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &cdc_ncm_class_driver
};

View File

@@ -36,6 +36,8 @@ struct usbh_cdc_ncm {
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -106,6 +106,32 @@ int usbh_hid_set_protocol(struct usbh_hid *hid_class, uint8_t protocol)
return usbh_control_transfer(hid_class->hport, setup, NULL);
}
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;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_SET_REPORT;
setup->wValue = (uint16_t)(((uint32_t)report_type << 8U) | (uint32_t)report_id);
setup->wIndex = 0;
setup->wLength = buflen;
return usbh_control_transfer(hid_class->hport, setup, buffer);
}
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;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_GET_REPORT;
setup->wValue = (uint16_t)(((uint32_t)report_type << 8U) | (uint32_t)report_id);
setup->wIndex = 0;
setup->wLength = buflen;
return usbh_control_transfer(hid_class->hport, setup, buffer);
}
int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;
@@ -200,7 +226,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info hid_custom_class_info = {
.class = USB_DEVICE_CLASS_HID,
.subclass = 0x00,
.protocol = 0x00,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &hid_class_driver
};

View File

@@ -15,9 +15,11 @@ struct usbh_hid {
struct usbh_urb intin_urb; /* INTR IN urb */
struct usbh_urb intout_urb; /* INTR OUT urb */
uint8_t report_desc[128];
uint8_t report_desc[256];
uint8_t intf; /* interface number */
uint8_t minor;
void *user_data;
};
#ifdef __cplusplus
@@ -26,6 +28,8 @@ extern "C" {
int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration);
int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer);
int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen);
int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen);
void usbh_hid_run(struct usbh_hid *hid_class);
void usbh_hid_stop(struct usbh_hid *hid_class);

View File

@@ -22,8 +22,8 @@
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(32, CONFIG_USB_ALIGN_SIZE)];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_BUS][CONFIG_USBHOST_MAX_EXTHUBS + 1][USB_ALIGN_UP(1, CONFIG_USB_ALIGN_SIZE)];
extern int usbh_free_devaddr(struct usbh_hubport *hport);
extern int usbh_enumerate(struct usbh_hubport *hport);
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" };
@@ -91,7 +91,7 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
if (ret < 0) {
return ret;
}
memcpy(buffer, g_hub_buf, USB_SIZEOF_HUB_DESC);
memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_DESC);
return ret;
}
#if 0
@@ -108,11 +108,11 @@ static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
setup->wIndex = 0;
setup->wLength = 2;
ret = usbh_control_transfer(hub->parent, setup, g_hub_buf);
ret = usbh_control_transfer(hub->parent, setup, g_hub_buf[hub->bus->busid]);
if (ret < 0) {
return ret;
}
memcpy(buffer, g_hub_buf, 2);
memcpy(buffer, g_hub_buf[hub->bus->busid], 2);
return ret;
}
#endif
@@ -280,22 +280,6 @@ static int usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
}
}
static void usbh_hubport_release(struct usbh_hubport *child)
{
if (child->connected) {
child->connected = false;
usbh_free_devaddr(child);
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
CLASS_DISCONNECT(child, i);
}
}
child->config.config_desc.bNumInterfaces = 0;
usbh_kill_urb(&child->ep0_urb);
usb_osal_mutex_delete(child->mutex);
}
}
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
static void hub_int_complete_callback(void *arg, int nbytes)
{
@@ -396,6 +380,10 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed), hub_int_timeout, hub, 0);
if (hub->int_timer == NULL) {
USB_LOG_ERR("No memory to alloc int_timer\r\n");
return -USB_ERR_NOMEM;
}
usb_osal_timer_start(hub->int_timer);
return 0;
}
@@ -412,7 +400,9 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
usbh_kill_urb(&hub->intin_urb);
}
usb_osal_timer_delete(hub->int_timer);
if (hub->int_timer) {
usb_osal_timer_delete(hub->int_timer);
}
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
child = &hub->child[port];
@@ -715,8 +705,7 @@ CLASS_INFO_DEFINE const struct usbh_class_info hub_class_info = {
.class = USB_DEVICE_CLASS_HUB,
.subclass = 0,
.protocol = 0,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &hub_class_driver
};
#endif

View File

@@ -431,7 +431,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info msc_class_info = {
.class = USB_DEVICE_CLASS_MASS_STORAGE,
.subclass = MSC_SUBCLASS_SCSI,
.protocol = MSC_PROTOCOL_BULK_ONLY,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &msc_class_driver
};

View File

@@ -20,6 +20,8 @@ struct usbh_msc {
uint8_t sdchar;
uint32_t blocknum; /* Number of blocks on the USB mass storage device */
uint16_t blocksize; /* Block size of USB mass storage device */
void *user_data;
};
struct usbh_msc_modeswitch_config {

View File

@@ -92,7 +92,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info xxx_class_info = {
.class = 0,
.subclass = 0,
.protocol = 0,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &xxx_class_driver
};

View File

@@ -12,6 +12,8 @@ struct usbh_xxx {
uint8_t intf; /* interface number */
uint8_t minor;
void *user_data;
};
void usbh_xxx_run(struct usbh_xxx *xxx_class);

View File

@@ -14,10 +14,10 @@
#define DEV_FORMAT "/dev/asix"
static struct usbh_asix g_asix_class;
#define CONFIG_USBHOST_ASIX_ETH_MAX_SEGSZE (1514U + 8)
#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_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_tx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_SEGSZE];
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_inttx_buffer[16];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_buf[32];
@@ -358,7 +358,7 @@ static int usbh_ax88772a_hw_reset(struct usbh_asix *asix_class)
if (ret < 0)
goto out;
ret = usbh_asix_write_cmd(asix_class, AX_CMD_SW_PHY_SELECT, asix_class->embd_phy | AX_PHYSEL_SSEN, 0, 0, NULL);
ret = usbh_asix_write_cmd(asix_class, AX_CMD_SW_PHY_SELECT, asix_class->embd_phy | AX_PHYSEL_SSEN, 0, NULL, 0);
if (ret < 0) {
USB_LOG_ERR("Select PHY #1 failed: %d\r\n", ret);
goto out;
@@ -422,7 +422,7 @@ static int usbh_ax88772a_hw_reset(struct usbh_asix *asix_class)
ret = usbh_asix_write_cmd(asix_class, AX_CMD_WRITE_IPG0,
AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
AX88772_IPG2_DEFAULT, 0, NULL);
AX88772_IPG2_DEFAULT, NULL, 0);
if (ret < 0) {
USB_LOG_ERR("Write IPG,IPG1,IPG2 failed: %d\r\n", ret);
goto out;
@@ -657,6 +657,11 @@ void usbh_asix_rx_thread(void *argument)
uint16_t len;
uint16_t len_crc;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create asix rx thread\r\n");
@@ -678,7 +683,7 @@ find_class:
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], USB_GET_MAXPACKETSIZE(g_asix_class.bulkin->wMaxPacketSize), 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], CONFIG_USBHOST_ASIX_ETH_MAX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_asix_class.bulkin_urb);
if (ret < 0) {
goto find_class;
@@ -697,9 +702,13 @@ find_class:
USB_LOG_DBG("rxlen:%d\r\n", g_asix_rx_length);
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
p = pbuf_alloc(PBUF_RAW, len, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = (uint8_t *)&g_asix_rx_buffer[4];
#else
memcpy(p->payload, (uint8_t *)&g_asix_rx_buffer[4], len);
#endif
g_asix_rx_length = 0;
err = netif->input(p, netif);
@@ -711,6 +720,10 @@ find_class:
USB_LOG_ERR("No memory to alloc pbuf for asix rx\r\n");
}
} 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;
}
}
}
// clang-format off
@@ -770,28 +783,23 @@ __WEAK void usbh_asix_stop(struct usbh_asix *asix_class)
{
}
static const uint16_t asix_id_table[][2] = {
{ 0x0B95, 0x772B },
{ 0x0B95, 0x7720 },
{ 0, 0 },
};
static const struct usbh_class_driver asix_class_driver = {
.driver_name = "asix",
.connect = usbh_asix_connect,
.disconnect = usbh_asix_disconnect
};
CLASS_INFO_DEFINE const struct usbh_class_info ax88772b_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
CLASS_INFO_DEFINE const struct usbh_class_info asix_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.vid = 0x0B95,
.pid = 0x772B,
.id_table = asix_id_table,
.class_driver = &asix_class_driver
};
CLASS_INFO_DEFINE const struct usbh_class_info ax88772_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.vid = 0x0B95,
.pid = 0x7720,
.class_driver = &asix_class_driver
};
};

View File

@@ -159,6 +159,8 @@ struct usbh_asix {
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -12,11 +12,8 @@
#define DEV_FORMAT "/dev/rtl8152"
#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SEGSZE (16 * 1024)
#define CONFIG_USBHOST_RTL8152_ETH_MAX_SEGSZE (2048)
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rtl8152_rx_buffer[CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rtl8152_tx_buffer[CONFIG_USBHOST_RTL8152_ETH_MAX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rtl8152_rx_buffer[CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rtl8152_tx_buffer[CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rtl8152_inttx_buffer[2];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rtl8152_buf[32];
@@ -2034,8 +2031,8 @@ static int usbh_rtl8152_connect(struct usbh_hubport *hport, uint8_t intf)
rtl8152_class->rtl_ops.init(rtl8152_class);
rtl8152_class->rtl_ops.up(rtl8152_class);
if (rtl8152_class->rx_buf_sz > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SEGSZE) {
USB_LOG_ERR("rx_buf_sz is overflow, default is %d\r\n", CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SEGSZE);
if (rtl8152_class->rx_buf_sz > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) {
USB_LOG_ERR("rx_buf_sz is overflow, default is %d\r\n", CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE);
return -USB_ERR_NOMEM;
}
@@ -2129,6 +2126,11 @@ void usbh_rtl8152_rx_thread(void *argument)
uint16_t len;
uint16_t data_offset;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
@@ -2160,7 +2162,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], USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize), 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], (CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_rtl8152_class.bulkin_urb);
if (ret < 0) {
goto find_class;
@@ -2168,7 +2170,7 @@ find_class:
g_rtl8152_rx_length += g_rtl8152_class.bulkin_urb.actual_length;
if (g_rtl8152_class.bulkin_urb.actual_length != USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize)) {
if (g_rtl8152_rx_length % USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize)) {
data_offset = 0;
USB_LOG_DBG("rxlen:%d\r\n", g_rtl8152_rx_length);
@@ -2179,10 +2181,13 @@ find_class:
USB_LOG_DBG("data_offset:%d, eth len:%d\r\n", data_offset, len);
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
p = pbuf_alloc(PBUF_RAW, len, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)];
#else
memcpy(p->payload, (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)], len);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
@@ -2199,6 +2204,10 @@ 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;
}
}
}
// clang-format off
@@ -2248,6 +2257,11 @@ __WEAK void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
{
}
static const uint16_t rtl_id_table[][2] = {
{ 0x0BDA, 0x8152 },
{ 0, 0 },
};
static const struct usbh_class_driver rtl8152_class_driver = {
.driver_name = "rtl8152",
.connect = usbh_rtl8152_connect,
@@ -2255,11 +2269,10 @@ static const struct usbh_class_driver rtl8152_class_driver = {
};
CLASS_INFO_DEFINE const struct usbh_class_info rtl8152_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.vid = 0x0BDA,
.pid = 0x8152,
.id_table = rtl_id_table,
.class_driver = &rtl8152_class_driver
};

View File

@@ -50,6 +50,8 @@ struct usbh_rtl8152 {
void (*autosuspend_en)(struct usbh_rtl8152 *tp, bool enable);
void (*change_mtu)(struct usbh_rtl8152 *tp);
} rtl_ops;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -335,6 +335,11 @@ __WEAK void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class)
{
}
static const uint16_t ch34x_id_table[][2] = {
{ 0x1A86, 0x7523 },
{ 0, 0 },
};
const struct usbh_class_driver ch34x_class_driver = {
.driver_name = "ch34x",
.connect = usbh_ch34x_connect,
@@ -342,11 +347,10 @@ const struct usbh_class_driver ch34x_class_driver = {
};
CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0xff,
.protocol = 0xff,
.vid = 0x1A86,
.pid = 0x7523,
.subclass = 0x00,
.protocol = 0x00,
.id_table = ch34x_id_table,
.class_driver = &ch34x_class_driver
};

View File

@@ -51,6 +51,8 @@ struct usbh_ch34x {
uint8_t intf;
uint8_t minor;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -274,6 +274,11 @@ __WEAK void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class)
{
}
static const uint16_t cp210x_id_table[][2] = {
{ 0x10C4, 0xEA60 },
{ 0, 0 },
};
const struct usbh_class_driver cp210x_class_driver = {
.driver_name = "cp210x",
.connect = usbh_cp210x_connect,
@@ -281,11 +286,10 @@ const struct usbh_class_driver cp210x_class_driver = {
};
CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0xff,
.protocol = 0xff,
.vid = 0x10C4,
.pid = 0xEA60,
.subclass = 0x00,
.protocol = 0x00,
.id_table = cp210x_id_table,
.class_driver = &cp210x_class_driver
};

View File

@@ -17,7 +17,7 @@
#define CP210X_SET_BREAK 0x05
#define CP210X_IMM_CHAR 0x06
#define CP210X_SET_MHS 0x07 // Set DTR, RTS
#define CP210X_GET_MDMSTS 0x08
#define CP210X_GET_MDMSTS 0x08
#define CP210X_SET_XON 0x09
#define CP210X_SET_XOFF 0x0A
#define CP210X_SET_EVENTMASK 0x0B
@@ -33,9 +33,9 @@
#define CP210X_EMBED_EVENTS 0x15
#define CP210X_GET_EVENTSTATE 0x16
#define CP210X_SET_CHARS 0x19
#define CP210X_GET_BAUDRATE 0x1D
#define CP210X_GET_BAUDRATE 0x1D
#define CP210X_SET_BAUDRATE 0x1E // Set baudrate
#define CP210X_VENDOR_SPECIFIC 0xFF
#define CP210X_VENDOR_SPECIFIC 0xFF
struct usbh_cp210x {
struct usbh_hubport *hport;
@@ -45,9 +45,11 @@ struct usbh_cp210x {
struct usbh_urb bulkin_urb;
struct cdc_line_coding line_coding;
uint8_t intf;
uint8_t minor;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -120,7 +120,7 @@ static int usbh_ftdi_set_data_format(struct usbh_ftdi *ftdi_class, uint8_t datab
/**
* D0-D7 databits BITS_7=7, BITS_8=8
* D8-D10 parity NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4
* D11-D12 STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2
* D11-D12 STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2
* D14 BREAK_OFF=0, BREAK_ON=1
**/
@@ -341,28 +341,23 @@ __WEAK void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class)
{
}
static const uint16_t ftdi_id_table[][2] = {
{ 0x0403, 0x6001 },
{ 0x0403, 0x6010 },
{ 0, 0 },
};
const struct usbh_class_driver ftdi_class_driver = {
.driver_name = "ftdi",
.connect = usbh_ftdi_connect,
.disconnect = usbh_ftdi_disconnect
};
CLASS_INFO_DEFINE const struct usbh_class_info ftdi1_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0xff,
.protocol = 0xff,
.vid = 0x0403,
.pid = 0x6001,
.class_driver = &ftdi_class_driver
};
CLASS_INFO_DEFINE const struct usbh_class_info ftdi2_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0xff,
.protocol = 0xff,
.vid = 0x0403,
.pid = 0x6010,
.subclass = 0x00,
.protocol = 0x00,
.id_table = ftdi_id_table,
.class_driver = &ftdi_class_driver
};

View File

@@ -51,6 +51,8 @@ struct usbh_ftdi {
uint8_t intf;
uint8_t minor;
uint8_t modem_status[2];
void *user_data;
};
#ifdef __cplusplus

426
class/vendor/serial/usbh_pl2303.c vendored Normal file
View File

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

62
class/vendor/serial/usbh_pl2303.h vendored Normal file
View File

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

View File

@@ -180,7 +180,7 @@ int usbh_video_open(struct usbh_video *video_class,
* Get MIN request (probe)
* Get CUR request (probe)
* Set CUR request (commit)
*
*
*/
step = 0;
ret = usbh_videostreaming_get_cur_probe(video_class);
@@ -300,12 +300,12 @@ void usbh_video_list_info(struct usbh_video *video_class)
uint16_t mps;
USB_LOG_INFO("============= Video device information ===================\r\n");
USB_LOG_INFO("bcdVDC:%04x\r\n", video_class->bcdVDC);
USB_LOG_INFO("Num of altsettings:%u\r\n", video_class->num_of_intf_altsettings);
USB_LOG_RAW("bcdVDC:%04x\r\n", video_class->bcdVDC);
USB_LOG_RAW("Num of altsettings:%u\r\n", video_class->num_of_intf_altsettings);
for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) {
if (i == 0) {
USB_LOG_INFO("Ingore altsetting 0\r\n");
USB_LOG_RAW("Ingore altsetting 0\r\n");
continue;
}
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc;
@@ -313,7 +313,7 @@ void usbh_video_list_info(struct usbh_video *video_class)
mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
USB_LOG_INFO("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
i,
ep_desc->bEndpointAddress,
ep_desc->bmAttributes,
@@ -322,15 +322,15 @@ void usbh_video_list_info(struct usbh_video *video_class)
mult);
}
USB_LOG_INFO("bNumFormats:%u\r\n", video_class->num_of_formats);
USB_LOG_RAW("bNumFormats:%u\r\n", video_class->num_of_formats);
for (uint8_t i = 0; i < video_class->num_of_formats; i++) {
USB_LOG_INFO(" FormatIndex:%u\r\n", i + 1);
USB_LOG_INFO(" FormatType:%s\r\n", format_type[video_class->format[i].format_type]);
USB_LOG_INFO(" bNumFrames:%u\r\n", video_class->format[i].num_of_frames);
USB_LOG_INFO(" Resolution:\r\n");
USB_LOG_RAW(" FormatIndex:%u\r\n", i + 1);
USB_LOG_RAW(" FormatType:%s\r\n", format_type[video_class->format[i].format_type]);
USB_LOG_RAW(" bNumFrames:%u\r\n", video_class->format[i].num_of_frames);
USB_LOG_RAW(" Resolution:\r\n");
for (uint8_t j = 0; j < video_class->format[i].num_of_frames; j++) {
USB_LOG_INFO(" FrameIndex:%u\r\n", j + 1);
USB_LOG_INFO(" wWidth: %d, wHeight: %d\r\n",
USB_LOG_RAW(" FrameIndex:%u\r\n", j + 1);
USB_LOG_RAW(" wWidth: %d, wHeight: %d\r\n",
video_class->format[i].frame[j].wWidth,
video_class->format[i].frame[j].wHeight);
}
@@ -508,8 +508,7 @@ CLASS_INFO_DEFINE const struct usbh_class_info video_ctrl_class_info = {
.class = USB_DEVICE_CLASS_VIDEO,
.subclass = VIDEO_SC_VIDEOCONTROL,
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &video_ctrl_class_driver
};
@@ -518,7 +517,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info video_streaming_class_info = {
.class = USB_DEVICE_CLASS_VIDEO,
.subclass = VIDEO_SC_VIDEOSTREAMING,
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &video_streaming_class_driver
};

View File

@@ -22,12 +22,19 @@ struct usbh_video_format {
uint8_t num_of_frames;
};
struct usbh_videoframe {
uint8_t *frame_buf;
uint32_t frame_bufsize;
uint32_t frame_format;
uint32_t frame_size;
};
struct usbh_videostreaming {
struct usbh_videoframe *frame;
uint32_t frame_format;
uint32_t bufoffset;
uint32_t buflen;
uint16_t width;
uint16_t heigth;
void (*video_one_frame_callback)(struct usbh_videostreaming *stream);
uint16_t height;
};
struct usbh_video {
@@ -48,6 +55,8 @@ struct usbh_video {
uint8_t num_of_intf_altsettings;
uint8_t num_of_formats;
struct usbh_video_format format[3];
void *user_data;
};
#ifdef __cplusplus

View File

@@ -17,23 +17,10 @@ static struct usbd_endpoint rndis_ep_data[3];
#define RNDIS_INQUIRY_PUT(src, len) (memcpy(infomation_buffer, src, len))
#define RNDIS_INQUIRY_PUT_LE32(value) (*(uint32_t *)infomation_buffer = (value))
#ifdef CONFIG_USB_HS
#define RNDIS_MAX_PACKET_SIZE 512
#else
#define RNDIS_MAX_PACKET_SIZE 64
#endif
#ifndef CONFIG_USB_HS
#define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */
#else
#define RNDIS_LINK_SPEED 480000000 /* Link baudrate (480Mbit/s for USB-HS) */
#endif
/* Device data structure */
struct usbd_rndis_priv {
uint32_t drv_version;
uint32_t link_status;
uint32_t speed;
uint32_t net_filter;
usb_eth_stat_t eth_state;
rndis_state_t init_state;
@@ -45,8 +32,13 @@ struct usbd_rndis_priv {
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
#endif
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44];
#if CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE < 1580
#undef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
#endif
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8];
@@ -169,8 +161,8 @@ static int rndis_init_cmd_handler(uint8_t *data, uint32_t len)
resp->Status = RNDIS_STATUS_SUCCESS;
resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
resp->Medium = RNDIS_MEDIUM_802_3;
resp->MaxPacketsPerTransfer = 1;
resp->MaxTransferSize = CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + sizeof(rndis_data_packet_t);
resp->MaxPacketsPerTransfer = CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE / 1580;
resp->MaxTransferSize = CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE;
resp->PacketAlignmentFactor = 0;
resp->AfListOffset = 0;
resp->AfListSize = 0;
@@ -225,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(CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE);
RNDIS_INQUIRY_PUT_LE32(0x05DC);
infomation_len = 4;
break;
case OID_GEN_VENDOR_ID:
@@ -250,7 +242,12 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
infomation_len = 4;
break;
case OID_GEN_LINK_SPEED:
RNDIS_INQUIRY_PUT_LE32(RNDIS_LINK_SPEED / 100);
if (usbd_get_ep_mps(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr) > 64) {
RNDIS_INQUIRY_PUT_LE32(480000000 / 100);
} else {
RNDIS_INQUIRY_PUT_LE32(12000000 / 100);
}
infomation_len = 4;
break;
case OID_GEN_CURRENT_PACKET_FILTER:
@@ -464,7 +461,7 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
if ((nbytes % RNDIS_MAX_PACKET_SIZE) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(0, ep, NULL, 0);
} else {
@@ -548,7 +545,6 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
g_usbd_rndis.drv_version = 0x0001;
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
g_usbd_rndis.speed = RNDIS_LINK_SPEED;
rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr = out_ep;
rndis_ep_data[RNDIS_OUT_EP_IDX].ep_cb = rndis_bulk_out;

View File

@@ -224,7 +224,7 @@ void usbh_bluetooth_hci_rx_thread(void *argument)
}
}
// clang-format off
delete :
delete :
USB_LOG_INFO("Delete hc acl rx thread\r\n");
usb_osal_thread_delete(NULL);
// clang-format on
@@ -309,7 +309,7 @@ void usbh_bluetooth_hci_evt_rx_thread(void *argument)
usb_osal_msleep(interval);
}
// clang-format off
delete :
delete :
USB_LOG_INFO("Delete hc event rx thread\r\n");
usb_osal_thread_delete(NULL);
// clang-format on
@@ -351,7 +351,7 @@ void usbh_bluetooth_hci_acl_rx_thread(void *argument)
}
}
// clang-format off
delete :
delete :
USB_LOG_INFO("Delete hc acl rx thread\r\n");
usb_osal_thread_delete(NULL);
// clang-format on
@@ -377,13 +377,17 @@ static const struct usbh_class_driver bluetooth_class_driver = {
};
#ifdef CONFIG_USBHOST_BLUETOOTH_HCI_H4
static const uint16_t bluetooth_id_table[][2] = {
{ 0x2fe3, 0x000c },
{ 0, 0 },
};
CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_h4_nrf_class_info = {
.match_flags = USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS,
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.vid = 0x2fe3,
.pid = 0x000c,
.id_table = bluetooth_id_table,
.class_driver = &bluetooth_class_driver
};
#else
@@ -392,8 +396,7 @@ CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_class_info = {
.class = USB_DEVICE_CLASS_WIRELESS,
.subclass = 0x01,
.protocol = 0x01,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &bluetooth_class_driver
};
#endif

View File

@@ -29,6 +29,8 @@ struct usbh_bluetooth {
struct usbh_urb *isoout_urb; /* Bulk OUT urb */
uint8_t num_of_intf_altsettings;
#endif
void *user_data;
};
#ifdef __cplusplus

View File

@@ -18,10 +18,6 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[4096];
#define CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE 1514
#define CONFIG_USBHOST_RNDIS_ETH_MSG_SIZE (CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE + 44)
/* eth rx size must be a multiple of 512 or 64 */
#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048)
#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048)
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE];
// static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_inttx_buffer[16];
@@ -430,12 +426,16 @@ void usbh_rndis_rx_thread(void *argument)
{
uint32_t g_rndis_rx_length;
uint32_t pmg_offset;
uint32_t payload_offset;
int ret;
err_t err;
struct pbuf *p, *q;
struct pbuf *p;
rndis_data_packet_t *pmsg;
rndis_data_packet_t temp;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create rndis rx thread\r\n");
@@ -455,50 +455,65 @@ find_class:
}
}
g_rndis_rx_length = 0;
while (1) {
g_rndis_rx_length = 0;
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, 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, (CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_RNDIS_ETH_MAX_RX_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;
pmg_offset = 0;
while (g_rndis_rx_length > 0) {
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_length);
g_rndis_rx_length += g_rndis_class.bulkin_urb.actual_length;
if (g_rndis_rx_length % USB_GET_MAXPACKETSIZE(g_rndis_class.bulkin->wMaxPacketSize)) {
pmg_offset = 0;
pmsg = (rndis_data_packet_t *)(g_rndis_rx_buffer + pmg_offset);
uint32_t total_len = g_rndis_rx_length;
/* Not word-aligned case */
if (pmg_offset & 0x3) {
memcpy(&temp, pmsg, sizeof(rndis_data_packet_t));
pmsg = &temp;
}
while (g_rndis_rx_length > 0) {
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_length);
if (pmsg->MessageType == REMOTE_NDIS_PACKET_MSG) {
p = pbuf_alloc(PBUF_RAW, pmsg->DataLength, PBUF_POOL);
if (p != NULL) {
payload_offset = 0;
for (q = p; q != NULL; q = q->next) {
void *src = (void *)(g_rndis_rx_buffer + pmg_offset + sizeof(rndis_generic_msg_t) + pmsg->DataOffset + payload_offset);
memcpy(q->payload, src, q->len);
payload_offset += q->len;
}
pmsg = (rndis_data_packet_t *)(g_rndis_rx_buffer + pmg_offset);
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
pmg_offset += pmsg->MessageLength;
g_rndis_rx_length -= pmsg->MessageLength;
} else {
g_rndis_rx_length = 0;
USB_LOG_ERR("No memory to alloc pbuf for rndis rx\r\n");
/* Not word-aligned case */
if (pmg_offset & 0x3) {
memcpy(&temp, pmsg, sizeof(rndis_data_packet_t));
pmsg = &temp;
}
} else {
if (pmsg->MessageType == REMOTE_NDIS_PACKET_MSG) {
p = pbuf_alloc(PBUF_RAW, pmsg->DataLength, type);
if (p != NULL) {
void *src = (void *)(g_rndis_rx_buffer + pmg_offset + sizeof(rndis_generic_msg_t) + pmsg->DataOffset);
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = src;
#else
memcpy(p->payload, src, pmsg->DataLength);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
pmg_offset += pmsg->MessageLength;
g_rndis_rx_length -= pmsg->MessageLength;
/* drop the last dummy byte, it is a short packet to tell us we have received a multiple of wMaxPacketSize */
if (g_rndis_rx_length < 4) {
g_rndis_rx_length = 0;
}
} else {
g_rndis_rx_length = 0;
USB_LOG_ERR("No memory to alloc pbuf for rndis rx\r\n");
}
} else {
USB_LOG_ERR("offset:%d,remain:%d,total:%d\r\n", pmg_offset, g_rndis_rx_length, total_len);
g_rndis_rx_length = 0;
USB_LOG_ERR("Error rndis packet message\r\n");
}
}
} 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;
USB_LOG_ERR("Error rndis packet message\r\n");
}
}
}
@@ -516,6 +531,7 @@ err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p)
struct pbuf *q;
uint8_t *buffer;
rndis_data_packet_t *hdr;
uint32_t len;
if (g_rndis_class.connect_status == false) {
return ERR_BUF;
@@ -535,14 +551,15 @@ err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p)
buffer += q->len;
}
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)) {
hdr->MessageLength += 1;
len += 1;
}
USB_LOG_DBG("txlen:%d\r\n", hdr->MessageLength);
USB_LOG_DBG("txlen:%d\r\n", len);
usbh_bulk_urb_fill(&g_rndis_class.bulkout_urb, g_rndis_class.hport, g_rndis_class.bulkout, g_rndis_tx_buffer, hdr->MessageLength, USB_OSAL_WAITING_FOREVER, NULL, NULL);
usbh_bulk_urb_fill(&g_rndis_class.bulkout_urb, g_rndis_class.hport, g_rndis_class.bulkout, g_rndis_tx_buffer, len, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_rndis_class.bulkout_urb);
if (ret < 0) {
return ERR_BUF;
@@ -570,7 +587,6 @@ CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = {
.class = USB_DEVICE_CLASS_WIRELESS,
.subclass = 0x01,
.protocol = 0x03,
.vid = 0x00,
.pid = 0x00,
.id_table = NULL,
.class_driver = &rndis_class_driver
};

View File

@@ -33,6 +33,8 @@ struct usbh_rndis {
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
#ifdef __cplusplus

View File

@@ -36,11 +36,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr);
/**
* @brief Get USB device speed
*
* @param[in] port port index
* @param[in] busid bus index
*
* @return port speed, USB_SPEED_LOW or USB_SPEED_FULL or USB_SPEED_HIGH
*/
uint8_t usbd_get_port_speed(uint8_t busid, const uint8_t port);
uint8_t usbd_get_port_speed(uint8_t busid);
/**
* @brief configure and enable endpoint.

View File

@@ -34,6 +34,10 @@
/**< maximum packet size (MPS) for EP 0 */
#define USB_CTRL_EP_MPS 64
/**< maximum packet size (MPS) for bulk EP */
#define USB_BULK_EP_MPS_HS 512
#define USB_BULK_EP_MPS_FS 64
/* USB PID Types */
#define USB_PID_OUT (0x01) /* Tokens */
#define USB_PID_IN (0x09)
@@ -538,7 +542,7 @@ struct usb_msosv2_subset_function_descriptor {
} __PACKED;
struct usb_msosv2_descriptor {
uint8_t *compat_id;
const uint8_t *compat_id;
uint16_t compat_id_len;
uint8_t vendor_code;
};
@@ -612,12 +616,12 @@ struct usb_webusb_url_descriptor {
struct usb_webusb_url_ex_descriptor {
uint8_t vendor_code;
uint8_t *string;
const uint8_t *string;
uint32_t string_len;
} __PACKED;
struct usb_bos_descriptor {
uint8_t *string;
const uint8_t *string;
uint32_t string_len;
};
@@ -660,6 +664,27 @@ struct usb_desc_header {
bmAttributes, /* bmAttributes */ \
USB_CONFIG_POWER_MA(bMaxPower) /* bMaxPower */
#define USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, bNumConfigurations) \
0x0A, /* bLength */ \
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, /* bDescriptorType */ \
WBVAL(bcdUSB), /* bcdUSB */ \
bDeviceClass, /* bDeviceClass */ \
bDeviceSubClass, /* bDeviceSubClass */ \
bDeviceProtocol, /* bDeviceProtocol */ \
0x40, /* bMaxPacketSize */ \
bNumConfigurations, /* bNumConfigurations */ \
0x00 /* bReserved */
#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT(wTotalLength, bNumInterfaces, bConfigurationValue, bmAttributes, bMaxPower) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_OTHER_SPEED, /* bDescriptorType */ \
WBVAL(wTotalLength), /* wTotalLength */ \
bNumInterfaces, /* bNumInterfaces */ \
bConfigurationValue, /* bConfigurationValue */ \
0x00, /* iConfiguration */ \
bmAttributes, /* bmAttributes */ \
USB_CONFIG_POWER_MA(bMaxPower) /* bMaxPower */
#define USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bNumEndpoints, \
bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol, iInterface) \
0x09, /* bLength */ \

View File

@@ -21,6 +21,8 @@ typedef void (*usb_timer_handler_t)(void *argument);
struct usb_osal_timer {
usb_timer_handler_t handler;
void *argument;
bool is_period;
uint32_t ticks;
void *timer;
};

View File

@@ -20,6 +20,8 @@
struct usbd_tx_rx_msg {
uint8_t ep;
uint8_t ep_mult;
uint16_t ep_mps;
uint32_t nbytes;
usbd_endpoint_callback cb;
};
@@ -49,7 +51,9 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
/** Currently selected configuration */
uint8_t configuration;
#ifdef CONFIG_USBDEV_ADVANCE_DESC
uint8_t speed;
#endif
#ifdef CONFIG_USBDEV_TEST_MODE
bool test_req;
#endif
@@ -99,6 +103,14 @@ static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descripto
USB_GET_ENDPOINT_TYPE(ep->bmAttributes),
USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize));
if (ep->bEndpointAddress & 0x80) {
g_usbd_core[busid].tx_msg[ep->bEndpointAddress & 0x7f].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
g_usbd_core[busid].tx_msg[ep->bEndpointAddress & 0x7f].ep_mult = USB_GET_MULT(ep->wMaxPacketSize);
} else {
g_usbd_core[busid].rx_msg[ep->bEndpointAddress & 0x7f].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
g_usbd_core[busid].rx_msg[ep->bEndpointAddress & 0x7f].ep_mult = USB_GET_MULT(ep->wMaxPacketSize);
}
return usbd_ep_open(busid, ep) == 0 ? true : false;
}
/**
@@ -139,6 +151,7 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
uint8_t index = 0U;
bool found = true;
uint32_t desc_len = 0;
const char *string = NULL;
const uint8_t *desc = NULL;
type = HI_BYTE(type_index);
@@ -146,6 +159,7 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
switch (type) {
case USB_DESCRIPTOR_TYPE_DEVICE:
g_usbd_core[busid].speed = usbd_get_port_speed(busid); /* before we get device descriptor, we have known steady port speed */
desc = g_usbd_core[busid].descriptors->device_descriptor_callback(g_usbd_core[busid].speed);
if (desc == NULL) {
found = false;
@@ -173,15 +187,45 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
desc = (uint8_t *)g_usbd_core[busid].descriptors->msosv1_descriptor->string;
desc_len = g_usbd_core[busid].descriptors->msosv1_descriptor->string[0];
} else {
desc = g_usbd_core[busid].descriptors->string_descriptor_callback(g_usbd_core[busid].speed, index);
if (desc == NULL) {
string = g_usbd_core[busid].descriptors->string_descriptor_callback(g_usbd_core[busid].speed, index);
if (string == NULL) {
found = false;
break;
}
desc_len = desc[0];
if (index == USB_STRING_LANGID_INDEX) {
(*data)[0] = 4;
(*data)[1] = USB_DESCRIPTOR_TYPE_STRING;
(*data)[2] = string[0];
(*data)[3] = string[1];
*len = 4;
return true;
}
uint16_t str_size = strlen(string);
uint16_t total_size = 2 * str_size + 2;
if (total_size > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
USB_LOG_ERR("string size overflow\r\n");
return false;
}
(*data)[0] = total_size;
(*data)[1] = USB_DESCRIPTOR_TYPE_STRING;
for (uint16_t i = 0; i < str_size; i++) {
(*data)[2 * i + 2] = string[i];
(*data)[2 * i + 3] = 0x00;
}
*len = total_size;
return true;
}
break;
case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
#ifndef CONFIG_USB_HS
return false;
#else
desc = g_usbd_core[busid].descriptors->device_quality_descriptor_callback(g_usbd_core[busid].speed);
if (desc == NULL) {
found = false;
@@ -189,6 +233,7 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
}
desc_len = desc[0];
break;
#endif
case USB_DESCRIPTOR_TYPE_OTHER_SPEED:
desc = g_usbd_core[busid].descriptors->other_speed_descriptor_callback(g_usbd_core[busid].speed);
if (desc == NULL) {
@@ -219,8 +264,8 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
/* nothing found */
USB_LOG_ERR("descriptor <type:%x,index:%x> not found!\r\n", type, index);
} else {
// *data = desc;
memcpy(*data, desc, desc_len);
*data = (uint8_t *)desc;
//memcpy(*data, desc, desc_len);
*len = desc_len;
}
return found;
@@ -244,8 +289,8 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
return false;
}
//*data = (uint8_t *)g_usbd_core[busid].msosv1_desc->string;
memcpy(*data, (uint8_t *)g_usbd_core[busid].msosv1_desc->string, g_usbd_core[busid].msosv1_desc->string[0]);
*data = (uint8_t *)g_usbd_core[busid].msosv1_desc->string;
//memcpy(*data, (uint8_t *)g_usbd_core[busid].msosv1_desc->string, g_usbd_core[busid].msosv1_desc->string[0]);
*len = g_usbd_core[busid].msosv1_desc->string[0];
return true;
@@ -256,8 +301,8 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
return false;
}
//*data = g_usbd_core[busid].bos_desc->string;
memcpy(*data, (uint8_t *)g_usbd_core[busid].bos_desc->string, g_usbd_core[busid].bos_desc->string_len);
*data = (uint8_t *)g_usbd_core[busid].bos_desc->string;
//memcpy(*data, (uint8_t *)g_usbd_core[busid].bos_desc->string, g_usbd_core[busid].bos_desc->string_len);
*len = g_usbd_core[busid].bos_desc->string_len;
return true;
}
@@ -303,7 +348,8 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
/* normally length is at offset 0 */
*len = p[DESC_bLength];
}
memcpy(*data, p, *len);
*data = p;
//memcpy(*data, p, *len);
} else {
/* nothing found */
USB_LOG_ERR("descriptor <type:0x%02x,index:0x%02x> not found!\r\n", type, index);
@@ -583,8 +629,8 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
struct usbd_interface *intf = g_usbd_core[busid].intf[i];
if (intf && (intf->intf_num == intf_num)) {
//*data = (uint8_t *)intf->hid_report_descriptor;
memcpy(*data, intf->hid_report_descriptor, intf->hid_report_descriptor_len);
*data = (uint8_t *)intf->hid_report_descriptor;
//memcpy(*data, intf->hid_report_descriptor, intf->hid_report_descriptor_len);
*len = intf->hid_report_descriptor_len;
return true;
}
@@ -773,8 +819,8 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
(g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id[2] << 16) +
(g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id[3] << 24);
//*data = (uint8_t *)g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id;
memcpy(*data, g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id, desclen);
*data = (uint8_t *)g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id;
//memcpy(*data, g_usbd_core[busid].descriptors->msosv1_descriptor->compat_id, desclen);
*len = desclen;
return 0;
case 0x05:
@@ -784,8 +830,8 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
(g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue][2] << 16) +
(g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue][3] << 24);
//*data = (uint8_t *)g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue];
memcpy(*data, g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue], desclen);
*data = (uint8_t *)g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue];
//memcpy(*data, g_usbd_core[busid].descriptors->msosv1_descriptor->comp_id_property[setup->wValue], desclen);
*len = desclen;
return 0;
default:
@@ -800,8 +846,8 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
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);
*data = (uint8_t *)g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id;
//memcpy(*data, g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id, desclen);
*len = g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id_len;
return 0;
default:
@@ -816,8 +862,8 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
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);
*data = (uint8_t *)g_usbd_core[busid].descriptors->webusb_url_descriptor->string;
//memcpy(*data, g_usbd_core[busid].descriptors->webusb_url_descriptor->string, desclen);
*len = desclen;
return 0;
default:
@@ -832,22 +878,22 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
switch (setup->wIndex) {
case 0x04:
USB_LOG_INFO("get Compat ID\r\n");
//*data = (uint8_t *)msosv1_desc->compat_id;
*data = (uint8_t *)g_usbd_core[busid].msosv1_desc->compat_id;
desclen = g_usbd_core[busid].msosv1_desc->compat_id[0] +
(g_usbd_core[busid].msosv1_desc->compat_id[1] << 8) +
(g_usbd_core[busid].msosv1_desc->compat_id[2] << 16) +
(g_usbd_core[busid].msosv1_desc->compat_id[3] << 24);
memcpy(*data, g_usbd_core[busid].msosv1_desc->compat_id, desclen);
//memcpy(*data, g_usbd_core[busid].msosv1_desc->compat_id, desclen);
*len = desclen;
return 0;
case 0x05:
USB_LOG_INFO("get Compat id properties\r\n");
//*data = (uint8_t *)msosv1_desc->comp_id_property[setup->wValue];
*data = (uint8_t *)g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue];
desclen = g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][0] +
(g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][1] << 8) +
(g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][2] << 16) +
(g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][3] << 24);
memcpy(*data, g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue], desclen);
//memcpy(*data, g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue], desclen);
*len = desclen;
return 0;
default:
@@ -860,8 +906,8 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
switch (setup->wIndex) {
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
//*data = (uint8_t *)msosv2_desc->compat_id;
memcpy(*data, g_usbd_core[busid].msosv2_desc->compat_id, g_usbd_core[busid].msosv2_desc->compat_id_len);
*data = (uint8_t *)g_usbd_core[busid].msosv2_desc->compat_id;
//memcpy(*data, g_usbd_core[busid].msosv2_desc->compat_id, g_usbd_core[busid].msosv2_desc->compat_id_len);
*len = g_usbd_core[busid].msosv2_desc->compat_id_len;
return 0;
default:
@@ -895,14 +941,12 @@ static bool usbd_setup_request_handler(uint8_t busid, struct usb_setup_packet *s
{
switch (setup->bmRequestType & USB_REQUEST_TYPE_MASK) {
case USB_REQUEST_STANDARD:
#ifndef CONFIG_USB_HS
//g_usbd_core[busid].speed = USB_SPEED_FULL; /* next time will support getting device speed */
if ((setup->bRequest == 0x06) && (setup->wValue == 0x0600) && (g_usbd_core[busid].speed <= USB_SPEED_FULL)) {
USB_LOG_WRN("Ignore DQD in fs\r\n"); /* Device Qualifier Descriptor */
return false;
}
#endif
if (usbd_standard_request_handler(busid, setup, data, len) < 0) {
/* Ignore error log for getting Device Qualifier Descriptor request */
if ((setup->bRequest == 0x06) && (setup->wValue == 0x0600)) {
//USB_LOG_DBG("Ignore DQD in fs\r\n");
return false;
}
USB_LOG_ERR("standard request error\r\n");
usbd_print_setup(setup);
return false;
@@ -972,6 +1016,9 @@ void usbd_event_reset_handler(uint8_t busid)
{
usbd_set_address(busid, 0);
g_usbd_core[busid].configuration = 0;
#ifdef CONFIG_USBDEV_ADVANCE_DESC
g_usbd_core[busid].speed = USB_SPEED_UNKNOWN;
#endif
struct usb_endpoint_descriptor ep0;
ep0.bLength = 7;
@@ -992,6 +1039,7 @@ void usbd_event_reset_handler(uint8_t busid)
void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
uint8_t *buf;
memcpy(setup, psetup, 8);
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
@@ -1009,6 +1057,7 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
g_usbd_core[busid].ep0_data_buf_residue = setup->wLength;
g_usbd_core[busid].ep0_data_buf_len = setup->wLength;
g_usbd_core[busid].zlp_flag = false;
buf = g_usbd_core[busid].ep0_data_buf;
/* handle class request when all the data is received */
if (setup->wLength && ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
@@ -1018,7 +1067,7 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
}
/* Ask installed handler to process request */
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
if (!usbd_setup_request_handler(busid, setup, &buf, &g_usbd_core[busid].ep0_data_buf_len)) {
usbd_ep_set_stall(busid, USB_CONTROL_IN_EP0);
return;
}
@@ -1027,9 +1076,23 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
g_usbd_core[busid].ep0_data_buf_residue = MIN(g_usbd_core[busid].ep0_data_buf_len, setup->wLength);
if (g_usbd_core[busid].ep0_data_buf_residue > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
USB_LOG_ERR("Request buffer too small\r\n");
usbd_ep_set_stall(busid, USB_CONTROL_IN_EP0);
return;
}
/* use *data = xxx; g_usbd_core[busid].ep0_data_buf records real data address, we should copy data into ep0 buffer.
* Why we should copy once? because some chips are not access to flash with dma if real data address is in flash address(such as ch32).
*/
if (buf != g_usbd_core[busid].ep0_data_buf) {
#ifdef CONFIG_USBDEV_EP0_INDATA_NO_COPY
g_usbd_core[busid].ep0_data_buf = buf;
#else
memcpy(g_usbd_core[busid].ep0_data_buf, buf, g_usbd_core[busid].ep0_data_buf_residue);
#endif
} else {
/* use memcpy(*data, xxx, len); has copied into ep0 buffer, we do nothing */
}
/* Send data or status to host */
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
/*
@@ -1189,6 +1252,24 @@ void usbd_add_endpoint(uint8_t busid, struct usbd_endpoint *ep)
}
}
uint16_t usbd_get_ep_mps(uint8_t busid, uint8_t ep)
{
if (ep & 0x80) {
return g_usbd_core[busid].tx_msg[ep & 0x7f].ep_mps;
} else {
return g_usbd_core[busid].rx_msg[ep & 0x7f].ep_mps;
}
}
uint8_t usbd_get_ep_mult(uint8_t busid, uint8_t ep)
{
if (ep & 0x80) {
return g_usbd_core[busid].tx_msg[ep & 0x7f].ep_mult;
} else {
return g_usbd_core[busid].rx_msg[ep & 0x7f].ep_mult;
}
}
bool usb_device_is_configured(uint8_t busid)
{
return g_usbd_core[busid].configuration;

View File

@@ -67,7 +67,7 @@ struct usb_descriptor {
const uint8_t *(*config_descriptor_callback)(uint8_t speed);
const uint8_t *(*device_quality_descriptor_callback)(uint8_t speed);
const uint8_t *(*other_speed_descriptor_callback)(uint8_t speed);
const uint8_t *(*string_descriptor_callback)(uint8_t speed, uint8_t index);
const char *(*string_descriptor_callback)(uint8_t speed, uint8_t index);
const struct usb_msosv1_descriptor *msosv1_descriptor;
const struct usb_msosv2_descriptor *msosv2_descriptor;
const struct usb_webusb_url_ex_descriptor *webusb_url_descriptor;
@@ -97,7 +97,10 @@ void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc);
void usbd_add_interface(uint8_t busid, struct usbd_interface *intf);
void usbd_add_endpoint(uint8_t busid, struct usbd_endpoint *ep);
uint16_t usbd_get_ep_mps(uint8_t busid, uint8_t ep);
uint8_t usbd_get_ep_mult(uint8_t busid, uint8_t ep);
bool usb_device_is_configured(uint8_t busid);
int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event));
int usbd_deinitialize(uint8_t busid);

View File

@@ -79,18 +79,24 @@ static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
return 0;
}
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;
}
static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol,
uint16_t vid, uint16_t pid)
{
struct usbh_class_info *index = NULL;
for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) {
if ((index->match_flags & USB_CLASS_MATCH_VENDOR) && !(index->vid == vid)) {
continue;
}
if ((index->match_flags & USB_CLASS_MATCH_PRODUCT) && !(index->pid == pid)) {
continue;
}
if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->class == class)) {
continue;
}
@@ -100,6 +106,16 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->protocol == protocol)) {
continue;
}
if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) {
/* scan id table */
uint32_t i;
for (i = 0; index->id_table[i][0] && index->id_table[i][0] != vid && index->id_table[i][1] != pid; i++) {
}
/* do not match, continue next */
if (!index->id_table[i][0]) {
continue;
}
}
return index->class_driver;
}
return NULL;
@@ -325,66 +341,6 @@ static int usbh_get_default_mps(int speed)
}
}
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;
}
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
{
struct usb_setup_packet *setup = hport->setup;
int ret;
uint8_t *src;
uint8_t *dst;
uint16_t len;
uint16_t i = 2;
uint16_t j = 0;
/* Get Manufacturer string */
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | index);
setup->wIndex = 0x0409;
setup->wLength = 255;
ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
if (ret < 0) {
return ret;
}
src = ep0_request_buffer[hport->bus->busid];
dst = output;
len = src[0];
while (i < len) {
dst[j] = src[i];
i += 2;
j++;
}
return 0;
}
int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting)
{
struct usb_setup_packet *setup = hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = altsetting;
setup->wIndex = intf;
setup->wLength = 0;
return usbh_control_transfer(hport, setup, NULL);
}
int usbh_enumerate(struct usbh_hubport *hport)
{
struct usb_interface_descriptor *intf_desc;
@@ -394,6 +350,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
int dev_addr;
uint16_t ep_mps;
uint8_t config_value;
uint8_t config_index;
int ret;
hport->setup = &g_setup_buffer[hport->bus->busid][hport->parent->index - 1][hport->port - 1];
@@ -497,10 +454,15 @@ int usbh_enumerate(struct usbh_hubport *hport)
((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->idProduct,
((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->bcdDevice);
USB_LOG_INFO("The device has %d bNumConfigurations\r\n", ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumConfigurations);
config_index = 0;
USB_LOG_DBG("The device selects config %d\r\n", config_index);
/* Read the first 9 bytes of the config descriptor */
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | 0);
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | config_index);
setup->wIndex = 0;
setup->wLength = USB_SIZEOF_CONFIG_DESC;
@@ -515,9 +477,15 @@ int usbh_enumerate(struct usbh_hubport *hport)
/* Read the full size of the configuration data */
uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->wTotalLength;
if (wTotalLength > CONFIG_USBHOST_REQUEST_BUFFER_LEN) {
ret = -USB_ERR_NOMEM;
USB_LOG_ERR("wTotalLength %d is overflow, default is %d\r\n", wTotalLength, CONFIG_USBHOST_REQUEST_BUFFER_LEN);
goto errout;
}
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | 0);
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | config_index);
setup->wIndex = 0;
setup->wLength = wTotalLength;
@@ -629,6 +597,24 @@ errout:
return ret;
}
void usbh_hubport_release(struct usbh_hubport *hport)
{
if (hport->connected) {
hport->connected = false;
usbh_free_devaddr(hport);
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->disconnect) {
CLASS_DISCONNECT(hport, i);
}
}
hport->config.config_desc.bNumInterfaces = 0;
usbh_kill_urb(&hport->ep0_urb);
if (hport->mutex) {
usb_osal_mutex_delete(hport->mutex);
}
}
}
static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base)
{
struct usbh_hub *hub;
@@ -713,7 +699,6 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
usb_osal_mutex_take(hport->mutex);
memset(urb, 0, sizeof(struct usbh_urb));
usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
ret = usbh_submit_urb(urb);
if (ret == 0) {
@@ -724,6 +709,54 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
return ret;
}
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
{
struct usb_setup_packet *setup = hport->setup;
int ret;
uint8_t *src;
uint8_t *dst;
uint16_t len;
uint16_t i = 2;
uint16_t j = 0;
/* Get Manufacturer string */
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | index);
setup->wIndex = 0x0409;
setup->wLength = 255;
ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
if (ret < 0) {
return ret;
}
src = ep0_request_buffer[hport->bus->busid];
dst = output;
len = src[0];
while (i < len) {
dst[j] = src[i];
i += 2;
j++;
}
return 0;
}
int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting)
{
struct usb_setup_packet *setup = hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = altsetting;
setup->wIndex = intf;
setup->wLength = 0;
return usbh_control_transfer(hport, setup, NULL);
}
void *usbh_find_class_instance(const char *devname)
{
struct usbh_hubport *hport;
@@ -803,7 +836,7 @@ int lsusb(int argc, char **argv)
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->driver_name) {
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,

View File

@@ -30,6 +30,7 @@ extern "C" {
#define USB_CLASS_MATCH_INTF_CLASS 0x0004
#define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008
#define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010
#define USB_CLASS_MATCH_VID_PID (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT)
#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i))
#define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i))
@@ -43,7 +44,7 @@ extern "C" {
#define CLASS_INFO_DEFINE __attribute__((section(".usbh_class_info"))) __USED __ALIGNED(1)
#endif
#define USBH_GET_URB_INTERVAL(interval, speed) (speed < USB_SPEED_HIGH ? interval: (1 << (interval - 1)))
#define USBH_GET_URB_INTERVAL(interval, speed) (speed < USB_SPEED_HIGH ? interval : (1 << (interval - 1)))
#define USBH_EP_INIT(ep, ep_desc) \
do { \
@@ -57,12 +58,11 @@ extern "C" {
} while (0)
struct usbh_class_info {
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
uint8_t class; /* Base device class code */
uint8_t subclass; /* Sub-class, depends on base class. Eg. */
uint8_t protocol; /* Protocol, depends on base class. Eg. */
uint16_t vid; /* Vendor ID (for vendor/product specific devices) */
uint16_t pid; /* Product ID (for vendor/product specific devices) */
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
uint8_t class; /* Base device class code */
uint8_t subclass; /* Sub-class, depends on base class. Eg. */
uint8_t protocol; /* Protocol, depends on base class. Eg. */
const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */
const struct usbh_class_driver *class_driver;
};
@@ -239,11 +239,11 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
/**
* @brief Retrieves a USB string descriptor from a specific hub port.
*
*
* This function is responsible for retrieving the USB string descriptor
* with the specified index from the USB device connected to the given hub port.
* The retrieved descriptor is stored in the output buffer provided.
*
*
* @param hport Pointer to the USB hub port structure.
* @param index Index of the string descriptor to retrieve.
* @param output Pointer to the buffer where the retrieved descriptor will be stored.
@@ -253,11 +253,11 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
/**
* @brief Sets the alternate setting for a USB interface on a specific hub port.
*
*
* This function is responsible for setting the alternate setting of the
* specified USB interface on the USB device connected to the given hub port.
* The interface and alternate setting are identified by the respective parameters.
*
*
* @param hport Pointer to the USB hub port structure.
* @param intf Interface number to set the alternate setting for.
* @param altsetting Alternate setting value to set for the interface.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_msc.h"
#include "usbd_cdc.h"
@@ -232,12 +237,6 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
volatile bool ep_tx_busy_flag = false;
#ifdef CONFIG_USB_HS
#define CDC_MAX_MPS 512
#else
#define CDC_MAX_MPS 64
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
@@ -278,7 +277,7 @@ void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
} else {

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_msc.h"
@@ -57,76 +62,13 @@ static const uint8_t device_quality_descriptor[] = {
0x00,
};
static const uint8_t string0_descriptor[] = {
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
static const char *string_descriptors[] = {
(const char[]){ 0x09, 0x04 }, /* Langid */
"CherryUSB", /* Manufacturer */
"CherryUSB CDC MSC DEMO", /* Product */
"2022123456", /* Serial Number */
};
static const uint8_t string1_descriptor[] = {
///////////////////////////////////////
/// string1 descriptor
///////////////////////////////////////
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
};
static const uint8_t string2_descriptor[] = {
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x26, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'C', 0x00, /* wcChar10 */
'-', 0x00, /* wcChar11 */
'M', 0x00, /* wcChar12 */
' ', 0x00, /* wcChar13 */
'D', 0x00, /* wcChar14 */
'E', 0x00, /* wcChar15 */
'M', 0x00, /* wcChar16 */
'O', 0x00, /* wcChar17 */
};
static const uint8_t string3_descriptor[] = {
///////////////////////////////////////
/// string3 descriptor
///////////////////////////////////////
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'2', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
};
static const uint8_t *string_descriptors[4] = { string0_descriptor, string1_descriptor, string2_descriptor, string3_descriptor };
static const uint8_t *device_descriptor_callback(uint8_t speed)
{
return device_descriptor;
@@ -142,7 +84,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
return device_quality_descriptor;
}
static const uint8_t *string_descriptor_callback(uint8_t speed, uint8_t index)
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
{
if (index > 3) {
return NULL;
@@ -238,17 +180,11 @@ static const uint8_t cdc_msc_descriptor[] = {
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
volatile bool ep_tx_busy_flag = false;
#ifdef CONFIG_USB_HS
#define CDC_MAX_MPS 512
#else
#define CDC_MAX_MPS 64
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
@@ -288,7 +224,7 @@ void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
} else {

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
@@ -119,12 +124,6 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[4][2048];
volatile bool ep_tx_busy_flag = false;
#ifdef CONFIG_USB_HS
#define CDC_MAX_MPS 512
#else
#define CDC_MAX_MPS 64
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
@@ -99,17 +104,11 @@ static const uint8_t cdc_descriptor[] = {
0x00
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
volatile bool ep_tx_busy_flag = false;
#ifdef CONFIG_USB_HS
#define CDC_MAX_MPS 512
#else
#define CDC_MAX_MPS 64
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
@@ -153,7 +152,7 @@ void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
} else {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usb_midi.h"
@@ -146,6 +151,9 @@ const uint8_t midi_descriptor[] = {
0x00
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[MIDI_EP_MPS];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[MIDI_EP_MPS];
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
@@ -160,6 +168,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
usbd_ep_start_read(busid, MIDI_OUT_EP, read_buffer, MIDI_EP_MPS);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
@@ -173,6 +182,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
void usbd_midi_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
usbd_ep_start_read(busid, MIDI_OUT_EP, read_buffer, MIDI_EP_MPS);
}
void usbd_midi_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)

View File

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

View File

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

View File

@@ -1,24 +1,7 @@
/**
* @file pic_data.h
* @brief
*
* Copyright (c) 2022 sakumisu
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __PIC_DATA_H_
#define __PIC_DATA_H_

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbh_core.h"
#include "usbh_cdc_acm.h"
#include "usbh_hid.h"
@@ -5,18 +10,42 @@
#include "usbh_video.h"
#include "usbh_audio.h"
#define TEST_USBH_CDC_ACM 1
#ifndef TEST_USBH_CDC_ACM
#define TEST_USBH_CDC_ACM 1
#endif
#ifndef TEST_USBH_CDC_SPEED
#define TEST_USBH_CDC_SPEED 0
#define TEST_USBH_HID 1
#define TEST_USBH_MSC 1
#endif
#ifndef TEST_USBH_HID
#define TEST_USBH_HID 1
#endif
#ifndef TEST_USBH_MSC
#define TEST_USBH_MSC 1
#endif
#ifndef TEST_USBH_MSC_FATFS
#define TEST_USBH_MSC_FATFS 0
#define TEST_USBH_AUDIO 0
#define TEST_USBH_VIDEO 0
#define TEST_USBH_CDC_ECM 0
#define TEST_USBH_CDC_NCM 0
#define TEST_USBH_RNDIS 0
#define TEST_USBH_ASIX 0
#define TEST_USBH_RTL8152 0
#endif
#ifndef TEST_USBH_AUDIO
#define TEST_USBH_AUDIO 0
#endif
#ifndef TEST_USBH_VIDEO
#define TEST_USBH_VIDEO 0
#endif
#ifndef TEST_USBH_CDC_ECM
#define TEST_USBH_CDC_ECM 0
#endif
#ifndef TEST_USBH_CDC_NCM
#define TEST_USBH_CDC_NCM 0
#endif
#ifndef TEST_USBH_CDC_RNDIS
#define TEST_USBH_CDC_RNDIS 0
#endif
#ifndef TEST_USBH_ASIX
#define TEST_USBH_ASIX 0
#endif
#ifndef TEST_USBH_RTL8152
#define TEST_USBH_RTL8152 0
#endif
#if TEST_USBH_CDC_ACM
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[512];
@@ -43,31 +72,28 @@ void usbh_cdc_acm_callback(void *arg, int nbytes)
static void usbh_cdc_acm_thread(void *argument)
{
int ret;
struct usbh_cdc_acm *cdc_acm_class;
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)argument;
// clang-format off
find_class:
// clang-format on
while ((cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0")) == NULL) {
goto delete;
}
/* test with only one buffer, if you have more cdc acm class, modify by yourself */
#if TEST_USBH_CDC_SPEED
const uint32_t test_len[] = { 512, 1 * 1024, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024 };
memset(cdc_speed_buffer, 0xAA, TEST_LEN);
for (uint8_t j = 0; j < 6; j++) {
uint32_t start_time = (uint32_t)bflb_mtimer_get_time_ms();
uint32_t start_time = (uint32_t)xTaskGetTickCount();
for (uint32_t i = 0; i < TEST_COUNT; i++) {
usbh_bulk_urb_fill(&cdc_acm_class->bulkout_urb, cdc_acm_class->hport, cdc_acm_class->bulkout, cdc_speed_buffer, test_len[j], 0XFFFFFFF, NULL, NULL);
ret = usbh_submit_urb(&cdc_acm_class->bulkout_urb);
if (ret < 0) {
USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
while (1) {}
while (1) {
}
} else {
}
}
USB_LOG_RAW("per packet len:%d, out speed:%d MB/S\r\n", test_len[j], (test_len[j] * TEST_COUNT / 1024 / 1024) * 1000 / ((uint32_t)bflb_mtimer_get_time_ms() - start_time));
uint32_t time_ms = xTaskGetTickCount() - start_time;
USB_LOG_RAW("per packet len:%d, out speed:%f MB/S\r\n", test_len[j], (test_len[j] * TEST_COUNT / 1024 / 1024) * 1000 / ((float)time_ms));
}
#endif
memset(cdc_buffer, 0, 512);
@@ -79,19 +105,20 @@ find_class:
ret = usbh_submit_urb(&cdc_acm_class->bulkout_urb);
if (ret < 0) {
USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
goto find_class;
goto delete;
} else {
USB_LOG_RAW("send over:%d\r\n", cdc_acm_class->bulkout_urb.actual_length);
}
usbh_bulk_urb_fill(&cdc_acm_class->bulkin_urb, cdc_acm_class->hport, cdc_acm_class->bulkin, cdc_buffer, cdc_acm_class->bulkin->wMaxPacketSize, 3000, usbh_cdc_acm_callback, cdc_acm_class);
usbh_bulk_urb_fill(&cdc_acm_class->bulkin_urb, cdc_acm_class->hport, cdc_acm_class->bulkin, cdc_buffer, cdc_acm_class->bulkin->wMaxPacketSize, 0xffffffff, usbh_cdc_acm_callback, cdc_acm_class);
ret = usbh_submit_urb(&cdc_acm_class->bulkin_urb);
if (ret < 0) {
USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
goto delete;
} else {
}
// clang-format off
delete:
delete:
usb_osal_thread_delete(NULL);
// clang-format on
}
@@ -110,7 +137,7 @@ void usbh_hid_callback(void *arg, int nbytes)
}
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
usbh_submit_urb(&hid_class->intin_urb);
} else if (nbytes == -USB_ERR_NAK) { /* for dwc2 */
} else if (nbytes == -USB_ERR_NAK) { /* only dwc2 should do this */
usbh_submit_urb(&hid_class->intin_urb);
} else {
}
@@ -119,22 +146,19 @@ void usbh_hid_callback(void *arg, int nbytes)
static void usbh_hid_thread(void *argument)
{
int ret;
struct usbh_hid *hid_class;
struct usbh_hid *hid_class = (struct usbh_hid *)argument;
;
// clang-format off
find_class:
// clang-format on
while ((hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0")) == NULL) {
goto delete;
}
/* test with only one buffer, if you have more hid class, modify by yourself */
/* Suggest you to use timer for int transfer and use ep interval */
usbh_int_urb_fill(&hid_class->intin_urb, hid_class->hport, hid_class->intin, hid_buffer, hid_class->intin->wMaxPacketSize, 0, usbh_hid_callback, hid_class);
ret = usbh_submit_urb(&hid_class->intin_urb);
if (ret < 0) {
goto find_class;
goto delete;
}
// clang-format off
delete:
delete:
usb_osal_thread_delete(NULL);
// clang-format on
}
@@ -211,21 +235,15 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t partition_table[512];
static void usbh_msc_thread(void *argument)
{
int ret;
struct usbh_msc *msc_class;
// clang-format off
find_class:
// clang-format on
while ((msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda")) == NULL) {
goto delete;
}
struct usbh_msc *msc_class = (struct usbh_msc *)argument;
/* test with only one buffer, if you have more msc class, modify by yourself */
#if 1
/* get the partition table */
ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
if (ret < 0) {
USB_LOG_RAW("scsi_read10 error,ret:%d\r\n", ret);
goto find_class;
goto delete;
}
for (uint32_t i = 0; i < 512; i++) {
if (i % 16 == 0) {
@@ -240,7 +258,7 @@ find_class:
usb_msc_fatfs_test();
#endif
// clang-format off
delete:
delete:
usb_osal_thread_delete(NULL);
// clang-format on
}
@@ -372,7 +390,7 @@ void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostre
}
#endif
#if TEST_USBH_CDC_ECM || TEST_USBH_CDC_NCM || TEST_USBH_RNDIS || TEST_USBH_ASIX || TEST_USBH_RTL8152
#if TEST_USBH_CDC_ECM || TEST_USBH_CDC_NCM || TEST_USBH_CDC_RNDIS || TEST_USBH_ASIX || TEST_USBH_RTL8152
#include "netif/etharp.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
@@ -387,7 +405,6 @@ void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostre
#include <rtthread.h>
#include <rtdevice.h>
#include <netif/ethernetif.h>
#include <netdev.h>
#else
#include "FreeRTOS.h"
@@ -395,8 +412,7 @@ void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostre
#include "semphr.h"
#include "timers.h"
TimerHandle_t dhcp_handle1;
TimerHandle_t dhcp_handle2;
TimerHandle_t dhcp_handle;
static void dhcp_timeout(TimerHandle_t xTimer)
{
@@ -471,8 +487,6 @@ static err_t usbh_cdc_ecm_if_init(struct netif *netif)
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
{
#ifdef __RTTHREAD__
struct netdev *netdev;
memset(&cdc_ecm_dev, 0, sizeof(struct eth_device));
cdc_ecm_dev.parent.control = rt_usbh_cdc_ecm_control;
@@ -499,8 +513,8 @@ void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
while (!netif_is_up(netif)) {
}
dhcp_handle1 = xTimerCreate((const char *)"dhcp1", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle1 == NULL) {
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
@@ -509,7 +523,7 @@ void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, netif);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle1, 0);
xTimerStart(dhcp_handle, 0);
#endif
#endif
}
@@ -523,6 +537,8 @@ void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
@@ -583,8 +599,6 @@ static err_t usbh_cdc_ncm_if_init(struct netif *netif)
void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
{
#ifdef __RTTHREAD__
struct netdev *netdev;
memset(&cdc_ncm_dev, 0, sizeof(struct eth_device));
cdc_ncm_dev.parent.control = rt_usbh_cdc_ncm_control;
@@ -592,7 +606,7 @@ void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
cdc_ncm_dev.eth_tx = rt_usbh_cdc_ncm_eth_tx;
cdc_ncm_dev.parent.user_data = cdc_ncm_class;
eth_device_init(&cdc_ncm_dev, "u0");
eth_device_init(&cdc_ncm_dev, "u1");
eth_device_linkchange(&cdc_ncm_dev, RT_TRUE);
usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, cdc_ncm_dev.netif);
@@ -611,8 +625,8 @@ void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
while (!netif_is_up(netif)) {
}
dhcp_handle1 = xTimerCreate((const char *)"dhcp1", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle1 == NULL) {
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
@@ -621,7 +635,7 @@ void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, netif);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle1, 0);
xTimerStart(dhcp_handle, 0);
#endif
#endif
}
@@ -635,6 +649,8 @@ void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
@@ -642,7 +658,7 @@ void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
}
#endif
#if TEST_USBH_RNDIS
#if TEST_USBH_CDC_RNDIS
#include "usbh_rndis.h"
struct netif g_rndis_netif;
@@ -738,8 +754,6 @@ static err_t usbh_rndis_if_init(struct netif *netif)
void usbh_rndis_run(struct usbh_rndis *rndis_class)
{
#ifdef __RTTHREAD__
struct netdev *netdev;
memset(&rndis_dev, 0, sizeof(struct eth_device));
rndis_dev.parent.control = rt_usbh_rndis_control;
@@ -747,11 +761,11 @@ void usbh_rndis_run(struct usbh_rndis *rndis_class)
rndis_dev.eth_tx = rt_usbh_rndis_eth_tx;
rndis_dev.parent.user_data = rndis_class;
eth_device_init(&rndis_dev, "u1");
eth_device_init(&rndis_dev, "u2");
eth_device_linkchange(&rndis_dev, RT_TRUE);
usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, rndis_dev.netif);
timer_init(rndis_class);
//timer_init(rndis_class);
#else
struct netif *netif = &g_rndis_netif;
@@ -767,19 +781,19 @@ void usbh_rndis_run(struct usbh_rndis *rndis_class)
while (!netif_is_up(netif)) {
}
dhcp_handle2 = xTimerCreate((const char *)"dhcp2", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle2 == NULL) {
dhcp_handle = xTimerCreate((const char *)"dhcp2", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, netif);
timer_init(rndis_class);
//timer_init(rndis_class);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle2, 0);
xTimerStart(dhcp_handle, 0);
#endif
#endif
}
@@ -788,18 +802,20 @@ void usbh_rndis_stop(struct usbh_rndis *rndis_class)
{
#ifdef __RTTHREAD__
eth_device_deinit(&rndis_dev);
rt_timer_stop(keep_timer);
rt_timer_delete(keep_timer);
// rt_timer_stop(keep_timer);
// rt_timer_delete(keep_timer);
#else
struct netif *netif = &g_rndis_netif;
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
xTimerStop(timer_handle, 0);
xTimerDelete(timer_handle, 0);
// xTimerStop(timer_handle, 0);
// xTimerDelete(timer_handle, 0);
#endif
}
#endif
@@ -857,8 +873,6 @@ static err_t usbh_asix_if_init(struct netif *netif)
void usbh_asix_run(struct usbh_asix *asix_class)
{
#ifdef __RTTHREAD__
struct netdev *netdev;
memset(&asix_dev, 0, sizeof(struct eth_device));
asix_dev.parent.control = rt_usbh_asix_control;
@@ -866,7 +880,7 @@ void usbh_asix_run(struct usbh_asix *asix_class)
asix_dev.eth_tx = rt_usbh_asix_eth_tx;
asix_dev.parent.user_data = asix_class;
eth_device_init(&asix_dev, "u2");
eth_device_init(&asix_dev, "u3");
eth_device_linkchange(&asix_dev, RT_TRUE);
usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, asix_dev.netif);
@@ -885,8 +899,8 @@ void usbh_asix_run(struct usbh_asix *asix_class)
while (!netif_is_up(netif)) {
}
dhcp_handle1 = xTimerCreate((const char *)"dhcp1", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle1 == NULL) {
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
@@ -895,7 +909,7 @@ void usbh_asix_run(struct usbh_asix *asix_class)
usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, netif);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle1, 0);
xTimerStart(dhcp_handle, 0);
#endif
#endif
}
@@ -909,6 +923,8 @@ void usbh_asix_stop(struct usbh_asix *asix_class)
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
@@ -969,8 +985,6 @@ static err_t usbh_rtl8152_if_init(struct netif *netif)
void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
{
#ifdef __RTTHREAD__
struct netdev *netdev;
memset(&rtl8152_dev, 0, sizeof(struct eth_device));
rtl8152_dev.parent.control = rt_usbh_rtl8152_control;
@@ -978,7 +992,7 @@ void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
rtl8152_dev.eth_tx = rt_usbh_rtl8152_eth_tx;
rtl8152_dev.parent.user_data = rtl8152_class;
eth_device_init(&rtl8152_dev, "u0");
eth_device_init(&rtl8152_dev, "u4");
eth_device_linkchange(&rtl8152_dev, RT_TRUE);
usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, rtl8152_dev.netif);
@@ -997,17 +1011,17 @@ void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
while (!netif_is_up(netif)) {
}
dhcp_handle1 = xTimerCreate((const char *)"dhcp1", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle1 == NULL) {
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_thread_create("usbh_rtl8152_rx", 2048, 20, usbh_rtl8152_rx_thread, netif);
usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, netif);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle1, 0);
xTimerStart(dhcp_handle, 0);
#endif
#endif
}
@@ -1021,6 +1035,8 @@ void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
@@ -1031,7 +1047,7 @@ void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
{
#if TEST_USBH_CDC_ACM
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, NULL);
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class);
#endif
}
@@ -1042,7 +1058,7 @@ void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
void usbh_hid_run(struct usbh_hid *hid_class)
{
#if TEST_USBH_HID
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, NULL);
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
#endif
}
@@ -1054,7 +1070,7 @@ void usbh_hid_stop(struct usbh_hid *hid_class)
void usbh_msc_run(struct usbh_msc *msc_class)
{
#if TEST_USBH_MSC
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, NULL);
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
#endif
}
@@ -1063,36 +1079,20 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
}
#endif
void usbh_audio_run(struct usbh_audio *audio_class)
{
#if TEST_USBH_AUDIO
#error "if you want to use iso, please contact with me"
usb_osal_thread_create("usbh_audio", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_audio_thread, NULL);
#endif
}
void usbh_audio_stop(struct usbh_audio *audio_class)
{
}
void usbh_video_run(struct usbh_video *video_class)
{
#if TEST_USBH_VIDEO
#error "if you want to use iso, please contact with me"
usb_osal_thread_create("usbh_video", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_video_thread, NULL);
#endif
}
void usbh_video_stop(struct usbh_video *video_class)
{
}
void usbh_class_test(void)
{
#ifdef __RTTHREAD__
/* do nothing */
#else
#if TEST_USBH_CDC_ECM || TEST_USBH_CDC_NCM || TEST_USBH_RNDIS || TEST_USBH_ASIX || TEST_USBH_RTL8152
#if TEST_USBH_CDC_ECM || TEST_USBH_CDC_NCM || TEST_USBH_CDC_RNDIS || TEST_USBH_ASIX || TEST_USBH_RTL8152
/* Initialize the LwIP stack */
tcpip_init(NULL, NULL);
#endif

View File

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

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#define MS_OS_20_DESCRIPTOR_LENGTH (0xB2)

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
@@ -82,7 +87,7 @@ __ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties [142] __ALIGN_END = {
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// registry propter descriptor
///////////////////////////////////////
@@ -117,7 +122,7 @@ __ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = {
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// registry propter descriptor
///////////////////////////////////////
@@ -419,7 +424,7 @@ void usbd_winusb_in2(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % WINUSB_EP_MPS) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, WINUSB_IN_EP2, NULL, 0);
} else {

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
@@ -270,7 +275,7 @@ void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % WINUSB_EP_MPS) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, WINUSB_IN_EP, NULL, 0);
} else {

View File

@@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_hid.h"
@@ -306,7 +311,7 @@ void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % WINUSB_EP_MPS) == 0 && nbytes) {
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, WINUSB_IN_EP, NULL, 0);
} else {

BIN
docs/assets/artinchip.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
docs/assets/bouffalolab.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/assets/eastsoft.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/assets/hpmicro.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/assets/nuvoton.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/assets/phytium.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
docs/assets/rtthread.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
docs/assets/sophgo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
docs/assets/thead.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -210,6 +210,8 @@ usbh_submit_urb
- **arg** 传输完成时携带的参数
- **iso_packet** iso 数据包
.. note:: timeout 如何没有特别对时间的要求,必须设置成 0xffffffff原则上不允许超时如果超时了一般不能再继续工作
`errorcode` 可以返回以下值:
.. code-block:: C

View File

@@ -6,8 +6,8 @@ project = 'CherryUSB'
copyright = '2024, sakumisu'
author = 'sakumisu'
release = '1.2.0'
version = '1.2.0'
release = '1.3.0'
version = '1.3.0'
# -- General configuration

View File

@@ -56,6 +56,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
quick_start/index
quick_start/rt-thread/rtthread
quick_start/other_chip
q&a
.. toctree::
:maxdepth: 1
@@ -107,4 +108,10 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
:maxdepth: 1
:caption: 工具使用
tools/index
tools/index
.. toctree::
:maxdepth: 1
:caption: 商业支持
support

View File

@@ -6,16 +6,16 @@ USB IP 勘误
FSDEV
--------------------------
FSDEV 仅支持从机。这个 ip 不同厂家基本都是基于标准的 usb 寄存器,所以用户使用时,仅需要修改 `USBD_IRQHandler``USB_BASE``USB_NUM_BIDIR_ENDPOINTS` 即可。有些芯片可能还需要配置 `PMA_ACCESS` 的值默认为2。下表为具体芯片相关宏的修改值
FSDEV 仅支持从机。这个 ip 不同厂家基本都是基于标准的 usb 寄存器,有些芯片可能还需要配置 `PMA_ACCESS` 的值默认为2。下表为具体芯片相关宏的修改值
.. list-table::
:widths: 30 20 30 30 30
:header-rows: 1
* - 芯片
- USBD_IRQHandler
- USB_BASE
- USB_NUM_BIDIR_ENDPOINTS
- 中断名
- 寄存器地址
- CONFIG_USBDEV_EP_NUM
- PMA_ACCESS
* - STM32F0
- USB_IRQHandler
@@ -67,7 +67,7 @@ fsdev 需要外置 dp 上拉才能使用,有些芯片可能是接上拉电阻
MUSB
--------------------------
MUSB IP 支持主从,并且由 **mentor** 定义了一套标准的寄存器偏移,所以如果是走的标准,则从机仅需要修改 `USBD_IRQHandler``USB_BASE``USB_NUM_BIDIR_ENDPOINTS` ,主机仅需要修改 `USBH_IRQHandler``USB_BASE` 以及 `CONIFG_USB_MUSB_EP_NUM` 即可。如果非标准,则需要实现以下宏的偏移,以标准为例:
MUSB IP 支持主从,并且由 **mentor** 定义了一套标准的寄存器偏移,如果非标准,则需要实现以下宏的偏移,以标准为例:
.. code-block:: C
@@ -127,9 +127,9 @@ MUSB IP 支持主从,并且由 **mentor** 定义了一套标准的寄存器偏
:header-rows: 1
* - 芯片
- USBD_IRQHandler
- USB_BASE
- USB_NUM_BIDIR_ENDPOINTS
- 中断名
- 寄存器地址
- CONFIG_USBDEV_EP_NUM
* - ES32F3xx
- USB_INT_Handler
- 0x40086400
@@ -150,8 +150,8 @@ MUSB IP 支持主从,并且由 **mentor** 定义了一套标准的寄存器偏
:header-rows: 1
* - 芯片
- USBH_IRQHandler
- USB_BASE
- 中断名
- 寄存器地址
- CONIFG_USB_MUSB_EP_NUM
* - ES32F3xx
- USB_INT_Handler
@@ -169,7 +169,7 @@ MUSB IP 支持主从,并且由 **mentor** 定义了一套标准的寄存器偏
DWC2
--------------------------
DWC2 IP 支持主从,并且由 **synopsys** 定义了一套标准的寄存器偏移。大部分厂家都使用标准的寄存器偏移(除了 GCCFG(GGPIO)寄存器),所以如果是从机仅需要修改 `USBD_IRQHandler``USB_BASE``USB_NUM_BIDIR_ENDPOINTS` ,主机仅需要修改 `USBH_IRQHandler``USB_BASE` 即可。
DWC2 IP 支持主从,并且由 **synopsys** 定义了一套标准的寄存器偏移。大部分厂家都使用标准的寄存器偏移(除了 GCCFG(GGPIO)寄存器),所以如果是从机仅需要修改 `中断名``USB_BASE``CONFIG_USBDEV_EP_NUM` ,主机仅需要修改 `中断名``USB_BASE` 即可。
.. note:: GCCFG(GGPIO) 根据不同的厂家设置不同,会影响 usb 枚举,需要根据厂家提供的手册进行配置,并实现 usbd_get_dwc2_gccfg_conf 和 usbh_get_dwc2_gccfg_conf 函数填充相应需要使能的bit
@@ -182,9 +182,9 @@ DWC2 IP 支持主从,并且由 **synopsys** 定义了一套标准的寄存器
:header-rows: 1
* - 芯片
- USBH_IRQHandler
- USB_BASE
- USB_NUM_BIDIR_ENDPOINTS
- 中断名
- 寄存器地址
- CONFIG_USBDEV_EP_NUM
* - STM32 非 H7
- OTG_FS_IRQHandler/OTG_HS_IRQHandler
- 0x50000000UL/0x40040000UL
@@ -201,9 +201,9 @@ DWC2 IP 支持主从,并且由 **synopsys** 定义了一套标准的寄存器
:header-rows: 1
* - 芯片
- USBH_IRQHandler
- USB_BASE
- CONFIG_USB_DWC2_PIPE_NUM
- 中断名
- 寄存器地址
- CONFIG_USBHOST_PIPE_NUM
* - STM32 全系列
- OTG_HS_IRQHandler
- 0x40040000UL
@@ -216,17 +216,17 @@ EHCI 是 intel 制定的标准主机控制器接口,任何厂家都必须实
.. code-block:: C
//Host Controller Operational Register BASE 距离基地址的偏移
#define CONFIG_USB_EHCI_HCOR_OFFSET (0x14)
//是否打印 ehci 配置信息
#define CONFIG_USB_EHCI_INFO_ENABLE
#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0)
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
#define CONFIG_USB_EHCI_QTD_NUM 3
#define CONFIG_USB_EHCI_ITD_NUM 20
//是否关闭保留寄存器的占位,默认保留 9 个双字的占位
#define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
//是否使能 configflag 寄存器中的 bit0
#define CONFIG_USB_EHCI_CONFIGFLAG
//是否使能 port power bit
#define CONFIG_USB_EHCI_PORT_POWER
//是否查看 ehci 配置信息
#define CONFIG_USB_EHCI_PRINT_HW_PARAM
#define CONFIG_USB_EHCI_ISO
// 不带 tt的 IP 一般使用OHCI
#define CONFIG_USB_EHCI_WITH_OHCI
同时由于 EHCI 只是主机控制器并且只支持高速,一般配合一个 otg 控制器和一个低速全速兼容控制单元,而速度的获取一般是在 otg 寄存器中,所以需要用户实现 `usbh_get_port_speed` 函数。

87
docs/source/q&a.rst Normal file
View File

@@ -0,0 +1,87 @@
Q & A
==============================
移植提问模板
----------------
- 使用的板子引脚USB IP
- USB 中断,时钟,引脚,寄存器地址是否正确,截图
- 是否能进 USB 中断
- 芯片是否带有 cache功能是否做了 no cache 处理,截图
- 硬件是否正常,是否使用杜邦线连接,如果正常,请说明正常原因
- 打开 CONFGI_USBDEV_SETUP_LOG_PRINT并提供 log
- 是否流片并销售
其余问题提问模板
------------------
具体说明现象,复现方式,使用我提供的 demo 再测试,以及提供完整 log
CherryUSB 版本推荐
---------------------
如果没有特别情况,请使用最新版本.详细版本更新说明请参考 https://github.com/cherry-embedded/CherryUSB/releases。
- <= v0.10.2 初代版本
用于定基本的框架,仅支持单 USB IP, 并且无法动态使用硬件 pipe.
使用 XHCI 需要切到这个版本,高版本后续重构. 部分 IP 只能使用此版本,后续版本删除不再使用
- v1.0.0 过度版本
**支持动态使用硬件 pipe不再固定**
- v1.1.0 过度版本
**主从机支持多 USB IP 且要相同 IP**;主机增加 bluetooth, chh340, ftdi, cp210x, asix 驱动
- v1.2.0
主机增加 rtl8152cdc ncm 主机驱动;增加 esp aic 主机驱动DWC2 优化代码方便阅读,并增加一些 FIFO 配置宏给用户,并增加 fifo check这个很重要也很坑
- v1.3.0
增加一些宏的 check;
主机增加 pl2303 驱动;使用 id table 来支持多个 vidpid增加 user_data 给用户使用;优化网络相关的 class 配置和性能;
从机增加一些获取端点信息的 api**统一 ep0 buffer 的使用,美化代码****支持多种速度描述符自动选择功能**
port 中 urb->timeout 清0 的处理有点问题(大数据量传输时会出现 no pipe alloc 异常,主要原因是刚启动传输就完成了,还没判断 timeout就被修改为0了没有进入 take sem 流程),此版本已修复
CherryUSB 性能能到多少
----------------------------------------------------------------
可以达到硬件极限性能,比如 HPM 系列,从机可以到 42MB/s, 主机 44MB/s全速芯片一般 800 ~ 1000KB/s当然需要硬件理论支持到这速度CherryUSB 就支持到这速度
ST IP 命名问题
------------------
ST 命名为 USB_OTG_FS, USB_OTG_HS并不是说明本身是高速或者全速只是代表可以支持到高速但是本身都是全速需要外挂高速phy。因此提问禁止说这两个词请使用 USB0(PA11/PA12),USB1(PB14/PB15) 代替。其余国产厂家同理。
GD IP 问题
------------------
GD IP 采用 DWC2但是读取的硬件参数都是 0我也不懂为什么不给人知道因此需要用户自行知道硬件信息并修改代码下面 check 的内容,然后删除 while1。
dwc2 has less endpoints than config, please check
---------------------------------------------------------------
该 IP 硬件上没有这么多端点,请修改 `CONFIG_USBDEV_EP_NUM`
Ep addr XXX overflow
------------------------------
该 IP 硬件上没有这么多端点, 请更换 IP or 减少端点使用。
This dwc2 version does not support dma mode, so stop working
----------------------------------------------------------------
该 DWC2 版本不支持 dma 模式,禁止使用。
__has_include 报错
------------------------------------------------------------------
如果报错,需要编译器支持 c99 语法,如果是 keil请用 ac6 编译器
CONFIG_USB_HS 何时使用
----------------------------------------------------------------
当你的芯片硬件支持高速,并想初始化成高速模式时开启,相关 IP 会根据该宏配置内部或者外部 高速 PHY。

View File

@@ -11,7 +11,7 @@
- BL702 是一个 USB2.0 全速芯片,共 8 个端点包含端点0。仅支持从机。
- BL616/BL808 是一个 USB2.0 并且内置高速 PHY 芯片,共 5个端点包含端点0。支持主从机。
- USB 的相关应用位于 `examples/usbdev``examples/usbhost` 目录下,根据官方环境搭建完成后,即可编译使用。
- USB 的相关应用位于 `examples/usbdev``examples/usbhost` 目录下,根据官方环境搭建完成后,即可编译使用。
基于 ST 系列芯片
@@ -22,8 +22,8 @@
默认提供以下 demo 工程:
- F103 使用 fsdev ip
- F429 主从使用 USB_OTG_HS, 引脚 pb14/pb15, 并且都使用 dma 模式
- H7 设备使用 USB_OTG_FS, 引脚 pa11/pa12主机使用 USB_OTG_HS ,引脚 pb14/pb15并且需要做 nocache 处理
- F429 主从使用 USB1, 引脚 pb14/pb15, 并且都使用 dma 模式
- H7 设备使用 USB0, 引脚 pa11/pa12主机使用 USB_OTG_HS ,引脚 pb14/pb15并且需要做 nocache 处理
默认删除 Drivers ,所以需要使用 stm32cubemx 生成一下 Drivers 目录下的文件demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate Code** 即可。
@@ -32,7 +32,7 @@
涵盖 F1/F4/H7其余芯片基本类似不再赘述具体区别有
- usb ip 区别F1使用 fsdevF4/H7使用 dwc2
- dwc2 ip 区别: USB_OTG_FS (引脚是 PA11/PA12) 和 USB_OTG_HS (引脚是 PB14/PB15), 其中 USB_OTG_HS 默认全速可以接外部PHY 形成高速主机,并且带 dma 功能
- dwc2 ip 区别: USB0 (引脚是 PA11/PA12) 和 USB1 (引脚是 PB14/PB15), 其中 USB1 默认全速可以接外部PHY 形成高速主机,并且带 dma 功能
- F4 无cacheH7 有 cache
如果是 STM32F7/STM32H7 这种带 cache 功能,需要将 usb 使用到的 ram 定位到 no cache ram 区域。举例如下
@@ -179,4 +179,4 @@ USB Host 移植要点
仓库参考https://github.com/CherryUSB/cherryusb_hpmicro
- HPM 系列芯片均 USB 2.0 并且内置高速 PHY支持主从机
- USB 的相关应用位于 `samples/cherryusb` ,根据官方环境搭建完成后,即可编译使用。
- USB 的相关应用位于 `samples/cherryusb` ,根据官方环境搭建完成后,即可编译使用。

View File

@@ -22,17 +22,41 @@ USB Host 移植要点
- 实现 `usb_hc_low_level_init` 函数(该函数主要负责 USB 时钟、引脚、中断的初始化)。该函数可以放在你想要放的任何参与编译的 c 文件中。如何进行 USB 的时钟、引脚、中断等初始化,请自行根据你使用的芯片原厂提供的源码中进行添加。
- 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base` `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
- 在中断函数中调用 `USBH_IRQHandler`,并传入 `busid`, 如果你的 SDK 中中断入口已经存在 `USBH_IRQHandler` ,请更改 USB 协议栈中的名称
- 如果使用的是 GCC ,需要在链接脚本(ld)中添加如下代码:
- 如果使用的是 GCC ,需要在链接脚本中添加如下代码(需要放在 flash 位置)
.. code-block:: C
/* section information for usbh class */
// 在 ld 文件中添加如下代码
. = ALIGN(4);
__usbh_class_info_start__ = .;
KEEP(*(.usbh_class_info))
__usbh_class_info_end__ = .;
- 如果使用的是 Segger Embedded Studio ,需要在链接脚本(icf)中添加如下代码
GCC 举例如下
.. code-block:: C
/* The program code and other data into "FLASH" Rom type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
__usbh_class_info_start__ = .;
KEEP(*(.usbh_class_info))
__usbh_class_info_end__ = .;
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} > FLASH
- Segger Embedded Studio 举例如下:
.. code-block:: C
@@ -56,13 +80,19 @@ GCC:
.. code-block:: C
// 放在 no cache ram 的 region 中
.no_cache_ram_region : AT (__no_cache_ram_addr)
MEMORY
{
. = ALIGN(4);
*(.noncacheable)
. = ALIGN(4);
} > no_cache_ram
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K - 64K
RAM_nocache (xrw) : ORIGIN = 0x20030000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
}
._nocache_ram :
{
. = ALIGN(4);
*(.noncacheable)
} >RAM_nocache
SCT:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -9,31 +9,28 @@
--------------------------
* 选择 Enable usb device mode 并敲回车进入。
* 首先第一个配置是配置 USB 的速度,分为 **FS、HS**,表示使用全速还是高速功能。高速功能要求内置高速 PHY 或者外接 PHY
* 其次第二个配置则是选择 USB device ip不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme。
* 选择你想使用的 class
* 选择是否使用 demo 模板
.. figure:: img/env1.png
.. figure:: img/env2.png
* 首先第一个配置是配置 USB 的速度,分为 **FS、HS**,表示使用全速还是高速功能。
.. figure:: img/env3.png
* 其次第二个配置则是选择 USB device ip不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme。
.. figure:: img/env4.png
* 选择好 USB device ip 以后,还需要选择是哪款芯片,第三个配置则是用来选择芯片,选择以后会配置相应的 ip 的一些信息和 glue 文件
.. figure:: img/env5.png
* 接下来是 class 的选择,用哪个 class 勾选哪个就可以了,使能 class 以后,双击进入可以选择一个 demo 的模板参与编译,当然也可以不选,自己写。
.. figure:: img/env6.png
* 最后退出保存即可。
* 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径,并实现以下内容:
* 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径,并修改以下内容:
.. figure:: img/config_file.png
.. code-block:: C
#include "rtthread.h"
#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)
#define usb_malloc(size) rt_malloc(size)
#define usb_free(ptr) rt_free(ptr)
#define memcpy rt_memcpy
* USB IP 相关的 config 需要用户自己根据芯片实际情况修改
* 退出以后不急着编译,需要在代码中实现 `usb_dc_low_level_init` 函数。
* 调用 `usbd_initialize` 并填入 `busid` 和 USB IP 的 `reg base` `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
* 以上内容我们推荐放在 **board.c** 中,如下代码:
@@ -60,19 +57,27 @@
--------------------------
* 选择 Enable usb host mode 并敲回车进入。
.. figure:: img/env7.png
* 选择 USB host ip不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme。选择好 USB host ip 以后,还需要选择是哪款芯片,第二个箭头则是用来选择芯片,选择以后会帮忙配置相对应的 ip 的一些信息,比如 `USB_BASE``USBH_Handler` 以及特殊的一些配置等等,如果没找到自己的芯片,可以手动在 `usb_hc_xxx.c` 中修改。
.. figure:: img/env8.png
* 选择 USB host ip不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme。
* 根据需要勾选 class 驱动
* 选择是否开启模板 demo请注意 msc 禁止使能,因为默认对接到 dfs。
.. figure:: img/env2.png
* 最后退出保存即可。
* 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径,并实现以下内容:
.. figure:: img/config_file.png
.. code-block:: C
#include "rtthread.h"
#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)
#define usb_malloc(size) rt_malloc(size)
#define usb_free(ptr) rt_free(ptr)
#define memcpy rt_memcpy
* USB IP 相关的 config 需要用户自己根据芯片实际情况修改
* 在代码中实现 `usb_hc_low_level_init` 函数
* 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base` `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
* 以上内容我们推荐放在 **board.c** 中,如下代码:

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