103 Commits

Author SHA1 Message Date
sakumisu
4d6b12c704 docs: release v1.5.2
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-07 21:49:51 +08:00
sakumisu
5d2a7ca6bc fix(port/musb/usb_hc_musb): add rxmap & txmap config
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-07 21:11:05 +08:00
sakumisu
3ab47e0295 feat(port): add urb->complete in usbh_kill_urb
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-06 21:24:59 +08:00
sakumisu
2081360f2c update(port/dwc2): add mode check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-05 21:46:01 +08:00
sakumisu
8cf12c1958 update(port/musb): add mode check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-05 21:27:45 +08:00
sakumisu
c0f544dafe fix(class/mtp): fix typo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-04 21:56:57 +08:00
sakumisu
599b11ef1a update(osal/idf): change xtaskcreate to xTaskCreatePinnedToCore
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-04 21:47:55 +08:00
sakumisu
7037fd0e8d update(port/dwc2/usb_hc_dwc2): only clean & invalid buffer in usbh_submit_urb, do not clean&invalid many times
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-02 21:09:50 +08:00
sakumisu
3905eff2f4 docs: update readme
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-02 17:55:46 +08:00
sakumisu
20ceaced92 update(core/usbh_core): check string support and then get string desc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-01 21:38:47 +08:00
sakumisu
9ddcbf58ca update(port/dwc2/usb_hc_dwc2): only set errorcode before urb waitup because split transfer will do many times
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-01 21:13:46 +08:00
sakumisu
6e9e769e10 docs: update image
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 21:23:02 +08:00
sakumisu
65288c9d5b update(port/dwc2/usb_hc_dwc2): stop split transfer when intr nak, follow with nosplit intr transfer
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 21:22:48 +08:00
sakumisu
4ab097d9dc fix(common/usb_util): fix missing __ICCARM_V8 define
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 18:15:42 +08:00
sakumisu
f994422c41 chore(scons): export hpmicro dir
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 18:14:49 +08:00
egahp
5ae04f1273 fix(port/dwc2/usb_dwc2_param): fix macro literal types
Signed-off-by: egahp <2687434412@qq.com>
2025-07-31 14:11:28 +08:00
sakumisu
e574ea8ae3 Revert "fix(port): reset sem when pipe free"
This reverts commit ccd4354960.
2025-07-30 22:50:21 +08:00
sakumisu
f949e16564 update(port/dwc2/usb_hc_dwc2): add new api for split transfer, make code simple
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-30 22:21:54 +08:00
sakumisu
1bec84471e docs: update img
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-29 18:22:38 +08:00
sakumisu
1f065cec44 update(port/musb/usb_hc_musb): check urb for iso to support iso later
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 22:08:20 +08:00
sakumisu
3b1853ceb5 fix(platform/rtthread): change RT_USING_CACHE to CONFIG_USB_DCACHE_ENABLE
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 21:23:23 +08:00
sakumisu
72d19ec8cc update(usb_config): change CONFIG_USBHOST_MAX_INTF_ALTSETTINGS to 2 as default to avoid -Warray-bounds warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 21:03:55 +08:00
sakumisu
90de3354b5 update(port/musb): If ep control register group exists, do not use epidx register
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 20:20:16 +08:00
sakumisu
3784ddc389 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 19:15:33 +08:00
sakumisu
81d8f22e05 update(port): remove all ips CONFIG_USBDEV_EP_NUM & CONFIG_USBHOST_PIPE_NUM
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 19:06:37 +08:00
sakumisu
3b04facd09 revert: revert 1a68d94c some changes
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 14:18:18 +08:00
sakumisu
8dd3106e62 update(common/usb_hc): change interval u16 to u32 for us
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 21:25:27 +08:00
sakumisu
9e4122f2a0 fix(osal/idf): fix esp timer handle
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 21:22:18 +08:00
sakumisu
083ec57384 update(core/usbh_core): do not assert when parse desc fail, just return error
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 21:06:19 +08:00
sakumisu
ccd4354960 fix(port): reset sem when pipe free
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 20:58:47 +08:00
sakumisu
60ac6fe3ad fix(port/ehci): remove usb_osal_msleep in critical section
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 20:46:12 +08:00
udoudou
0986e8b5ec Fix the bug that dwc2_halt may cause hardware abnormality 2025-07-27 20:30:08 +08:00
udoudou
ae2a24642b Fix a bug where the channel might not be released 2025-07-27 20:30:08 +08:00
udoudou
1a68d94c32 add reset port timeout check for dwc2 2025-07-27 20:30:08 +08:00
sakumisu
c102f4adfa update(usb_config): change CONFIG_USBHOST_MAX_INTF_ALTSETTINGS to 1 as default for less memory usage
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 10:26:31 +08:00
sakumisu
d589b9417d update(osal/idf): change freertos timer to esp_timer
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 10:21:00 +08:00
sakumisu
7b39de9630 update(port/dwc2/usb_glue_kendryte): update dwc2 param
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-26 16:48:12 +08:00
sakumisu
6702ab9225 update(port/dwc2): invalid data before start read
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-26 16:11:47 +08:00
sakumisu
ecb98f399d update: add output_len param for usbh_get_string_desc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-25 22:37:25 +08:00
sakumisu
a9ec951c93 update(common/usb_hc): change interval u8 to u16 for us
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-25 22:24:35 +08:00
sakumisu
9de28f9342 style: format log
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-25 18:45:38 +08:00
sakumisu
dc7e53d79f fix(port/dwc2/usb_hc_dwc2): exit porten loop check when device disconnets
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-24 21:03:22 +08:00
sakumisu
d3a5aae7af fix(class/hub/usbh_hub): fix port to port+1
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-24 21:00:21 +08:00
Matthew
7153fb9756 fix(platform/rtthread): add RT_DEVICE_FLAG_INT_RX falg to device 2025-07-24 18:29:34 +08:00
Matthew
0e31b40407 fix(platform/rtthread): restart read at usbd_cdc_acm_bulk_out 2025-07-24 18:29:34 +08:00
sakumisu
fa5a9fbcaa update(platform/rtthread): remove align size check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-22 20:24:41 +08:00
sakumisu
68b28a43f3 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-22 18:20:37 +08:00
sakumisu
ddda03c4cb update(port): remove CONFIG_USBDEV_EP_NUM & CONFIG_USBHOST_PIPE_NUM for some ips because they are constant
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-21 21:22:54 +08:00
sakumisu
96ab19e398 fix(core/usbh_core): change 2ms to 10ms because some platform's tick is 100hz then 2ms = 0ms, refs: #342
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-20 21:29:48 +08:00
sakumisu
2783793b17 fix(port/dwc2/usb_hc_dwc2): check buf is valid then using dcache clean
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-20 21:25:20 +08:00
sakumisu
e499871a59 fix(port/dwc2/usb_glue_st): reduce f4 total size for some specific f4 chips
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-19 10:08:52 +08:00
Derek Konigsberg
7c38af1b04 Clear error code after intentionally ignoring it
In the case of handling a stall on a max lun request, we need to clear the error code in `ret` after ignoring it. This is necessary so the connect function won't fail.

Fix #339
2025-07-19 09:20:49 +08:00
sakumisu
cc3e91e8d7 fix(port/dwc2/usb_hc_dwc2): invalid indata before urb done
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 23:16:41 +08:00
sakumisu
a95e06a951 update(cherrymp): update local ringbuf
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 22:50:48 +08:00
sakumisu
502c88084c update: remove zephyr bluetooth submodule
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 22:46:55 +08:00
sakumisu
a9f0374fa7 style: format code
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 22:36:23 +08:00
sakumisu
56c864b008 fix(port/dwc2/usb_hc_dwc2): fix control split transfer with short packet
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 21:36:19 +08:00
sakumisu
80f0f97efa fix(port/dwc2/usb_glue_at): fix host rx size
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-17 23:01:32 +08:00
sakumisu
4fdbe4ed26 docs: update image
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-17 22:23:45 +08:00
sakumisu
1e8e440721 fix(demo): ignore zero bytes for bl ip
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-16 22:54:21 +08:00
sakumisu
605a967282 style: remove some logs
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-16 22:17:19 +08:00
sakumisu
7a357a10da feat(port/dwc2): support ep mult
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-16 21:49:54 +08:00
LiPeng
d58037e3d4 Add FS support for ESP32-P4 2025-07-14 20:50:16 +08:00
sakumisu
f3b5025b64 update(cherryusb): update to v1.5.1
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-14 11:49:37 +08:00
sakumisu
e32486f9a8 feat: support sifli
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 20:25:58 +08:00
sakumisu
064507bfe8 update(core/usbd_core): add ep0 state log
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 17:17:38 +08:00
sakumisu
e61141a45e update(port/dwc2/usb_dc_dwc2): use usbd_get_ep0_next_state for reading setup
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 17:17:19 +08:00
sakumisu
4ce8c507b0 update(demo): remove ep num check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 16:39:33 +08:00
sakumisu
85e420eb54 update(port/fsdev): assert for fsdev log
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 16:39:20 +08:00
sakumisu
40a052ba7f chore(kconfig): add more config
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-11 18:34:46 +08:00
sakumisu
3249811a90 fix(port/dwc2/usb_dc_dwc2): align with CONFIG_USB_ALIGN_SIZE not only 32
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-11 18:34:26 +08:00
sakumisu
c5b1e1af27 fix typo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-11 15:16:01 +08:00
sakumisu
78a802faa6 update(port/dwc2/usb_glue_at): update at glue with dwc2 param
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-10 21:52:58 +08:00
sakumisu
811550ad25 chore(port/dwc2): update readme
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-10 21:52:14 +08:00
mlwang
4093a3b01d fix(port/ehci): Fix the urb leak when there is no data in the control transmission 2025-07-10 21:45:45 +08:00
MDLZCOOL
9de928d6af Modify kconfig for better template choose 2025-07-10 20:19:16 +08:00
sakumisu
5a94ed80cb feat(port/dwc2): add user fifo config api
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-07 20:28:14 +08:00
sakumisu
22e150a8e6 refactor(port/dwc2): support custom config for each dwc2 usb port
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-05 16:39:54 +08:00
sakumisu
8e0ff856fe update(class/mtp): support obj remove & add event
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-03 20:54:30 +08:00
FanhuaCloud
739db92ef0 fix:(port/ch58x/usb_ch58x_dc_usbfs.c) fix out endpoint cannot receive bug 2025-07-03 16:15:08 +08:00
sakumisu
53e42e6ceb fix(platform/rtthread/usbh_serial): remove unused variable
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-02 20:17:20 +08:00
sakumisu
832e4c45fb fix(class/hub): change urb interval unit to us
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-01 21:21:59 +08:00
sakumisu
52ea7e8dcf fix(demo): fix webusb desc len
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-01 09:51:56 +08:00
sakumisu
5a3b87e08c feat(demo): add mavlink with cdc acm
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-26 18:28:46 +08:00
sakumisu
6f1228c029 fix(platform/rtthread): change ssize_t to rt_ssize_t
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-25 15:10:44 +08:00
sakumisu
e96e5fd9ca feat(platform/rtthread): support cdc acm chardev
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-25 14:07:06 +08:00
sakumisu
9d4faca7db fix(vendor/serial/usbh_ftdi): fix missing break
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-24 18:21:09 +08:00
sakumisu
c22615ea6f feat(platform/rtthread): support adb shell and serial framework
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-24 18:20:38 +08:00
sakumisu
749cd8531f docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-24 18:05:08 +08:00
sakumisu
734cacb177 fix(port/dwc2/usb_glue_st): fix GCCFG in stm32h7rs
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-23 22:20:17 +08:00
sakumisu
1f7070f5c9 revert(port/dwc2/usb_hc_dwc2): revert 4f831f58 change
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-23 20:12:34 +08:00
sakumisu
8d8f3e757e fix warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-19 20:02:19 +08:00
KK
5e890a078f msc: add support for SCSI_CMD_SYNCHCACHE10 (0x35) to fix unsupported command error 2025-06-17 16:18:03 +08:00
sakumisu
e530d86af7 docs: update version message
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-16 20:30:31 +08:00
sakumisu
300907dd4c update(platform/rtthread): move cache check into usb_check.c
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-16 20:30:23 +08:00
sakumisu
0916749a32 update(idf): increase host stack size
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-14 22:56:30 +08:00
sakumisu
9d29fece51 fix warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-14 21:44:54 +08:00
马龙伟
8df2be2a52 add usb net under idf platform 2025-06-14 21:02:54 +08:00
sakumisu
7f3ddf5d83 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-13 21:55:37 +08:00
sakumisu
6a226e3e3c refactor(port/ch32): classify ch32 port
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-12 21:35:51 +08:00
sakumisu
8b63acd46c update(port/bl): add fs support
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-12 20:45:53 +08:00
sakumisu
f7094028b8 fix(idf): fix p4 config
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-05 22:12:26 +08:00
sakumisu
5f9d06a9f5 update(platform/fatfs): change memalign to aligned_alloc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-05 12:40:54 +08:00
141 changed files with 5939 additions and 1710 deletions

3
.gitmodules vendored
View File

@@ -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

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 showhttps://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" />

View File

@@ -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" />

View File

@@ -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')

View File

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

View File

@@ -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()

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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*/

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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))

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View 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;
}
}
}
}

View File

@@ -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

View File

@@ -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

View 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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 = {

View File

@@ -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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -7,6 +7,10 @@
- 有多少个接口就调用多少次 `usbd_add_interface`,参数填相关 `xxx_init_intf`, 如果没有支持的,手动创建一个 intf 填入
- 有多少个端点就调用多少次 `usbd_add_endpoint`,当中断完成时,会调用到注册的端点回调中。
参考下面这张图:
.. figure:: img/api_device1.png
CORE
-----------------

View File

@@ -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;
};

View File

@@ -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** 传输长度

View File

@@ -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

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 KiB

View 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

View File

@@ -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 的不需要使用定时器。

View File

@@ -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

View File

@@ -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

View File

@@ -1,2 +1,4 @@
usbh_serial
===============
当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。

View File

@@ -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

View File

@@ -56,3 +56,7 @@ Klipper is a 3d-printer firmware.
适配链接:待开放
MAKCU/KMBOX
--------------
懂的都懂,不开放

View File

@@ -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 引脚必须为 4PB14/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 引脚必须为 4PB14/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 口,
然后不同使能的配置也不一样,因此不做支持。

View File

@@ -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/BL808USB2.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/s3USB2.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使用 fsdevF4/H7使用 dwc2
- dwc2 ip 区别: USB0 (引脚是 PA11/PA12) 和 USB1 (引脚是 PB14/PB15), 其中 USB1 默认全速可以接外部PHY 形成高速主机,并且带 dma 功能
- F4 无cacheH7 有 cache
- F4 无 cacheH7 有 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 ipV1.5.0 开始需要增加 **fsdev/usb_glue_st.c**`usb_config.h` 中实现以下宏:
- 如果使用 fsdev ipV1.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
- 如果芯片带 cachecache 修改参考 :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` 章节
- 如果芯片带 cachecache 修改参考 :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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -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 编译器
* 如果芯片带 cachecache 修改参考 :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` 章节
* 如果芯片带 cachecache 修改参考 :ref:`usb_cache` 章节

View File

@@ -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
- 如果芯片带 cachecache 修改参考 :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` 章节
- 如果芯片带 cachecache 修改参考 :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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -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
-----------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 MiB

View File

@@ -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 驱动适配
- 技术支持相关

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -138,6 +138,10 @@ USB 对这个问题的解决办法,就是强制插 0也就是位填充
在数据被NRZI编码之前在数据流中每六个连续的1之后插入一个0以强制NRZI数据流中的过渡这使接收器逻辑至少每七位有一次数据转换以保证数据和时钟的锁定。比特填充是从同步模式开始启用。结束同步模式的数据 "一 "被算作是序列中的第一个 "一"。序列中的第一个。除了高速EOP期间发射器的位填充总是被强制执行。如果需要按照
位填充规则的要求零位将被插入即使它是数据包结束EOP信号前的最后一位。接收器必须对NRZI数据进行解码识别填充位并将其丢弃。
.. caution:: 以下内容可以用一张图概括,了解即可,没有必要死记硬背
.. figure:: img/usbstruct.png
USB 字段(域)
---------------------

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 503 KiB

After

Width:  |  Height:  |  Size: 684 KiB

View File

@@ -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 目录重新分类
- cmakesconskconfig 更新
- 使用 USB_ASSERT_MSG 对部分代码检查
- N32H4mm32f5 支持
- 使用 USB_ASSERT_MSG 对部分代码检查,全面性 warning 修复
- N32H4/MM32F5 device 支持
- 默认使能 CONFIG_USBDEV_ADVANCE_DESC
v1.5.1
----------------------
- 支持 rt-thread 下使用 adb shellhost 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 timerfreertos timer会有启动失败的可能性xTaskCreate 使用 xTaskCreatePinnedToCore 替换,方便多核使用
- 主机枚举中,删除描述符溢出相关的 ASSERT 操作改成返回错误。获取字符串描述符改成支持才获取。2 ms 延时改成 10ms因为一些 os 使用的是 100hz会造成延时失效
- **dwc2 ep mult 支持split 传输代码优化,对 split 相关的 cache 处理修改**
- **dwc2 halt 中不能清除 USB_OTG_HCCHAR_EPDIRreset port 中使用超时机制,防止在枚举时由于拔出而造成死等**
- 更新 DWC2 中 at32stm32kendryteespressif 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

View File

@@ -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

View File

@@ -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"

View File

@@ -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)

View File

@@ -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

View File

@@ -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);

View File

@@ -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
View 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

View File

@@ -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

View 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);

View 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);
}

View File

@@ -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);
}

View 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

View File

@@ -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) {

View File

@@ -2,4 +2,15 @@
## Support Chip List
- CH32V30x
## CH32FS
- CH32V30X/CH32V20X/CH32V10X/CH32X035
## CH32HS
- CH32V30X
## CH58X
- CH57X/CH58X(usbfs)
- CH585(usbhs)

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