137 Commits

Author SHA1 Message Date
sakumisu
c746f57ddc docs: bump version to v1.5.3
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-25 14:23:48 +08:00
sakumisu
3882560646 update: remove ununsed osal
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-25 14:22:49 +08:00
Zhihong Chen
9cf680148e port: update hpmicro port files for otg
Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2025-11-25 14:22:15 +08:00
sakumisu
e25c12f6a8 fix warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-25 14:22:15 +08:00
sakumisu
f09198704b refactor(otg): refactor otg framework
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-25 14:22:08 +08:00
sakumisu
af519ac42c feat(class): support more match flags for cdc acm & rndis
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-25 14:18:36 +08:00
sakumisu
c34cbc5bfb update(core): change assert with USB_ASSERT_MSG
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-24 20:34:16 +08:00
sakumisu
38dff565cf update(platform/daplink): sync with cherrydap
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-24 20:34:01 +08:00
sakumisu
6067343775 fix(osal/usb_osal_ucosiii): fix msleep opt
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-23 21:37:29 +08:00
sakumisu
6c34938883 feat(core/usbh_core): support interfacenum match flag
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-23 21:37:23 +08:00
sakumisu
7cd4ff71d7 update(port/dwc2/usb_glue_st): increase ep1 tx fifo for audio demo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-19 22:21:54 +08:00
sakumisu
999ddb1a9d update(core/usbh_core): print interface num when load driver
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-13 22:05:52 +08:00
sakumisu
01b22bb138 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-13 22:04:44 +08:00
sakumisu
e0dc9c9890 refactor(core/usbh_core): refactor lsusb
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-11 22:45:49 +08:00
sakumisu
6105d7a1d6 ci: update bl & hpm demo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-10 20:34:16 +08:00
sakumisu
757187e967 fix(port/dwc2/usb_dc_dwc2): invalid cache before all read setup
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-09 22:28:52 +08:00
蒙蒙plus
a33396fa93 fix(usb_dc_dwc2): add unaligned read/write macros for IAR compiler 2025-11-09 22:28:02 +08:00
Rbb666
ab8efcb07d fix:Fix RNDIS DHCP dependency,and delay implementation 2025-11-09 22:27:51 +08:00
sakumisu
5c9550d00e fix(osal/usb_osal_threadx): delete self in another thread
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-05 20:42:07 +08:00
sakumisu
c8a713a49a update(platform/rtthread): change LWIP_NO_RX_THREAD check error to warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-05 20:42:07 +08:00
sakumisu
87c49f9359 ci: enable all class
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-05 20:42:07 +08:00
sakumisu
6e8a63fd77 feat(platform/idf): add fatfs port for host msc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-04 23:03:50 +08:00
sakumisu
71a966bbd5 fix(osal/usb_osal_ucosiii): lock before free
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-04 21:58:34 +08:00
sakumisu
32cf0e0b3c fix(class/hub): delete thread before delete mq
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-04 21:58:34 +08:00
sakumisu
88b1158b4f update(platform/rtthread): add more check for chip cache
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-04 21:58:34 +08:00
sakumisu
38a4c5e375 fix(osal/usb_osal_ucosiii): memset after malloc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-03 22:19:13 +08:00
sakumisu
b758fa814a feat(osal): add ucosiii osal
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-03 22:18:55 +08:00
sakumisu
9730f63b2c feat: support custom ep0 mps
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-03 22:17:43 +08:00
sakumisu
0365aa0d63 feat(demo): add mongoose rndis demo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-03 22:17:10 +08:00
sakumisu
649ad6686b update(core/usbh_core): add retry for control transfer, some devices are flakey
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-03 22:01:45 +08:00
sakumisu
868dbee668 chore: add build ci
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-03 21:45:57 +08:00
sakumisu
84b1d3feeb update(port/chipidea): add dcache support for device
Signed-off-by: sakumisu <1203593632@qq.com>
2025-11-01 00:22:19 +08:00
MDLZCOOL
1045f877c8 refactor(usb_osal_threadx): optimize the creation and deletion of threads
- Allocate only once at `usb_osal_thread_create`.
- Fixed a null pointer crash in `usb_osal_thread_delete`.
- Standardized the return value of `usb_osal_sem_give`.
2025-10-27 17:40:42 +08:00
HalfSweet
12694eed49 feat: Add MUSB IP without multipoint feature support 2025-10-27 17:40:42 +08:00
sakumisu
ed344579ff update(port/hpmicro): add dcache support for device
Signed-off-by: sakumisu <1203593632@qq.com>
2025-10-27 17:40:42 +08:00
sakumisu
c3b01eed25 update(demo/cdc_acm_rttchardev): add finsh & console switch with usb
Signed-off-by: sakumisu <1203593632@qq.com>
2025-10-27 17:40:42 +08:00
sakumisu
f087e0777a update(platform): remove CONFIG_USB_DCACHE_ENABLE, always check align size
Signed-off-by: sakumisu <1203593632@qq.com>
2025-10-27 17:40:42 +08:00
sakumisu
82487c80aa update(port/dwc2/usb_glue_hc): update hc port
Signed-off-by: sakumisu <1203593632@qq.com>
2025-10-09 21:30:56 +08:00
sakumisu
86e9422e06 update(hub/usbh_hub): add check for nports
Signed-off-by: sakumisu <1203593632@qq.com>
2025-10-09 21:30:56 +08:00
sakumisu
6c239e175f feat(class/video/usbh_video): support bulk mode
Signed-off-by: sakumisu <1203593632@qq.com>
2025-10-09 21:30:56 +08:00
sakumisu
1b973b5cc5 fix(port/ehci): clear iaad status before set
Signed-off-by: sakumisu <1203593632@qq.com>
2025-09-27 22:21:15 +08:00
LiPeng
102af3be37 fix: Remove usb component private requirement for idf v6 2025-09-11 16:58:55 +08:00
sakumisu
347df77372 fix(demo): fix missing ecm mac address string
Signed-off-by: sakumisu <1203593632@qq.com>
2025-09-01 20:04:09 +08:00
sakumisu
778465654b docs: remove ununsed code
Signed-off-by: sakumisu <1203593632@qq.com>
2025-09-01 20:03:59 +08:00
sakumisu
e2791c7d04 refactor(core/usbh_core): refactor devaddr allocation, use auto increment
Signed-off-by: sakumisu <1203593632@qq.com>
2025-09-01 20:03:45 +08:00
sakumisu
7902c1c352 style: remove printf with USB_LOG_XXX
Signed-off-by: sakumisu <1203593632@qq.com>
2025-09-01 20:03:19 +08:00
LiPeng
1768079a89 bugfix: Fix support for idf versions lower than 5.3 2025-09-01 20:03:07 +08:00
LiPeng
c77557510e bugfix: Fix some compilation errors 2025-09-01 20:01:50 +08:00
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
194 changed files with 14392 additions and 2749 deletions

83
.github/workflows/build_tests.yml vendored Normal file
View File

@@ -0,0 +1,83 @@
name: Build Tests
on:
push:
branches:
- master
- release/v1.5
pull_request:
branches:
- master
- release/v1.5
jobs:
build_hpmicro:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build
- name: Download hpm_sdk
run: |
cd ~
git clone https://github.com/hpmicro/hpm_sdk.git
- name: Download RISC-V toolchain
run: |
cd ~
wget https://github.com/hpmicro/riscv-gnu-toolchain/releases/download/2023.10.18/rv32imac_zicsr_zifencei_multilib_b_ext-linux.tar.gz
tar -xzf rv32imac_zicsr_zifencei_multilib_b_ext-linux.tar.gz
- name: Build hpm demo
run: |
cd tests/hpmicro
export HPM_SDK_BASE=~/hpm_sdk
export GNURISCV_TOOLCHAIN_PATH=~/rv32imac_zicsr_zifencei_multilib_b_ext-linux
export HPM_SDK_TOOLCHAIN_VARIANT=
cmake -S . -B build -GNinja -DBOARD=hpm6800evk -DHPM_BUILD_TYPE=flash_sdram_xip -DCMAKE_BUILD_TYPE=debug -DEXTRA_C_FLAGS="-Werror";cmake --build build
build_bouffalolab:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y cmake make
- name: Download bouffalo_sdk
run: |
cd ~
git clone https://github.com/bouffalolab/bouffalo_sdk.git
- name: Download RISC-V toolchain
run: |
cd ~
git clone https://github.com/bouffalolab/toolchain_gcc_t-head_linux.git
- name: Build bouffalo demo
run: |
cd tests/bouffalolab
export BL_SDK_BASE=~/bouffalo_sdk
export PATH=~/toolchain_gcc_t-head_linux/bin:$PATH
make CHIP=bl616 BOARD=bl616dk -j12
build_espressif:
strategy:
matrix:
idf_ver: ["latest"]
runs-on: ubuntu-latest
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Build espressif demo
shell: bash
run: |
. ${IDF_PATH}/export.sh
pip install idf-component-manager ruamel.yaml idf-build-apps --upgrade
idf-build-apps build -p ./tests/espressif --recursive --target esp32s3

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.vscode
build
**/Drivers/**
**/MDK-ARM/DebugConfig/**
**/MDK-ARM/RTE/**

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

@@ -64,6 +64,14 @@ elseif(ESP_PLATFORM)
idf_component_get_property(freertos_include freertos ORIG_INCLUDE_PATH)
if(CONFIG_CHERRYUSB_HOST_MSC)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_fatfs.c)
endif()
set(priv_req esp_mm esp_netif esp_timer fatfs)
if(${IDF_VERSION_MAJOR} LESS 6)
list(APPEND priv_req usb)
endif()
idf_component_register(
SRCS
${cherryusb_srcs}
@@ -71,7 +79,7 @@ elseif(ESP_PLATFORM)
${cherryusb_incs}
${freertos_include}
PRIV_REQUIRES
usb esp_mm esp_netif
${priv_req}
LDFRAGMENTS
${ldfragments}
)

136
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
@@ -116,6 +118,7 @@ if CHERRYUSB
config CHERRYUSB_DEVICE_CDC_NCM
bool
prompt "Enable usb cdc ncm device"
depends on !IDF_CMAKE
default n
config CHERRYUSB_DEVICE_MTP
@@ -123,55 +126,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 +273,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
@@ -280,6 +339,7 @@ if CHERRYUSB
config CHERRYUSB_HOST_BLUETOOTH
bool
prompt "Enable usb bluetooth driver"
depends on !IDF_CMAKE
default n
config CHERRYUSB_HOST_ASIX
@@ -334,12 +394,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 +430,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,24 @@ if PKG_USING_CHERRYUSB
choice
prompt "Version"
default PKG_USING_CHERRYUSB_V010500
default PKG_USING_CHERRYUSB_V010503
help
Select the package version
config PKG_USING_CHERRYUSB_LATEST_VERSION
bool "latest"
config PKG_USING_CHERRYUSB_V010502
bool "v1.5.3"
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 +492,12 @@ if PKG_USING_CHERRYUSB
config PKG_CHERRYUSB_VER
string
default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION
default "v1.5.3" if PKG_USING_CHERRYUSB_V010503
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/>=v1.5.0 | 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)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
|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/>=v1.5.0 | 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)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
|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 = 3
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)
@@ -316,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)
@@ -329,11 +335,15 @@ 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()
if(CONFIG_CHERRYUSB_DEVICE AND CONFIG_CHERRYUSB_HOST)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/core/usbotg_core.c)
endif()
if(DEFINED CONFIG_CHERRYUSB_OSAL)
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_freertos.c)

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,18 +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
// #define CONFIG_USB_MUSB_WITHOUT_MULTIPOINT
/* 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)
@@ -342,4 +318,7 @@
#define usb_ramaddr2phyaddr(addr) (addr)
#endif
/* Enable OTG support, only support hpmicro now */
// #define CONFIG_USB_OTG_ENABLE
#endif

View File

@@ -176,9 +176,6 @@ int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *repo
int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len)
{
struct usb_setup_packet *setup;
int ret;
uint8_t len;
uint32_t offset;
if (!aoa_class || !aoa_class->hport) {
return -USB_ERR_INVAL;
@@ -198,7 +195,6 @@ int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *ev
static int usbh_aoa_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;
int ret = 0;
struct usbh_aoa *aoa_class = &g_aoa_class;

View File

@@ -266,11 +266,20 @@ const struct usbh_class_driver cdc_data_class_driver = {
.disconnect = usbh_cdc_data_disconnect
};
CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_none_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
.bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
.bInterfaceProtocol = 0x00,
.bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE,
.id_table = NULL,
.class_driver = &cdc_acm_class_driver
};
CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_at_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
.bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
.bInterfaceProtocol = CDC_COMMON_PROTOCOL_AT_COMMANDS,
.id_table = NULL,
.class_driver = &cdc_acm_class_driver
};

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

@@ -106,7 +106,6 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
{
struct usb_setup_packet *req = setup;
uint32_t addr;
uint8_t *phaddr;
/* Data setup request */
if (req->wLength > 0U) {
if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
@@ -143,7 +142,7 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
addr = ((g_usbd_dfu.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + g_usbd_dfu.data_ptr;
/* Return the physical address where data are stored */
phaddr = dfu_read_flash((uint8_t *)addr, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);
dfu_read_flash((uint8_t *)addr, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);
/* Send the status data over EP0 */
memcpy(*data, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);

View File

@@ -106,7 +106,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
memcpy(buffer, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1));
return ret;
}
@@ -148,7 +148,7 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol)
if (ret < 8) {
return ret;
}
memcpy(protocol, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
memcpy(protocol, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1));
return ret;
}
@@ -190,7 +190,7 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, buflen));
memcpy(buffer, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, buflen));
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;
}
@@ -373,6 +373,11 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5);
}
if (hub->nports > CONFIG_USBHOST_MAX_EHPORTS) {
USB_LOG_ERR("Hub nports %u overflow\r\n", hub->nports);
return -USB_ERR_NOMEM;
}
for (uint8_t port = 0; port < hub->nports; port++) {
hub->child[port].port = port + 1;
hub->child[port].parent = hub;
@@ -403,7 +408,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 +421,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 +502,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 +537,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 +567,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 +581,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;
}
}
@@ -704,7 +713,6 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
{
struct usbh_hubport *hport;
struct usbh_hub *hub;
size_t flags;
hub = &bus->hcd.roothub;
for (uint8_t port = 0; port < hub->nports; port++) {
@@ -713,14 +721,10 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
usbh_hubport_release(hport);
}
flags = usb_osal_enter_critical_section();
usb_hc_deinit(bus);
usb_osal_leave_critical_section(flags);
usb_osal_mq_delete(bus->hub_mq);
usb_osal_thread_delete(bus->hub_thread);
usb_osal_mq_delete(bus->hub_mq);
return 0;
}

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,7 +742,6 @@ 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:
@@ -812,7 +749,6 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
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;
}
@@ -820,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);
@@ -837,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;
}
@@ -921,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*/
@@ -943,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

@@ -1034,17 +1034,17 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si
static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t byteen,
uint16_t size, void *data, uint16_t type)
{
int ret;
int ret = -USB_ERR_INVAL;
uint16_t byteen_start, byteen_end, byen;
uint16_t limit = 512;
uint8_t *buf = data;
/* both size and indix must be 4 bytes align */
if ((size & 3) || !size || (index & 3) || !buf)
return -USB_ERR_INVAL;
return ret;
if ((uint32_t)index + (uint32_t)size > 0xffff)
return -USB_ERR_INVAL;
return ret;
byteen_start = byteen & BYTE_EN_START_MASK;
byteen_end = byteen & BYTE_EN_END_MASK;
@@ -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);
@@ -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

@@ -122,12 +122,12 @@ int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class)
return usbh_video_get(video_class, VIDEO_REQUEST_GET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
}
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwFrameInterval)
{
video_class->probe.bFormatIndex = formatindex;
video_class->probe.bFrameIndex = frameindex;
video_class->probe.dwMaxPayloadTransferSize = 0;
video_class->probe.dwFrameInterval = 333333;
video_class->probe.dwFrameInterval = dwFrameInterval;
return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
}
@@ -136,7 +136,6 @@ int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t f
memcpy(&video_class->commit, &video_class->probe, sizeof(struct video_probe_and_commit_controls));
video_class->commit.bFormatIndex = formatindex;
video_class->commit.bFrameIndex = frameindex;
video_class->commit.dwFrameInterval = 333333;
return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26);
}
@@ -154,6 +153,7 @@ int usbh_video_open(struct usbh_video *video_class,
bool found = false;
uint8_t formatidx = 0;
uint8_t frameidx = 0;
uint32_t dwDefaultFrameInterval = 0;
uint8_t step;
if (!video_class || !video_class->hport) {
@@ -172,6 +172,7 @@ int usbh_video_open(struct usbh_video *video_class,
if ((wWidth == video_class->format[i].frame[j].wWidth) &&
(wHeight == video_class->format[i].frame[j].wHeight)) {
frameidx = j + 1;
dwDefaultFrameInterval = video_class->format[i].frame[j].dwDefaultFrameInterval;
found = true;
break;
}
@@ -204,7 +205,7 @@ int usbh_video_open(struct usbh_video *video_class,
}
step = 1;
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval);
if (ret < 0) {
goto errout;
}
@@ -228,7 +229,7 @@ int usbh_video_open(struct usbh_video *video_class,
}
step = 5;
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval);
if (ret < 0) {
goto errout;
}
@@ -246,26 +247,30 @@ int usbh_video_open(struct usbh_video *video_class,
}
step = 8;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = altsetting;
setup->wIndex = video_class->data_intf;
setup->wLength = 0;
if (!video_class->is_bulk) {
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = altsetting;
setup->wIndex = video_class->data_intf;
setup->wLength = 0;
ret = usbh_control_transfer(video_class->hport, setup, NULL);
if (ret < 0) {
goto errout;
}
ret = usbh_control_transfer(video_class->hport, setup, NULL);
if (ret < 0) {
goto errout;
}
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc;
mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
if (ep_desc->bEndpointAddress & 0x80) {
video_class->isoin_mps = mps * (mult + 1);
USBH_EP_INIT(video_class->isoin, ep_desc);
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc;
mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
if (ep_desc->bEndpointAddress & 0x80) {
video_class->isoin_mps = mps * (mult + 1);
USBH_EP_INIT(video_class->isoin, ep_desc);
} else {
return -USB_ERR_NODEV;
}
} else {
video_class->isoout_mps = mps * (mult + 1);
USBH_EP_INIT(video_class->isoout, ep_desc);
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc;
USBH_EP_INIT(video_class->bulkin, ep_desc);
}
USB_LOG_INFO("Open video and select formatidx:%u, frameidx:%u, altsetting:%u\r\n", formatidx, frameidx, altsetting);
@@ -292,54 +297,62 @@ int usbh_video_close(struct usbh_video *video_class)
video_class->is_opened = false;
if (video_class->isoin) {
video_class->isoin = NULL;
if (video_class->is_bulk) {
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_ENDPOINT;
setup->bRequest = USB_REQUEST_CLEAR_FEATURE;
setup->wValue = USB_FEATURE_ENDPOINT_HALT;
setup->wIndex = video_class->bulkin->bEndpointAddress;
setup->wLength = 0;
} else {
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = 0;
setup->wIndex = video_class->data_intf;
setup->wLength = 0;
}
if (video_class->isoout) {
video_class->isoout = NULL;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = 0;
setup->wIndex = video_class->data_intf;
setup->wLength = 0;
ret = usbh_control_transfer(video_class->hport, setup, NULL);
if (ret < 0) {
return ret;
}
return ret;
}
void usbh_video_list_info(struct usbh_video *video_class)
{
struct usb_endpoint_descriptor *ep_desc;
uint8_t mult;
uint16_t mps;
USB_LOG_INFO("============= Video device information ===================\r\n");
USB_LOG_RAW("bcdVDC:%04x\r\n", video_class->bcdVDC);
USB_LOG_RAW("Num of altsettings:%u\r\n", video_class->num_of_intf_altsettings);
USB_LOG_RAW("Num of altsettings:%u (%s mode)\r\n", video_class->num_of_intf_altsettings, video_class->num_of_intf_altsettings == 1 ? "bulk" : "iso");
for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) {
if (i == 0) {
USB_LOG_RAW("Ingore altsetting 0\r\n");
continue;
video_class->is_bulk = video_class->num_of_intf_altsettings == 1 ? true : false;
if (video_class->is_bulk) {
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc;
USB_LOG_RAW("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
ep_desc->bEndpointAddress,
ep_desc->bmAttributes,
USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize),
ep_desc->bInterval,
USB_GET_MULT(ep_desc->wMaxPacketSize));
} else {
for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) {
if (i == 0) {
USB_LOG_RAW("Ingore altsetting 0\r\n");
continue;
}
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc;
USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
i,
ep_desc->bEndpointAddress,
ep_desc->bmAttributes,
USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize),
ep_desc->bInterval,
USB_GET_MULT(ep_desc->wMaxPacketSize));
}
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc;
mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
i,
ep_desc->bEndpointAddress,
ep_desc->bmAttributes,
mps,
ep_desc->bInterval,
mult);
}
USB_LOG_RAW("bNumFormats:%u\r\n", video_class->num_of_formats);
@@ -350,9 +363,10 @@ void usbh_video_list_info(struct usbh_video *video_class)
USB_LOG_RAW(" Resolution:\r\n");
for (uint8_t j = 0; j < video_class->format[i].num_of_frames; j++) {
USB_LOG_RAW(" FrameIndex:%u\r\n", j + 1);
USB_LOG_RAW(" wWidth: %d, wHeight: %d\r\n",
video_class->format[i].frame[j].wWidth,
video_class->format[i].frame[j].wHeight);
USB_LOG_RAW(" wWidth: %d, wHeight: %d, fps: %d\r\n",
video_class->format[i].frame[j].wWidth,
video_class->format[i].frame[j].wHeight,
(1000 / (video_class->format[i].frame[j].dwDefaultFrameInterval / 10000)));
}
}
@@ -438,12 +452,14 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wWidth;
video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wHeight;
video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->dwDefaultFrameInterval;
break;
case VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE:
frame_index = p[DESC_bFrameIndex];
video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wWidth;
video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wHeight;
video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->dwDefaultFrameInterval;
break;
default:
break;
@@ -476,12 +492,6 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
struct usbh_video *video_class = (struct usbh_video *)hport->config.intf[intf].priv;
if (video_class) {
if (video_class->isoin) {
}
if (video_class->isoout) {
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister Video Class:%s\r\n", hport->config.intf[intf].devname);

View File

@@ -14,6 +14,7 @@
struct usbh_video_resolution {
uint16_t wWidth;
uint16_t wHeight;
uint32_t dwDefaultFrameInterval;
};
struct usbh_video_format {
@@ -40,7 +41,7 @@ struct usbh_videostreaming {
struct usbh_video {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *isoin; /* ISO IN endpoint */
struct usb_endpoint_descriptor *isoout; /* ISO OUT endpoint */
struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
uint8_t ctrl_intf; /* interface number */
uint8_t data_intf; /* interface number */
@@ -48,9 +49,9 @@ struct usbh_video {
struct video_probe_and_commit_controls probe;
struct video_probe_and_commit_controls commit;
uint16_t isoin_mps;
uint16_t isoout_mps;
bool is_opened;
uint8_t current_format;
bool is_bulk;
uint16_t bcdVDC;
uint8_t num_of_intf_altsettings;
uint8_t num_of_formats;

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;
@@ -607,3 +602,12 @@ CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = {
.id_table = NULL,
.class_driver = &rndis_class_driver
};
CLASS_INFO_DEFINE const struct usbh_class_info rndis_cdcacm_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
.bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
.bInterfaceProtocol = 0xff,
.id_table = NULL,
.class_driver = &rndis_class_driver
};

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

@@ -12,6 +12,10 @@
extern "C" {
#endif
#define USBOTG_MODE_HOST 0
#define USBOTG_MODE_DEVICE 1
#define USBOTG_MODE_OTG 2
/**
* @brief usb otg controller hardware or gpio id simulator init.
*
@@ -24,12 +28,6 @@ int usb_otg_init(uint8_t busid);
* @return On success will return 0, and others indicate fail.
*/
int usb_otg_deinit(uint8_t busid);
/**
* @brief get current role mode.
*
* @return return USBOTG_MODE_HOST or USBOTG_MODE_DEVICE.
*/
uint8_t usbotg_get_current_mode(uint8_t busid);
/* called by user */
void USBOTG_IRQHandler(uint8_t busid);

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 0x010503
#define CHERRYUSB_VERSION_STR "v1.5.3"
#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;
}
}
@@ -1143,18 +1145,26 @@ void usbd_event_suspend_handler(uint8_t busid)
void usbd_event_reset_handler(uint8_t busid)
{
struct usb_endpoint_descriptor ep0;
usbd_set_address(busid, 0);
g_usbd_core[busid].device_address = 0;
g_usbd_core[busid].configuration = 0;
g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
#ifdef CONFIG_USBDEV_ADVANCE_DESC
g_usbd_core[busid].speed = USB_SPEED_UNKNOWN;
USB_ASSERT_MSG(g_usbd_core[busid].descriptors->device_descriptor_callback != NULL,
"device_descriptor_callback is NULL\r\n");
struct usb_device_descriptor *device_desc = (struct usb_device_descriptor *)g_usbd_core[busid].descriptors->device_descriptor_callback(g_usbd_core[busid].speed);
ep0.wMaxPacketSize = device_desc->bMaxPacketSize0;
#else
ep0.wMaxPacketSize = USB_CTRL_EP_MPS;
#endif
struct usb_endpoint_descriptor ep0;
ep0.bLength = 7;
ep0.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT;
ep0.wMaxPacketSize = USB_CTRL_EP_MPS;
ep0.bmAttributes = USB_ENDPOINT_TYPE_CONTROL;
ep0.bEndpointAddress = USB_CONTROL_IN_EP0;
ep0.bInterval = 0;
@@ -1171,9 +1181,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 +1255,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 +1280,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 +1328,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 +1358,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;
}
}
@@ -1525,11 +1544,7 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
int ret;
struct usbd_bus *bus;
if (busid >= CONFIG_USBDEV_MAX_BUS) {
USB_LOG_ERR("bus overflow\r\n");
while (1) {
}
}
USB_ASSERT_MSG(busid < CONFIG_USBDEV_MAX_BUS, "bus overflow\r\n");
bus = &g_usbdev_bus[busid];
bus->reg_base = reg_base;
@@ -1558,23 +1573,18 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
int usbd_deinitialize(uint8_t busid)
{
if (busid >= CONFIG_USBDEV_MAX_BUS) {
USB_LOG_ERR("bus overflow\r\n");
while (1) {
}
}
USB_ASSERT_MSG(busid < CONFIG_USBDEV_MAX_BUS, "bus overflow\r\n");
g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT);
usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
usb_dc_deinit(busid);
g_usbd_core[busid].intf_offset = 0;
#ifdef CONFIG_USBDEV_EP0_THREAD
if (g_usbd_core[busid].usbd_ep0_mq) {
usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq);
}
if (g_usbd_core[busid].usbd_ep0_thread) {
usb_osal_thread_delete(g_usbd_core[busid].usbd_ep0_thread);
}
if (g_usbd_core[busid].usbd_ep0_mq) {
usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq);
}
#endif
return 0;

View File

@@ -33,29 +33,27 @@ struct usbh_bus g_usbhost_bus[CONFIG_USBHOST_MAX_BUS];
static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
{
uint8_t startaddr = devgen->next;
uint8_t devaddr;
uint8_t lastaddr = devgen->last;
uint8_t devaddr = lastaddr;
int index;
int bitno;
for (;;) {
devaddr = devgen->next;
if (devgen->next >= 0x7f) {
devgen->next = 2;
} else {
devgen->next++;
devaddr++;
if (devaddr > 0x7f) {
devaddr = 2;
}
if (devaddr == lastaddr) {
return -USB_ERR_NOMEM;
}
index = devaddr >> 5;
bitno = devaddr & 0x1f;
if ((devgen->alloctab[index] & (1 << bitno)) == 0) {
devgen->alloctab[index] |= (1 << bitno);
if ((devgen->alloctab[index] & (1ul << bitno)) == 0) {
devgen->alloctab[index] |= (1ul << bitno);
devgen->last = devaddr;
return (int)devaddr;
}
if (startaddr == devaddr) {
return -USB_ERR_NOMEM;
}
}
}
@@ -69,15 +67,11 @@ static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
bitno = devaddr & USB_DEV_ADDR_MARK_MASK;
/* Free the address */
if ((devgen->alloctab[index] |= (1 << bitno)) != 0) {
devgen->alloctab[index] &= ~(1 << bitno);
if ((devgen->alloctab[index] & (1ul << bitno)) != 0) {
devgen->alloctab[index] &= ~(1ul << bitno);
} else {
return -1;
}
if (devaddr < devgen->next) {
devgen->next = devaddr;
}
}
return 0;
@@ -91,7 +85,7 @@ static int usbh_free_devaddr(struct usbh_hubport *hport)
return 0;
}
static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol,
static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, uint8_t intf,
uint16_t vid, uint16_t pid)
{
struct usbh_class_info *index = NULL;
@@ -106,6 +100,9 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) {
continue;
}
if ((index->match_flags & USB_CLASS_MATCH_INTF_NUM) && !(index->bInterfaceNumber == intf)) {
continue;
}
if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) {
/* scan id table */
uint32_t i;
@@ -228,12 +225,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);
@@ -266,60 +272,6 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
return 0;
}
static void usbh_print_hubport_info(struct usbh_hubport *hport)
{
USB_LOG_RAW("Device Descriptor:\r\n");
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength);
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType);
USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB);
USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass);
USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass);
USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol);
USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0);
USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor);
USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct);
USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice);
USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer);
USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct);
USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber);
USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
USB_LOG_RAW("Config Descriptor:\r\n");
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength);
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType);
USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength);
USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces);
USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration);
USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes);
USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower);
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
USB_LOG_RAW("\tInterface Descriptor:\r\n");
USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n");
USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
}
}
}
}
static void usbh_print_setup(struct usb_setup_packet *setup)
{
(void)setup;
@@ -389,7 +341,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 +383,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 +425,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 +454,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 +473,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;
@@ -573,18 +546,25 @@ int usbh_enumerate(struct usbh_hubport *hport)
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
intf_desc = &hport->config.intf[i].altsetting[0].intf_desc;
struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol, hport->device_desc.idVendor, hport->device_desc.idProduct);
USB_ASSERT_MSG(intf_desc->bInterfaceNumber == i, "Interface number mismatch, do not support non-standard device\r\n");
struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass,
intf_desc->bInterfaceSubClass,
intf_desc->bInterfaceProtocol,
intf_desc->bInterfaceNumber,
hport->device_desc.idVendor,
hport->device_desc.idProduct);
if (class_driver == NULL) {
USB_LOG_ERR("do not support Class:0x%02x,Subclass:0x%02x,Protocl:0x%02x\r\n",
USB_LOG_ERR("Do not support Class:0x%02x, Subclass:0x%02x, Protocl:0x%02x on interface %u\r\n",
intf_desc->bInterfaceClass,
intf_desc->bInterfaceSubClass,
intf_desc->bInterfaceProtocol);
intf_desc->bInterfaceProtocol,
i);
continue;
}
hport->config.intf[i].class_driver = class_driver;
USB_LOG_INFO("Loading %s class driver\r\n", class_driver->driver_name);
USB_LOG_INFO("Loading %s class driver on interface %u\r\n", class_driver->driver_name, i);
ret = CLASS_CONNECT(hport, i);
}
@@ -600,6 +580,7 @@ void usbh_hubport_release(struct usbh_hubport *hport)
{
if (hport->connected) {
hport->connected = false;
usbh_kill_urb(&hport->ep0_urb);
usbh_free_devaddr(hport);
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->disconnect) {
@@ -607,7 +588,6 @@ void usbh_hubport_release(struct usbh_hubport *hport)
}
}
hport->config.config_desc.bNumInterfaces = 0;
usbh_kill_urb(&hport->ep0_urb);
if (hport->mutex) {
usb_osal_mutex_delete(hport->mutex);
}
@@ -622,7 +602,7 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_bas
bus->hcd.reg_base = reg_base;
/* devaddr 1 is for roothub */
bus->devgen.next = 2;
bus->devgen.last = 0x7f;
usb_slist_add_tail(&g_bus_head, &bus->list);
}
@@ -631,11 +611,7 @@ int usbh_initialize(uint8_t busid, uintptr_t reg_base)
{
struct usbh_bus *bus;
if (busid >= CONFIG_USBHOST_MAX_BUS) {
USB_LOG_ERR("bus overflow\r\n");
while (1) {
}
}
USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
bus = &g_usbhost_bus[busid];
@@ -663,11 +639,7 @@ int usbh_deinitialize(uint8_t busid)
{
struct usbh_bus *bus;
if (busid >= CONFIG_USBHOST_MAX_BUS) {
USB_LOG_ERR("bus overflow\r\n");
while (1) {
}
}
USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
bus = &g_usbhost_bus[busid];
@@ -681,6 +653,7 @@ int usbh_deinitialize(uint8_t busid)
int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
{
struct usbh_urb *urb;
volatile uint8_t retry = 3;
int ret;
if (!hport || !setup) {
@@ -693,17 +666,26 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
usbh_print_setup(setup);
resubmit:
usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
ret = usbh_submit_urb(urb);
if (ret == 0) {
ret = urb->actual_length;
}
if (ret < 0 && (ret != -USB_ERR_TIMEOUT)) {
retry--;
if (retry > 0) {
USB_LOG_WRN("Control transfer failed, errorcode %d, retrying...\r\n", ret);
goto resubmit;
}
}
usb_osal_mutex_give(hport->mutex);
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 +711,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;
@@ -782,73 +768,6 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn
return NULL;
}
static void usbh_list_all_interface_driver(struct usbh_hub *hub)
{
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
if (hport->connected) {
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
for (uint8_t j = 0; j < hub->index; j++) {
USB_LOG_RAW("\t");
}
USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n",
hport->port,
hport->dev_addr,
itf,
hport->config.intf[itf].class_driver->driver_name,
speed_table[hport->speed]);
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
hub_next = hport->config.intf[itf].priv;
if (hub_next && hub_next->connected) {
usbh_list_all_interface_driver(hub_next);
}
}
}
}
}
}
}
static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *hub)
{
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
if (hport->connected) {
USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
bus->busid,
hub->index,
hport->port,
hport->dev_addr,
hport->device_desc.idVendor,
hport->device_desc.idProduct);
usbh_print_hubport_info(hport);
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
hub_next = hport->config.intf[itf].priv;
if (hub_next && hub_next->connected) {
usbh_list_all_interface_desc(bus, hub_next);
}
}
}
}
}
}
}
static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port)
{
struct usbh_hubport *hport;
@@ -926,64 +845,341 @@ struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t
return hport;
}
static void usbh_print_hubport_info(struct usbh_hubport *hport)
{
USB_LOG_RAW("Device Descriptor:\r\n");
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength);
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType);
USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB);
USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass);
USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass);
USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol);
USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0);
USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor);
USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct);
USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice);
USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer);
USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct);
USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber);
USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
USB_LOG_RAW("Config Descriptor:\r\n");
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength);
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType);
USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength);
USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces);
USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration);
USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes);
USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower);
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
USB_LOG_RAW("\tInterface Descriptor:\r\n");
USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n");
USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
}
}
}
}
static void usbh_list_device(struct usbh_hub *hub, bool astree, bool verbose, int dev_addr, int vid, int pid)
{
static const char *speed_table[] = {
"UNKNOWN",
"low-speed",
"full-speed",
"high-speed",
"wireless",
"super-speed",
"super-speed-plus",
};
static const char *root_speed_table[] = {
"UNKNOWN",
"1.1",
"1.1",
"2.0",
"2.5",
"3.0",
"3.0",
};
static const uint16_t speed_baud[] = {
0,
12,
12,
480,
480,
5000,
10000,
};
struct usbh_bus *bus;
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
uint8_t imbuf[64];
uint8_t ipbuf[64];
const char *pimstr;
const char *pipstr;
bool imvalid = false;
bool ipvalid = false;
int ret;
bus = hub->bus;
(void)speed_table;
if (hub->is_roothub) {
if (astree) {
USB_LOG_RAW("/: Bus %02u.Port 1: Dev %u, Class=root_hub, Driver=hcd, %uM\r\n",
bus->busid, hub->hub_addr, speed_baud[hub->speed]);
} else {
if ((dev_addr < 0) || (hub->hub_addr == dev_addr)) {
if (((vid < 0) || (vid == 0xffff)) && ((pid < 0) || (pid == 0xffff))) {
USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s root hub\r\n",
bus->busid, hub->hub_addr, 0xffff, 0xffff,
"Cherry-Embedded", root_speed_table[hub->speed]);
}
}
}
}
for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
if (hport->connected) {
ret = 0;
if (hport->device_desc.iManufacturer) {
memset(imbuf, 0, sizeof(imbuf));
ret = usbh_get_string_desc(hport, hport->device_desc.iManufacturer, imbuf, sizeof(imbuf));
if (ret == 0) {
imvalid = true;
}
}
if (hport->device_desc.iProduct) {
memset(ipbuf, 0, sizeof(ipbuf));
ret = usbh_get_string_desc(hport, hport->device_desc.iProduct, ipbuf, sizeof(ipbuf));
if (ret == 0) {
ipvalid = true;
}
}
if (imvalid) {
pimstr = (const char *)imbuf;
} else {
pimstr = "Not specified Manufacturer";
}
if (ipvalid) {
pipstr = (const char *)ipbuf;
} else {
pipstr = "Not specified Product";
}
if (!astree) {
if ((dev_addr < 0) || (hport->dev_addr == dev_addr)) {
if (((vid < 0) || (vid == hport->device_desc.idVendor)) && ((pid < 0) || (pid == hport->device_desc.idProduct))) {
USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s\r\n",
bus->busid, hport->dev_addr, hport->device_desc.idVendor, hport->device_desc.idProduct,
pimstr, pipstr);
if (verbose) {
usbh_print_hubport_info(hport);
}
}
}
}
for (uint8_t intf = 0; intf < hport->config.config_desc.bNumInterfaces; intf++) {
if (hport->config.intf[intf].class_driver && hport->config.intf[intf].class_driver->driver_name) {
if (astree) {
for (uint8_t j = 0; j < hub->index; j++) {
USB_LOG_RAW(" ");
}
USB_LOG_RAW("|__ Port %u: Dev %u, If %u, ClassDriver=%s, %uM\r\n",
hport->port, hport->dev_addr, intf, hport->config.intf[intf].class_driver->driver_name, speed_baud[hport->speed]);
}
if (!strcmp(hport->config.intf[intf].class_driver->driver_name, "hub")) {
hub_next = hport->config.intf[intf].priv;
if (hub_next && hub_next->connected) {
usbh_list_device(hub_next, astree, verbose, dev_addr, vid, pid);
}
}
} else if (astree) {
for (uint8_t j = 0; j < hub->index; j++) {
USB_LOG_RAW(" ");
}
USB_LOG_RAW("|__ Port %u: Dev %u, If 0 ClassDriver=none, %uM\r\n",
hport->port, hport->dev_addr, speed_baud[hport->speed]);
}
}
}
}
}
void lsusb_help(void)
{
USB_LOG_RAW("List USB Devices\r\n"
"Usage: lsusb [options]...\r\n"
"\r\n"
"-v, --verbose\r\n"
" - increase verbosity (show descriptors)\r\n"
"-s [[bus]:][dev_addr]\r\n"
" - show only devices with specified device and/or\r\n"
" bus numbers (in decimal)\r\n"
"-d vendor:[product]\r\n"
" - show only devices with the specified vendor and\r\n"
" product ID numbers (in hexadecimal)\r\n"
"-t, --tree\r\n"
" - dump the physical USB device hierarchy as a tree\r\n"
"-V, --version\r\n"
" - show version of the cherryusb\r\n"
"-h, --help\r\n"
" - show usage and help information\r\n");
}
int lsusb(int argc, char **argv)
{
usb_slist_t *bus_list;
struct usbh_hub *hub;
struct usbh_bus *bus;
size_t flags;
int busid = -1;
int dev_addr = -1;
int vid = -1;
int pid = -1;
bool astree = false;
bool verbose = false;
if (argc < 2) {
USB_LOG_RAW("Usage: lsusb [options]...\r\n");
USB_LOG_RAW("List USB devices\r\n");
USB_LOG_RAW(" -v, --verbose\r\n");
USB_LOG_RAW(" Increase verbosity (show descriptors)\r\n");
// USB_LOG_RAW(" -s [[bus]:[devnum]]\r\n");
// USB_LOG_RAW(" Show only devices with specified device and/or bus numbers (in decimal)\r\n");
// USB_LOG_RAW(" -d vendor:[product]\r\n");
// USB_LOG_RAW(" Show only devices with the specified vendor and product ID numbers (in hexadecimal)\r\n");
USB_LOG_RAW(" -t, --tree\r\n");
USB_LOG_RAW(" Dump the physical USB device hierachy as a tree\r\n");
USB_LOG_RAW(" -V, --version\r\n");
USB_LOG_RAW(" Show version of program\r\n");
USB_LOG_RAW(" -h, --help\r\n");
USB_LOG_RAW(" Show usage and help\r\n");
return 0;
}
if (argc > 3) {
lsusb_help();
return 0;
}
flags = usb_osal_enter_critical_section();
while (argc > 1) {
argc--;
argv++;
if (strcmp(argv[1], "-V") == 0) {
USB_LOG_RAW("CherryUSB Version %s\r\n", CHERRYUSB_VERSION_STR);
}
if (!strcmp(*argv, "-V") || !strcmp(*argv, "--version")) {
USB_LOG_RAW("CherryUSB version %s\r\n", CHERRYUSB_VERSION_STR);
return 0;
} else if (!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) {
lsusb_help();
return 0;
} else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) {
verbose = true;
} else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--tree")) {
astree = true;
} else if (!strcmp(*argv, "-s")) {
if (argc > 1) {
argc--;
argv++;
if (strcmp(argv[1], "-t") == 0) {
usb_slist_for_each(bus_list, &g_bus_head)
{
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
hub = &bus->hcd.roothub;
if (*argv[0] == '-') {
continue;
}
USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
bus->busid,
hub->index,
hub->nports);
usbh_list_all_interface_driver(hub);
char *endptr;
const char *colon = strchr(*argv, ':');
(void)endptr;
if (colon != NULL) {
const char *str;
if (colon > *argv) {
busid = strtol(*argv, &endptr, 10);
}
str = colon + 1;
if (*str != '\0') {
dev_addr = strtol(str, &endptr, 10);
if (dev_addr <= 0 || dev_addr >= 128) {
dev_addr = -1;
}
}
} else {
dev_addr = strtol(*argv, &endptr, 10);
if (dev_addr <= 0 || dev_addr >= 128) {
dev_addr = -1;
}
}
}
} else if (!strcmp(*argv, "-d")) {
if (argc > 1) {
argc--;
argv++;
if (*argv[0] == '-') {
continue;
}
char *endptr;
const char *colon = strchr(*argv, ':');
(void)endptr;
if (colon == NULL) {
continue;
}
const char *str;
vid = strtol(*argv, &endptr, 16);
if (vid < 0 || vid > 0xffff) {
vid = -1;
continue;
}
str = colon + 1;
if (*str != '\0') {
pid = strtol(str, &endptr, 16);
if (pid < 0 || pid > 0xffff) {
pid = -1;
}
}
}
}
}
if (strcmp(argv[1], "-v") == 0) {
usb_slist_for_each(bus_list, &g_bus_head)
{
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
hub = &bus->hcd.roothub;
usbh_list_all_interface_desc(bus, hub);
}
if (astree) {
busid = -1;
dev_addr = -1;
vid = -1;
pid = -1;
verbose = false;
}
usb_slist_for_each(bus_list, &g_bus_head)
{
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
if (busid >= 0) {
if (bus->busid != busid) {
continue;
}
}
usbh_list_device(&bus->hcd.roothub, astree, verbose, dev_addr, vid, pid);
}
usb_osal_leave_critical_section(flags);
return 0;
}

View File

@@ -33,6 +33,7 @@ extern "C" {
#define USB_CLASS_MATCH_INTF_CLASS 0x0004
#define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008
#define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010
#define USB_CLASS_MATCH_INTF_NUM 0x0020
#define USB_CLASS_MATCH_VID_PID (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT)
#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i))
@@ -47,7 +48,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 { \
@@ -65,6 +66,7 @@ struct usbh_class_info {
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. */
uint8_t bInterfaceNumber; /* Interface number */
const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */
const struct usbh_class_driver *class_driver;
};
@@ -150,7 +152,7 @@ struct usbh_devaddr_map {
* alloctab[3]:addr from 96~127
*
*/
uint8_t next; /* Next device address */
uint8_t last; /* Last device address */
uint32_t alloctab[4]; /* Bit allocation table */
};
@@ -255,9 +257,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

@@ -5,39 +5,57 @@
*/
#include "usbotg_core.h"
#ifdef CONFIG_USB_OTG_ENABLE
#undef USB_DBG_TAG
#define USB_DBG_TAG "usbotg_core"
#include "usb_log.h"
#define CONFIG_USB_OTG_MAX_BUS CONFIG_USBHOST_MAX_BUS
struct usbotg_core_priv {
uint8_t busid;
uint32_t reg_base;
usb_osal_sem_t change_sem;
usb_osal_thread_t change_thread;
bool usbh_initialized;
bool usbd_initialized;
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base);
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base);
} g_usbotg_core[CONFIG_USBHOST_MAX_BUS];
void *device_event_callback;
void *host_event_callback;
uint8_t current_mode;
usb_osal_sem_t change_sem;
usb_osal_thread_t change_thread;
} g_usbotg_core[CONFIG_USB_OTG_MAX_BUS];
static void usbotg_host_initialize(uint8_t busid)
{
if (g_usbotg_core[busid].usbh_initialized) {
return;
}
if (g_usbotg_core[busid].usbd_initialized) {
g_usbotg_core[busid].usbd_initialized = false;
usbd_deinitialize(busid);
}
if (g_usbotg_core[busid].usbh_initialize && !g_usbotg_core[busid].usbh_initialized) {
g_usbotg_core[busid].usbh_initialized = true;
g_usbotg_core[busid].usbh_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base);
}
USB_LOG_INFO("Switch to HOST mode\r\n");
usbh_initialize(busid, g_usbotg_core[busid].reg_base);
g_usbotg_core[busid].usbh_initialized = true;
}
static void usbotg_device_initialize(uint8_t busid)
{
if (g_usbotg_core[busid].usbd_initialized) {
return;
}
if (g_usbotg_core[busid].usbh_initialized) {
g_usbotg_core[busid].usbh_initialized = false;
usbh_deinitialize(busid);
}
if (g_usbotg_core[busid].usbd_initialize && !g_usbotg_core[busid].usbd_initialize) {
g_usbotg_core[busid].usbd_initialized = true;
g_usbotg_core[busid].usbd_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base);
}
USB_LOG_INFO("Switch to DEVICE mode\r\n");
usbd_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base, g_usbotg_core[busid].device_event_callback);
g_usbotg_core[busid].usbd_initialized = true;
}
static void usbotg_rolechange_thread(void *argument)
@@ -48,58 +66,49 @@ static void usbotg_rolechange_thread(void *argument)
while (1) {
if (usb_osal_sem_take(g_usbotg_core[busid].change_sem, USB_OSAL_WAITING_FOREVER) == 0) {
if (usbotg_get_current_mode(busid) == USBOTG_MODE_HOST) {
if (g_usbotg_core[busid].current_mode == USBOTG_MODE_HOST) {
usbotg_host_initialize(busid);
} else if (usbotg_get_current_mode(busid) == USBOTG_MODE_DEVICE) {
} else if (g_usbotg_core[busid].current_mode == USBOTG_MODE_DEVICE) {
usbotg_device_initialize(busid);
}
}
}
}
int usbotg_initialize(uint8_t otg_mode, uint8_t busid, uint32_t reg_base,
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base),
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base))
int usbotg_initialize(uint8_t busid, uint32_t reg_base, void *device_event_callback, void *host_event_callback, uint8_t default_role)
{
char thread_name[32] = { 0 };
if (busid >= CONFIG_USBHOST_MAX_BUS) {
USB_LOG_ERR("bus overflow\r\n");
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
g_usbotg_core[busid].busid = busid;
g_usbotg_core[busid].reg_base = reg_base;
g_usbotg_core[busid].device_event_callback = device_event_callback;
g_usbotg_core[busid].host_event_callback = host_event_callback;
g_usbotg_core[busid].change_sem = usb_osal_sem_create(0);
if (g_usbotg_core[busid].change_sem == NULL) {
USB_LOG_ERR("Failed to create change_sem\r\n");
while (1) {
}
}
g_usbotg_core[busid].busid = busid;
g_usbotg_core[busid].reg_base = reg_base;
g_usbotg_core[busid].usbh_initialize = usbh_initialize;
g_usbotg_core[busid].usbd_initialize = usbd_initialize;
if (otg_mode == USBOTG_MODE_OTG) {
g_usbotg_core[busid].change_sem = usb_osal_sem_create(0);
if (g_usbotg_core[busid].change_sem == NULL) {
USB_LOG_ERR("Failed to create change_sem\r\n");
return -1;
}
snprintf(thread_name, 32, "usbotg%u", busid);
g_usbotg_core[busid].change_thread = usb_osal_thread_create(thread_name, CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbotg_rolechange_thread, (void *)(uintptr_t)busid);
if (g_usbotg_core[busid].change_thread == NULL) {
USB_LOG_ERR("Failed to create usbotg thread\r\n");
return -1;
}
} else {
if (otg_mode == USBOTG_MODE_HOST) {
usbotg_host_initialize(busid);
} else if (otg_mode == USBOTG_MODE_DEVICE) {
usbotg_device_initialize(busid);
snprintf(thread_name, 32, "usbotg%u", busid);
g_usbotg_core[busid].change_thread = usb_osal_thread_create(thread_name, 2048, 10, usbotg_rolechange_thread, (void *)(uintptr_t)busid);
if (g_usbotg_core[busid].change_thread == NULL) {
USB_LOG_ERR("Failed to create usbotg thread\r\n");
while (1) {
}
}
usbotg_trigger_role_change(busid, default_role);
return 0;
}
int usbotg_deinitialize(uint8_t busid, uint32_t reg_base)
int usbotg_deinitialize(uint8_t busid)
{
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
if (g_usbotg_core[busid].usbd_initialized) {
g_usbotg_core[busid].usbd_initialized = false;
usbd_deinitialize(busid);
@@ -110,28 +119,37 @@ int usbotg_deinitialize(uint8_t busid, uint32_t reg_base)
usbh_deinitialize(busid);
}
if (g_usbotg_core[busid].change_thread) {
usb_osal_thread_delete(g_usbotg_core[busid].change_thread);
}
if (g_usbotg_core[busid].change_sem) {
usb_otg_deinit(busid);
usb_osal_sem_delete(g_usbotg_core[busid].change_sem);
}
if (g_usbotg_core[busid].change_thread) {
usb_osal_thread_delete(g_usbotg_core[busid].change_thread);
}
return 0;
}
void usbotg_trigger_role_change(uint8_t busid)
void usbotg_trigger_role_change(uint8_t busid, uint8_t mode)
{
usb_osal_sem_give(g_usbotg_core[busid].change_sem);
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
g_usbotg_core[busid].current_mode = mode;
if (g_usbotg_core[busid].change_sem) {
usb_osal_sem_give(g_usbotg_core[busid].change_sem);
}
}
void USBOTG_IRQHandler(uint8_t busid)
{
if (usbotg_get_current_mode(busid) == USBOTG_MODE_HOST) {
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
if (g_usbotg_core[busid].current_mode == USBOTG_MODE_HOST && g_usbotg_core[busid].usbh_initialized) {
USBH_IRQHandler(busid);
} else if (usbotg_get_current_mode(busid) == USBOTG_MODE_DEVICE) {
} else if (g_usbotg_core[busid].current_mode == USBOTG_MODE_DEVICE && g_usbotg_core[busid].usbd_initialized) {
USBD_IRQHandler(busid);
}
}
}
#endif /* CONFIG_USB_OTG_ENABLE */

View File

@@ -10,22 +10,15 @@
extern "C" {
#endif
#define USBOTG_MODE_UNKNOWN 0
#define USBOTG_MODE_OTG 1
#define USBOTG_MODE_HOST 2
#define USBOTG_MODE_DEVICE 3
#include "usbd_core.h"
#include "usbh_core.h"
#include "usb_otg.h"
int usbotg_initialize(uint8_t otg_mode, uint8_t busid, uint32_t reg_base,
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base),
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base));
int usbotg_deinitialize(uint8_t busid, uint32_t reg_base);
int usbotg_initialize(uint8_t busid, uint32_t reg_base, void *device_event_callback, void *host_event_callback, uint8_t default_role);
int usbotg_deinitialize(uint8_t busid);
/* called by user */
void usbotg_trigger_role_change(uint8_t busid);
void usbotg_trigger_role_change(uint8_t busid, uint8_t mode);
#ifdef __cplusplus
}

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,19 +274,26 @@ 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)) {
/* shell failed to be initialized */
printf("Failed to initialize shell\r\n");
USB_LOG_RAW("Failed to initialize shell\r\n");
for (;;) {
;
}
}
#endif
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &adb_descriptor);
#else

View File

@@ -297,11 +297,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value); /* uac1 can only use 10.14 */
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
#endif
printf("OPEN1\r\n");
USB_LOG_INFO("OPEN1\r\n");
} else {
tx_flag = 1;
ep_tx_busy_flag = false;
printf("OPEN2\r\n");
USB_LOG_INFO("OPEN2\r\n");
}
}
@@ -309,11 +309,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
{
if (intf == 1) {
rx_flag = 0;
printf("CLOSE1\r\n");
USB_LOG_INFO("CLOSE1\r\n");
} else {
tx_flag = 0;
ep_tx_busy_flag = false;
printf("CLOSE2\r\n");
USB_LOG_INFO("CLOSE2\r\n");
}
}

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,232 @@
/*
* 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);
}
static int cdc_acm_enter(int argc, char **argv)
{
(void)argc;
(void)argv;
finsh_set_device("usb-acm0");
rt_console_set_device("usb-acm0");
return 0;
}
MSH_CMD_EXPORT(cdc_acm_enter, cdc_acm_enter);
static int cdc_acm_exit(int argc, char **argv)
{
(void)argc;
(void)argv;
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
return 0;
}
MSH_CMD_EXPORT(cdc_acm_exit, cdc_acm_exit);

View File

@@ -68,6 +68,7 @@ static const char *string_descriptors[] = {
"CherryUSB", /* Manufacturer */
"CherryUSB CDC ECM DEMO", /* Product */
"2022123456", /* Serial Number */
"aabbccddeeff", /* ecm mac address */
};
static const uint8_t *device_descriptor_callback(uint8_t speed)

View File

@@ -189,14 +189,14 @@ void usbd_rndis_data_send_done(uint32_t len)
#error rndis must enable RT_LWIP_DHCP
#endif
#ifndef LWIP_USING_DHCPD
#error rndis must enable LWIP_USING_DHCPD
#ifdef LWIP_USING_DHCPD
#include <dhcp_server.h>
#endif
#include <rtthread.h>
#include <rtdevice.h>
#include <netif/ethernetif.h>
#include <dhcp_server.h>
#include <netdev.h>
struct eth_device rndis_dev;
@@ -250,7 +250,14 @@ void rndis_lwip_init(void)
eth_device_init(&rndis_dev, "u0");
eth_device_linkchange(&rndis_dev, RT_TRUE);
#ifdef LWIP_USING_DHCPD
dhcpd_start("u0");
#else
struct netdev *netdev = netdev_get_by_name("u0");
if (netdev) {
netdev_dhcp_enabled(netdev, RT_TRUE);
}
#endif
}
void usbd_rndis_data_recv_done(uint32_t len)

View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_rndis.h"
#include "rndis_protocol.h"
#include "mongoose.h"
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
#error Do not define CONFIG_USBDEV_RNDIS_USING_LWIP in this demo
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02
#define CDC_INT_EP 0x83
/*!< config descriptor size */
#define USB_CONFIG_SIZE (9 + CDC_RNDIS_DESCRIPTOR_LEN)
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_hs[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_HS, 0x02),
};
static const uint8_t config_descriptor_fs[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_FS, 0x02),
};
static const uint8_t device_quality_descriptor[] = {
USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, 0x01),
};
static const uint8_t other_speed_config_descriptor_hs[] = {
USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_FS, 0x02),
};
static const uint8_t other_speed_config_descriptor_fs[] = {
USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_HS, 0x02),
};
static const char *string_descriptors[] = {
(const char[]){ 0x09, 0x04 }, /* Langid */
"CherryUSB", /* Manufacturer */
"CherryUSB RNDIS MONGOOSE DEMO", /* Product */
"2025123456", /* Serial Number */
};
static const uint8_t *device_descriptor_callback(uint8_t speed)
{
(void)speed;
return device_descriptor;
}
static const uint8_t *config_descriptor_callback(uint8_t speed)
{
if (speed == USB_SPEED_HIGH) {
return config_descriptor_hs;
} else if (speed == USB_SPEED_FULL) {
return config_descriptor_fs;
} else {
return NULL;
}
}
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
{
(void)speed;
return device_quality_descriptor;
}
static const uint8_t *other_speed_config_descriptor_callback(uint8_t speed)
{
if (speed == USB_SPEED_HIGH) {
return other_speed_config_descriptor_hs;
} else if (speed == USB_SPEED_FULL) {
return other_speed_config_descriptor_fs;
} else {
return NULL;
}
}
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
{
(void)speed;
if (index >= (sizeof(string_descriptors) / sizeof(char *))) {
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,
.other_speed_descriptor_callback = other_speed_config_descriptor_callback,
.string_descriptor_callback = string_descriptor_callback,
};
static uint8_t rndis_mac[6] = { 0x20, 0x89, 0x84, 0x6A, 0x96, 0xAA };
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[USB_ALIGN_UP(CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE, CONFIG_USB_ALIGN_SIZE)];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[USB_ALIGN_UP(CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE, CONFIG_USB_ALIGN_SIZE)];
volatile bool g_rndis_tx_busy_flag = false;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
(void)busid;
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:
g_rndis_tx_busy_flag = false;
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
static struct mg_tcpip_if *s_ifp;
void usbd_rndis_data_recv_done(uint32_t len)
{
(void)len;
rndis_data_packet_t *hdr;
uint8_t *buf;
hdr = (rndis_data_packet_t *)g_rndis_rx_buffer;
buf = (uint8_t *)hdr + hdr->DataOffset + sizeof(rndis_generic_msg_t);
mg_tcpip_qwrite((void *)buf, hdr->DataLength, s_ifp);
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
}
void usbd_rndis_data_send_done(uint32_t len)
{
(void)len;
g_rndis_tx_busy_flag = false;
}
static size_t usb_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp)
{
(void)ifp;
rndis_data_packet_t *hdr;
if (!usb_device_is_configured(0))
return 0;
hdr = (rndis_data_packet_t *)g_rndis_tx_buffer;
memset(hdr, 0, sizeof(rndis_data_packet_t));
hdr->MessageType = REMOTE_NDIS_PACKET_MSG;
hdr->MessageLength = sizeof(rndis_data_packet_t) + len;
hdr->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_generic_msg_t);
hdr->DataLength = len;
memcpy(g_rndis_tx_buffer + sizeof(rndis_data_packet_t), buf, len);
g_rndis_tx_busy_flag = true;
usbd_rndis_start_write(g_rndis_tx_buffer, sizeof(rndis_data_packet_t) + len);
while (g_rndis_tx_busy_flag) {
}
return len;
}
static bool usb_poll(struct mg_tcpip_if *ifp, bool s1)
{
(void)ifp;
return s1 ? usb_device_is_configured(0) : false;
}
struct mg_tcpip_driver driver = { .tx = usb_tx, .poll = usb_poll };
struct usbd_interface intf0;
struct usbd_interface intf1;
struct mg_mgr mgr; // Initialise Mongoose event manager
void cdc_rndis_mongoose_init(uint8_t busid, uint32_t reg_base)
{
mg_mgr_init(&mgr); // and attach it to the interface
static struct mg_tcpip_if mif = { .mac = { 2, 0, 1, 2, 3, 0x77 },
.enable_dhcp_server = true,
.driver = &driver,
.recv_queue.size = 4096 };
s_ifp = &mif;
mif.ip = mg_htonl(MG_U32(192, 168, 7, 1));
mif.mask = mg_htonl(MG_U32(255, 255, 255, 0));
mg_tcpip_init(&mgr, &mif);
web_init(&mgr);
usbd_desc_register(busid, &cdc_descriptor);
usbd_add_interface(busid, usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, rndis_mac));
usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, rndis_mac));
usbd_initialize(busid, reg_base, usbd_event_handler);
}
// call mg_mgr_poll(&mgr, 0); in main loop

BIN
demo/mongoose/mongoose.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

View File

@@ -0,0 +1,22 @@
#pragma once
// See https://mongoose.ws/documentation/#build-options
#define MG_ARCH MG_ARCH_CUSTOM
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#define MG_ENABLE_TCPIP 1
#define MG_ENABLE_CUSTOM_MILLIS 1
#define MG_ENABLE_CUSTOM_RANDOM 1
#define MG_ENABLE_PACKED_FS 1
#define MG_IO_SIZE 1460

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"
@@ -236,7 +236,7 @@ int usb_msc_fatfs_test()
while (write_size > 0) {
res_sd = f_write(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum);
if (res_sd != FR_OK) {
printf("Write file failed, cause: %s\n", res_sd);
USB_LOG_RAW("Write file failed, cause: %s\n", res_sd);
goto unmount;
}
write_size -= BUF_SIZE;
@@ -262,7 +262,7 @@ int usb_msc_fatfs_test()
while (write_size > 0) {
res_sd = f_read(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum);
if (res_sd != FR_OK) {
printf("Read file failed, cause: %s\n", res_sd);
USB_LOG_RAW("Read file failed, cause: %s\n", res_sd);
goto unmount;
}
write_size -= BUF_SIZE;
@@ -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;
@@ -465,11 +469,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
audio_rx_flag = 1;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, AUDIO_OUT_EP, audio_read_buffer, AUDIO_OUT_PACKET);
printf("OPEN1\r\n");
USB_LOG_RAW("OPEN1\r\n");
} else if (intf == 4) {
audio_tx_flag = 1;
audio_iso_tx_busy = false;
printf("OPEN2\r\n");
USB_LOG_RAW("OPEN2\r\n");
}
}
@@ -477,11 +481,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
{
if (intf == 3) {
audio_rx_flag = 0;
printf("CLOSE1\r\n");
USB_LOG_RAW("CLOSE1\r\n");
} else if (intf == 4) {
audio_tx_flag = 0;
audio_iso_tx_busy = false;
printf("CLOSE2\r\n");
USB_LOG_RAW("CLOSE2\r\n");
}
}

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.3'
version = '1.5.3'
# -- 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

@@ -1,2 +1,5 @@
usbd_audiov1
===============
.. note:: 在使用windows 时当修改描述符任意参数时必须同步修改字符串描述符并且卸载驱动否则windows会认为设备未更改继续使用旧的驱动导致无法识别设备。Linux 不受此限制。

View File

@@ -1,2 +1,6 @@
usbd_audiov2
===============
.. note:: 在使用windows 时当修改描述符任意参数时必须同步修改字符串描述符并且卸载驱动否则windows会认为设备未更改继续使用旧的驱动导致无法识别设备。Linux 不受此限制。
.. note:: windows 10 uac2.0 功能不完善,请使用 windows 11 测试uac2.0 功能。Linux 不受此限制。

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**
@@ -139,26 +150,10 @@ USB Device 移植要点
.. figure:: img/stm32_8.png
- 如果使用 dwc2 ip需要增加 **dwc2/usb_glue_st.c** 文件,并`usb_config.h` 中实现以下宏:
- 如果使用 fsdev ipV1.5.0 开始需要增加 **fsdev/usb_glue_st.c**`usb_config.h` 中实现以下宏,具体数值不同芯片不一样
.. code-block:: C
// 以下细节如有出入,请对照 stm32xxx.h 文件修改
// 需要根据硬件实际的 fifo 深度进行修改,默认是最基础的配置
#define CONFIG_USBDEV_EP_NUM 6
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1012 - 16 * 6)
#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)
- 如果使用 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 +172,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 +183,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 +194,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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

View File

@@ -80,6 +80,21 @@ 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 RNDIS 网卡
-----------------------
演示 USB Host 驱动手机,手机开启 USB 共享网络即可使用 RNDIS 。
.. figure:: img/usbhost_rndis.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: 8.2 MiB

View File

@@ -7,20 +7,25 @@
.. 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
@@ -34,5 +39,5 @@
.. figure:: img/rndistx.png
.. figure:: img/rndisrx.png
- 定制化 class 驱动或者 IP 驱动
- 定制化 class 驱动或者 IP 驱动适配
- 技术支持相关

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