Compare commits
103 Commits
v1.5.0-rc2
...
v1.5.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d6b12c704 | ||
|
|
5d2a7ca6bc | ||
|
|
3ab47e0295 | ||
|
|
2081360f2c | ||
|
|
8cf12c1958 | ||
|
|
c0f544dafe | ||
|
|
599b11ef1a | ||
|
|
7037fd0e8d | ||
|
|
3905eff2f4 | ||
|
|
20ceaced92 | ||
|
|
9ddcbf58ca | ||
|
|
6e9e769e10 | ||
|
|
65288c9d5b | ||
|
|
4ab097d9dc | ||
|
|
f994422c41 | ||
|
|
5ae04f1273 | ||
|
|
e574ea8ae3 | ||
|
|
f949e16564 | ||
|
|
1bec84471e | ||
|
|
1f065cec44 | ||
|
|
3b1853ceb5 | ||
|
|
72d19ec8cc | ||
|
|
90de3354b5 | ||
|
|
3784ddc389 | ||
|
|
81d8f22e05 | ||
|
|
3b04facd09 | ||
|
|
8dd3106e62 | ||
|
|
9e4122f2a0 | ||
|
|
083ec57384 | ||
|
|
ccd4354960 | ||
|
|
60ac6fe3ad | ||
|
|
0986e8b5ec | ||
|
|
ae2a24642b | ||
|
|
1a68d94c32 | ||
|
|
c102f4adfa | ||
|
|
d589b9417d | ||
|
|
7b39de9630 | ||
|
|
6702ab9225 | ||
|
|
ecb98f399d | ||
|
|
a9ec951c93 | ||
|
|
9de28f9342 | ||
|
|
dc7e53d79f | ||
|
|
d3a5aae7af | ||
|
|
7153fb9756 | ||
|
|
0e31b40407 | ||
|
|
fa5a9fbcaa | ||
|
|
68b28a43f3 | ||
|
|
ddda03c4cb | ||
|
|
96ab19e398 | ||
|
|
2783793b17 | ||
|
|
e499871a59 | ||
|
|
7c38af1b04 | ||
|
|
cc3e91e8d7 | ||
|
|
a95e06a951 | ||
|
|
502c88084c | ||
|
|
a9f0374fa7 | ||
|
|
56c864b008 | ||
|
|
80f0f97efa | ||
|
|
4fdbe4ed26 | ||
|
|
1e8e440721 | ||
|
|
605a967282 | ||
|
|
7a357a10da | ||
|
|
d58037e3d4 | ||
|
|
f3b5025b64 | ||
|
|
e32486f9a8 | ||
|
|
064507bfe8 | ||
|
|
e61141a45e | ||
|
|
4ce8c507b0 | ||
|
|
85e420eb54 | ||
|
|
40a052ba7f | ||
|
|
3249811a90 | ||
|
|
c5b1e1af27 | ||
|
|
78a802faa6 | ||
|
|
811550ad25 | ||
|
|
4093a3b01d | ||
|
|
9de928d6af | ||
|
|
5a94ed80cb | ||
|
|
22e150a8e6 | ||
|
|
8e0ff856fe | ||
|
|
739db92ef0 | ||
|
|
53e42e6ceb | ||
|
|
832e4c45fb | ||
|
|
52ea7e8dcf | ||
|
|
5a3b87e08c | ||
|
|
6f1228c029 | ||
|
|
e96e5fd9ca | ||
|
|
9d4faca7db | ||
|
|
c22615ea6f | ||
|
|
749cd8531f | ||
|
|
734cacb177 | ||
|
|
1f7070f5c9 | ||
|
|
8d8f3e757e | ||
|
|
5e890a078f | ||
|
|
e530d86af7 | ||
|
|
300907dd4c | ||
|
|
0916749a32 | ||
|
|
9d29fece51 | ||
|
|
8df2be2a52 | ||
|
|
7f3ddf5d83 | ||
|
|
6a226e3e3c | ||
|
|
8b63acd46c | ||
|
|
f7094028b8 | ||
|
|
5f9d06a9f5 |
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "third_party/zephyr_bluetooth-2.7.5/zephyr_bluetooth"]
|
||||
path = third_party/zephyr_bluetooth-2.7.5/zephyr_bluetooth
|
||||
url = https://github.com/sakumisu/zephyr_bluetooth.git
|
||||
@@ -71,7 +71,7 @@ elseif(ESP_PLATFORM)
|
||||
${cherryusb_incs}
|
||||
${freertos_include}
|
||||
PRIV_REQUIRES
|
||||
usb esp_mm
|
||||
usb esp_mm esp_netif esp_timer
|
||||
LDFRAGMENTS
|
||||
${ldfragments}
|
||||
)
|
||||
|
||||
134
Kconfig
@@ -52,6 +52,8 @@ if CHERRYUSB
|
||||
bool "musb_sunxi"
|
||||
config CHERRYUSB_DEVICE_MUSB_BK
|
||||
bool "musb_bk"
|
||||
config CHERRYUSB_DEVICE_MUSB_SIFLI
|
||||
bool "musb_sifli"
|
||||
config CHERRYUSB_DEVICE_MUSB_CUSTOM
|
||||
bool "musb_custom"
|
||||
config CHERRYUSB_DEVICE_CHIPIDEA_MCX
|
||||
@@ -123,55 +125,109 @@ if CHERRYUSB
|
||||
prompt "Enable usb mtp device, it is commercial charge"
|
||||
default n
|
||||
|
||||
config CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
prompt "Enable usb dfu device"
|
||||
default n
|
||||
|
||||
config CHERRYUSB_DEVICE_ADB
|
||||
bool
|
||||
prompt "Enable usb adb device"
|
||||
default n
|
||||
|
||||
config CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
prompt "Enable usb dfu device"
|
||||
default n
|
||||
|
||||
config USBDEV_REQUEST_BUFFER_LEN
|
||||
int
|
||||
prompt "Set device control transfer max buffer size"
|
||||
default 512
|
||||
|
||||
config USBDEV_MSC_MAX_BUFSIZE
|
||||
int
|
||||
prompt "Set usb msc device max buffer size"
|
||||
default 512
|
||||
help
|
||||
Set the maximum buffer size for usb msc device, it is used to transfer data.
|
||||
you can change it to a larger value if you need larger speed but must be a power of blocksize.
|
||||
|
||||
config USBDEV_RNDIS_USING_LWIP
|
||||
bool
|
||||
prompt "Enable usb rndis device with lwip for lan"
|
||||
default n
|
||||
|
||||
config USBDEV_CDC_ECM_USING_LWIP
|
||||
bool
|
||||
prompt "Enable usb cdc ecm device with lwip for lan"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "Select usb device template"
|
||||
prompt "Select usb device template, please select class driver first"
|
||||
default CHERRYUSB_DEVICE_TEMPLATE_NONE
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_NONE
|
||||
bool "none (Implement it yourself)"
|
||||
bool
|
||||
prompt "none (Implement it yourself)"
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
|
||||
bool "cdc_acm"
|
||||
bool
|
||||
prompt "cdc_acm"
|
||||
depends on CHERRYUSB_DEVICE_CDC_ACM
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_MSC
|
||||
bool "msc"
|
||||
bool
|
||||
prompt "msc_ram"
|
||||
depends on CHERRYUSB_DEVICE_MSC
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
|
||||
bool "hid_keyboard"
|
||||
bool
|
||||
prompt "hid_keyboard"
|
||||
depends on CHERRYUSB_DEVICE_HID
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
|
||||
bool "hid_mouse"
|
||||
bool
|
||||
prompt "hid_mouse"
|
||||
depends on CHERRYUSB_DEVICE_HID
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
|
||||
bool "hid_custom"
|
||||
bool
|
||||
prompt "hid_custom"
|
||||
depends on CHERRYUSB_DEVICE_HID
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_VIDEO
|
||||
bool "video"
|
||||
bool
|
||||
prompt "video"
|
||||
depends on CHERRYUSB_DEVICE_VIDEO
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
|
||||
bool "audio_v1_mic_speaker_multichan"
|
||||
bool
|
||||
prompt "audio_v1_mic_speaker_multichan"
|
||||
depends on CHERRYUSB_DEVICE_AUDIO
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
|
||||
bool "audio_v2_mic_speaker_multichan"
|
||||
bool
|
||||
prompt "audio_v2_mic_speaker_multichan"
|
||||
depends on CHERRYUSB_DEVICE_AUDIO
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
|
||||
bool "cdc_rndis"
|
||||
bool
|
||||
prompt "cdc_rndis"
|
||||
depends on CHERRYUSB_DEVICE_CDC_RNDIS
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
|
||||
bool "cdc_ecm"
|
||||
bool
|
||||
prompt "cdc_ecm"
|
||||
depends on CHERRYUSB_DEVICE_CDC_ECM
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
|
||||
bool "cdc_ncm"
|
||||
bool
|
||||
prompt "cdc_ncm"
|
||||
depends on CHERRYUSB_DEVICE_CDC_NCM
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
|
||||
bool "cdc_acm_msc"
|
||||
bool
|
||||
prompt "cdc_acm_msc"
|
||||
depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
|
||||
bool "cdc_acm_msc_hid"
|
||||
bool
|
||||
prompt "cdc_acm_msc_hid"
|
||||
depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC && CHERRYUSB_DEVICE_HID
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
|
||||
bool "winusbv1"
|
||||
bool
|
||||
prompt "winusbv1"
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
|
||||
bool "winusbv2_cdc"
|
||||
bool
|
||||
prompt "winusbv2_cdc"
|
||||
depends on CHERRYUSB_DEVICE_CDC_ACM
|
||||
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
|
||||
bool "winusbv2_hid"
|
||||
bool
|
||||
prompt "winusbv2_hid"
|
||||
depends on CHERRYUSB_DEVICE_HID
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
menuconfig CHERRYUSB_HOST
|
||||
@@ -216,6 +272,8 @@ if CHERRYUSB
|
||||
bool "musb_sunxi"
|
||||
config CHERRYUSB_HOST_MUSB_BK
|
||||
bool "musb_bk"
|
||||
config CHERRYUSB_HOST_MUSB_SIFLI
|
||||
bool "musb_sifli"
|
||||
config CHERRYUSB_HOST_MUSB_CUSTOM
|
||||
bool "musb_custom"
|
||||
config CHERRYUSB_HOST_PUSB2
|
||||
@@ -334,12 +392,27 @@ if CHERRYUSB
|
||||
config USBHOST_PLATFORM_RTL8152
|
||||
bool
|
||||
|
||||
config CHERRYUSB_HOST_TEMPLATE
|
||||
bool
|
||||
prompt "Use usb host template"
|
||||
default n
|
||||
config USBHOST_PSC_PRIO
|
||||
int
|
||||
prompt "Set hubport change thread priority, 0 is the max priority"
|
||||
default 0
|
||||
|
||||
if CHERRYUSB_HOST_TEMPLATE
|
||||
config USBHOST_PSC_STACKSIZE
|
||||
int
|
||||
prompt "Set hubport change thread stacksize"
|
||||
default 4096
|
||||
|
||||
config USBHOST_REQUEST_BUFFER_LEN
|
||||
int
|
||||
prompt "Set host control transfer max buffer size"
|
||||
default 512
|
||||
|
||||
config USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
int
|
||||
prompt "Set host control transfer timeout, unit is ms"
|
||||
default 500
|
||||
|
||||
menu "Select USB host template, please select class driver first"
|
||||
config TEST_USBH_CDC_ACM
|
||||
int
|
||||
prompt "demo for test cdc acm"
|
||||
@@ -355,7 +428,6 @@ if CHERRYUSB
|
||||
prompt "demo for test msc"
|
||||
default 0
|
||||
depends on CHERRYUSB_HOST_MSC
|
||||
endif
|
||||
endmenu
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
162
Kconfig.rtt
@@ -52,6 +52,8 @@ if RT_USING_CHERRYUSB
|
||||
bool "musb_sunxi"
|
||||
config RT_CHERRYUSB_DEVICE_MUSB_BK
|
||||
bool "musb_bk"
|
||||
config RT_CHERRYUSB_DEVICE_MUSB_SIFLI
|
||||
bool "musb_sifli"
|
||||
config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
|
||||
bool "musb_custom"
|
||||
config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
|
||||
@@ -125,50 +127,125 @@ if RT_USING_CHERRYUSB
|
||||
prompt "Enable usb mtp device, it is commercial charge"
|
||||
default n
|
||||
|
||||
config RT_CHERRYUSB_DEVICE_ADB
|
||||
bool
|
||||
prompt "Enable usb adb device"
|
||||
default n
|
||||
|
||||
config RT_CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
prompt "Enable usb dfu device"
|
||||
default n
|
||||
|
||||
config RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
prompt "Enable chardev for cdc acm device"
|
||||
default n
|
||||
|
||||
config CONFIG_USBDEV_REQUEST_BUFFER_LEN
|
||||
int
|
||||
prompt "Set device control transfer max buffer size"
|
||||
default 512
|
||||
|
||||
config CONFIG_USBDEV_MSC_MAX_BUFSIZE
|
||||
int
|
||||
prompt "Set usb msc device max buffer size"
|
||||
default 512
|
||||
help
|
||||
Set the maximum buffer size for usb msc device, it is used to transfer data.
|
||||
you can change it to a larger value if you need larger speed but must be a power of blocksize.
|
||||
|
||||
config CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
bool
|
||||
prompt "Enable usb rndis device with lwip for lan"
|
||||
default n
|
||||
|
||||
config CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
bool
|
||||
prompt "Enable usb cdc ecm device with lwip for lan"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "Select usb device template"
|
||||
prompt "Select usb device template, please select class driver first"
|
||||
default RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
|
||||
bool "none (Implement it yourself)"
|
||||
bool
|
||||
prompt "none (Implement it yourself)"
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
|
||||
bool "cdc_acm"
|
||||
bool
|
||||
prompt "cdc_acm"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_ACM
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
|
||||
bool "msc_ram"
|
||||
bool
|
||||
prompt "msc_ram"
|
||||
depends on RT_CHERRYUSB_DEVICE_MSC
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
|
||||
bool "msc_blkdev"
|
||||
bool
|
||||
prompt "msc_blkdev"
|
||||
depends on RT_CHERRYUSB_DEVICE_MSC
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
|
||||
bool "hid_keyboard"
|
||||
bool
|
||||
prompt "hid_keyboard"
|
||||
depends on RT_CHERRYUSB_DEVICE_HID
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
|
||||
bool "hid_mouse"
|
||||
bool
|
||||
prompt "hid_mouse"
|
||||
depends on RT_CHERRYUSB_DEVICE_HID
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
|
||||
bool "hid_custom"
|
||||
bool
|
||||
prompt "hid_custom"
|
||||
depends on RT_CHERRYUSB_DEVICE_HID
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_VIDEO
|
||||
bool "video"
|
||||
bool
|
||||
prompt "video"
|
||||
depends on RT_CHERRYUSB_DEVICE_VIDEO
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
|
||||
bool "audio_v1_mic_speaker_multichan"
|
||||
bool
|
||||
prompt "audio_v1_mic_speaker_multichan"
|
||||
depends on RT_CHERRYUSB_DEVICE_AUDIO
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
|
||||
bool "audio_v2_mic_speaker_multichan"
|
||||
bool
|
||||
prompt "audio_v2_mic_speaker_multichan"
|
||||
depends on RT_CHERRYUSB_DEVICE_AUDIO
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
|
||||
bool "cdc_rndis"
|
||||
bool
|
||||
prompt "cdc_rndis"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_RNDIS
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
|
||||
bool "cdc_ecm"
|
||||
bool
|
||||
prompt "cdc_ecm"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_ECM
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
|
||||
bool "cdc_ncm"
|
||||
bool
|
||||
prompt "cdc_ncm"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_NCM
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
|
||||
bool "cdc_acm_msc"
|
||||
bool
|
||||
prompt "cdc_acm_msc"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
|
||||
bool "cdc_acm_msc_hid"
|
||||
bool
|
||||
prompt "cdc_acm_msc_hid"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC && RT_CHERRYUSB_DEVICE_HID
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
|
||||
bool "winusbv1"
|
||||
bool
|
||||
prompt "winusbv1"
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
|
||||
bool "winusbv2_cdc"
|
||||
bool
|
||||
prompt "winusbv2_cdc"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_ACM
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
|
||||
bool "winusbv2_hid"
|
||||
bool
|
||||
prompt "winusbv2_hid"
|
||||
depends on RT_CHERRYUSB_DEVICE_HID
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB
|
||||
bool
|
||||
prompt "adb"
|
||||
depends on RT_CHERRYUSB_DEVICE_ADB
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
prompt "cdc_acm_chardev"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
endchoice
|
||||
|
||||
config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
|
||||
@@ -220,6 +297,8 @@ if RT_USING_CHERRYUSB
|
||||
bool "musb_sunxi"
|
||||
config RT_CHERRYUSB_HOST_MUSB_BK
|
||||
bool "musb_bk"
|
||||
config RT_CHERRYUSB_HOST_MUSB_SIFLI
|
||||
bool "musb_sifli"
|
||||
config RT_CHERRYUSB_HOST_MUSB_CUSTOM
|
||||
bool "musb_custom"
|
||||
config RT_CHERRYUSB_HOST_PUSB2
|
||||
@@ -332,6 +411,26 @@ if RT_USING_CHERRYUSB
|
||||
config CONFIG_USBHOST_PLATFORM_RTL8152
|
||||
bool
|
||||
|
||||
config CONFIG_USBHOST_PSC_PRIO
|
||||
int
|
||||
prompt "Set hubport change thread priority, 0 is the max priority"
|
||||
default 0
|
||||
|
||||
config CONFIG_USBHOST_PSC_STACKSIZE
|
||||
int
|
||||
prompt "Set hubport change thread stacksize"
|
||||
default 4096
|
||||
|
||||
config CONFIG_USBHOST_REQUEST_BUFFER_LEN
|
||||
int
|
||||
prompt "Set host control transfer max buffer size"
|
||||
default 512
|
||||
|
||||
config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
int
|
||||
prompt "Set host control transfer timeout, unit is ms"
|
||||
default 500
|
||||
|
||||
config RT_LWIP_PBUF_POOL_BUFSIZE
|
||||
int "The size of each pbuf in the pbuf pool"
|
||||
range 1500 2000
|
||||
@@ -342,23 +441,22 @@ if RT_USING_CHERRYUSB
|
||||
depends on RT_CHERRYUSB_HOST_MSC
|
||||
default "/"
|
||||
|
||||
config RT_CHERRYUSB_HOST_TEMPLATE
|
||||
bool
|
||||
prompt "Use usb host template"
|
||||
default n
|
||||
|
||||
if RT_CHERRYUSB_HOST_TEMPLATE
|
||||
config TEST_USBH_CDC_ACM
|
||||
menu "Select USB host template, please select class driver first"
|
||||
config CONFIG_TEST_USBH_CDC_ACM
|
||||
int
|
||||
prompt "demo for test cdc acm"
|
||||
prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead"
|
||||
default 0
|
||||
depends on CHERRYUSB_HOST_CDC_ACM
|
||||
config TEST_USBH_HID
|
||||
depends on RT_CHERRYUSB_HOST_CDC_ACM
|
||||
config CONFIG_TEST_USBH_HID
|
||||
int
|
||||
prompt "demo for test hid"
|
||||
default 0
|
||||
depends on CHERRYUSB_HOST_HID
|
||||
endif
|
||||
depends on RT_CHERRYUSB_HOST_HID
|
||||
config CONFIG_TEST_USBH_MSC
|
||||
int
|
||||
prompt "demo for test msc, cannot enable this demo, we have used dfs instead"
|
||||
default 0
|
||||
depends on RT_CHERRYUSB_HOST_MSC
|
||||
endmenu
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
174
Kconfig.rttpkg
@@ -53,6 +53,8 @@ if PKG_USING_CHERRYUSB
|
||||
bool "musb_sunxi"
|
||||
config PKG_CHERRYUSB_DEVICE_MUSB_BK
|
||||
bool "musb_bk"
|
||||
config PKG_CHERRYUSB_DEVICE_MUSB_SIFLI
|
||||
bool "musb_sifli"
|
||||
config PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM
|
||||
bool "musb_custom"
|
||||
config PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX
|
||||
@@ -124,50 +126,125 @@ if PKG_USING_CHERRYUSB
|
||||
prompt "Enable usb mtp device, it is commercial charge"
|
||||
default n
|
||||
|
||||
config PKG_CHERRYUSB_DEVICE_ADB
|
||||
bool
|
||||
prompt "Enable usb adb device"
|
||||
default n
|
||||
|
||||
config PKG_CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
prompt "Enable usb dfu device"
|
||||
default n
|
||||
|
||||
config PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
prompt "Enable chardev for cdc acm device"
|
||||
default n
|
||||
|
||||
config CONFIG_USBDEV_REQUEST_BUFFER_LEN
|
||||
int
|
||||
prompt "Set device control transfer max buffer size"
|
||||
default 512
|
||||
|
||||
config CONFIG_USBDEV_MSC_MAX_BUFSIZE
|
||||
int
|
||||
prompt "Set usb msc device max buffer size"
|
||||
default 512
|
||||
help
|
||||
Set the maximum buffer size for usb msc device, it is used to transfer data.
|
||||
you can change it to a larger value if you need larger speed but must be a power of blocksize.
|
||||
|
||||
config CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
bool
|
||||
prompt "Enable usb rndis device with lwip for lan"
|
||||
default n
|
||||
|
||||
config CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
bool
|
||||
prompt "Enable usb cdc ecm device with lwip for lan"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "Select usb device template"
|
||||
prompt "Select usb device template, please select class driver first"
|
||||
default PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE
|
||||
bool "none (Implement it yourself)"
|
||||
bool
|
||||
prompt "none (Implement it yourself)"
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
|
||||
bool "cdc_acm"
|
||||
bool
|
||||
prompt "cdc_acm"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC
|
||||
bool "msc_ram"
|
||||
bool
|
||||
prompt "msc_ram"
|
||||
depends on PKG_CHERRYUSB_DEVICE_MSC
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
|
||||
bool "msc_blkdev"
|
||||
bool
|
||||
prompt "msc_blkdev"
|
||||
depends on PKG_CHERRYUSB_DEVICE_MSC
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
|
||||
bool "hid_keyboard"
|
||||
bool
|
||||
prompt "hid_keyboard"
|
||||
depends on PKG_CHERRYUSB_DEVICE_HID
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
|
||||
bool "hid_mouse"
|
||||
bool
|
||||
prompt "hid_mouse"
|
||||
depends on PKG_CHERRYUSB_DEVICE_HID
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
|
||||
bool "hid_custom"
|
||||
bool
|
||||
prompt "hid_custom"
|
||||
depends on PKG_CHERRYUSB_DEVICE_HID
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_VIDEO
|
||||
bool "video"
|
||||
bool
|
||||
prompt "video"
|
||||
depends on PKG_CHERRYUSB_DEVICE_VIDEO
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
|
||||
bool "audio_v1_mic_speaker_multichan"
|
||||
bool
|
||||
prompt "audio_v1_mic_speaker_multichan"
|
||||
depends on PKG_CHERRYUSB_DEVICE_AUDIO
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
|
||||
bool "audio_v2_mic_speaker_multichan"
|
||||
bool
|
||||
prompt "audio_v2_mic_speaker_multichan"
|
||||
depends on PKG_CHERRYUSB_DEVICE_AUDIO
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
|
||||
bool "cdc_rndis"
|
||||
bool
|
||||
prompt "cdc_rndis"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_RNDIS
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
|
||||
bool "cdc_ecm"
|
||||
bool
|
||||
prompt "cdc_ecm"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_ECM
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
|
||||
bool "cdc_ncm"
|
||||
bool
|
||||
prompt "cdc_ncm"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_NCM
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
|
||||
bool "cdc_acm_msc"
|
||||
bool
|
||||
prompt "cdc_acm_msc"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
|
||||
bool "cdc_acm_msc_hid"
|
||||
bool
|
||||
prompt "cdc_acm_msc_hid"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC && PKG_CHERRYUSB_DEVICE_HID
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
|
||||
bool "winusbv1"
|
||||
bool
|
||||
prompt "winusbv1"
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
|
||||
bool "winusbv2_cdc"
|
||||
bool
|
||||
prompt "winusbv2_cdc"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
|
||||
bool "winusbv2_hid"
|
||||
bool
|
||||
prompt "winusbv2_hid"
|
||||
depends on PKG_CHERRYUSB_DEVICE_HID
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB
|
||||
bool
|
||||
prompt "adb"
|
||||
depends on PKG_CHERRYUSB_DEVICE_ADB
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
prompt "cdc_acm_chardev"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
endchoice
|
||||
|
||||
config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
|
||||
@@ -219,6 +296,8 @@ if PKG_USING_CHERRYUSB
|
||||
bool "musb_sunxi"
|
||||
config PKG_CHERRYUSB_HOST_MUSB_BK
|
||||
bool "musb_bk"
|
||||
config PKG_CHERRYUSB_HOST_MUSB_SIFLI
|
||||
bool "musb_sifli"
|
||||
config PKG_CHERRYUSB_HOST_MUSB_CUSTOM
|
||||
bool "musb_custom"
|
||||
config PKG_CHERRYUSB_HOST_PUSB2
|
||||
@@ -331,6 +410,26 @@ if PKG_USING_CHERRYUSB
|
||||
config CONFIG_USBHOST_PLATFORM_RTL8152
|
||||
bool
|
||||
|
||||
config CONFIG_USBHOST_PSC_PRIO
|
||||
int
|
||||
prompt "Set hubport change thread priority, 0 is the max priority"
|
||||
default 0
|
||||
|
||||
config CONFIG_USBHOST_PSC_STACKSIZE
|
||||
int
|
||||
prompt "Set hubport change thread stacksize"
|
||||
default 4096
|
||||
|
||||
config CONFIG_USBHOST_REQUEST_BUFFER_LEN
|
||||
int
|
||||
prompt "Set host control transfer max buffer size"
|
||||
default 512
|
||||
|
||||
config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
int
|
||||
prompt "Set host control transfer timeout, unit is ms"
|
||||
default 500
|
||||
|
||||
config RT_LWIP_PBUF_POOL_BUFSIZE
|
||||
int "The size of each pbuf in the pbuf pool"
|
||||
range 1500 2000
|
||||
@@ -341,23 +440,23 @@ if PKG_USING_CHERRYUSB
|
||||
depends on RT_CHERRYUSB_HOST_MSC
|
||||
default "/"
|
||||
|
||||
config PKG_CHERRYUSB_HOST_TEMPLATE
|
||||
bool
|
||||
prompt "Use usb host template"
|
||||
default n
|
||||
|
||||
if PKG_CHERRYUSB_HOST_TEMPLATE
|
||||
config TEST_USBH_CDC_ACM
|
||||
menu "Select USB host template, please select class driver first"
|
||||
config CONFIG_TEST_USBH_CDC_ACM
|
||||
int
|
||||
prompt "demo for test cdc acm"
|
||||
prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead"
|
||||
default 0
|
||||
depends on PKG_CHERRYUSB_HOST_CDC_ACM
|
||||
config TEST_USBH_HID
|
||||
config CONFIG_TEST_USBH_HID
|
||||
int
|
||||
prompt "demo for test hid"
|
||||
default 0
|
||||
depends on PKG_CHERRYUSB_HOST_HID
|
||||
endif
|
||||
config CONFIG_TEST_USBH_MSC
|
||||
int
|
||||
prompt "demo for test msc, cannot enable this demo, we have used dfs instead"
|
||||
default 0
|
||||
depends on PKG_CHERRYUSB_HOST_MSC
|
||||
endmenu
|
||||
endif
|
||||
|
||||
config PKG_CHERRYUSB_PATH
|
||||
@@ -366,24 +465,22 @@ if PKG_USING_CHERRYUSB
|
||||
|
||||
choice
|
||||
prompt "Version"
|
||||
default PKG_USING_CHERRYUSB_V010500
|
||||
default PKG_USING_CHERRYUSB_V010502
|
||||
help
|
||||
Select the package version
|
||||
|
||||
config PKG_USING_CHERRYUSB_LATEST_VERSION
|
||||
bool "latest"
|
||||
config PKG_USING_CHERRYUSB_V010502
|
||||
bool "v1.5.2"
|
||||
config PKG_USING_CHERRYUSB_V010501
|
||||
bool "v1.5.1"
|
||||
config PKG_USING_CHERRYUSB_V010500
|
||||
bool "v1.5.0"
|
||||
config PKG_USING_CHERRYUSB_V010403
|
||||
bool "v1.4.3"
|
||||
config PKG_USING_CHERRYUSB_V010402
|
||||
bool "v1.4.2"
|
||||
config PKG_USING_CHERRYUSB_V010400
|
||||
bool "v1.4.0"
|
||||
config PKG_USING_CHERRYUSB_V010301
|
||||
bool "v1.3.1"
|
||||
config PKG_USING_CHERRYUSB_V010300
|
||||
bool "v1.3.0"
|
||||
config PKG_USING_CHERRYUSB_V010200
|
||||
bool "v1.2.0"
|
||||
config PKG_USING_CHERRYUSB_V001002
|
||||
@@ -393,12 +490,11 @@ if PKG_USING_CHERRYUSB
|
||||
config PKG_CHERRYUSB_VER
|
||||
string
|
||||
default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION
|
||||
default "v1.5.2" if PKG_USING_CHERRYUSB_V010502
|
||||
default "v1.5.1" if PKG_USING_CHERRYUSB_V010501
|
||||
default "v1.5.0" if PKG_USING_CHERRYUSB_V010500
|
||||
default "v1.4.3" if PKG_USING_CHERRYUSB_V010403
|
||||
default "v1.4.2" if PKG_USING_CHERRYUSB_V010402
|
||||
default "v1.4.0" if PKG_USING_CHERRYUSB_V010400
|
||||
default "v1.3.1" if PKG_USING_CHERRYUSB_V010301
|
||||
default "v1.3.0" if PKG_USING_CHERRYUSB_V010300
|
||||
default "v1.2.0" if PKG_USING_CHERRYUSB_V010200
|
||||
default "v0.10.2" if PKG_USING_CHERRYUSB_V001002
|
||||
endif
|
||||
|
||||
44
README.md
@@ -40,6 +40,8 @@ Taking into account USB performance issues and trying to achieve the theoretical
|
||||
- Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
|
||||
- Packetization is handled in interrupt
|
||||
|
||||
Performance show:https://cherryusb.cherry-embedded.org/show/
|
||||
|
||||
## Directory Structure
|
||||
|
||||
| Directory | Description |
|
||||
@@ -103,7 +105,7 @@ CherryUSB Host Stack has the following functions:
|
||||
- Support blocking transfers and asynchronous transfers
|
||||
- Support Composite Device
|
||||
- Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2/ehci/xhci/rp2040)
|
||||
- Support Communication Device Class (CDC_ACM, CDC_ECM)
|
||||
- Support Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM)
|
||||
- Support Human Interface Device (HID)
|
||||
- Support Mass Storage Class (MSC)
|
||||
- Support USB Video CLASS (UVC1.0, UVC1.5)
|
||||
@@ -141,7 +143,7 @@ Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affe
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
```
|
||||
|
||||
@@ -187,24 +189,25 @@ TODO
|
||||
|
||||
## Demo Repo
|
||||
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note |
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|
||||
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update |
|
||||
|
||||
## Package Support
|
||||
|
||||
@@ -226,5 +229,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
|
||||
|
||||
Thanks to the following companies for their support (in no particular order):
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" /> <img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/sifli.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
|
||||
44
README_zh.md
@@ -40,6 +40,8 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(
|
||||
- 长度无限制,方便对接硬件 DMA 并且发挥 DMA 的优势
|
||||
- 分包过程在中断中执行
|
||||
|
||||
性能展示:https://cherryusb.cherry-embedded.org/show/
|
||||
|
||||
## 目录结构
|
||||
|
||||
| 目录名 | 描述 |
|
||||
@@ -103,7 +105,7 @@ CherryUSB Host 协议栈当前实现以下功能:
|
||||
- 支持阻塞式传输和异步传输
|
||||
- 支持复合设备
|
||||
- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,仅支持 dwc2/ehci/xhci/rp2040)
|
||||
- 支持 Communication Device Class (CDC_ACM, CDC_ECM)
|
||||
- 支持 Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM)
|
||||
- 支持 Human Interface Device (HID)
|
||||
- 支持 Mass Storage Class (MSC)
|
||||
- Support USB Video CLASS (UVC1.0、UVC1.5)
|
||||
@@ -141,7 +143,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2,关闭 log)
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
```
|
||||
|
||||
@@ -187,24 +189,25 @@ TODO
|
||||
|
||||
## 示例仓库
|
||||
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note |
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|
||||
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update |
|
||||
|
||||
## 软件包支持
|
||||
|
||||
@@ -228,5 +231,4 @@ CherryUSB 微信群:与我联系后邀请加入
|
||||
|
||||
感谢以下企业支持(顺序不分先后):
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" /> <img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/sifli.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
|
||||
32
SConscript
@@ -70,6 +70,9 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_BK']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_bk.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_SIFLI']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_sifli.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX']):
|
||||
@@ -87,6 +90,7 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_BL']):
|
||||
src += Glob('port/bouffalolab/usb_dc_bl.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_HPM']):
|
||||
path += [cwd + '/port/hpmicro']
|
||||
src += Glob('port/hpmicro/usb_dc_hpm.c')
|
||||
src += Glob('port/hpmicro/usb_glue_hpm.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_AIC']):
|
||||
@@ -127,13 +131,17 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
src += Glob('class/cdc/usbd_cdc_ncm.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_DFU']):
|
||||
src += Glob('class/dfu/usbd_dfu.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_ADB']):
|
||||
src += Glob('class/adb/usbd_adb.c')
|
||||
src += Glob('platform/rtthread/usbd_adb_shell.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV']):
|
||||
src += Glob('platform/rtthread/usbd_serial.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM']):
|
||||
src += Glob('demo/cdc_acm_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC']):
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC']) or GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV']):
|
||||
src += Glob('demo/msc_ram_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV']):
|
||||
src += Glob('platform/rtthread/usbd_msc_blkdev.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE']):
|
||||
src += Glob('demo/hid_mouse_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD']):
|
||||
@@ -162,6 +170,10 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
src += Glob('demo/winusb2.0_cdc_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID']):
|
||||
src += Glob('demo/winusb2.0_hid_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB']):
|
||||
src += Glob('demo/adb/usbd_adb_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV']):
|
||||
src += Glob('demo/cdc_acm_rttchardev_template.c')
|
||||
|
||||
# USB HOST
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
@@ -173,6 +185,7 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/ehci/usb_glue_bouffalo.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_EHCI_HPM']):
|
||||
path += [cwd + '/port/hpmicro']
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/hpmicro/usb_hc_hpm.c')
|
||||
src += Glob('port/hpmicro/usb_glue_hpm.c')
|
||||
@@ -222,6 +235,9 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_BK']):
|
||||
src += Glob('port/musb/usb_hc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_bk.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_SIFLI']):
|
||||
src += Glob('port/musb/usb_hc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_sifli.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_CUSTOM']):
|
||||
src += Glob('port/musb/usb_hc_musb.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_KINETIS_MCX']):
|
||||
@@ -281,10 +297,16 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_PL2303']):
|
||||
src += Glob('class/vendor/serial/usbh_pl2303.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']):
|
||||
CPPDEFINES+=['TEST_USBH_MSC=0']
|
||||
if GetDepend(['CONFIG_TEST_USBH_HID']):
|
||||
src += Glob('demo/usb_host.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_CDC_ACM']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_FTDI']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_CH34X']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_CP210X']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_PL2303']):
|
||||
src += Glob('platform/rtthread/usbh_serial.c')
|
||||
|
||||
if GetDepend('RT_USING_DFS') and GetDepend(['PKG_CHERRYUSB_HOST_MSC']):
|
||||
src += Glob('platform/rtthread/usbh_dfs.c')
|
||||
|
||||
|
||||
2
VERSION
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 5
|
||||
PATCHLEVEL = 0
|
||||
PATCHLEVEL = 2
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
||||
@@ -120,6 +120,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
|
||||
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_BK)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
|
||||
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_SIFLI)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_sifli.c)
|
||||
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_CUSTOM)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
|
||||
elseif(CONFIG_CHERRYUSB_DEVICE_CHIPIDEA_MCX)
|
||||
@@ -257,7 +260,11 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
OR CONFIG_CHERRYUSB_HOST_RTL8152
|
||||
OR CONFIG_CHERRYUSB_HOST_BL616
|
||||
)
|
||||
list(APPEND cherryusb_srcs platform/lwip/usbh_lwip.c)
|
||||
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_net.c)
|
||||
else()
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/lwip/usbh_lwip.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_CHERRYUSB_HOST_EHCI_BL)
|
||||
@@ -312,6 +319,9 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
elseif(CONFIG_CHERRYUSB_HOST_MUSB_BK)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
|
||||
elseif(CONFIG_CHERRYUSB_HOST_MUSB_SIFLI)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_sifli.c)
|
||||
elseif(CONFIG_CHERRYUSB_HOST_MUSB_CUSTOM)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
|
||||
@@ -325,7 +335,7 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c)
|
||||
endif()
|
||||
|
||||
if(CHERRYUSB_HOST_TEMPLATE)
|
||||
if(CONFIG_TEST_USBH_CDC_ACM OR CONFIG_TEST_USBH_HID OR CONFIG_TEST_USBH_MSC)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/demo/usb_host.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -47,9 +47,6 @@
|
||||
#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
|
||||
*/
|
||||
@@ -157,7 +154,7 @@
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
@@ -253,40 +250,22 @@
|
||||
/* ================ 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
|
||||
#define CONFIG_USBDEV_MAX_BUS 1
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBDEV_SOF_ENABLE
|
||||
|
||||
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. */
|
||||
// #define CONFIG_USB_HS
|
||||
|
||||
/* ---------------- FSDEV Configuration ---------------- */
|
||||
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
|
||||
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
|
||||
*/
|
||||
// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
|
||||
/* IN Endpoints Max packet Size / 4 */
|
||||
// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 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)
|
||||
|
||||
/* enable dwc2 buffer dma mode for device
|
||||
* in xxx32 chips, only pb14/pb15 can support dma mode, pa11/pa12 is not supported(only a few supports, but we ignore them)
|
||||
*/
|
||||
// #define CONFIG_USB_DWC2_DMA_ENABLE
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
#define CONFIG_USB_MUSB_EP_NUM 8
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
@@ -294,15 +273,11 @@
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
#endif
|
||||
|
||||
/* ---------------- EHCI Configuration ---------------- */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_EHCI_QH_NUM 10
|
||||
#define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USB_EHCI_QH_NUM * 3)
|
||||
#define CONFIG_USB_EHCI_ITD_NUM 4
|
||||
// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
|
||||
@@ -313,7 +288,7 @@
|
||||
|
||||
/* ---------------- OHCI Configuration ---------------- */
|
||||
#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0)
|
||||
#define CONFIG_USB_OHCI_ED_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_OHCI_ED_NUM 10
|
||||
#define CONFIG_USB_OHCI_TD_NUM 3
|
||||
// #define CONFIG_USB_OHCI_DESC_DCACHE_ENABLE
|
||||
|
||||
@@ -321,19 +296,19 @@
|
||||
#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))
|
||||
// nothing to define
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
#define CONFIG_USB_MUSB_PIPE_NUM 8
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
|
||||
* the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
|
||||
*
|
||||
* in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them).
|
||||
*/
|
||||
// #define CONFIG_USB_HS
|
||||
|
||||
#ifndef usb_phyaddr2ramaddr
|
||||
#define usb_phyaddr2ramaddr(addr) (addr)
|
||||
#endif
|
||||
|
||||
@@ -121,7 +121,7 @@ get_mac:
|
||||
}
|
||||
|
||||
memset(mac_buffer, 0, 12);
|
||||
ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer);
|
||||
ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer, 12);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ get_mac:
|
||||
}
|
||||
|
||||
memset(mac_buffer, 0, 12);
|
||||
ret = usbh_get_string_desc(cdc_ncm_class->hport, mac_str_idx, (uint8_t *)mac_buffer);
|
||||
ret = usbh_get_string_desc(cdc_ncm_class->hport, mac_str_idx, (uint8_t *)mac_buffer, 12);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -179,15 +179,15 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length
|
||||
USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
|
||||
return -2;
|
||||
} else {
|
||||
USB_LOG_RAW("Hub Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_RAW("PortPwrCtrlMask: 0x%02x \r\n", desc->PortPwrCtrlMask);
|
||||
USB_LOG_DBG("Hub Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_DBG("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_DBG("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_DBG("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_DBG("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_DBG("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_DBG("PortPwrCtrlMask: 0x%02x \r\n", desc->PortPwrCtrlMask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -203,14 +203,14 @@ static int parse_hub_ss_descriptor(struct usb_hub_ss_descriptor *desc, uint16_t
|
||||
USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
|
||||
return -2;
|
||||
} else {
|
||||
USB_LOG_RAW("SuperSpeed Hub Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_DBG("SuperSpeed Hub Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_DBG("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_DBG("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_DBG("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_DBG("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_DBG("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -403,7 +403,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
|
||||
USB_LOG_INFO("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange);
|
||||
USB_LOG_DBG("port %u, status:0x%03x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -416,7 +416,7 @@ 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);
|
||||
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed) / 1000, 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;
|
||||
@@ -497,7 +497,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
USB_LOG_DBG("port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
/* First, clear all change bits */
|
||||
mask = 1;
|
||||
@@ -532,7 +532,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("Port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
USB_LOG_DBG("Port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
if (!(portchange & HUB_PORT_STATUS_C_CONNECTION) &&
|
||||
((portstatus & HUB_PORT_STATUS_CONNECTION) == connection)) {
|
||||
@@ -562,7 +562,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
if (portstatus & HUB_PORT_STATUS_CONNECTION) {
|
||||
ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_RESET);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to reset port %u,errorcode:%d\r\n", port, ret);
|
||||
USB_LOG_ERR("Failed to reset port %u, errorcode: %d\r\n", port + 1, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -576,11 +576,15 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("Port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
if (!(portstatus & HUB_PORT_STATUS_RESET) && (portstatus & HUB_PORT_STATUS_ENABLE)) {
|
||||
if (portchange & HUB_PORT_STATUS_C_RESET) {
|
||||
ret = usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_RESET);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to clear port %u reset change, errorcode: %d\r\n", port, ret);
|
||||
USB_LOG_ERR("Failed to clear port %u reset change, errorcode: %d\r\n", port + 1, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usb_scsi.h"
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
#include "usb_osal.h"
|
||||
#endif
|
||||
|
||||
#undef USB_DBG_TAG
|
||||
#define USB_DBG_TAG "usbd_msc"
|
||||
#include "usb_log.h"
|
||||
|
||||
#define MSD_OUT_EP_IDX 0
|
||||
#define MSD_IN_EP_IDX 1
|
||||
@@ -516,19 +517,14 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
|
||||
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
|
||||
return false;
|
||||
}
|
||||
g_usbd_msc[busid].stage = MSC_DATA_IN;
|
||||
@@ -554,19 +550,14 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
|
||||
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
|
||||
return false;
|
||||
}
|
||||
g_usbd_msc[busid].stage = MSC_DATA_IN;
|
||||
@@ -594,14 +585,10 @@ static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -627,14 +614,10 @@ static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -646,52 +629,6 @@ static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, g_usbd_msc[busid].block_buffer, data_len);
|
||||
return true;
|
||||
}
|
||||
/* do not use verify to reduce code size */
|
||||
#if 0
|
||||
static bool SCSI_verify10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/* Logical Block Address of First Block */
|
||||
uint32_t lba = 0;
|
||||
uint32_t blk_num = 0;
|
||||
|
||||
if ((g_usbd_msc[busid].cbw.CB[1] & 0x02U) == 0x00U) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((g_usbd_msc[busid].cbw.CB[1] & 0x02U) == 0x02U) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDFIELDINCBA);
|
||||
return false; /* Error, Verify Mode Not supported*/
|
||||
}
|
||||
|
||||
lba = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]);
|
||||
USB_LOG_DBG("lba: 0x%x\r\n", lba);
|
||||
|
||||
g_usbd_msc[busid].scsi_blk_addr = lba * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
|
||||
/* Number of Blocks to transfer */
|
||||
blk_num = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]);
|
||||
|
||||
USB_LOG_DBG("num (block) : 0x%x\r\n", blk_num);
|
||||
g_usbd_msc[busid].scsi_blk_len = blk_num * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
|
||||
if ((lba + blk_num) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usbd_msc[busid].cbw.dDataLength != g_usbd_msc[busid].scsi_blk_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].stage = MSC_DATA_OUT;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool SCSI_processRead(uint8_t busid)
|
||||
{
|
||||
@@ -722,6 +659,7 @@ static bool SCSI_processRead(uint8_t busid)
|
||||
static bool SCSI_processWrite(uint8_t busid, uint32_t nbytes)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
|
||||
USB_LOG_DBG("write lba:%d\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
if (usbd_msc_sector_write(busid, g_usbd_msc[busid].cbw.bLUN, g_usbd_msc[busid].start_sector, g_usbd_msc[busid].block_buffer, nbytes) != 0) {
|
||||
@@ -804,13 +742,13 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
|
||||
ret = SCSI_write12(busid, NULL, 0);
|
||||
break;
|
||||
case SCSI_CMD_VERIFY10:
|
||||
//ret = SCSI_verify10(NULL, 0);
|
||||
ret = false;
|
||||
break;
|
||||
|
||||
case SCSI_CMD_SYNCHCACHE10:
|
||||
ret = true;
|
||||
break;
|
||||
default:
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
USB_LOG_WRN("unsupported cmd:0x%02x\r\n", g_usbd_msc[busid].cbw.CB[0]);
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
@@ -818,7 +756,7 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
|
||||
if (ret) {
|
||||
if (g_usbd_msc[busid].stage == MSC_READ_CBW) {
|
||||
if (len2send) {
|
||||
USB_LOG_DBG("Send info len:%d\r\n", len2send);
|
||||
USB_LOG_DBG("Send info len: %d\r\n", len2send);
|
||||
usbd_msc_send_info(busid, buf2send, len2send);
|
||||
} else {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_PASSED);
|
||||
@@ -835,7 +773,7 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
switch (g_usbd_msc[busid].stage) {
|
||||
case MSC_READ_CBW:
|
||||
if (SCSI_CBWDecode(busid, nbytes) == false) {
|
||||
USB_LOG_ERR("Command:0x%02x decode err\r\n", g_usbd_msc[busid].cbw.CB[0]);
|
||||
USB_LOG_ERR("Command: 0x%02x decode err\r\n", g_usbd_msc[busid].cbw.CB[0]);
|
||||
usbd_msc_bot_abort(busid);
|
||||
return;
|
||||
}
|
||||
@@ -919,7 +857,6 @@ static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
USB_LOG_DBG("event:%d\r\n", event);
|
||||
if (event == MSC_DATA_OUT) {
|
||||
if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
@@ -941,7 +878,6 @@ void usbd_msc_polling(uint8_t busid)
|
||||
|
||||
if (event != 0) {
|
||||
g_usbd_msc[busid].event = 0;
|
||||
USB_LOG_DBG("event:%d\r\n", event);
|
||||
if (event == MSC_DATA_OUT) {
|
||||
if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
|
||||
@@ -284,6 +284,7 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret == -USB_ERR_STALL) {
|
||||
USB_LOG_WRN("Device does not support multiple LUNs\r\n");
|
||||
g_msc_buf[msc_class->sdchar - 'a'][0] = 0;
|
||||
ret = 0;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ struct mtp_object {
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
/*Length of template descriptor: 23 bytes*/
|
||||
/*Length of template descriptor: 30 bytes*/
|
||||
#define MTP_DESCRIPTOR_LEN (9 + 7 + 7 + 7)
|
||||
|
||||
// clang-format off
|
||||
@@ -675,9 +675,8 @@ struct mtp_object {
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x1c, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x06 /* bLength */
|
||||
WBVAL(0x1c), /* wMaxPacketSize */ \
|
||||
0x06 /* bInterval */
|
||||
// clang-format on
|
||||
|
||||
#endif
|
||||
@@ -36,6 +36,9 @@ struct usbd_interface *usbd_mtp_init_intf(struct usbd_interface *intf,
|
||||
const uint8_t in_ep,
|
||||
const uint8_t int_ep);
|
||||
|
||||
int usbd_mtp_notify_object_add(const char *path);
|
||||
int usbd_mtp_notify_object_remove(const char *path);
|
||||
|
||||
const char *usbd_mtp_fs_root_path(void);
|
||||
const char *usbd_mtp_fs_description(void);
|
||||
|
||||
|
||||
10
class/vendor/net/usbh_rtl8152.c
vendored
@@ -1121,7 +1121,7 @@ static inline int usb_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_
|
||||
|
||||
static uint32_t ocp_read_dword(struct usbh_rtl8152 *tp, uint16_t type, uint16_t index)
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t data = 0;
|
||||
|
||||
generic_ocp_read(tp, index, sizeof(data), &data, type);
|
||||
|
||||
@@ -1138,7 +1138,7 @@ static void ocp_write_dword(struct usbh_rtl8152 *tp, uint16_t type, uint16_t ind
|
||||
static uint16_t ocp_read_word(struct usbh_rtl8152 *tp, uint16_t type, uint16_t index)
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t tmp;
|
||||
uint32_t tmp = 0;
|
||||
uint16_t byen = BYTE_EN_WORD;
|
||||
uint8_t shift = index & 2;
|
||||
|
||||
@@ -1178,7 +1178,7 @@ static void ocp_write_word(struct usbh_rtl8152 *tp, uint16_t type, uint16_t inde
|
||||
static uint8_t ocp_read_byte(struct usbh_rtl8152 *tp, uint16_t type, uint16_t index)
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t tmp;
|
||||
uint32_t tmp = 0;
|
||||
uint8_t shift = index & 3;
|
||||
|
||||
index &= ~3;
|
||||
@@ -1254,7 +1254,7 @@ static inline int r8152_mdio_read(struct usbh_rtl8152 *tp, uint32_t reg_addr)
|
||||
static uint8_t usbh_rtl8152_get_version(struct usbh_rtl8152 *rtl8152_class)
|
||||
{
|
||||
uint8_t version;
|
||||
uint32_t temp;
|
||||
uint32_t temp = 0;
|
||||
uint32_t ocp_data;
|
||||
|
||||
usbh_rtl8152_read_regs(rtl8152_class, PLA_TCR0, MCU_TYPE_PLA, 4, &temp);
|
||||
@@ -2050,7 +2050,7 @@ static int usbh_rtl8152_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
|
||||
memset(mac_buffer, 0, 12);
|
||||
ret = usbh_get_string_desc(rtl8152_class->hport, 3, (uint8_t *)mac_buffer);
|
||||
ret = usbh_get_string_desc(rtl8152_class->hport, 3, (uint8_t *)mac_buffer, 12);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
1
class/vendor/serial/usbh_ftdi.c
vendored
@@ -350,6 +350,7 @@ static int usbh_ftdi_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
switch (version) {
|
||||
case 0x400:
|
||||
ftdi_class->chip_type = FT232B;
|
||||
break;
|
||||
case 0x500:
|
||||
ftdi_class->chip_type = FT2232C;
|
||||
break;
|
||||
|
||||
@@ -68,7 +68,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
||||
|
||||
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)cmd);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("rndis_initialize_msg_t send error, ret: %d\r\n", ret);
|
||||
USB_LOG_ERR("init send error, ret: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -84,14 +84,14 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
||||
|
||||
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("rndis_initialize_cmplt_t recv error, ret: %d\r\n", ret);
|
||||
USB_LOG_ERR("init recv error, ret: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rndis_class->max_transfer_pkts = resp->MaxPacketsPerTransfer;
|
||||
rndis_class->max_transfer_size = resp->MaxTransferSize;
|
||||
USB_LOG_INFO("MaxPacketsPerTransfer:%u\r\n", (unsigned int)resp->MaxPacketsPerTransfer);
|
||||
USB_LOG_INFO("MaxTransferSize:%u\r\n", (unsigned int)resp->MaxTransferSize);
|
||||
USB_LOG_INFO("MaxPacketsPerTransfer: %u\r\n", (unsigned int)resp->MaxPacketsPerTransfer);
|
||||
USB_LOG_INFO("MaxTransferSize: %u\r\n", (unsigned int)resp->MaxTransferSize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -312,14 +312,13 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
USB_LOG_INFO("rndis init success\r\n");
|
||||
|
||||
ret = usbh_rndis_query_msg_transfer(rndis_class, OID_GEN_SUPPORTED_LIST, 0, tmp_buffer, &data_len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
oid_num = (data_len / 4);
|
||||
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%u\r\n", (unsigned int)oid_num);
|
||||
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num: %u\r\n", (unsigned int)oid_num);
|
||||
|
||||
oid_support_list = (uint32_t *)tmp_buffer;
|
||||
|
||||
@@ -380,10 +379,8 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Ignore rndis query iod:%08x\r\n", (unsigned int)oid);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
USB_LOG_INFO("rndis query iod:%08x success\r\n", (unsigned int)oid);
|
||||
}
|
||||
|
||||
uint32_t packet_filter = 0x0f;
|
||||
@@ -391,14 +388,12 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
USB_LOG_INFO("rndis set OID_GEN_CURRENT_PACKET_FILTER success\r\n");
|
||||
|
||||
uint8_t multicast_list[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x01 };
|
||||
ret = usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
USB_LOG_INFO("rndis set OID_802_3_MULTICAST_LIST success\r\n");
|
||||
|
||||
USB_LOG_INFO("rndis MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
|
||||
rndis_class->mac[0],
|
||||
@@ -487,7 +482,7 @@ find_class:
|
||||
usbh_bulk_urb_fill(&g_rndis_class.bulkin_urb, g_rndis_class.hport, g_rndis_class.bulkin, &g_rndis_rx_buffer[g_rndis_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL);
|
||||
ret = usbh_submit_urb(&g_rndis_class.bulkin_urb);
|
||||
if (ret < 0) {
|
||||
goto find_class;
|
||||
break;
|
||||
}
|
||||
|
||||
g_rndis_rx_length += g_rndis_class.bulkin_urb.actual_length;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define USB_ERR_RANGE 7
|
||||
#define USB_ERR_STALL 8
|
||||
#define USB_ERR_BABBLE 9
|
||||
#define USB_ERR_NAK 10
|
||||
#define USB_ERR_NAK 10 /* only for dwc2 buffer dma mode */
|
||||
#define USB_ERR_DT 11
|
||||
#define USB_ERR_IO 12
|
||||
#define USB_ERR_SHUTDOWN 13
|
||||
|
||||
@@ -39,7 +39,7 @@ struct usbh_urb {
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
uint8_t data_toggle;
|
||||
uint8_t interval;
|
||||
uint32_t interval;
|
||||
struct usb_setup_packet *setup;
|
||||
uint8_t *transfer_buffer;
|
||||
uint32_t transfer_buffer_length;
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__) || defined(__ICCRISCV__)
|
||||
#if (__VER__ >= 8000000)
|
||||
#define __ICCARM_V8 1
|
||||
#else
|
||||
#define __ICCARM_V8 0
|
||||
#endif
|
||||
|
||||
#ifndef __USED
|
||||
#if defined(__ICCARM_V8) || defined(__ICCRISCV__)
|
||||
#define __USED __attribute__((used))
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#undef CHERRYUSB_VERSION_STR
|
||||
#endif
|
||||
|
||||
#define CHERRYUSB_VERSION 0x010500
|
||||
#define CHERRYUSB_VERSION_STR "v1.5.0"
|
||||
#define CHERRYUSB_VERSION 0x010502
|
||||
#define CHERRYUSB_VERSION_STR "v1.5.2"
|
||||
|
||||
#endif
|
||||
@@ -83,8 +83,8 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
|
||||
uint8_t intf_altsetting[16];
|
||||
uint8_t intf_offset;
|
||||
|
||||
struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM];
|
||||
struct usbd_tx_rx_msg rx_msg[CONFIG_USBDEV_EP_NUM];
|
||||
struct usbd_tx_rx_msg tx_msg[16];
|
||||
struct usbd_tx_rx_msg rx_msg[16];
|
||||
|
||||
void (*event_handler)(uint8_t busid, uint8_t event);
|
||||
} g_usbd_core[CONFIG_USBDEV_MAX_BUS];
|
||||
@@ -95,15 +95,25 @@ static void usbd_class_event_notify_handler(uint8_t busid, uint8_t event, void *
|
||||
|
||||
static void usbd_print_setup(struct usb_setup_packet *setup)
|
||||
{
|
||||
USB_LOG_INFO("Setup: "
|
||||
"bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
|
||||
setup->bmRequestType,
|
||||
setup->bRequest,
|
||||
setup->wValue,
|
||||
setup->wIndex,
|
||||
setup->wLength);
|
||||
USB_LOG_ERR("Setup: "
|
||||
"bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
|
||||
setup->bmRequestType,
|
||||
setup->bRequest,
|
||||
setup->wValue,
|
||||
setup->wIndex,
|
||||
setup->wLength);
|
||||
}
|
||||
|
||||
#if (CONFIG_USB_DBG_LEVEL >= USB_DBG_LOG)
|
||||
static const char *usb_ep0_state_string[] = {
|
||||
"setup",
|
||||
"indata",
|
||||
"outdata",
|
||||
"instatus",
|
||||
"outstatus"
|
||||
};
|
||||
#endif
|
||||
|
||||
static bool is_device_configured(uint8_t busid)
|
||||
{
|
||||
return (g_usbd_core[busid].configuration != 0);
|
||||
@@ -524,8 +534,6 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
|
||||
if_desc = (void *)p;
|
||||
}
|
||||
|
||||
USB_LOG_DBG("Current iface %u alt setting %u",
|
||||
cur_iface, cur_alt_setting);
|
||||
break;
|
||||
|
||||
case USB_DESCRIPTOR_TYPE_ENDPOINT:
|
||||
@@ -942,7 +950,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -956,7 +963,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -972,7 +978,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1000,7 +1005,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1013,7 +1017,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = g_usbd_core[busid].msosv2_desc->compat_id_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1029,7 +1032,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1171,9 +1173,14 @@ static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_se
|
||||
{
|
||||
uint8_t *buf;
|
||||
|
||||
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
usbd_print_setup(setup);
|
||||
#endif
|
||||
USB_LOG_DBG("[%s] 0x%02x 0x%02x 0x%04x 0x%04x 0x%04x\r\n",
|
||||
usb_ep0_state_string[usbd_get_ep0_next_state(busid)],
|
||||
setup->bmRequestType,
|
||||
setup->bRequest,
|
||||
setup->wValue,
|
||||
setup->wIndex,
|
||||
setup->wLength);
|
||||
|
||||
if (setup->wLength > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
|
||||
if ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT) {
|
||||
USB_LOG_ERR("Request buffer too small\r\n");
|
||||
@@ -1240,7 +1247,6 @@ static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_se
|
||||
*/
|
||||
if ((setup->wLength > g_usbd_core[busid].ep0_data_buf_len) && (!(g_usbd_core[busid].ep0_data_buf_len % USB_CTRL_EP_MPS))) {
|
||||
g_usbd_core[busid].zlp_flag = true;
|
||||
USB_LOG_DBG("EP0 Set zlp\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,7 +1272,10 @@ static void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32
|
||||
g_usbd_core[busid].ep0_data_buf += nbytes;
|
||||
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
|
||||
|
||||
USB_LOG_DBG("EP0 send %d bytes, %d remained\r\n", (unsigned int)nbytes, (unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
|
||||
USB_LOG_DBG("[%s] in %d bytes, %d remained\r\n",
|
||||
usb_ep0_state_string[usbd_get_ep0_next_state(busid)],
|
||||
(unsigned int)nbytes,
|
||||
(unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
|
||||
|
||||
if (g_usbd_core[busid].ep0_data_buf_residue != 0) {
|
||||
/* Start sending the remain data */
|
||||
@@ -1311,12 +1320,15 @@ static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint3
|
||||
(void)ep;
|
||||
(void)setup;
|
||||
|
||||
USB_LOG_DBG("[%s] out %d bytes, %d remained\r\n",
|
||||
usb_ep0_state_string[usbd_get_ep0_next_state(busid)],
|
||||
(unsigned int)nbytes,
|
||||
(unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
|
||||
|
||||
if (nbytes > 0) {
|
||||
g_usbd_core[busid].ep0_data_buf += nbytes;
|
||||
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
|
||||
|
||||
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", (unsigned int)nbytes, (unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
|
||||
|
||||
if (g_usbd_core[busid].ep0_data_buf_residue == 0) {
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_OUT);
|
||||
@@ -1338,9 +1350,8 @@ static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint3
|
||||
usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
|
||||
}
|
||||
} else {
|
||||
g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
|
||||
/* Read out status completely, do nothing */
|
||||
USB_LOG_DBG("EP0 recv out status\r\n");
|
||||
g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
100
core/usbh_core.c
@@ -228,12 +228,21 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
|
||||
cur_ep_num = intf_desc->bNumEndpoints;
|
||||
cur_ep = 0;
|
||||
|
||||
USB_ASSERT_MSG(cur_iface < CONFIG_USBHOST_MAX_INTERFACES,
|
||||
"Interface num %d overflow", cur_iface);
|
||||
USB_ASSERT_MSG(cur_alt_setting < CONFIG_USBHOST_MAX_INTF_ALTSETTINGS,
|
||||
"Interface altsetting num %d overflow", cur_alt_setting);
|
||||
USB_ASSERT_MSG(cur_ep_num <= CONFIG_USBHOST_MAX_ENDPOINTS,
|
||||
"Endpoint num %d overflow", cur_ep_num);
|
||||
if (cur_iface >= CONFIG_USBHOST_MAX_INTERFACES) {
|
||||
USB_LOG_ERR("Interface num %d overflow\r\n", cur_iface);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
if (cur_ep_num >= CONFIG_USBHOST_MAX_ENDPOINTS) {
|
||||
USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep_num);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
if (cur_alt_setting >= CONFIG_USBHOST_MAX_INTF_ALTSETTINGS) {
|
||||
USB_LOG_ERR("Interface altsetting num %d overflow\r\n", cur_alt_setting);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
#if 0
|
||||
USB_LOG_DBG("Interface Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", intf_desc->bLength);
|
||||
@@ -389,7 +398,11 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
|
||||
ret = parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse device descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Extract the correct max packetsize from the device descriptor */
|
||||
dev_desc = (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid];
|
||||
@@ -427,7 +440,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
}
|
||||
|
||||
/* Wait device set address completely */
|
||||
usb_osal_msleep(2);
|
||||
usb_osal_msleep(10);
|
||||
|
||||
/*Reconfigure EP0 with the correct address */
|
||||
hport->dev_addr = dev_addr;
|
||||
@@ -469,7 +482,11 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_CONFIG_DESC);
|
||||
ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_CONFIG_DESC);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse config descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Read the full size of the configuration data */
|
||||
uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->wTotalLength;
|
||||
@@ -494,9 +511,10 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
|
||||
ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], wTotalLength);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse config fail\r\n");
|
||||
USB_LOG_ERR("Parse config descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumInterfaces);
|
||||
hport->raw_config_desc = usb_osal_malloc(wTotalLength + 1);
|
||||
if (hport->raw_config_desc == NULL) {
|
||||
@@ -512,35 +530,47 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
#ifdef CONFIG_USBHOST_GET_STRING_DESC
|
||||
uint8_t string_buffer[128];
|
||||
|
||||
/* Get Manufacturer string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
if (hport->device_desc.iManufacturer > 0) {
|
||||
/* Get Manufacturer string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support Manufacturer string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
|
||||
if (hport->device_desc.iProduct > 0) {
|
||||
/* Get Product string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Product string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get Product string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
USB_LOG_INFO("Product: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support Product string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Product: %s\r\n", string_buffer);
|
||||
if (hport->device_desc.iSerialNumber > 0) {
|
||||
/* Get SerialNumber string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get SerialNumber string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get SerialNumber string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support SerialNumber string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
|
||||
#endif
|
||||
/* Select device configuration 1 */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
@@ -703,7 +733,7 @@ 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)
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output, uint16_t output_len)
|
||||
{
|
||||
struct usb_setup_packet *setup = hport->setup;
|
||||
int ret;
|
||||
@@ -729,6 +759,10 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
|
||||
dst = output;
|
||||
len = src[0];
|
||||
|
||||
if (((len - 2) / 2) > output_len) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
while (i < len) {
|
||||
dst[j] = src[i];
|
||||
i += 2;
|
||||
|
||||
@@ -47,7 +47,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 * 1000) : ((1 << (interval - 1)) * 125))
|
||||
|
||||
#define USBH_EP_INIT(ep, ep_desc) \
|
||||
do { \
|
||||
@@ -255,9 +255,10 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
|
||||
* @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.
|
||||
* @param output_len Length of the output buffer.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output);
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output, uint16_t output_len);
|
||||
|
||||
/**
|
||||
* @brief Sets the alternate setting for a USB interface on a specific hub port.
|
||||
|
||||
@@ -164,7 +164,7 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor msc_bootuf2_descriptor = {
|
||||
const struct usb_descriptor adb_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
@@ -274,9 +274,16 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
|
||||
static struct usbd_interface intf0;
|
||||
|
||||
#ifdef RT_USING_MSH
|
||||
extern void usbd_adb_shell_init(uint8_t in_ep, uint8_t out_ep);
|
||||
#else
|
||||
extern int shell_init(bool need_login);
|
||||
#endif
|
||||
void cherryadb_init(uint8_t busid, uint32_t reg_base)
|
||||
{
|
||||
#ifdef RT_USING_MSH
|
||||
usbd_adb_shell_init(WINUSB_IN_EP, WINUSB_OUT_EP);
|
||||
#else
|
||||
/* default password is : 12345678 */
|
||||
/* shell_init() must be called in-task */
|
||||
if (0 != shell_init(false)) {
|
||||
@@ -286,7 +293,7 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &adb_descriptor);
|
||||
#else
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
#include "usbd_cdc_acm.h"
|
||||
#include "usbd_hid.h"
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM < 7
|
||||
#error endpoint number is too small for this demo, please try other chips
|
||||
#endif
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
|
||||
337
demo/cdc_acm_mavlink_template.c
Normal file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
#include "chry_ringbuffer.h"
|
||||
#include <mavlink.h>
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x83
|
||||
|
||||
#define USBD_VID 0xFFFF
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x26, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'C', 0x00, /* wcChar10 */
|
||||
'D', 0x00, /* wcChar11 */
|
||||
'C', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
chry_ringbuffer_t usb_rx_rb;
|
||||
uint8_t usb_rx_buffer[2048];
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t temp_rx_buffer[512];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_tx_buffer[MAVLINK_MAX_PACKET_LEN];
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
ep_tx_busy_flag = false;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, CDC_OUT_EP, temp_rx_buffer, usbd_get_ep_mps(busid, CDC_OUT_EP));
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
|
||||
|
||||
chry_ringbuffer_write(&usb_rx_rb, temp_rx_buffer, nbytes);
|
||||
usbd_ep_start_read(busid, CDC_OUT_EP, temp_rx_buffer, usbd_get_ep_mps(busid, CDC_OUT_EP));
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
|
||||
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
|
||||
} else {
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*!< endpoint call back */
|
||||
struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = CDC_OUT_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = CDC_IN_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
static struct usbd_interface intf0;
|
||||
static struct usbd_interface intf1;
|
||||
|
||||
void cdc_acm_mavlink_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
chry_ringbuffer_init(&usb_rx_rb, usb_rx_buffer, sizeof(usb_rx_buffer));
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
|
||||
usbd_add_endpoint(busid, &cdc_out_ep);
|
||||
usbd_add_endpoint(busid, &cdc_in_ep);
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
void cdc_acm_mavlink_write(uint8_t *data, uint32_t len)
|
||||
{
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return;
|
||||
}
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(0, CDC_IN_EP, data, len);
|
||||
while (ep_tx_busy_flag) {
|
||||
}
|
||||
}
|
||||
|
||||
void send_heartbeat(void)
|
||||
{
|
||||
mavlink_message_t message;
|
||||
|
||||
const uint8_t system_id = 42;
|
||||
const uint8_t base_mode = 0;
|
||||
const uint8_t custom_mode = 0;
|
||||
mavlink_msg_heartbeat_pack_chan(
|
||||
system_id,
|
||||
MAV_COMP_ID_PERIPHERAL,
|
||||
MAVLINK_COMM_0,
|
||||
&message,
|
||||
MAV_TYPE_GENERIC,
|
||||
MAV_AUTOPILOT_GENERIC,
|
||||
base_mode,
|
||||
custom_mode,
|
||||
MAV_STATE_STANDBY);
|
||||
|
||||
const int len = mavlink_msg_to_send_buffer(usb_tx_buffer, &message);
|
||||
cdc_acm_mavlink_write(usb_tx_buffer, len);
|
||||
}
|
||||
|
||||
void handle_heartbeat(const mavlink_message_t *message)
|
||||
{
|
||||
mavlink_heartbeat_t heartbeat;
|
||||
mavlink_msg_heartbeat_decode(message, &heartbeat);
|
||||
|
||||
USB_LOG_RAW("Got heartbeat from ");
|
||||
switch (heartbeat.autopilot) {
|
||||
case MAV_AUTOPILOT_GENERIC:
|
||||
USB_LOG_RAW("generic");
|
||||
break;
|
||||
case MAV_AUTOPILOT_ARDUPILOTMEGA:
|
||||
USB_LOG_RAW("ArduPilot");
|
||||
break;
|
||||
case MAV_AUTOPILOT_PX4:
|
||||
USB_LOG_RAW("PX4");
|
||||
break;
|
||||
default:
|
||||
USB_LOG_RAW("other");
|
||||
break;
|
||||
}
|
||||
USB_LOG_RAW(" autopilot\n");
|
||||
|
||||
send_heartbeat();
|
||||
}
|
||||
|
||||
void mavlink_polling(void)
|
||||
{
|
||||
uint8_t ch;
|
||||
bool ret;
|
||||
mavlink_message_t message;
|
||||
mavlink_status_t status;
|
||||
|
||||
ret = chry_ringbuffer_read_byte(&usb_rx_rb, &ch);
|
||||
if (ret) {
|
||||
if (mavlink_parse_char(MAVLINK_COMM_0, ch, &message, &status) == 1) {
|
||||
USB_LOG_INFO(
|
||||
"Received message %d from %d/%d\n",
|
||||
message.msgid, message.sysid, message.compid);
|
||||
|
||||
switch (message.msgid) {
|
||||
case MAVLINK_MSG_ID_HEARTBEAT:
|
||||
handle_heartbeat(&message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,6 @@
|
||||
#include "usbd_cdc_acm.h"
|
||||
#include "usbd_msc.h"
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM < 6
|
||||
#error endpoint number is too small for this demo, please try other chips
|
||||
#endif
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM < 8
|
||||
#error endpoint number is too small for this demo, please try other chips
|
||||
#endif
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x01
|
||||
|
||||
208
demo/cdc_acm_rttchardev_template.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x83
|
||||
|
||||
#define USBD_VID 0xFFFF
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x26, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'C', 0x00, /* wcChar10 */
|
||||
'D', 0x00, /* wcChar11 */
|
||||
'C', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep);
|
||||
|
||||
void cdc_acm_chardev_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
#endif
|
||||
usbd_cdc_acm_serial_init(busid, CDC_IN_EP, CDC_OUT_EP);
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
@@ -10,17 +10,17 @@
|
||||
#include "usbh_video.h"
|
||||
#include "usbh_audio.h"
|
||||
|
||||
#ifndef TEST_USBH_CDC_ACM
|
||||
#define TEST_USBH_CDC_ACM 1
|
||||
#ifndef CONFIG_TEST_USBH_CDC_ACM
|
||||
#define CONFIG_TEST_USBH_CDC_ACM 1
|
||||
#endif
|
||||
#ifndef TEST_USBH_CDC_SPEED
|
||||
#define TEST_USBH_CDC_SPEED 0
|
||||
#endif
|
||||
#ifndef TEST_USBH_HID
|
||||
#define TEST_USBH_HID 1
|
||||
#ifndef CONFIG_TEST_USBH_HID
|
||||
#define CONFIG_TEST_USBH_HID 1
|
||||
#endif
|
||||
#ifndef TEST_USBH_MSC
|
||||
#define TEST_USBH_MSC 1
|
||||
#ifndef CONFIG_TEST_USBH_MSC
|
||||
#define CONFIG_TEST_USBH_MSC 1
|
||||
#endif
|
||||
#ifndef TEST_USBH_MSC_FATFS
|
||||
#define TEST_USBH_MSC_FATFS 0
|
||||
@@ -28,18 +28,18 @@
|
||||
#ifndef TEST_USBH_MSC_FATFS_SPEED
|
||||
#define TEST_USBH_MSC_FATFS_SPEED 0
|
||||
#endif
|
||||
#ifndef TEST_USBH_AUDIO
|
||||
#define TEST_USBH_AUDIO 0
|
||||
#ifndef CONFIG_TEST_USBH_AUDIO
|
||||
#define CONFIG_TEST_USBH_AUDIO 0
|
||||
#endif
|
||||
#ifndef TEST_USBH_VIDEO
|
||||
#define TEST_USBH_VIDEO 0
|
||||
#ifndef CONFIG_TEST_USBH_VIDEO
|
||||
#define CONFIG_TEST_USBH_VIDEO 0
|
||||
#endif
|
||||
|
||||
#if defined(TEST_USBH_CDC_ECM) || defined(TEST_USBH_CDC_RNDIS) || defined(TEST_USBH_ASIX) || defined(TEST_USBH_RTL8152)
|
||||
#error we have move those class implements into platform/none/usbh_lwip.c, and you should call tcpip_init(NULL, NULL) in your app
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_CDC_ACM
|
||||
#if CONFIG_TEST_USBH_CDC_ACM
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[4096];
|
||||
|
||||
#if TEST_USBH_CDC_SPEED
|
||||
@@ -115,7 +115,7 @@ delete:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_HID
|
||||
#if CONFIG_TEST_USBH_HID
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128];
|
||||
|
||||
void usbh_hid_callback(void *arg, int nbytes)
|
||||
@@ -157,7 +157,7 @@ delete:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_MSC
|
||||
#if CONFIG_TEST_USBH_MSC
|
||||
|
||||
#if TEST_USBH_MSC_FATFS
|
||||
#include "ff.h"
|
||||
@@ -326,7 +326,7 @@ delete:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_CDC_ACM
|
||||
#if CONFIG_TEST_USBH_CDC_ACM
|
||||
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class);
|
||||
@@ -337,7 +337,7 @@ void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_HID
|
||||
#if CONFIG_TEST_USBH_HID
|
||||
void usbh_hid_run(struct usbh_hid *hid_class)
|
||||
{
|
||||
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
|
||||
@@ -348,7 +348,7 @@ void usbh_hid_stop(struct usbh_hid *hid_class)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_MSC
|
||||
#if CONFIG_TEST_USBH_MSC
|
||||
void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
|
||||
@@ -359,11 +359,11 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_AUDIO
|
||||
#if CONFIG_TEST_USBH_AUDIO
|
||||
#error "commercial charge"
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_VIDEO
|
||||
#if CONFIG_TEST_USBH_VIDEO
|
||||
#error "commercial charge"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -448,6 +448,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
video_iso_tx_busy = false;
|
||||
|
||||
@@ -252,6 +252,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
|
||||
@@ -252,6 +252,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
|
||||
@@ -256,6 +256,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
|
||||
@@ -135,7 +135,7 @@ uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = {
|
||||
struct usb_webusb_descriptor webusb_url_desc = {
|
||||
.vendor_code = USBD_WEBUSB_VENDOR_CODE,
|
||||
.string = USBD_WebUSBURLDescriptor,
|
||||
.string_len = USBD_WINUSB_DESC_SET_LEN
|
||||
.string_len = URL_DESCRIPTOR_LENGTH
|
||||
};
|
||||
|
||||
struct usb_msosv2_descriptor msosv2_desc = {
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM < 6
|
||||
#error endpoint number is too small for this demo, please try other chips
|
||||
#endif
|
||||
|
||||
#define WINUSB_IN_EP 0x81
|
||||
#define WINUSB_OUT_EP 0x02
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_hid.h"
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM < 4
|
||||
#error endpoint number is too small for this demo, please try other chips
|
||||
#endif
|
||||
|
||||
#define WINUSB_IN_EP 0x81
|
||||
#define WINUSB_OUT_EP 0x02
|
||||
|
||||
|
||||
BIN
docs/assets/sifli.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
@@ -7,6 +7,10 @@
|
||||
- 有多少个接口就调用多少次 `usbd_add_interface`,参数填相关 `xxx_init_intf`, 如果没有支持的,手动创建一个 intf 填入
|
||||
- 有多少个端点就调用多少次 `usbd_add_endpoint`,当中断完成时,会调用到注册的端点回调中。
|
||||
|
||||
参考下面这张图:
|
||||
|
||||
.. figure:: img/api_device1.png
|
||||
|
||||
CORE
|
||||
-----------------
|
||||
|
||||
|
||||
@@ -15,12 +15,11 @@ CLASS 驱动信息结构体
|
||||
.. code-block:: C
|
||||
|
||||
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 bInterfaceClass; /* Base device class code */
|
||||
uint8_t bInterfaceSubClass; /* Sub-class, depends on base class. Eg. */
|
||||
uint8_t bInterfaceProtocol; /* 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -186,33 +186,36 @@ usbh_submit_urb
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
struct usbh_urb {
|
||||
void *hcpriv;
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
uint8_t data_toggle;
|
||||
struct usb_setup_packet *setup;
|
||||
uint8_t *transfer_buffer;
|
||||
uint32_t transfer_buffer_length;
|
||||
int transfer_flags;
|
||||
uint32_t actual_length;
|
||||
uint32_t timeout;
|
||||
int errorcode;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint32_t start_frame;
|
||||
usbh_complete_callback_t complete;
|
||||
void *arg;
|
||||
#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__)
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
#else
|
||||
struct usbh_iso_frame_packet iso_packet[0];
|
||||
#endif
|
||||
};
|
||||
struct usbh_urb {
|
||||
usb_slist_t list;
|
||||
void *hcpriv;
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
uint8_t data_toggle;
|
||||
uint8_t interval;
|
||||
struct usb_setup_packet *setup;
|
||||
uint8_t *transfer_buffer;
|
||||
uint32_t transfer_buffer_length;
|
||||
int transfer_flags;
|
||||
uint32_t actual_length;
|
||||
uint32_t timeout;
|
||||
int errorcode;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint32_t start_frame;
|
||||
usbh_complete_callback_t complete;
|
||||
void *arg;
|
||||
#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__)
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
#else
|
||||
struct usbh_iso_frame_packet iso_packet[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
- **hcpriv** 主机控制器驱动私有成员
|
||||
- **hport** 当前 urb 使用的 hport
|
||||
- **ep** 当前 urb 使用的 ep
|
||||
- **data_toggle** 当前 data toggle
|
||||
- **interval** urb 传输间隔,单位 us,如果 interval 大于 1000us,则需要使用软件定时器来维护
|
||||
- **setup** setup 请求缓冲区,端点0使用
|
||||
- **transfer_buffer** 传输的数据缓冲区
|
||||
- **transfer_buffer_length** 传输长度
|
||||
|
||||
@@ -6,8 +6,8 @@ project = 'CherryUSB'
|
||||
copyright = '2022 ~ 2025, sakumisu'
|
||||
author = 'sakumisu'
|
||||
|
||||
release = '1.5.0'
|
||||
version = '1.5.0'
|
||||
release = '1.5.2'
|
||||
version = '1.5.2'
|
||||
|
||||
# -- General configuration
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
BIN
docs/source/demo/img/rtt_adb_shell1.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
docs/source/demo/img/rtt_adb_shell2.png
Normal file
|
After Width: | Height: | Size: 497 KiB |
28
docs/source/demo/usbd_adb.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
usbd_adb
|
||||
===============
|
||||
|
||||
本节主要介绍如何使用 adb device。支持 **cherrysh** 和 rt-thread **msh**,只需要在 main 中添加以下初始化即可。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
cherryadb_init(0, xxxxx);
|
||||
|
||||
如果使用 rt-thread,还需要在 menuconfig 中使能 adb device。
|
||||
|
||||
.. figure:: img/rtt_adb_shell1.png
|
||||
|
||||
进入 adb
|
||||
--------------
|
||||
|
||||
- 使用 **cherrysh** 时枚举完成以后自动进入 adb 模式
|
||||
- 使用 **msh** 需要在 **msh** 中输入 ``adb_enter`` 进入 adb 模式
|
||||
|
||||
退出 adb
|
||||
--------------
|
||||
|
||||
- 使用 **cherrysh** 时输入 ``exit`` 退出 adb 模式
|
||||
- 使用 **msh** 需要在 **msh** 中输入 ``adb_exit`` 退出 adb 模式
|
||||
|
||||
.. figure:: img/cherryadb.png
|
||||
|
||||
.. figure:: img/rtt_adb_shell2.png
|
||||
@@ -48,4 +48,8 @@ usbh_hid
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed), hub_int_timeout, hub, 0);
|
||||
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed) / 1000, hub_int_timeout, hub, 0);
|
||||
|
||||
.. note::
|
||||
|
||||
这里的 `USBH_GET_URB_INTERVAL` 是一个宏定义,用于根据 binterval 计算 URB 的传输间隔时间, 单位是 us,而定时器最低是 ms ,因此需要除以 1000。对于小于等于 1ms 的不需要使用定时器。
|
||||
@@ -18,7 +18,7 @@ usbh_msc
|
||||
|
||||
|
||||
- 不使用 fatfs,则直接使用 usbh_msc_scsi_read10 或者 usbh_msc_scsi_write10 函数进行读写操作。
|
||||
- 如果使用 fatfs,则需要在 usbh_msc_thread 中调用 fatfs 的接口进行读写操作。msc读写适配fatfs 参考 `platform/none/usbh_fatfs.c`
|
||||
- 如果使用 fatfs,则需要在 usbh_msc_thread 中调用 fatfs 的接口进行读写操作。msc读写适配fatfs 参考 `platform/fatfs/usbh_fatfs.c`
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
|
||||
@@ -104,3 +104,5 @@ TCPIP_THREAD_STACKSIZE 推荐大于 1K,防止栈溢出。
|
||||
#if TCPIP_THREAD_STACKSIZE < 1024
|
||||
#error TCPIP_THREAD_STACKSIZE must be >= 1024
|
||||
#endif
|
||||
|
||||
- 具体移植文章可以参考 https://club.rt-thread.org/ask/article/5cf3e9e0b2d95800.html
|
||||
@@ -1,2 +1,4 @@
|
||||
usbh_serial
|
||||
===============
|
||||
|
||||
当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。
|
||||
@@ -107,6 +107,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
|
||||
demo/usbd_video
|
||||
demo/usbd_winusb
|
||||
demo/usbd_webusb
|
||||
demo/usbd_adb
|
||||
demo/usbh_serial
|
||||
demo/usbh_hid
|
||||
demo/usbh_msc
|
||||
|
||||
@@ -56,3 +56,7 @@ Klipper is a 3d-printer firmware.
|
||||
适配链接:待开放
|
||||
|
||||
|
||||
MAKCU/KMBOX
|
||||
--------------
|
||||
|
||||
懂的都懂,不开放
|
||||
@@ -10,12 +10,13 @@ Q & A
|
||||
|
||||
提问中请包含以下信息:
|
||||
|
||||
- 使用的版本
|
||||
- 使用的板子,引脚,USB IP
|
||||
- USB 中断,时钟,引脚,寄存器地址是否正确,截图
|
||||
- 是否配置 USB 中断,USB 时钟,USB 引脚,USB phy 配置,以及 USB 寄存器地址是否正确,截图
|
||||
- 是否能进 USB 中断
|
||||
- 芯片是否带有 cache功能,是否做了 no cache 处理,截图
|
||||
- 硬件是否正常,是否使用杜邦线连接,如果正常,请说明正常原因
|
||||
- 打开 CONFIG_USBDEV_SETUP_LOG_PRINT,并提供 log
|
||||
- USB 电路是否画正确,是否使用杜邦线连接,是否直连,如果正常,请说明正常原因
|
||||
- 如果能进中断,配置 **#define CONFIG_USB_DBG_LEVEL USB_DBG_LOG** 并提供 log,仅限商业 IP, 其余 IP 禁止开启 log,否则无法枚举
|
||||
- 是否流片并销售
|
||||
|
||||
其余问题提问模板
|
||||
@@ -36,12 +37,7 @@ ST 命名为 USB_OTG_FS, USB_OTG_HS,并不是说明本身是高速或者全速
|
||||
GD IP 问题
|
||||
------------------
|
||||
|
||||
GD IP 采用 DWC2,但是读取的硬件参数都是 0(我也不懂为什么不给人知道),因此需要用户自行知道硬件信息,以下列举 GD32F4 的信息:
|
||||
|
||||
CONFIG_USBDEV_EP_NUM pa11/pa12 引脚必须为 4,PB14/PB15 引脚必须为 6,并删除 usb_dc_dwc2.c 中 while(1){}
|
||||
|
||||
- 当 CONFIG_USBDEV_EP_NUM 为4 时,fifo_num 不得大于 320 字
|
||||
- 当 CONFIG_USBDEV_EP_NUM 为6 时,fifo_num 不得大于 1280 字
|
||||
GD IP 采用 DWC2,但是读取的硬件参数都是 0(我也不懂为什么不给人知道),因此需要用户自行知道硬件信息,从 1.5.0 开始由于需要读取硬件信息,因此无法直接使用。
|
||||
|
||||
其次 GD 复位以后无法使用 EPDIS 功能关闭端点,需要用户删除 reset 中断中的以下代码:
|
||||
|
||||
@@ -50,11 +46,6 @@ CONFIG_USBDEV_EP_NUM pa11/pa12 引脚必须为 4,PB14/PB15 引脚必须为 6
|
||||
USB_OTG_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
|
||||
USB_OTG_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
|
||||
|
||||
dwc2 has less endpoints than config, please check
|
||||
---------------------------------------------------------------
|
||||
|
||||
该 IP 硬件上没有这么多端点,请修改 `CONFIG_USBDEV_EP_NUM`
|
||||
|
||||
Ep addr XXX overflow
|
||||
------------------------------
|
||||
|
||||
@@ -75,7 +66,6 @@ CONFIG_USB_HS 何时使用
|
||||
|
||||
当你的芯片硬件支持高速,并想初始化成高速模式时开启,相关 IP 会根据该宏配置内部或者外部 高速 PHY。
|
||||
|
||||
|
||||
Failed to enable port
|
||||
----------------------------------------------------------------
|
||||
|
||||
@@ -84,6 +74,25 @@ Failed to enable port
|
||||
移植 usb host 出现 urb 返回 -12/-14
|
||||
----------------------------------------------------------------
|
||||
|
||||
-12 就检查 phy 配置,通信不良
|
||||
检查 phy 配置,cache 配置(如果有),电源供电(建议自供电)
|
||||
|
||||
-14 就检查 phy 配置,cache 配置(如果有),fifo配置,寄存器地址, IP 是否真的标准等等
|
||||
USB_ERR_NAK 说明
|
||||
----------------------------------------------------------------
|
||||
USB_ERR_NAK 只存在于 DWC2 buffer dma 模式,DWC2 在 buffer dma模式下对于中断传输不支持硬件处理 NAK 中断,因此需要软件处理,导致 NAK 中断非常多,建议搭配定时器使用。
|
||||
DWC2 scatter/gather dma 模式下全部由硬件处理,但是不支持 split 传输。总结, **半斤 IP**。
|
||||
|
||||
USB host 连接 USB 网卡问题
|
||||
----------------------------------------------------------------
|
||||
|
||||
表现为能识别网卡并且分配到 IP 地址,但是无法 ping 通,这是因为网卡自身需要开启自动拨号,通常需要使用 AT 口设置。具体为 EC20/ML307 等模块。
|
||||
|
||||
PC 识别的 COM 口如何更改名称
|
||||
----------------------------------------------------------------
|
||||
|
||||
这是微软对 CDC ACM 的驱动问题,无法修改,如需修改,请联系微软并缴纳费用即可更改。
|
||||
|
||||
connect 和 disconnect event 不触发
|
||||
----------------------------------------------------------------
|
||||
|
||||
当前仅 hpm 芯片支持 connect 和 disconnect 事件,其他芯片请使用 USB 检测 vbus 电路。DWC2 IP 支持,但是由于需要占用引脚,并且大多是log 口,
|
||||
然后不同使能的配置也不一样,因此不做支持。
|
||||
@@ -4,60 +4,71 @@
|
||||
在学习 USB 或者是学习 CherryUSB 代码之前,我们需要先基于现有的 demo 进行快速验证,为什么?是为了提升对 USB 的兴趣,能有信心进行下一步的动作,如果 demo 都跑不起来,或者自己摸索写代码,或者先看 USB 基本概念,结果看到最后,
|
||||
发现一点都看不懂,概念好多,根本记不住,从而丧失对 USB 的兴趣。因此,先跑 demo 非常重要。下面我将给大家罗列目前支持的 demo 仓库。
|
||||
|
||||
基于 bouffalolab 系列芯片
|
||||
---------------------------
|
||||
基于 bouffalolab 系列芯片(官方 SDK 支持)
|
||||
------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_bouffalolab
|
||||
|
||||
- BL616/BL808 是一个 USB2.0 并且内置高速 PHY 芯片,共 5个端点(包含端点0)。支持主从机。
|
||||
- BL616/BL808:USB2.0 内置 HS phy 芯片,支持主从机。device 支持 5 个端点(包括端点0),不支持双向同时使用。
|
||||
- USB 的相关应用位于 `examples/usbdev` 和 `examples/usbhost` 目录下,根据官方环境搭建完成后,即可编译使用。
|
||||
|
||||
基于 HPMicro 系列芯片
|
||||
---------------------------
|
||||
基于 HPMicro 系列芯片(官方 SDK 支持)
|
||||
-----------------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_hpmicro
|
||||
|
||||
- HPM 系列芯片均 USB 2.0 并且内置高速 PHY,支持主从机,端点共 8/16 个,并且可以同时使用双向,不同芯片个数有差异
|
||||
- HPM 系列: USB2.0 内置 HS phy 芯片,支持主从机。device 支持 8/16 端点(包括端点0),并且可以同时使用双向,不同芯片个数有差异。
|
||||
- USB 的相关应用位于 `samples/cherryusb` ,根据官方环境搭建完成后,即可编译使用。
|
||||
|
||||
基于 esp32s2/s3/p4 系列芯片
|
||||
---------------------------
|
||||
基于 esp32s2/s3/p4 系列芯片(官方 SDK 即将支持)
|
||||
-------------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_esp32
|
||||
|
||||
- esp32s2/s3 支持全速主从机,esp32p4 支持高速主从机
|
||||
- 默认提供主机 demo,并且使用 esp 组件库进行开发, 在 https://components.espressif.com/ 中搜索 cherryusb 即可
|
||||
- esp32s2/s3:USB2.0 内置全速 PHY 芯片,支持主从机,device 支持 7 个端点(包括端点0),并且可以同时使用双向。
|
||||
- esp32p4:一个 USB2.0 内置全速 PHY 芯片,一个 USB2.0 内置高速 PHY 芯片,支持主从机。
|
||||
- 默认 demo 采用组件库安装的形式,在 https://components.espressif.com/ 中搜索 cherryusb 即可
|
||||
|
||||
基于飞腾派系列芯片
|
||||
---------------------------
|
||||
基于飞腾派系列芯片(官方 SDK 支持)
|
||||
-----------------------------------
|
||||
|
||||
仓库参考:https://gitee.com/phytium_embedded/phytium-free-rtos-sdk
|
||||
|
||||
- 飞腾派支持两个 USB3.0 主机(采用 XHCI), 两个 USB2.0 主从机
|
||||
- USB 的相关应用位于 `example/peripheral/usb` ,根据官方环境搭建完成后,即可编译使用。
|
||||
|
||||
基于 Essemi 系列芯片
|
||||
---------------------------
|
||||
基于 Essemi 系列芯片(官方 SDK 支持)
|
||||
-----------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_es32
|
||||
|
||||
- 支持全速和高速主从机
|
||||
- 支持全速和高速主从机。device 支持 6 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
基于 Artinchip 系列芯片(官方 SDK 支持)
|
||||
-----------------------------------------------
|
||||
|
||||
仓库参考:https://gitee.com/artinchip/luban-lite
|
||||
|
||||
- 支持全速和高速主从机,主机采用 EHCI + OHCI。device 支持 8 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
基于 canmv-k230 芯片(官方 SDK 支持)
|
||||
---------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/k230_sdk
|
||||
|
||||
- K230: 两个 USB2.0 内置 HS PHY 芯片,支持主从机。device 支持 16 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
基于 NXP MCX系列芯片
|
||||
---------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_mcx 或者 https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx
|
||||
|
||||
- 支持全速 IP 和高速 IP, 高速 IP 支持主机和从机
|
||||
- 支持全速 IP 和高速 IP, 高速 IP 支持主机和从机。device 支持 8 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
- 支持全速和高速主从机
|
||||
基于 RP2040/RP2035 芯片(官方 SDK 即将支持)
|
||||
--------------------------------------------
|
||||
|
||||
基于 Artinchip 系列芯片
|
||||
---------------------------
|
||||
|
||||
仓库参考:https://gitee.com/artinchip/luban-lite
|
||||
|
||||
- 支持全速和高速主从机,主机采用 EHCI + OHCI。
|
||||
仓库参考: https://github.com/CherryUSB/pico-examples 和 https://github.com/CherryUSB/pico-sdk
|
||||
|
||||
基于 ST 系列芯片
|
||||
---------------------------
|
||||
@@ -67,8 +78,8 @@
|
||||
默认提供以下 demo 工程:
|
||||
|
||||
- F103 使用 fsdev ip
|
||||
- F429 主从使用 USB1, 引脚 pb14/pb15, 并且都使用 dma 模式
|
||||
- H7 设备使用 USB0, 引脚 pa11/pa12,没有开DMA 模式。主机使用 USB1 ,引脚 pb14/pb15,并且需要做 nocache 处理
|
||||
- F429 主从使用 USB1, 引脚 pb14/pb15, 默认从机没有开启 DMA 模式
|
||||
- H7 设备使用 USB0, 引脚 pa11/pa12,没有开 DMA 模式。主机使用 USB1 ,引脚 pb14/pb15,并且需要做 nocache 处理
|
||||
|
||||
demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate Code** 即可。
|
||||
|
||||
@@ -78,7 +89,7 @@ demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate
|
||||
|
||||
- usb ip 区别:F1使用 fsdev,F4/H7使用 dwc2
|
||||
- dwc2 ip 区别: USB0 (引脚是 PA11/PA12) 和 USB1 (引脚是 PB14/PB15), 其中 USB1 默认全速,可以接外部PHY 形成高速主机,并且带 dma 功能
|
||||
- F4 无cache,H7 有 cache
|
||||
- F4 无 cache,H7 有 cache
|
||||
|
||||
如果是 STM32F7/STM32H7 这种带 cache 功能,需要将 usb 使用到的 ram 定位到 no cache ram 区域。举例如下
|
||||
|
||||
@@ -116,12 +127,12 @@ USB Device 移植要点
|
||||
- 如果使用 fsdev ip,勾选 **USB** 。如果使用 dwc2 ip,勾选 **USB_OTG_FS** 或者勾选 **USB_OTG_HS**。开启 USB 中断,其他配置对我们没用,代码中不会使用任何 st 的 usb 库。
|
||||
|
||||
.. figure:: img/stm32_3_1.png
|
||||
.. figure:: img/stm32_3.png
|
||||
.. figure:: img/stm32_3_2.png
|
||||
|
||||
- 配置 usb clock 为 48M
|
||||
|
||||
.. figure:: img/stm32_4_1.png
|
||||
.. figure:: img/stm32_4.png
|
||||
.. figure:: img/stm32_4_2.png
|
||||
|
||||
- 选择好工程,这里我们选择 keil,设置好 stack 和 heap,如果使用 msc 可以推荐设置大点,然后点击 **Generate Code**。
|
||||
|
||||
@@ -154,11 +165,10 @@ USB Device 移植要点
|
||||
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
|
||||
|
||||
- 如果使用 fsdev ip,(V1.5.0 开始需要增加 **fsdev/usb_glue_st.c**) 在 `usb_config.h` 中实现以下宏:
|
||||
- 如果使用 fsdev ip,(V1.5.0 开始需要增加 **fsdev/usb_glue_st.c**) 在 `usb_config.h` 中实现以下宏,具体数值不同芯片不一样:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
#define CONFIG_USBDEV_EP_NUM 8
|
||||
#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2
|
||||
|
||||
- 编译器推荐使用 **AC6**。勾选 **Microlib**,并实现 **printf** ,方便后续查看 log。
|
||||
@@ -177,6 +187,8 @@ USB Device 移植要点
|
||||
|
||||
.. figure:: img/stm32_13.png
|
||||
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
|
||||
- 调用 template 的内容初始化,并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
|
||||
|
||||
.. figure:: img/stm32_15.png
|
||||
@@ -186,7 +198,7 @@ USB Host 移植要点
|
||||
|
||||
前面 6 步与 Device 一样。需要注意,host 驱动只支持带 dma 的 hs port (引脚是 PB14/PB15),所以 fs port (引脚是 PA11/PA12)不做支持(没有 dma 你玩什么主机)。
|
||||
|
||||
- 添加 CherryUSB 必须要的源码( **usbh_core.c** 、 **usbh_hub.c** 、 **usb_hc_dwc2.c** 、以及 **osal** 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 **usb host.c** 添加方便测试。
|
||||
- 添加 CherryUSB 必须要的源码( **usbh_core.c** 、 **usbh_hub.c** 、 **usb_hc_dwc2.c** 、 **usb_glue_st.c** 以及 **osal** 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 **usb host.c** 添加方便测试。
|
||||
|
||||
.. figure:: img/stm32_16.png
|
||||
|
||||
@@ -197,28 +209,16 @@ USB Host 移植要点
|
||||
|
||||
- 复制一份 **cherryusb_config_template.h**,放到 `Core/Inc` 目录下,并命名为 `usb_config.h`
|
||||
|
||||
- 增加 **usb_glue_st.c** 文件,并在 `usb_config.h` 中实现以下宏:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// 以下细节如有出入,请对照 stm32xxx.h 文件修改
|
||||
// 需要根据硬件实际的 fifo 深度进行修改,默认是最基础的配置
|
||||
#define CONFIG_USBHOST_PIPE_NUM 12
|
||||
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
|
||||
#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4)
|
||||
|
||||
.. note :: 以下两个步骤从 V1.5.0 开始不再需要,**fsdev/usb_glue_st.c**, **dwc2/usb_glue_st.c** 文件中已经实现
|
||||
|
||||
- 拷贝 **xxx_msp.c** 中的 `HAL_HCD_MspInit` 函数中的内容到 `usb_hc_low_level_init` 函数中,屏蔽 st 生成的 usb 初始化
|
||||
- 在中断函数中调用 `USBH_IRQHandler`,并传入 `busid`
|
||||
|
||||
.. figure:: img/stm32_19.png
|
||||
|
||||
- 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
|
||||
- 启动线程
|
||||
|
||||
.. figure:: img/stm32_18.png
|
||||
.. figure:: img/stm32_19.png
|
||||
|
||||
- 如果使用 **msc**,并且带文件系统,需要自行添加文件系统文件了,对应的 porting 编写参考 **fatfs_usbh.c** 文件。
|
||||
|
||||
.. figure:: img/stm32_21.png
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 16 KiB |
@@ -28,35 +28,19 @@
|
||||
#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)
|
||||
|
||||
* USB IP 相关的 config 需要用户自己根据芯片实际情况修改
|
||||
* 退出以后不急着编译,需要在代码中实现 `usb_dc_low_level_init` 函数。
|
||||
* 在代码中实现 `usb_dc_low_level_init` 函数
|
||||
* 在 USB 中断函数中调用 `USBD_IRQHandler`,并传入 `busid`
|
||||
* 调用 `usbd_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
|
||||
* 以上内容我们推荐放在 **board.c** 中,如下代码:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void OTG_HS_IRQHandler(void)
|
||||
{
|
||||
extern void USBD_IRQHandler(uint8_t busid);
|
||||
USBD_IRQHandler(0);
|
||||
}
|
||||
|
||||
int usbd_init(void)
|
||||
{
|
||||
xxx_template_init(0, USB_OTG_HS_PERIPH_BASE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_APP_EXPORT(usbd_init);
|
||||
|
||||
* 使用 `scons --target=mdk5` 或者 `scons` 进行编译,如果是mdk,需要使用 AC6 编译器
|
||||
* 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
|
||||
主机配置
|
||||
--------------------------
|
||||
|
||||
* 选择 Enable usb host mode 并敲回车进入。
|
||||
* 选择 USB host ip,不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme。
|
||||
* 选择 Enable usb host mode 并敲回车进入
|
||||
* 选择 USB host ip,不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme
|
||||
* 根据需要勾选 class 驱动
|
||||
* 选择是否开启模板 demo,请注意, msc 禁止使能,因为默认对接到 dfs。
|
||||
* 选择是否开启模板 demo,推荐不用
|
||||
|
||||
.. figure:: img/env2.png
|
||||
|
||||
@@ -71,77 +55,8 @@
|
||||
|
||||
* USB IP 相关的 config 需要用户自己根据芯片实际情况修改
|
||||
* 在代码中实现 `usb_hc_low_level_init` 函数
|
||||
* 在 USB 中断函数中调用 `USBH_IRQHandler`,并传入 `busid`
|
||||
* 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
|
||||
* 以上内容我们推荐放在 **board.c** 中,如下代码:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void OTG_HS_IRQHandler(void)
|
||||
{
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
USBH_IRQHandler(0);
|
||||
}
|
||||
|
||||
int usbh_init(void)
|
||||
{
|
||||
usbh_initialize(0, USB_OTG_HS_PERIPH_BASE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_APP_EXPORT(usbh_init);
|
||||
|
||||
* 使用 `scons --target=mdk5` 或者 `scons` 进行编译,如果是mdk,需要使用 AC6 编译器
|
||||
* 如果使用的是 GCC ,需要在链接脚本(需要放在 flash 位置)中添加如下代码:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
|
||||
举例如下:
|
||||
|
||||
.. 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
|
||||
|
||||
借助 STM32CubeMX 生成 USB 初始化
|
||||
----------------------------------
|
||||
|
||||
使用 STM32CubeMX 主要是用来生成 usb 时钟、引脚、中断的配置。我们需要点击如图所示文件,并配置好 USB 的时钟、中断,点击 `Generate Code`。
|
||||
|
||||
.. figure:: img/stm32cubemx0.png
|
||||
.. figure:: img/stm32cubemx1.png
|
||||
.. figure:: img/stm32cubemx2.png
|
||||
.. figure:: img/stm32cubemx_clk.png
|
||||
|
||||
- 将 `main.c` 中的 `SystemClock_Config` 替换掉 `board.c` 中的配置
|
||||
|
||||
.. figure:: img/stm32_init2.png
|
||||
|
||||
.. note :: 下面步骤从 V1.5.0 开始不再需要,**fsdev/usb_glue_st.c**, **dwc2/usb_glue_st.c** 文件中已经实现
|
||||
|
||||
- 将 `stm32xxxx_hal_msp.c` 中的 `HAL_PCD_MspInit` 或者是 `HAL_HCD_MspInit` 中的内容复制到 `usb_dc_low_level_init` 和 `usb_hc_low_level_init` 函数中,举例如下:
|
||||
|
||||
.. figure:: img/stm32_init.png
|
||||
* 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
* 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
|
||||
@@ -6,23 +6,35 @@
|
||||
USB Device 移植要点
|
||||
-----------------------
|
||||
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,其中 `usbd_core.c` 和 `usb_dc_xxx.c` 为必须添加项。而 `usb_dc_xxx.c` 是芯片所对应的 USB IP dcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,头文件路径建议全部添加。其中 `usbd_core.c` 和 `usb_dc_xxx.c` 为必须添加项。而 `usb_dc_xxx.c` 是芯片所对应的 USB IP dcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径
|
||||
- 实现 `usb_dc_low_level_init` 函数(该函数主要负责 USB 时钟、引脚、中断的初始化)。该函数可以放在你想要放的任何参与编译的 c 文件中。如何进行 USB 的时钟、引脚、中断等初始化,请自行根据你使用的芯片原厂提供的源码中进行添加。
|
||||
- 描述符的注册、class的注册、接口的注册、端点中断的注册。不会的参考 demo 下的 template
|
||||
- 调用 `usbd_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
|
||||
- 在中断函数中调用 `USBD_IRQHandler`,并传入 `busid`, 如果你的 SDK 中中断入口已经存在 `USBD_IRQHandler` ,请更改 USB 协议栈中的名称
|
||||
- 编译使用。各个 class 如何使用,参考 demo 下的 template
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 注册描述符并调用 `usbd_initialize`,填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`,可以直接使用 demo 下的 template
|
||||
|
||||
USB Host 移植要点
|
||||
-----------------------
|
||||
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,其中 `usbh_core.c` 、 `usb_hc_xxx.c` 以及 **osal** 目录下源文件(根据不同的 os 选择对应的源文件)为必须添加项。而 `usb_hc_xxx.c` 是芯片所对应的 USB IP hcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,头文件路径建议全部添加。其中 `usbh_core.c` 、 `usb_hc_xxx.c` 以及 **osal** 目录下源文件(根据不同的 os 选择对应的源文件)为必须添加项。而 `usb_hc_xxx.c` 是芯片所对应的 USB IP hcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径
|
||||
- 实现 `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 ,需要在链接脚本中添加如下代码(需要放在 flash 位置):
|
||||
- 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 调用 `usbh_initialize` ,填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS` 。基础的 cdc + hid + msc 参考 `usb_host.c` 文件,其余参考 **platform** 目录下适配
|
||||
|
||||
.. _usbh_link_script:
|
||||
|
||||
主机链接脚本修改
|
||||
-----------------------
|
||||
|
||||
在使用主机时,如果没有修改链接脚本,会报 `__usbh_class_info_start__` 和 `__usbh_class_info_end__` 未定义的错误。因为主机协议栈需要在链接脚本中添加一个 section 来存储 class 信息。
|
||||
|
||||
- 如果使用的是 KEIL 无需修改
|
||||
|
||||
- 如果使用的是 GCC ,需要在链接脚本中添加如下代码(需要放在 flash 位置,建议放最后):
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
@@ -68,15 +80,17 @@ GCC 举例如下:
|
||||
place in AXI_SRAM { block cherryusb_usbh_class_info };
|
||||
keep { section .usbh_class_info};
|
||||
|
||||
- 编译使用。各个 class 如何使用,参考 demo 下的 `usb_host.c` 文件
|
||||
|
||||
带 cache 功能的芯片使用注意
|
||||
.. _usb_cache:
|
||||
|
||||
cache 配置修改
|
||||
-------------------------------
|
||||
|
||||
协议栈以及 port 中不会对 cache 区域的 ram 进行 clean 或者 invalid,所以需要使用一块非 cache 区域的 ram 来维护。 `USB_NOCACHE_RAM_SECTION` 宏表示将变量指定到非 cache ram上,
|
||||
因此,用户需要在对应的链接脚本中添加 no cache ram 的 section。默认 `USB_NOCACHE_RAM_SECTION` 定义为 `__attribute__((section(".noncacheable")))`。
|
||||
对于带 cache 的芯片,协议栈以及 port 中不会对 cache 区域的 ram 进行 clean 或者 invalid,所以需要使用一块非 cache 区域的 ram 来维护。
|
||||
`USB_NOCACHE_RAM_SECTION` 宏表示将变量指定到非 cache ram上,默认 `USB_NOCACHE_RAM_SECTION` 定义为 `__attribute__((section(".noncacheable")))`。
|
||||
因此,用户需要在对应的链接脚本中添加 no cache ram 的 section,并且 section 段包含 `.noncacheable`。
|
||||
|
||||
.. note:: 需要注意,光指定 section 是不够的,还需要配置该 section 中的 ram 是真的 nocache,一般需要配置 mpu 属性(arm 的参考 stm32h7 demo)。
|
||||
.. note:: 需要注意,光修改链接脚本中的 nocache section 是不够的,还需要配置该 section 中的 ram 是真的 nocache,一般需要配置 mpu 属性(arm 的参考 stm32h7 demo)。
|
||||
|
||||
GCC:
|
||||
|
||||
|
||||
BIN
docs/source/show/img/usbhost_ax88772_1.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
docs/source/show/img/usbhost_ax88772_2.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
@@ -80,6 +80,14 @@ USB Host UVC
|
||||
|
||||
.. figure:: img/usbhost_uvc.gif
|
||||
|
||||
USB Host ASIX 网卡
|
||||
-----------------------
|
||||
|
||||
演示 USB Host 驱动 AX88772 USB 以太网模块。
|
||||
|
||||
.. figure:: img/usbhost_ax88772_1.png
|
||||
.. figure:: img/usbhost_ax88772_2.png
|
||||
|
||||
USB Host WIFI
|
||||
-----------------------
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 314 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 327 KiB |
BIN
docs/source/support/img/dwc2_hostuvc3.png
Normal file
|
After Width: | Height: | Size: 319 KiB |
BIN
docs/source/support/img/tmcdev1.png
Normal file
|
After Width: | Height: | Size: 565 KiB |
BIN
docs/source/support/img/tmcdev2.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
docs/source/support/img/usbhost_uvc.gif
Normal file
|
After Width: | Height: | Size: 8.2 MiB |
@@ -7,27 +7,37 @@
|
||||
|
||||
.. figure:: img/ohci.png
|
||||
|
||||
- 主机 UVC & UAC 类 EHCI IP 中 ISO 驱动和 UAC/UVC 框架
|
||||
- EHCI IP 中 ISO 驱动和 UAC/UVC 框架,搭配主机 UVC & UAC 类(这部分是开源的)使用。iso 支持一个微帧 1/2/3 包,支持 MJPEG 和 YUV 摄像头
|
||||
|
||||
.. figure:: img/ehci_hostuvc1.png
|
||||
.. figure:: img/ehci_hostuvc2.png
|
||||
|
||||
- 主机 UVC & UAC 类 DWC2 IP 中 ISO 驱动和 UAC/UVC 框架
|
||||
演示 USB Host UVC 驱动 648 * 480 YUV 摄像头。FPS 30。
|
||||
|
||||
.. figure:: img/usbhost_uvc.gif
|
||||
|
||||
- DWC2 IP 中 ISO 驱动和 UAC/UVC 框架,搭配主机 UVC & UAC 类(这部分是开源的)使用。iso 支持一个微帧 1/2/3 包,支持 MJPEG 和 YUV 摄像头
|
||||
|
||||
.. figure:: img/dwc2_hostuvc1.png
|
||||
.. figure:: img/dwc2_hostuvc2.png
|
||||
.. figure:: img/dwc2_hostuvc3.png
|
||||
.. figure:: img/dwc2_hostuac.png
|
||||
|
||||
- 主机 UVC & UAC 类 MUSB IP 中 ISO 驱动和 UAC/UVC 框架, MUSB 需要为 mentor 公司制定的标准 IP
|
||||
- MUSB IP 中 ISO 驱动和 UAC/UVC 框架,搭配主机 UVC & UAC 类(这部分是开源的)使用。MUSB 需要为 mentor 公司制定的标准 IP
|
||||
|
||||
- 从机 MTP 类驱动, 支持多文件和多文件夹
|
||||
- 从机 MTP 类驱动, 支持多文件和多文件夹,支持 MCU 端增删文件并与 PC 同步
|
||||
|
||||
.. figure:: img/mtpdev.png
|
||||
|
||||
- 从机 TMC 类驱动
|
||||
|
||||
.. figure:: img/tmcdev1.png
|
||||
.. figure:: img/tmcdev2.png
|
||||
|
||||
- USB 网卡类高性能版本优化,包含 CDC-NCM, CDC-RNDIS, 私有类驱动(支持多包发送和接收),下面举例 RNDIS
|
||||
|
||||
.. figure:: img/rndistx.png
|
||||
.. figure:: img/rndisrx.png
|
||||
|
||||
- 定制化 class 驱动或者 IP 驱动
|
||||
- 定制化 class 驱动或者 IP 驱动适配
|
||||
- 技术支持相关
|
||||
BIN
docs/source/usb/img/usbstruct.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
@@ -138,6 +138,10 @@ USB 对这个问题的解决办法,就是强制插 0,也就是(位填充
|
||||
在数据被NRZI编码之前,在数据流中每六个连续的1之后插入一个0,以强制NRZI数据流中的过渡,这使接收器逻辑至少每七位有一次数据转换,以保证数据和时钟的锁定。比特填充是从同步模式开始启用。结束同步模式的数据 "一 "被算作是序列中的第一个 "一"。序列中的第一个。除了高速EOP期间,发射器的位填充总是被强制执行。如果需要按照
|
||||
位填充规则的要求,零位将被插入,即使它是数据包结束(EOP)信号前的最后一位。接收器必须对NRZI数据进行解码,识别填充位,并将其丢弃。
|
||||
|
||||
.. caution:: 以下内容可以用一张图概括,了解即可,没有必要死记硬背
|
||||
|
||||
.. figure:: img/usbstruct.png
|
||||
|
||||
USB 字段(域)
|
||||
---------------------
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 503 KiB After Width: | Height: | Size: 684 KiB |
@@ -106,7 +106,7 @@ v1.5.0
|
||||
|
||||
- **协议栈内部全局 buffer 需要使用 USB_ALIGN_UP 对齐, 用于开启 dcache 并且不使能 nocache 时使用**
|
||||
- **完善 ehci/ohci dcache 模式下的处理**, add CONFIG_USB_EHCI_DESC_DCACHE_ENABLE for qh&qtd&itd, add CONFIG_USB_OHCI_DESC_DCACHE_ENABLE for ed&td
|
||||
- **平台代码更新,平台相关转移到 platform,增加 lvgl 键鼠支持,blackmagic 支持,filex 支持**
|
||||
- **平台代码更新,平台相关转移到 platform,增加 lvgl 键鼠支持,blackmagic 支持,filex 支持, zephyr disk支持,esp-idf netif支持**
|
||||
- **device sof callback 支持**
|
||||
- **dwc2 、fsdev st 下实现底层 API 和中断,直接调用 HAL_PCD_MSP 和 HAL_HCD_MSP,不需要用户复制粘贴**
|
||||
- **DWC2 实现 SPLIT 功能,高速模式下支持外部高速 hub 对接 FS/LS 设备**
|
||||
@@ -116,11 +116,36 @@ v1.5.0
|
||||
- rndis/ECM device, msc demo 更新,支持 rt-thread 下免修改
|
||||
- **memcpy 全部使用 usb_memcpy 替换,arm 库存在非对其访问问题**
|
||||
- **重构 device mtp 驱动(收费使用)**
|
||||
- **device tmc 驱动(收费使用)**
|
||||
- **重构device video 传输,直接在图像数据中填充 uvc header,达到zero memcpy**
|
||||
- **增加 usb_osal_thread_schedule_other api,用于在释放 class 资源之前,先释放所有 class 线程,避免释放 class 资源以后线程还在使用该 class 资源**
|
||||
- **dwc2 device 增加 dcache 功能,可用于 STM32H7/H7R/ESP32P4**
|
||||
- **dwc2 device 增加 dcache 功能,可用于 cortex-M7/ESP32P4**
|
||||
- **bouffalo/hpm/esp/st/nxp dcache api 支持**
|
||||
- ch32 device iso 更新
|
||||
- ch32 device iso 更新,IP 目录重新分类
|
||||
- cmake,scons,kconfig 更新
|
||||
- 使用 USB_ASSERT_MSG 对部分代码检查
|
||||
- N32H4,mm32f5 支持
|
||||
- 使用 USB_ASSERT_MSG 对部分代码检查,全面性 warning 修复
|
||||
- N32H4/MM32F5 device 支持
|
||||
- 默认使能 CONFIG_USBDEV_ADVANCE_DESC
|
||||
|
||||
v1.5.1
|
||||
----------------------
|
||||
|
||||
- 支持 rt-thread 下使用 adb shell,host serial/device cdc_acm 对接 rtdevice 框架
|
||||
- **dwc2 增加多个 usbport 不同参数的配置功能,比如一个全速一个高速,fifo配置和phy配置不同**
|
||||
- **ehci 在控制传输中如果没有 nodata 阶段会导致 data qtd 未释放,导致内存泄漏**
|
||||
- **dwc2 读取 setup 使用 usbd_get_next_ep0_state 去判断,避免 setup 和 ep0 out 使用在 USB_OTG_DOEPINT_XFRC 状态下冲突**
|
||||
- sifli usb device 初步支持
|
||||
|
||||
v1.5.2
|
||||
----------------------
|
||||
|
||||
- 对 1.5.1 下 rt-thread 组件的一些 bugfix
|
||||
- idf timer osal 替换为 esp timer,freertos timer会有启动失败的可能性;xTaskCreate 使用 xTaskCreatePinnedToCore 替换,方便多核使用
|
||||
- 主机枚举中,删除描述符溢出相关的 ASSERT 操作,改成返回错误。获取字符串描述符改成支持才获取。2 ms 延时改成 10ms,因为一些 os 使用的是 100hz,会造成延时失效
|
||||
- **dwc2 ep mult 支持,split 传输代码优化,对 split 相关的 cache 处理修改**
|
||||
- **dwc2 halt 中不能清除 USB_OTG_HCCHAR_EPDIR,reset port 中使用超时机制,防止在枚举时由于拔出而造成死等**
|
||||
- 更新 DWC2 中 at32,stm32,kendryte,espressif glue 代码
|
||||
- musb 对于标准的 IP 结构采用独立 EP 控制寄存器组,不使用 EPIDX 寄存器去控制
|
||||
- 删除所有 CONFIG_USBDEV_EP_NUM & CONFIG_USBHOST_PIPE_NUM,不再使用,因为 IP 本身会携带这些信息,或者厂家 SDK 提供了对应的宏
|
||||
- CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 默认使用 2 减少内存,只有 UVC 和UAC 使用(商业收费),所以不需要开很大
|
||||
- urb interval 从 u8 改 u32,最大支持 2^15 * 125us
|
||||
@@ -1,4 +1,4 @@
|
||||
version: "1.5.0"
|
||||
version: "1.5.2"
|
||||
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
|
||||
tags:
|
||||
- usb
|
||||
@@ -18,7 +18,7 @@ repository: https://github.com/cherry-embedded/CherryUSB.git
|
||||
documentation: https://cherryusb.readthedocs.io/
|
||||
issues: https://github.com/cherry-embedded/CherryUSB/issues
|
||||
dependencies:
|
||||
idf: ">=5.0"
|
||||
idf: ">=4.4.1"
|
||||
targets:
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
@@ -168,7 +168,7 @@
|
||||
#define CONFIG_USBHOST_PSC_PRIO 0
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 4096
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
@@ -246,92 +246,19 @@
|
||||
#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define ESP_USBD_BASE 0x60080000
|
||||
|
||||
#define ESP_USB_FS0_BASE 0x60080000
|
||||
#define ESP_USBD_BASE ESP_USB_FS0_BASE
|
||||
#define ESP_USBH_BASE ESP_USB_FS0_BASE
|
||||
#define CONFIG_USBDEV_MAX_BUS 1
|
||||
// esp32s2/s3 has 7 endpoints in device mode (include ep0)
|
||||
#define CONFIG_USBDEV_EP_NUM 7
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
//esp32s2/s3 can support up to 5 IN endpoints(include ep0) at the same time
|
||||
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (320 / 4)
|
||||
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (64 / 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 (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
|
||||
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
|
||||
|
||||
#define CONFIG_USB_DWC2_DMA_ENABLE
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ESP_USBD_BASE 0x50000000UL
|
||||
|
||||
#define CONFIG_USBDEV_MAX_BUS 1
|
||||
#define CONFIG_USBDEV_EP_NUM 7 // 16
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
//esp32s2/s3 can support up to 5 IN endpoints(include ep0) at the same time
|
||||
#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 (512 / 4)
|
||||
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
|
||||
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
|
||||
|
||||
#define CONFIG_USB_DWC2_DMA_ENABLE
|
||||
#define CONFIG_USB_HS
|
||||
#else
|
||||
#error "Unsupported SoC"
|
||||
#endif
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define ESP_USBH_BASE 0x60080000
|
||||
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
// esp32s2/s3 has 8 endpoints in host mode (include ep0)
|
||||
#define CONFIG_USBHOST_PIPE_NUM 8
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
/* largest non-periodic USB packet used / 4 */
|
||||
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (240 / 4)
|
||||
/* largest periodic USB packet used / 4 */
|
||||
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (240 / 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 ((200 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ESP_USBH_BASE 0x50000000UL
|
||||
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
#define CONFIG_USBHOST_PIPE_NUM 16
|
||||
|
||||
/* ---------------- 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 (512 / 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 ((896 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
|
||||
|
||||
#define ESP_USB_HS0_BASE 0x50000000
|
||||
#define ESP_USB_FS0_BASE 0x50040000
|
||||
#define ESP_USBD_BASE ESP_USB_HS0_BASE
|
||||
#define ESP_USBH_BASE ESP_USB_HS0_BASE
|
||||
#define CONFIG_USBDEV_MAX_BUS 2
|
||||
#define CONFIG_USBHOST_MAX_BUS 2
|
||||
#define CONFIG_USB_HS
|
||||
#else
|
||||
#error "Unsupported SoC"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
@@ -16,7 +17,7 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size,
|
||||
{
|
||||
TaskHandle_t htask = NULL;
|
||||
stack_size /= sizeof(StackType_t);
|
||||
xTaskCreate(entry, name, stack_size, args, configMAX_PRIORITIES - 1 - prio, &htask);
|
||||
xTaskCreatePinnedToCore(entry, name, stack_size, args, configMAX_PRIORITIES - 1 - prio, &htask, CONFIG_ESP_TIMER_TASK_AFFINITY);
|
||||
return (usb_osal_thread_t)htask;
|
||||
}
|
||||
|
||||
@@ -145,9 +146,9 @@ int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
|
||||
}
|
||||
}
|
||||
|
||||
static void __usb_timeout(TimerHandle_t *handle)
|
||||
static void usb_timeout(void *arg)
|
||||
{
|
||||
struct usb_osal_timer *timer = (struct usb_osal_timer *)pvTimerGetTimerID((TimerHandle_t)handle);
|
||||
struct usb_osal_timer *timer = (struct usb_osal_timer *)arg;
|
||||
|
||||
timer->handler(timer->argument);
|
||||
}
|
||||
@@ -155,50 +156,56 @@ static void __usb_timeout(TimerHandle_t *handle)
|
||||
struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ms, usb_timer_handler_t handler, void *argument, bool is_period)
|
||||
{
|
||||
struct usb_osal_timer *timer;
|
||||
(void)name;
|
||||
|
||||
timer = pvPortMalloc(sizeof(struct usb_osal_timer));
|
||||
|
||||
if (timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(timer, 0, sizeof(struct usb_osal_timer));
|
||||
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = usb_timeout,
|
||||
// argument specified here will be passed to timer callback function
|
||||
.arg = (void *)timer,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = name,
|
||||
.skip_unhandled_events = true
|
||||
};
|
||||
|
||||
timer->handler = handler;
|
||||
timer->argument = argument;
|
||||
timer->is_period = is_period;
|
||||
timer->timeout_ms = timeout_ms;
|
||||
|
||||
timer->timer = (void *)xTimerCreate("usb_tim", pdMS_TO_TICKS(timeout_ms), is_period, timer, (TimerCallbackFunction_t)__usb_timeout);
|
||||
if (timer->timer == NULL) {
|
||||
if (esp_timer_create(&timer_args, (esp_timer_handle_t *)&timer->timer) != ESP_OK) {
|
||||
vPortFree(timer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
void usb_osal_timer_delete(struct usb_osal_timer *timer)
|
||||
{
|
||||
xTimerStop(timer->timer, 0);
|
||||
xTimerDelete(timer->timer, 0);
|
||||
esp_timer_stop((esp_timer_handle_t)timer->timer);
|
||||
esp_timer_delete((esp_timer_handle_t)timer->timer);
|
||||
vPortFree(timer);
|
||||
}
|
||||
|
||||
void usb_osal_timer_start(struct usb_osal_timer *timer)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
int ret;
|
||||
esp_timer_stop((esp_timer_handle_t)timer->timer);
|
||||
|
||||
if (xPortInIsrContext()) {
|
||||
ret = xTimerStartFromISR(timer->timer, &xHigherPriorityTaskWoken);
|
||||
if (ret == pdPASS) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
if (timer->is_period) {
|
||||
esp_timer_start_periodic((esp_timer_handle_t)timer->timer, ((uint64_t)timer->timeout_ms) * 1000);
|
||||
} else {
|
||||
xTimerStart(timer->timer, 0);
|
||||
esp_timer_start_once((esp_timer_handle_t)timer->timer, ((uint64_t)timer->timeout_ms) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_osal_timer_stop(struct usb_osal_timer *timer)
|
||||
{
|
||||
xTimerStop(timer->timer, 0);
|
||||
esp_timer_stop((esp_timer_handle_t)timer->timer);
|
||||
}
|
||||
|
||||
size_t usb_osal_enter_critical_section(void)
|
||||
|
||||
@@ -18,7 +18,8 @@ lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl61
|
||||
- DFS support with usb host msc.
|
||||
- lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl616_wifi).
|
||||
- msh support with lsusb
|
||||
|
||||
- device char support with host cdc_acm/ftdi/ch34x/cp210x/pl2303
|
||||
- shell support with adb
|
||||
|
||||
## Nuttx
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ FATFS s_sd_disk;
|
||||
FIL s_file;
|
||||
BYTE work[FF_MAX_SS];
|
||||
|
||||
const TCHAR driver_num_buf[4] = { '0', ':', '/', '\0' };
|
||||
const TCHAR driver_num_buf[3] = { '0', ':', '\0' };
|
||||
|
||||
const char *show_error_string(FRESULT fresult);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ int USB_disk_read(BYTE *buff, LBA_t sector, UINT count)
|
||||
align_buf = (uint8_t *)buff;
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = (uint8_t *)memalign(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
|
||||
align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
|
||||
if (!align_buf) {
|
||||
printf("msc get align buf failed\r\n");
|
||||
return -USB_ERR_NOMEM;
|
||||
@@ -66,7 +66,7 @@ int USB_disk_write(const BYTE *buff, LBA_t sector, UINT count)
|
||||
align_buf = (uint8_t *)buff;
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = (uint8_t *)memalign(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
|
||||
align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
|
||||
if (!align_buf) {
|
||||
printf("msc get align buf failed\r\n");
|
||||
return -USB_ERR_NOMEM;
|
||||
|
||||
408
platform/idf/usbh_net.c
Normal file
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Loogg
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include "lwip/netif.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_netif.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
#if TCPIP_THREAD_STACKSIZE < 1024
|
||||
#error TCPIP_THREAD_STACKSIZE must be >= 1024
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBHOST_PLATFORM_CDC_ECM
|
||||
// #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS
|
||||
// #define CONFIG_USBHOST_PLATFORM_CDC_NCM
|
||||
// #define CONFIG_USBHOST_PLATFORM_ASIX
|
||||
// #define CONFIG_USBHOST_PLATFORM_RTL8152
|
||||
// #define CONFIG_USBHOST_PLATFORM_BL616
|
||||
|
||||
struct usbh_net_netif_glue {
|
||||
esp_netif_driver_base_t base;
|
||||
esp_event_handler_instance_t ins_got_ip;
|
||||
void *usbh_class;
|
||||
esp_err_t (*transmit)(void *h, void *buffer, size_t len);
|
||||
};
|
||||
|
||||
static void usbh_net_input_common(struct usbh_net_netif_glue *netif_glue, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
uint8_t *input_buf = buf;
|
||||
|
||||
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
|
||||
input_buf = usb_osal_malloc(len);
|
||||
if (input_buf == NULL) {
|
||||
USB_LOG_ERR("No memory to alloc input buffer\r\n");
|
||||
return;
|
||||
}
|
||||
usb_memcpy(input_buf, buf, len);
|
||||
#endif
|
||||
|
||||
esp_netif_receive(netif_glue->base.netif, input_buf, len, NULL);
|
||||
}
|
||||
|
||||
static void usbh_net_free(void *h, void *buffer)
|
||||
{
|
||||
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
|
||||
usb_osal_free(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static esp_err_t usbh_net_post_attach(esp_netif_t *esp_netif, void *args)
|
||||
{
|
||||
struct usbh_net_netif_glue *netif_glue = (struct usbh_net_netif_glue *)args;
|
||||
|
||||
netif_glue->base.netif = esp_netif;
|
||||
|
||||
// set driver related config to esp-netif
|
||||
esp_netif_driver_ifconfig_t driver_ifconfig = {
|
||||
.handle = netif_glue,
|
||||
.transmit = netif_glue->transmit,
|
||||
.driver_free_rx_buffer = usbh_net_free,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void usbh_net_action_got_ip(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
struct usbh_net_netif_glue *netif_glue = (struct usbh_net_netif_glue *)handler_args;
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||
const esp_netif_ip_info_t *ip_info = &event->ip_info;
|
||||
USB_LOG_INFO("NETIF %s Got IP Address\r\n", esp_netif_get_ifkey(netif_glue->base.netif));
|
||||
USB_LOG_INFO("IP:" IPSTR "\r\n", IP2STR(&ip_info->ip));
|
||||
USB_LOG_INFO("MASK:" IPSTR "\r\n", IP2STR(&ip_info->netmask));
|
||||
USB_LOG_INFO("GW:" IPSTR "\r\n\r\n", IP2STR(&ip_info->gw));
|
||||
}
|
||||
|
||||
static esp_err_t usbh_net_netif_glue_init_common(struct usbh_net_netif_glue *netif_glue, void *usbh_class, esp_err_t (*transmit)(void *h, void *buffer, size_t len))
|
||||
{
|
||||
netif_glue->usbh_class = usbh_class;
|
||||
netif_glue->transmit = transmit;
|
||||
netif_glue->base.post_attach = usbh_net_post_attach;
|
||||
|
||||
return esp_event_handler_instance_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, usbh_net_action_got_ip, netif_glue, &netif_glue->ins_got_ip);
|
||||
}
|
||||
|
||||
static esp_err_t usbh_net_netif_glue_deinit_common(struct usbh_net_netif_glue *netif_glue)
|
||||
{
|
||||
return esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, netif_glue->ins_got_ip);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM
|
||||
#include "usbh_cdc_ecm.h"
|
||||
|
||||
struct usbh_net_netif_glue g_cdc_ecm_netif_glue;
|
||||
|
||||
static esp_err_t usbh_cdc_ecm_transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
int ret;
|
||||
(void)h;
|
||||
|
||||
usb_memcpy(usbh_cdc_ecm_get_eth_txbuf(), buffer, len);
|
||||
ret = usbh_cdc_ecm_eth_output(len);
|
||||
if (ret < 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen)
|
||||
{
|
||||
usbh_net_input_common(&g_cdc_ecm_netif_glue, buf, buflen);
|
||||
}
|
||||
|
||||
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
|
||||
{
|
||||
memset(&g_cdc_ecm_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
|
||||
|
||||
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||
base_cfg.if_key = "u0";
|
||||
base_cfg.if_desc = "usbh cdc ecm";
|
||||
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
netif_cfg.base = &base_cfg;
|
||||
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
usbh_net_netif_glue_init_common(&g_cdc_ecm_netif_glue, cdc_ecm_class, usbh_cdc_ecm_transmit);
|
||||
esp_netif_attach(esp_netif, &g_cdc_ecm_netif_glue.base);
|
||||
|
||||
esp_netif_set_mac(esp_netif, cdc_ecm_class->mac);
|
||||
|
||||
esp_netif_action_start(esp_netif, NULL, 0, NULL);
|
||||
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
|
||||
|
||||
usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL);
|
||||
}
|
||||
|
||||
void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
|
||||
{
|
||||
(void)cdc_ecm_class;
|
||||
|
||||
usbh_net_netif_glue_deinit_common(&g_cdc_ecm_netif_glue);
|
||||
esp_netif_action_stop(g_cdc_ecm_netif_glue.base.netif, NULL, 0, NULL);
|
||||
esp_netif_destroy(g_cdc_ecm_netif_glue.base.netif);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS
|
||||
#include "usbh_rndis.h"
|
||||
|
||||
struct usb_osal_timer *timer_handle;
|
||||
|
||||
static void rndis_dev_keepalive_timeout(void *arg)
|
||||
{
|
||||
struct usbh_rndis *rndis_class = (struct usbh_rndis *)arg;
|
||||
usbh_rndis_keepalive(rndis_class);
|
||||
}
|
||||
|
||||
void timer_init(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
timer_handle = usb_osal_timer_create("rndis_keepalive", 5000, rndis_dev_keepalive_timeout, rndis_class, true);
|
||||
if (NULL != timer_handle) {
|
||||
usb_osal_timer_start(timer_handle);
|
||||
} else {
|
||||
USB_LOG_ERR("timer creation failed! \r\n");
|
||||
for (;;) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct usbh_net_netif_glue g_rndis_netif_glue;
|
||||
|
||||
static esp_err_t usbh_rndis_transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
int ret;
|
||||
(void)h;
|
||||
|
||||
usb_memcpy(usbh_rndis_get_eth_txbuf(), buffer, len);
|
||||
ret = usbh_rndis_eth_output(len);
|
||||
if (ret < 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen)
|
||||
{
|
||||
usbh_net_input_common(&g_rndis_netif_glue, buf, buflen);
|
||||
}
|
||||
|
||||
void usbh_rndis_run(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
memset(&g_rndis_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
|
||||
|
||||
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||
base_cfg.if_key = "u2";
|
||||
base_cfg.if_desc = "usbh rndis";
|
||||
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
netif_cfg.base = &base_cfg;
|
||||
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
usbh_net_netif_glue_init_common(&g_rndis_netif_glue, rndis_class, usbh_rndis_transmit);
|
||||
esp_netif_attach(esp_netif, &g_rndis_netif_glue.base);
|
||||
|
||||
esp_netif_set_mac(esp_netif, rndis_class->mac);
|
||||
|
||||
esp_netif_action_start(esp_netif, NULL, 0, NULL);
|
||||
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
|
||||
|
||||
usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL);
|
||||
|
||||
//timer_init(rndis_class);
|
||||
}
|
||||
|
||||
void usbh_rndis_stop(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
(void)rndis_class;
|
||||
|
||||
usbh_net_netif_glue_deinit_common(&g_rndis_netif_glue);
|
||||
esp_netif_action_stop(g_rndis_netif_glue.base.netif, NULL, 0, NULL);
|
||||
esp_netif_destroy(g_rndis_netif_glue.base.netif);
|
||||
|
||||
// xTimerStop(timer_handle, 0);
|
||||
// xTimerDelete(timer_handle, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM
|
||||
#include "usbh_cdc_ncm.h"
|
||||
|
||||
struct usbh_net_netif_glue g_cdc_ncm_netif_glue;
|
||||
|
||||
static esp_err_t usbh_cdc_ncm_transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
int ret;
|
||||
(void)h;
|
||||
|
||||
usb_memcpy(usbh_cdc_ncm_get_eth_txbuf(), buffer, len);
|
||||
ret = usbh_cdc_ncm_eth_output(len);
|
||||
if (ret < 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen)
|
||||
{
|
||||
usbh_net_input_common(&g_cdc_ncm_netif_glue, buf, buflen);
|
||||
}
|
||||
|
||||
void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
|
||||
{
|
||||
memset(&g_cdc_ncm_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
|
||||
|
||||
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||
base_cfg.if_key = "u1";
|
||||
base_cfg.if_desc = "usbh cdc ncm";
|
||||
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
netif_cfg.base = &base_cfg;
|
||||
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
usbh_net_netif_glue_init_common(&g_cdc_ncm_netif_glue, cdc_ncm_class, usbh_cdc_ncm_transmit);
|
||||
esp_netif_attach(esp_netif, &g_cdc_ncm_netif_glue.base);
|
||||
|
||||
esp_netif_set_mac(esp_netif, cdc_ncm_class->mac);
|
||||
|
||||
esp_netif_action_start(esp_netif, NULL, 0, NULL);
|
||||
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
|
||||
|
||||
usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL);
|
||||
}
|
||||
|
||||
void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
|
||||
{
|
||||
(void)cdc_ncm_class;
|
||||
|
||||
usbh_net_netif_glue_deinit_common(&g_cdc_ncm_netif_glue);
|
||||
esp_netif_action_stop(g_cdc_ncm_netif_glue.base.netif, NULL, 0, NULL);
|
||||
esp_netif_destroy(g_cdc_ncm_netif_glue.base.netif);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_PLATFORM_ASIX
|
||||
#include "usbh_asix.h"
|
||||
|
||||
struct usbh_net_netif_glue g_asix_netif_glue;
|
||||
|
||||
static esp_err_t usbh_asix_transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
int ret;
|
||||
(void)h;
|
||||
|
||||
usb_memcpy(usbh_asix_get_eth_txbuf(), buffer, len);
|
||||
ret = usbh_asix_eth_output(len);
|
||||
if (ret < 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen)
|
||||
{
|
||||
usbh_net_input_common(&g_asix_netif_glue, buf, buflen);
|
||||
}
|
||||
|
||||
void usbh_asix_run(struct usbh_asix *asix_class)
|
||||
{
|
||||
memset(&g_asix_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
|
||||
|
||||
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||
base_cfg.if_key = "u3";
|
||||
base_cfg.if_desc = "usbh asix";
|
||||
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
netif_cfg.base = &base_cfg;
|
||||
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
usbh_net_netif_glue_init_common(&g_asix_netif_glue, asix_class, usbh_asix_transmit);
|
||||
esp_netif_attach(esp_netif, &g_asix_netif_glue.base);
|
||||
|
||||
esp_netif_set_mac(esp_netif, asix_class->mac);
|
||||
|
||||
esp_netif_action_start(esp_netif, NULL, 0, NULL);
|
||||
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
|
||||
|
||||
usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL);
|
||||
}
|
||||
|
||||
void usbh_asix_stop(struct usbh_asix *asix_class)
|
||||
{
|
||||
(void)asix_class;
|
||||
|
||||
usbh_net_netif_glue_deinit_common(&g_asix_netif_glue);
|
||||
esp_netif_action_stop(g_asix_netif_glue.base.netif, NULL, 0, NULL);
|
||||
esp_netif_destroy(g_asix_netif_glue.base.netif);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_PLATFORM_RTL8152
|
||||
#include "usbh_rtl8152.h"
|
||||
|
||||
struct usbh_net_netif_glue g_rtl8152_netif_glue;
|
||||
|
||||
static esp_err_t usbh_rtl8152_transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
int ret;
|
||||
(void)h;
|
||||
|
||||
usb_memcpy(usbh_rtl8152_get_eth_txbuf(), buffer, len);
|
||||
ret = usbh_rtl8152_eth_output(len);
|
||||
if (ret < 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen)
|
||||
{
|
||||
usbh_net_input_common(&g_rtl8152_netif_glue, buf, buflen);
|
||||
}
|
||||
|
||||
void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
|
||||
{
|
||||
memset(&g_rtl8152_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
|
||||
|
||||
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||
base_cfg.if_key = "u4";
|
||||
base_cfg.if_desc = "usbh rtl8152";
|
||||
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
netif_cfg.base = &base_cfg;
|
||||
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
usbh_net_netif_glue_init_common(&g_rtl8152_netif_glue, rtl8152_class, usbh_rtl8152_transmit);
|
||||
esp_netif_attach(esp_netif, &g_rtl8152_netif_glue.base);
|
||||
|
||||
esp_netif_set_mac(esp_netif, rtl8152_class->mac);
|
||||
|
||||
esp_netif_action_start(esp_netif, NULL, 0, NULL);
|
||||
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
|
||||
|
||||
usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL);
|
||||
}
|
||||
|
||||
void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
|
||||
{
|
||||
(void)rtl8152_class;
|
||||
|
||||
usbh_net_netif_glue_deinit_common(&g_rtl8152_netif_glue);
|
||||
esp_netif_action_stop(g_rtl8152_netif_glue.base.netif, NULL, 0, NULL);
|
||||
esp_netif_destroy(g_rtl8152_netif_glue.base.netif);
|
||||
}
|
||||
#endif
|
||||
@@ -1,4 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2022 ~ 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "rtthread.h"
|
||||
#include "usb_config.h"
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST) || defined(RT_CHERRYUSB_HOST)
|
||||
|
||||
@@ -6,8 +12,21 @@
|
||||
#error must enable RT_USING_TIMER_SOFT to support timer callback in thread
|
||||
#endif
|
||||
|
||||
#if RT_TIMER_THREAD_STACK_SIZE < 2048
|
||||
#error "RT_TIMER_THREAD_STACK_SIZE must be >= 2048"
|
||||
#if RT_TIMER_THREAD_STACK_SIZE < 1024
|
||||
#error "RT_TIMER_THREAD_STACK_SIZE must be >= 1024"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_ARM_CORTEX_M7) || \
|
||||
defined(SOC_HPM6000) || defined(SOC_HPM6E00) || defined(SOC_HPM6P00) || \
|
||||
defined(BSP_USING_BL61X) || defined(BSP_USING_BL808)
|
||||
#ifndef RT_USING_CACHE
|
||||
#error RT_USING_CACHE must be enabled in this chip
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifndef CONFIG_USB_DCACHE_ENABLE
|
||||
#warning CONFIG_USB_DCACHE_ENABLE must be enabled if you do not config nocache ram
|
||||
#endif
|
||||
#endif
|
||||
|
||||
156
platform/rtthread/usbd_adb_shell.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_adb.h"
|
||||
|
||||
#ifndef CONFIG_USBDEV_SHELL_RX_BUFSIZE
|
||||
#define CONFIG_USBDEV_SHELL_RX_BUFSIZE (2048)
|
||||
#endif
|
||||
|
||||
struct usbd_adb_shell {
|
||||
struct rt_device parent;
|
||||
usb_osal_sem_t tx_done;
|
||||
struct rt_ringbuffer rx_rb;
|
||||
rt_uint8_t rx_rb_buffer[CONFIG_USBDEV_SHELL_RX_BUFSIZE];
|
||||
} g_usbd_adb_shell;
|
||||
|
||||
void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len)
|
||||
{
|
||||
rt_ringbuffer_put(&g_usbd_adb_shell.rx_rb, data, len);
|
||||
|
||||
if (g_usbd_adb_shell.parent.rx_indicate) {
|
||||
g_usbd_adb_shell.parent.rx_indicate(&g_usbd_adb_shell.parent, len);
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_adb_notify_write_done(void)
|
||||
{
|
||||
if (g_usbd_adb_shell.tx_done) {
|
||||
usb_osal_sem_give(g_usbd_adb_shell.tx_done);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t usbd_adb_shell_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
{
|
||||
while (!usb_device_is_configured(0)) {
|
||||
rt_thread_mdelay(10);
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t usbd_adb_shell_close(struct rt_device *dev)
|
||||
{
|
||||
if (g_usbd_adb_shell.tx_done) {
|
||||
usb_osal_sem_give(g_usbd_adb_shell.tx_done);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_adb_shell_read(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
return rt_ringbuffer_get(&g_usbd_adb_shell.rx_rb, (rt_uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_adb_shell_write(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if (usbd_adb_can_write() && size) {
|
||||
usb_osal_sem_reset(g_usbd_adb_shell.tx_done);
|
||||
usbd_abd_write(ADB_SHELL_LOALID, buffer, size);
|
||||
usb_osal_sem_take(g_usbd_adb_shell.tx_done, 0xffffffff);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops usbd_adb_shell_ops = {
|
||||
NULL,
|
||||
usbd_adb_shell_open,
|
||||
usbd_adb_shell_close,
|
||||
usbd_adb_shell_read,
|
||||
usbd_adb_shell_write,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
void usbd_adb_shell_init(uint8_t in_ep, uint8_t out_ep)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *device;
|
||||
|
||||
device = &(g_usbd_adb_shell.parent);
|
||||
|
||||
device->type = RT_Device_Class_Char;
|
||||
device->rx_indicate = RT_NULL;
|
||||
device->tx_complete = RT_NULL;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &usbd_adb_shell_ops;
|
||||
#else
|
||||
device->init = NULL;
|
||||
device->open = usbd_adb_shell_open;
|
||||
device->close = usbd_adb_shell_close;
|
||||
device->read = usbd_adb_shell_read;
|
||||
device->write = usbd_adb_shell_write;
|
||||
device->control = NULL;
|
||||
#endif
|
||||
device->user_data = NULL;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, "adb-sh", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
device->fops = NULL;
|
||||
#endif
|
||||
|
||||
g_usbd_adb_shell.tx_done = usb_osal_sem_create(0);
|
||||
rt_ringbuffer_init(&g_usbd_adb_shell.rx_rb, g_usbd_adb_shell.rx_rb_buffer, sizeof(g_usbd_adb_shell.rx_rb_buffer));
|
||||
}
|
||||
|
||||
static int adb_enter(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
finsh_set_device("adb-sh");
|
||||
rt_console_set_device("adb-sh");
|
||||
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(adb_enter, adb_enter);
|
||||
|
||||
static int adb_exit(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
usbd_adb_close(ADB_SHELL_LOALID);
|
||||
|
||||
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(adb_exit, adb_exit);
|
||||
279
platform/rtthread/usbd_serial.c
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
#define DEV_FORMAT_CDC_ACM "usb-acm%d"
|
||||
|
||||
#ifndef CONFIG_USBDEV_MAX_CDC_ACM_CLASS
|
||||
#define CONFIG_USBDEV_MAX_CDC_ACM_CLASS (4)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_SERIAL_RX_BUFSIZE
|
||||
#define CONFIG_USBDEV_SERIAL_RX_BUFSIZE (2048)
|
||||
#endif
|
||||
|
||||
struct usbd_serial {
|
||||
struct rt_device parent;
|
||||
uint8_t busid;
|
||||
uint8_t in_ep;
|
||||
uint8_t out_ep;
|
||||
struct usbd_interface intf_ctrl;
|
||||
struct usbd_interface intf_data;
|
||||
usb_osal_sem_t tx_done;
|
||||
uint8_t minor;
|
||||
char name[32];
|
||||
struct rt_ringbuffer rx_rb;
|
||||
rt_uint8_t rx_rb_buffer[CONFIG_USBDEV_SERIAL_RX_BUFSIZE];
|
||||
};
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbd_serial_cdc_acm_rx_buf[CONFIG_USBDEV_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(512, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbd_serial g_usbd_serial_cdc_acm[CONFIG_USBDEV_MAX_CDC_ACM_CLASS];
|
||||
|
||||
static struct usbd_serial *usbd_serial_alloc(void)
|
||||
{
|
||||
uint8_t devno;
|
||||
struct usbd_serial *serial;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) {
|
||||
if ((g_devinuse & (1U << devno)) == 0) {
|
||||
g_devinuse |= (1U << devno);
|
||||
|
||||
serial = &g_usbd_serial_cdc_acm[devno];
|
||||
memset(serial, 0, sizeof(struct usbd_serial));
|
||||
serial->minor = devno;
|
||||
snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->minor);
|
||||
return serial;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbd_serial_free(struct usbd_serial *serial)
|
||||
{
|
||||
uint8_t devno = serial->minor;
|
||||
|
||||
if (devno < 32) {
|
||||
g_devinuse &= ~(1U << devno);
|
||||
}
|
||||
memset(serial, 0, sizeof(struct usbd_serial));
|
||||
}
|
||||
|
||||
static rt_err_t usbd_serial_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbd_serial *)dev;
|
||||
|
||||
if (!usb_device_is_configured(serial->busid)) {
|
||||
USB_LOG_ERR("USB device is not configured\n");
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
usbd_ep_start_read(serial->busid, serial->out_ep,
|
||||
g_usbd_serial_cdc_acm_rx_buf[serial->minor],
|
||||
usbd_get_ep_mps(serial->busid, serial->out_ep));
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_serial_read(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbd_serial *)dev;
|
||||
|
||||
if (!usb_device_is_configured(serial->busid)) {
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
return rt_ringbuffer_get(&serial->rx_rb, (rt_uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_serial_write(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
int ret = 0;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbd_serial *)dev;
|
||||
|
||||
if (!usb_device_is_configured(serial->busid)) {
|
||||
return -RT_EPERM;
|
||||
}
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
USB_LOG_ERR("serial get align buf failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
usb_memcpy(align_buf, buffer, size);
|
||||
}
|
||||
#endif
|
||||
usb_osal_sem_reset(serial->tx_done);
|
||||
usbd_ep_start_write(serial->busid, serial->in_ep, align_buf, size);
|
||||
ret = usb_osal_sem_take(serial->tx_done, 3000);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("serial write timeout\n");
|
||||
ret = -RT_ETIMEOUT;
|
||||
} else {
|
||||
ret = size;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
rt_free_align(align_buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops usbd_serial_ops = {
|
||||
NULL,
|
||||
usbd_serial_open,
|
||||
NULL,
|
||||
usbd_serial_read,
|
||||
usbd_serial_write,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
rt_err_t usbd_serial_register(struct usbd_serial *serial,
|
||||
void *data)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *device;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
device = &(serial->parent);
|
||||
|
||||
device->type = RT_Device_Class_Char;
|
||||
device->rx_indicate = RT_NULL;
|
||||
device->tx_complete = RT_NULL;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &usbd_serial_ops;
|
||||
#else
|
||||
device->init = NULL;
|
||||
device->open = usbd_serial_open;
|
||||
device->close = NULL;
|
||||
device->read = usbd_serial_read;
|
||||
device->write = usbd_serial_write;
|
||||
device->control = NULL;
|
||||
#endif
|
||||
device->user_data = data;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
device->fops = NULL;
|
||||
#endif
|
||||
rt_ringbuffer_init(&serial->rx_rb, serial->rx_rb_buffer, sizeof(serial->rx_rb_buffer));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
for (uint8_t devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) {
|
||||
serial = &g_usbd_serial_cdc_acm[devno];
|
||||
if (serial->out_ep == ep) {
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbd_serial_cdc_acm_rx_buf[serial->minor], nbytes);
|
||||
usbd_ep_start_read(serial->busid, serial->out_ep,
|
||||
g_usbd_serial_cdc_acm_rx_buf[serial->minor],
|
||||
usbd_get_ep_mps(serial->busid, serial->out_ep));
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(busid, ep, NULL, 0);
|
||||
} else {
|
||||
for (uint8_t devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) {
|
||||
serial = &g_usbd_serial_cdc_acm[devno];
|
||||
if ((serial->in_ep == ep) && serial->tx_done) {
|
||||
usb_osal_sem_give(serial->tx_done);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = out_ep,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = in_ep,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
serial = usbd_serial_alloc();
|
||||
if (serial == NULL) {
|
||||
USB_LOG_ERR("No more serial device available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
serial->busid = busid;
|
||||
serial->in_ep = in_ep;
|
||||
serial->out_ep = out_ep;
|
||||
serial->tx_done = usb_osal_sem_create(0);
|
||||
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &serial->intf_ctrl));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &serial->intf_data));
|
||||
usbd_add_endpoint(busid, &cdc_out_ep);
|
||||
usbd_add_endpoint(busid, &cdc_in_ep);
|
||||
|
||||
if (usbd_serial_register(serial, NULL) != RT_EOK) {
|
||||
USB_LOG_ERR("Failed to register serial device\n");
|
||||
usbd_serial_free(serial);
|
||||
return;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("USB CDC ACM Serial Device %s initialized\n", serial->name);
|
||||
}
|
||||
@@ -19,22 +19,6 @@
|
||||
#define CONFIG_USB_DFS_MOUNT_POINT "/"
|
||||
#endif
|
||||
|
||||
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7RS) ||\
|
||||
defined(SOC_HPM5000) || defined(SOC_HPM6000) || defined(SOC_HPM6E00) || defined(BSP_USING_BL61X)
|
||||
#ifndef RT_USING_CACHE
|
||||
#error usbh msc must enable RT_USING_CACHE in this chip
|
||||
#endif
|
||||
#if RT_ALIGN_SIZE != 32 && RT_ALIGN_SIZE != 64
|
||||
#error usbh msc must set cache line to 32 or 64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifndef CONFIG_USB_DCACHE_ENABLE
|
||||
#error CONFIG_USB_DCACHE_ENABLE must be enabled to use msc disk
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static rt_err_t rt_udisk_init(rt_device_t dev)
|
||||
{
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||
@@ -46,15 +30,15 @@ static rt_err_t rt_udisk_init(rt_device_t dev)
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
rt_size_t size)
|
||||
static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||
int ret;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
@@ -69,7 +53,7 @@ static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
rt_kprintf("usb mass_storage read failed\n");
|
||||
return 0;
|
||||
}
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
usb_memcpy(buffer, align_buf, size * msc_class->blocksize);
|
||||
rt_free_align(align_buf);
|
||||
@@ -78,15 +62,15 @@ static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||
rt_size_t size)
|
||||
static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||
int ret;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
@@ -102,7 +86,7 @@ static ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||
rt_kprintf("usb mass_storage write failed\n");
|
||||
return 0;
|
||||
}
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
rt_free_align(align_buf);
|
||||
}
|
||||
|
||||
914
platform/rtthread/usbh_serial.c
Normal file
@@ -0,0 +1,914 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_cdc_acm.h"
|
||||
#include "usbh_ftdi.h"
|
||||
#include "usbh_cp210x.h"
|
||||
#include "usbh_ch34x.h"
|
||||
#include "usbh_pl2303.h"
|
||||
|
||||
#define DEV_FORMAT_VENDOR "ttyUSB%d"
|
||||
#define DEV_FORMAT_CDC_ACM "ttyACM%d"
|
||||
|
||||
#define USBH_RX_MAX_SIZE 2048
|
||||
|
||||
#ifndef CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS
|
||||
#define CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS (4)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_SERIAL_RX_BUFSIZE
|
||||
#define CONFIG_USBHOST_SERIAL_RX_BUFSIZE (USBH_RX_MAX_SIZE * 2)
|
||||
#endif
|
||||
|
||||
enum usbh_serial_type {
|
||||
USBH_SERIAL_TYPE_CDC_ACM = 0,
|
||||
USBH_SERIAL_TYPE_FTDI,
|
||||
USBH_SERIAL_TYPE_CP210X,
|
||||
USBH_SERIAL_TYPE_CH34X,
|
||||
USBH_SERIAL_TYPE_PL2303,
|
||||
};
|
||||
|
||||
struct usbh_serial {
|
||||
struct rt_device parent;
|
||||
enum usbh_serial_type type;
|
||||
uint8_t minor;
|
||||
char name[CONFIG_USBHOST_DEV_NAMELEN];
|
||||
struct rt_ringbuffer rx_rb;
|
||||
rt_uint8_t rx_rb_buffer[CONFIG_USBHOST_SERIAL_RX_BUFSIZE];
|
||||
};
|
||||
|
||||
static uint32_t g_devinuse_vendor = 0;
|
||||
static uint32_t g_devinuse_cdc_acm = 0;
|
||||
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_vendor_rx_buf[CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)];
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_cdc_acm_rx_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbh_serial *usbh_serial_alloc(uint8_t type)
|
||||
{
|
||||
uint8_t devno;
|
||||
struct usbh_serial *serial;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS; devno++) {
|
||||
if ((g_devinuse_vendor & (1U << devno)) == 0) {
|
||||
g_devinuse_vendor |= (1U << devno);
|
||||
|
||||
serial = rt_malloc(sizeof(struct usbh_serial));
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
serial->type = type;
|
||||
serial->minor = devno;
|
||||
snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_VENDOR, serial->minor);
|
||||
return serial;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_serial_free(struct usbh_serial *serial)
|
||||
{
|
||||
uint8_t devno = serial->minor;
|
||||
|
||||
if (devno < 32) {
|
||||
g_devinuse_vendor &= ~(1U << devno);
|
||||
}
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
rt_free(serial);
|
||||
}
|
||||
|
||||
static struct usbh_serial *usbh_serial_cdc_acm_alloc(uint8_t type)
|
||||
{
|
||||
uint8_t devno;
|
||||
struct usbh_serial *serial;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) {
|
||||
if ((g_devinuse_cdc_acm & (1U << devno)) == 0) {
|
||||
g_devinuse_cdc_acm |= (1U << devno);
|
||||
|
||||
serial = rt_malloc(sizeof(struct usbh_serial));
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
serial->type = type;
|
||||
serial->minor = devno;
|
||||
snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->minor);
|
||||
return serial;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_serial_cdc_acm_free(struct usbh_serial *serial)
|
||||
{
|
||||
uint8_t devno = serial->minor;
|
||||
|
||||
if (devno < 32) {
|
||||
g_devinuse_cdc_acm &= ~(1U << devno);
|
||||
}
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
rt_free(serial);
|
||||
}
|
||||
|
||||
static rt_err_t usbh_serial_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
switch (serial->type) {
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CP210X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t usbh_serial_close(struct rt_device *dev)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
switch (serial->type) {
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CP210X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_ssize_t usbh_serial_read(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
return rt_ringbuffer_get(&serial->rx_rb, (rt_uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
static rt_ssize_t usbh_serial_write(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret = 0;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
USB_LOG_ERR("serial get align buf failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
usb_memcpy(align_buf, buffer, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (serial->type) {
|
||||
#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
ret = usbh_cdc_acm_bulk_out_transfer((struct usbh_cdc_acm *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_cdc_acm_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
ret = usbh_ftdi_bulk_out_transfer((struct usbh_ftdi *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_ftdi_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
ret = usbh_ch34x_bulk_out_transfer((struct usbh_ch34x *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_ch34x_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
ret = usbh_pl2303_bulk_out_transfer((struct usbh_pl2303 *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_pl2303_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
rt_free_align(align_buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_err_t usbh_serial_control(struct rt_device *dev,
|
||||
int cmd,
|
||||
void *args)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
struct serial_configure *config;
|
||||
struct cdc_line_coding line_coding;
|
||||
int ret = -RT_EINVAL;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
switch (serial->type) {
|
||||
#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_cdc_acm *cdc_acm_class;
|
||||
cdc_acm_class = (struct usbh_cdc_acm *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_cdc_acm_set_line_coding(cdc_acm_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_ftdi *ftdi_class;
|
||||
ftdi_class = (struct usbh_ftdi *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_ftdi_set_line_coding(ftdi_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X)
|
||||
case USBH_SERIAL_TYPE_CP210X:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_cp210x *cp210x_class;
|
||||
cp210x_class = (struct usbh_cp210x *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_cp210x_set_line_coding(cp210x_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_ch34x *ch34x_class;
|
||||
ch34x_class = (struct usbh_ch34x *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_ch34x_set_line_coding(ch34x_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_pl2303 *pl2303_class;
|
||||
pl2303_class = (struct usbh_pl2303 *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_pl2303_set_line_coding(pl2303_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops usbh_serial_ops = {
|
||||
NULL,
|
||||
usbh_serial_open,
|
||||
usbh_serial_close,
|
||||
usbh_serial_read,
|
||||
usbh_serial_write,
|
||||
usbh_serial_control
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <dfs_file.h>
|
||||
|
||||
#ifdef RT_USING_POSIX_TERMIOS
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
static rt_err_t usbh_serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
|
||||
{
|
||||
rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/* fops for serial */
|
||||
static int usbh_serial_fops_open(struct dfs_file *fd)
|
||||
{
|
||||
rt_err_t ret = 0;
|
||||
rt_uint16_t flags = 0;
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
switch (fd->flags & O_ACCMODE)
|
||||
{
|
||||
case O_RDONLY:
|
||||
USB_LOG_DBG("fops open: O_RDONLY!");
|
||||
flags = RT_DEVICE_FLAG_RDONLY;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
USB_LOG_DBG("fops open: O_WRONLY!");
|
||||
flags = RT_DEVICE_FLAG_WRONLY;
|
||||
break;
|
||||
case O_RDWR:
|
||||
USB_LOG_DBG("fops open: O_RDWR!");
|
||||
flags = RT_DEVICE_FLAG_RDWR;
|
||||
break;
|
||||
default:
|
||||
USB_LOG_ERR("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fd->flags & O_ACCMODE) != O_WRONLY)
|
||||
rt_device_set_rx_indicate(device, usbh_serial_fops_rx_ind);
|
||||
ret = rt_device_open(device, flags);
|
||||
if (ret == RT_EOK) return 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_close(struct dfs_file *fd)
|
||||
{
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
|
||||
rt_device_set_rx_indicate(device, RT_NULL);
|
||||
rt_device_close(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
|
||||
{
|
||||
rt_device_t device;
|
||||
int flags = (int)(rt_base_t)args;
|
||||
int mask = O_NONBLOCK | O_APPEND;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
switch (cmd)
|
||||
{
|
||||
case FIONREAD:
|
||||
break;
|
||||
case FIONWRITE:
|
||||
break;
|
||||
case F_SETFL:
|
||||
flags &= mask;
|
||||
fd->flags &= ~mask;
|
||||
fd->flags |= flags;
|
||||
break;
|
||||
}
|
||||
|
||||
return rt_device_control(device, cmd, args);
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_read(struct dfs_file *fd, void *buf, size_t count)
|
||||
{
|
||||
int size = 0;
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
|
||||
do
|
||||
{
|
||||
size = rt_device_read(device, -1, buf, count);
|
||||
if (size <= 0)
|
||||
{
|
||||
if (fd->flags & O_NONBLOCK)
|
||||
{
|
||||
size = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER);
|
||||
}
|
||||
}while (size <= 0);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_write(struct dfs_file *fd, const void *buf, size_t count)
|
||||
{
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
return rt_device_write(device, -1, buf, count);
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req)
|
||||
{
|
||||
int mask = 0;
|
||||
int flags = 0;
|
||||
rt_device_t device;
|
||||
struct usbh_serial *serial;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)device;
|
||||
|
||||
/* only support POLLIN */
|
||||
flags = fd->flags & O_ACCMODE;
|
||||
if (flags == O_RDONLY || flags == O_RDWR)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
rt_poll_add(&(device->wait_queue), req);
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
if (rt_ringbuffer_data_len(&serial->rx_rb))
|
||||
mask |= POLLIN;
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
// mask|=POLLOUT;
|
||||
return mask;
|
||||
}
|
||||
|
||||
const static struct dfs_file_ops usbh_serial_fops =
|
||||
{
|
||||
usbh_serial_fops_open,
|
||||
usbh_serial_fops_close,
|
||||
usbh_serial_fops_ioctl,
|
||||
usbh_serial_fops_read,
|
||||
usbh_serial_fops_write,
|
||||
RT_NULL, /* flush */
|
||||
RT_NULL, /* lseek */
|
||||
RT_NULL, /* getdents */
|
||||
usbh_serial_fops_poll,
|
||||
};
|
||||
#endif /* RT_USING_POSIX_DEVIO */
|
||||
|
||||
rt_err_t usbh_serial_register(struct usbh_serial *serial,
|
||||
void *data)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *device;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
device = &(serial->parent);
|
||||
|
||||
device->type = RT_Device_Class_Char;
|
||||
device->rx_indicate = RT_NULL;
|
||||
device->tx_complete = RT_NULL;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &usbh_serial_ops;
|
||||
#else
|
||||
device->init = NULL;
|
||||
device->open = usbh_serial_open;
|
||||
device->close = usbh_serial_close;
|
||||
device->read = usbh_serial_read;
|
||||
device->write = usbh_serial_write;
|
||||
device->control = usbh_serial_control;
|
||||
#endif
|
||||
device->user_data = data;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
device->fops = &usbh_serial_fops;
|
||||
#endif
|
||||
rt_ringbuffer_init(&serial->rx_rb, serial->rx_rb_buffer, sizeof(serial->rx_rb_buffer));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usbh_serial_unregister(struct usbh_serial *serial)
|
||||
{
|
||||
RT_ASSERT(serial != NULL);
|
||||
|
||||
rt_device_unregister(&serial->parent);
|
||||
|
||||
if (serial->type == USBH_SERIAL_TYPE_CDC_ACM) {
|
||||
usbh_serial_cdc_acm_free(serial);
|
||||
} else {
|
||||
usbh_serial_free(serial);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
|
||||
void usbh_cdc_acm_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cdc_acm_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)cdc_acm_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_cdc_acm_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cdc_acm_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_cdc_acm_alloc(USBH_SERIAL_TYPE_CDC_ACM);
|
||||
cdc_acm_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, cdc_acm_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_cdc_acm_set_line_coding(cdc_acm_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)cdc_acm_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
|
||||
void usbh_ftdi_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_ftdi *ftdi_class = (struct usbh_ftdi *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ftdi_class->bulkin_urb;
|
||||
|
||||
if (nbytes >= 2) {
|
||||
serial = (struct usbh_serial *)ftdi_class->user_data;
|
||||
|
||||
nbytes -= 2; // Skip the first two bytes (header)
|
||||
rt_ringbuffer_put(&serial->rx_rb, &g_usbh_serial_vendor_rx_buf[serial->minor][2], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate && nbytes) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ftdi_run(struct usbh_ftdi *ftdi_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ftdi_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_FTDI);
|
||||
ftdi_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, ftdi_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_ftdi_set_line_coding(ftdi_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)ftdi_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
|
||||
void usbh_ch34x_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_ch34x *ch34x_class = (struct usbh_ch34x *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ch34x_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)ch34x_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ch34x_run(struct usbh_ch34x *ch34x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ch34x_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CH34X);
|
||||
ch34x_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, ch34x_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_ch34x_set_line_coding(ch34x_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)ch34x_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X)
|
||||
void usbh_cp210x_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_cp210x *cp210x_class = (struct usbh_cp210x *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cp210x_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)cp210x_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cp210x_run(struct usbh_cp210x *cp210x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cp210x_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CP210X);
|
||||
cp210x_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, cp210x_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_cp210x_set_line_coding(cp210x_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)cp210x_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
|
||||
void usbh_pl2303_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_pl2303 *pl2303_class = (struct usbh_pl2303 *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &pl2303_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)pl2303_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &pl2303_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_PL2303);
|
||||
pl2303_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, pl2303_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_pl2303_set_line_coding(pl2303_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)pl2303_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
@@ -478,6 +478,11 @@ int usb_dc_init(uint8_t busid)
|
||||
|
||||
regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
|
||||
regval |= USB_SFRST_HOV;
|
||||
#ifdef CONFIG_USB_HS
|
||||
regval &= ~USB_FORCE_FS;
|
||||
#else
|
||||
regval |= USB_FORCE_FS;
|
||||
#endif
|
||||
putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
|
||||
|
||||
while (getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET) & USB_SFRST_HOV) {
|
||||
|
||||
@@ -2,4 +2,15 @@
|
||||
|
||||
## Support Chip List
|
||||
|
||||
- CH32V30x
|
||||
## CH32FS
|
||||
|
||||
- CH32V30X/CH32V20X/CH32V10X/CH32X035
|
||||
|
||||
## CH32HS
|
||||
|
||||
- CH32V30X
|
||||
|
||||
## CH58X
|
||||
|
||||
- CH57X/CH58X(usbfs)
|
||||
- CH585(usbhs)
|
||||
|
||||