Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3336919e0d | ||
|
|
8b070570a7 | ||
|
|
af792eabab | ||
|
|
3be08d16f7 | ||
|
|
5dafdcb895 | ||
|
|
f24c37d3aa | ||
|
|
a7a7afc6bb | ||
|
|
66b893e64f | ||
|
|
3a3de9cb69 | ||
|
|
13e4670f3d | ||
|
|
1d9a36b61c | ||
|
|
b1c81a92f5 | ||
|
|
af92236cf4 | ||
|
|
0985a7e5fa | ||
|
|
8b805ee6d7 | ||
|
|
5e6bd78f80 | ||
|
|
f2133f5ca2 | ||
|
|
9657585f1f | ||
|
|
a225ee383b | ||
|
|
60747ce435 | ||
|
|
490cac1a0f | ||
|
|
207fb7b128 | ||
|
|
d23a8a8d00 | ||
|
|
4243394225 | ||
|
|
62c9c8b747 | ||
|
|
7b38b4b323 | ||
|
|
e1aa49e086 | ||
|
|
fabeebd4c5 | ||
|
|
58550b3ed5 | ||
|
|
363533be4c | ||
|
|
074662a50d | ||
|
|
532e05e293 | ||
|
|
b55d40e512 | ||
|
|
263a66ed9b | ||
|
|
775ac135de | ||
|
|
aecae9434b | ||
|
|
5a7042fe15 | ||
|
|
18c4454228 | ||
|
|
cd8b103a71 | ||
|
|
8ecbd32483 | ||
|
|
d0f79ff668 | ||
|
|
7272ccfc02 | ||
|
|
e081642c76 | ||
|
|
b51da4fbf9 | ||
|
|
97c5e37453 | ||
|
|
cdd308f3e8 | ||
|
|
6db4fbba4c | ||
|
|
102801e45c | ||
|
|
0ceb7ef885 | ||
|
|
ae5a9d1e57 | ||
|
|
7ebcafe158 | ||
|
|
81cebaf78c | ||
|
|
5fec929b93 | ||
|
|
4bf0e126af | ||
|
|
ccef9b92cc | ||
|
|
9cb992bed7 | ||
|
|
183d49efbd | ||
|
|
8d18a8b6e5 | ||
|
|
5f79fdc865 | ||
|
|
2f5f2b906f | ||
|
|
0556ae199b | ||
|
|
2da4edf76b | ||
|
|
45e9a2fde8 | ||
|
|
5b72907f6d | ||
|
|
6abe6befa8 | ||
|
|
7ee77b42ee | ||
|
|
404225ade4 | ||
|
|
694b201ff7 | ||
|
|
23e2787a43 | ||
|
|
a3302584ce | ||
|
|
8625e4409e | ||
|
|
190fb36c43 | ||
|
|
a24d2bdc07 | ||
|
|
ceaf0923c5 | ||
|
|
2cb6c598c1 | ||
|
|
4e6b0d0923 | ||
|
|
017eb5560d | ||
|
|
b97fc903c0 | ||
|
|
81ddf9bded | ||
|
|
8995cf9568 | ||
|
|
76f58b93fe | ||
|
|
70c7f1ccbd | ||
|
|
29c72f3455 | ||
|
|
51b9640489 | ||
|
|
32f96f4248 | ||
|
|
e3886fe99d | ||
|
|
d8714d8169 | ||
|
|
9d5479e0c3 | ||
|
|
ed8a3ceca3 | ||
|
|
3592794393 | ||
|
|
4357a1d7d1 | ||
|
|
c1cb6e397b | ||
|
|
c8be4d6fd3 | ||
|
|
725d635c76 | ||
|
|
1eef5f3e35 | ||
|
|
1dd45e3e5a | ||
|
|
8119a500b2 | ||
|
|
c5f2ffa6f9 | ||
|
|
db10c62b59 | ||
|
|
808cd454a3 | ||
|
|
a41c66c2c3 | ||
|
|
6ef086a085 | ||
|
|
5494b0e99a |
304
Kconfig.cherryusb
Normal 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
|
||||
10
README.md
@@ -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" />
|
||||
10
README_zh.md
@@ -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" />
|
||||
|
||||
51
SConscript
@@ -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)
|
||||
|
||||
|
||||
4
VERSION
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 2
|
||||
PATCHLEVEL = 99
|
||||
VERSION_MINOR = 3
|
||||
PATCHLEVEL = 0
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -25,6 +25,8 @@ struct usbh_cdc_acm {
|
||||
|
||||
uint8_t intf;
|
||||
uint8_t minor;
|
||||
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
52
class/vendor/net/usbh_asix.c
vendored
@@ -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
|
||||
};
|
||||
};
|
||||
2
class/vendor/net/usbh_asix.h
vendored
@@ -159,6 +159,8 @@ struct usbh_asix {
|
||||
ip_addr_t ipaddr;
|
||||
ip_addr_t netmask;
|
||||
ip_addr_t gateway;
|
||||
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
41
class/vendor/net/usbh_rtl8152.c
vendored
@@ -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
|
||||
};
|
||||
|
||||
2
class/vendor/net/usbh_rtl8152.h
vendored
@@ -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
|
||||
|
||||
14
class/vendor/serial/usbh_ch34x.c
vendored
@@ -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
|
||||
};
|
||||
2
class/vendor/serial/usbh_ch34x.h
vendored
@@ -51,6 +51,8 @@ struct usbh_ch34x {
|
||||
|
||||
uint8_t intf;
|
||||
uint8_t minor;
|
||||
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
14
class/vendor/serial/usbh_cp210x.c
vendored
@@ -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
|
||||
};
|
||||
10
class/vendor/serial/usbh_cp210x.h
vendored
@@ -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
|
||||
|
||||
29
class/vendor/serial/usbh_ftdi.c
vendored
@@ -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
|
||||
};
|
||||
2
class/vendor/serial/usbh_ftdi.h
vendored
@@ -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
@@ -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
@@ -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 */
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -33,6 +33,8 @@ struct usbh_rndis {
|
||||
ip_addr_t ipaddr;
|
||||
ip_addr_t netmask;
|
||||
ip_addr_t gateway;
|
||||
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 */ \
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
149
core/usbd_core.c
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
173
core/usbh_core.c
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_ecm.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_rndis.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_dfu.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_hid.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_hid.h"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_msc.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_msc.h"
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
208
demo/usb_host.c
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
After Width: | Height: | Size: 9.6 KiB |
BIN
docs/assets/bouffalolab.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
docs/assets/eastsoft.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/assets/hpmicro.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
docs/assets/nuvoton.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/assets/phytium.jpg
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
docs/assets/rtthread.jpg
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
docs/assets/sophgo.jpg
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
docs/assets/thead.jpg
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
@@ -210,6 +210,8 @@ usbh_submit_urb
|
||||
- **arg** 传输完成时携带的参数
|
||||
- **iso_packet** iso 数据包
|
||||
|
||||
.. note:: timeout 如何没有特别对时间的要求,必须设置成 0xffffffff,原则上不允许超时,如果超时了,一般不能再继续工作
|
||||
|
||||
`errorcode` 可以返回以下值:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
主机增加 rtl8152,cdc ncm 主机驱动;增加 esp ,aic 主机驱动;DWC2 优化代码方便阅读,并增加一些 FIFO 配置宏给用户,并增加 fifo check(这个很重要也很坑)
|
||||
|
||||
- v1.3.0
|
||||
|
||||
增加一些宏的 check;
|
||||
主机增加 pl2303 驱动;使用 id table 来支持多个 vid,pid;增加 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。
|
||||
@@ -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使用 fsdev,F4/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 无cache,H7 有 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` ,根据官方环境搭建完成后,即可编译使用。
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
@@ -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** 中,如下代码:
|
||||
|
||||