153 Commits

Author SHA1 Message Date
sakumisu
44dc3c00f6 docs: release v1.4.3
Signed-off-by: sakumisu <1203593632@qq.com>
2025-03-04 18:54:30 +08:00
sakumisu
4d5aa30778 update(cherrymp): remove malloc free
Signed-off-by: sakumisu <1203593632@qq.com>
2025-03-04 17:13:02 +08:00
sakumisu
e581097309 fix(core/usbd_core): fix two bugs
- fix current_desc_len += p[DESC_bLength] before p+= p[DESC_bLength]
- fix reset all eps when alt_setting=0

Signed-off-by: sakumisu <1203593632@qq.com>
2025-03-04 17:13:02 +08:00
sakumisu
6378fb88d0 update(port/kinetis): add MCXA156 support
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-26 20:49:09 +08:00
sakumisu
db0f5475b4 fix(port/ch32): add EPn_SET_TX_LEN for mps
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-25 22:16:09 +08:00
Chen Leeren
27c307abed Add ch585 usbhs dc 2025-02-25 22:14:09 +08:00
Chen Leeren
374e6d6e4d Fix ch58x fs ip send bug 2025-02-25 22:14:09 +08:00
sakumisu
c09ceb2537 fix(demo): split feedback caculate macro with AUDIO_FREQ_TO_FEEDBACK_XS and AUDIO_FEEDBACK_TO_BUF_XS
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-25 22:12:16 +08:00
sakumisu
56afada2cc chore: fix wformat warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-22 21:48:25 +08:00
sakumisu
8ac0b65b30 fix(port/dwc2/usb_glue_st): set GCCFG zero in host for stm32h7rs
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-22 19:12:51 +08:00
sakumisu
68434ccf7d update(demo): add cdc simple transfer for winusb2.0+cdc demo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-16 20:29:05 +08:00
sakumisu
17a591f719 update(osal/idf): reduce tx fifo for more space for ep5 & ep6
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-16 20:26:30 +08:00
sakumisu
23d2327a52 fix(core/usbd_core): fix return with break in ep0 thread
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-12 13:01:12 +08:00
sakumisu
de7a73bc2f update(port/dwc2/usb_glue_esp): add freertos/task.h for old esp-idf
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-11 21:28:50 +08:00
sakumisu
147dc4ab5d fix(core/usbh_core): check hport is valid in usbh_control_transfer
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-09 21:53:12 +08:00
sakumisu
20c298b6ba docs: update readme
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-09 15:33:53 +08:00
sakumisu
0c5d2ad729 feat(class/hid): add HID_X_DESCRIPTOR_INIT macro
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-08 22:59:09 +08:00
sakumisu
e90b29c2e7 feat(port/ehci): add t113 glue
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-08 22:45:23 +08:00
sakumisu
ac6db49d00 fix(core/usbh_core): return valid hport which is connected
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-07 20:15:08 +08:00
sakumisu
43e6b5b1b1 fix(demo): fix typo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-06 20:10:17 +08:00
sakumisu
40122200d1 chore: add more header path
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-05 22:49:13 +08:00
sakumisu
e85d898503 update(demo): add CONFIG_USBDEV_ADVANCE_DESC template
Signed-off-by: sakumisu <1203593632@qq.com>
2025-02-01 19:23:22 +08:00
sakumisu
e592a548e9 feat(core/usbd_core): add ep0 setup handler into thread feature 2025-02-01 14:45:02 +08:00
sakumisu
afc9213cd1 fix(port/dwc2/usb_hc_dwc2): fix warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-26 23:37:11 +08:00
sakumisu
0826c164da chore(kconfig): add rp2040
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-26 20:01:27 +08:00
sakumisu
609c85db68 update(platform/rtthread/usbh_dfs): move mount into another thread
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-26 19:56:39 +08:00
sakumisu
d3aafb2174 update(port/rp2040/usb_hc_rp2040): add lock for ep0
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-26 15:19:34 +08:00
sakumisu
95baa7845c chore: fix wformat warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-26 13:18:50 +08:00
sakumisu
c827c2e50b update(class/msc/usbh_msc): move msc scsi commands out to prevent blocking enum thread
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-26 12:50:48 +08:00
sakumisu
49d9775a1b feat(port/rp2040): update rp2040 host driver, use irq_add_shared_handler to register irq handler
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-25 19:11:27 +08:00
sakumisu
5573472397 fix(port/musb/usb_hc_musb): fix musb_write_packet size with urb->transfer_buffer_length
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-25 19:08:15 +08:00
sakumisu
fd033f25c5 feat(core/usbh_core): add usbh_printf_setup api for debug
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-25 19:08:15 +08:00
sakumisu
3e9f2b7777 docs: update hpmicro logo 2025-01-24 17:45:39 +08:00
sakumisu
efbfc9d70f update(port/template): update template
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-23 23:04:34 +08:00
sakumisu
f447de38dc update(port/rp2040): init ep_control & buffer_control in usb_dc_init
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-23 22:28:31 +08:00
sakumisu
8f44b8bad8 feat(platform/nuttx): update fs & net & cdcacm support
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-23 17:58:53 +08:00
sakumisu
c399be3ea2 feat(common): add usb_phyaddr2ramaddr & usb_ramaddr2phyaddr macro
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-22 17:54:54 +08:00
chenzhihong007
1aa2d038aa osal: fix rtthread usb_osal_thread_delete() API (#288)
Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2025-01-22 10:28:55 +08:00
sakumisu
6769eac6e0 feat(osal): add argument macro for different os, especially for nuttx
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-20 18:23:59 +08:00
sakumisu
646e84bedc update(platform/nuttx): add more macros check for net and msc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-20 18:20:21 +08:00
sakumisu
322595b910 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-19 21:23:26 +08:00
sakumisu
ea27f5b238 feat(port/rp2040): update rp2040 driver to latest
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-19 20:46:12 +08:00
sakumisu
d4940ebd22 update(nimble): remove nimble submodule, because it costs time to pull
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-19 17:38:43 +08:00
sakumisu
e1398982f3 update(platform/usbd_msc_blkdev): add rtt blkdev for msc here
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-19 17:34:32 +08:00
sakumisu
76b7a0172b update(class/wireless/usbd_rndis): support transfer api for enet & wireless without lwip
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-16 18:17:50 +08:00
sakumisu
6c3b828e77 update(class/msc/usbh_msc): add retry macro
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-16 16:49:58 +08:00
sakumisu
0a295ee5eb fix(audio): fix audio feedback value caculation
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-16 16:29:13 +08:00
chenzhihong007
5b74cecc4a [update] class: msc host: update msc host class stack (#285)
- use CONFIG_USBHOST_MSC_TIMEOUT as inquiry timeout
- separate cbw/csw from g_msc_buf
- try again ready check when device not ready
- print errcode in error log

Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2025-01-16 10:48:11 +08:00
sakumisu
99e2e6bfd4 feat(core/otg): add otg framework
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-15 17:11:27 +08:00
sakumisu
64394bf246 update: add USBH_IRQHandler & USBD_IRQHandler function declaration
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-15 17:10:19 +08:00
sakumisu
1a1b475523 update(port): add ehci/ohci/dwc2 dcache support
Signed-off-by: sakumisu <1203593632@qq.com>
2025-01-15 17:09:22 +08:00
sakumisu
a1ac569236 update(demo): add macro for caculating feedback value 2025-01-13 21:28:06 +08:00
sakumisu
570d2b5ff8 feat(demo): add feedback for audio v1 speaker template 2024-12-28 17:48:54 +08:00
sakumisu
cc9c226aba feat(demo): add feedback for audio v2 speaker template 2024-12-28 16:50:25 +08:00
sakumisu
1be34f4d36 fix(core/usbd_core): fix ep config for more eps when call usbd_set_interface 2024-12-28 16:43:19 +08:00
sakumisu
515b83e0f8 docs: release v1.4.2 2024-12-23 20:04:02 +08:00
sakumisu
be6537637c chore: fix missing license 2024-12-23 20:01:05 +08:00
yangpeng
e6801fcbb8 修复VID/PID匹配逻辑 2024-12-20 16:37:59 +08:00
sakumisu
75e6dc6300 update(port/dwc2/usb_glue_gd): add check for ep 2024-12-19 21:20:33 +08:00
sakumisu
effee4d4c2 update(port/dwc2/usb_glue_at): import system_core_clock 2024-12-16 21:30:26 +08:00
sakumisu
05b46c8bad update(port/dwc2/usb_glue_st): support stm32h7rs 2024-12-16 20:55:02 +08:00
sakumisu
ddc19a9d65 update(port/dwc2/usb_dc_dwc2): support up to 16 endpoints 2024-12-16 20:53:52 +08:00
sakumisu
886f1ec6b4 fix warning 2024-12-09 20:53:02 +08:00
sakumisu
7980cb056c docs: update rst 2024-12-09 20:18:07 +08:00
sakumisu
f86443a70b update(port/ohci): update ohci common code 2024-12-09 20:17:50 +08:00
sakumisu
bfc1139d80 docs: add vendor rst 2024-12-04 23:04:12 +08:00
sakumisu
8d2afc1540 update(port/ehci/usb_glue_aic): add check for CONFIG_USB_OHCI_HCOR_OFFSET 2024-12-04 22:47:08 +08:00
sakumisu
87b8a4ad7f docs: update rst 2024-12-01 20:59:32 +08:00
sakumisu
9ff35e9020 update(port/dwc2/usb_hc_dwc2): do not support hs hub with ls/fs device 2024-11-29 22:42:54 +08:00
sakumisu
a03a9cd481 chore: add canaan logo 2024-11-29 22:41:56 +08:00
sakumisu
88d57eb99b update(cherrymp): use own osal 2024-11-28 18:25:47 +08:00
sakumisu
5850e27743 update(port/fsdev): add check for iso, we do not support 2024-11-27 22:14:05 +08:00
sakumisu
015aa77487 docs: update rst 2024-11-27 20:17:05 +08:00
sakumisu
4416dfa5cf fix(class/cdc/usbd_cdc_ecm): fix missing return 2024-11-27 19:37:42 +08:00
sakumisu
d874bed6aa chore: add missing license 2024-11-26 21:27:22 +08:00
sakumisu
7f75da270f update(cherrymp): change mq to sem for fast run 2024-11-26 21:04:14 +08:00
sakumisu
1a39169f6e update(port/dwc2/usb_dc_dwc2): clear crst bit because some mcu cannot be self-clearing, refs:#276 2024-11-25 21:03:51 +08:00
Zhihong Chen
82a0d243f8 usbd_video: use pingpang buffer to improve tx performance
- use pingpang buffer to improve tx performance

Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2024-11-25 16:55:28 +08:00
sakumisu
ac3be8cb3a update(class/audio): change volume unit with dB, fix uac2.0 volume range 2024-11-25 16:21:25 +08:00
sakumisu
a72ecd2202 update: change memcpy to fast memcpy 2024-11-24 23:04:27 +08:00
sakumisu
c6bdacee6d docs: add share rst 2024-11-21 21:42:03 +08:00
sakumisu
ea03856337 fix warning 2024-11-21 21:00:10 +08:00
sakumisu
1c1217f8fa fix(port/dwc2/usb_dc_dwc2): do not clear other intr bits 2024-11-21 20:57:24 +08:00
Zhihong Chen
093a1836f0 demo: video_static_h264_template.c: fix end brace
Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2024-11-18 17:31:02 +08:00
Zhihong Chen
70ef616676 HPMicro: update hpmicro port files
Signed-off-by: Zhihong Chen <zhihong.chen@hpmicro.com>
2024-11-18 17:31:02 +08:00
sakumisu
6517919bd2 refactor(class/video/usbd_video): refactor video stream transfer, support n frames in one transfer 2024-11-16 22:35:58 +08:00
sakumisu
2b72d8c6d8 chore(scons): add kendryte config 2024-11-13 22:44:44 +08:00
sakumisu
261502f3b2 fix(cherrymp): fix bool to uint32_t 2024-11-13 22:44:38 +08:00
sakumisu
e3ff8ffe6a update(demo): set hid busy before write 2024-11-13 21:49:58 +08:00
sakumisu
24fc172ad8 update(demo/usbd_rndis): update send & recv done api, add check for this demo 2024-11-11 21:50:13 +08:00
sakumisu
58d552d03d update(class/cdc/usbd_cdc_ecm): support transfer api for enet & wireless without lwip 2024-11-11 21:48:13 +08:00
sakumisu
d0edc30c11 update(demo/usb_host): move test macro before run api 2024-11-11 21:44:33 +08:00
sakumisu
6ea1e2f94f update(osal/freertos): update usb_osal_mq_recv and usb_osal_mq_send for isr api 2024-11-06 20:14:35 +08:00
sakumisu
037c2a8323 update(platform/rtthread): remove unused idle task check 2024-11-04 20:07:43 +08:00
sakumisu
608ee773de chore(cmake): update idf config for lwip & freertos 2024-11-04 20:07:19 +08:00
sakumisu
c51a6f35a6 feat(class/aoa): add usb aoa host 2024-10-31 21:45:19 +08:00
sakumisu
a13bee0663 feat(core/usbh_core): add usbh_find_hubport api 2024-10-31 21:45:19 +08:00
sakumisu
fd1baa62df update(osal/usb_osal_thread): implement usb_osal_sem_reset 2024-10-31 21:45:19 +08:00
sakumisu
6e6fdda62a update(port/ehci/usb_glue_aic): remove lsusb shell, add check for ehci configflag 2024-10-31 21:45:19 +08:00
Dozingfiretruck
f02ff21cfb add:cherryusb_config_template.h add CONFIG_USB_HS configuration description 2024-10-31 12:28:32 +08:00
sakumisu
d6aae26371 update(class/audio/usbh_auido): update audio volume and mute api, caculate volume with volume min & max 2024-10-30 22:19:37 +08:00
sakumisu
77136aa743 update(core/usbd_core): implement USB_REQUEST_GET_INTERFACE request, refs:#268 2024-10-30 22:19:14 +08:00
sakumisu
4784017f56 chore: update comment 2024-10-30 21:04:06 +08:00
electretmike
149fb046bc fix: rename class to class_code, for c++ compatibility (#269)
Co-authored-by: Michiel van Leeuwen <michiel@embeddedacoustics.com>
2024-10-30 15:11:46 +08:00
sakumisu
f437b3e51c docs: release v1.4.1 2024-10-20 20:49:36 +08:00
sakumisu
65151b9534 feat(class/video/usbd_video): add usbd_video_stream_start_write api for video split tranfer, every transfer with one ep_mps 2024-10-18 17:18:51 +08:00
sakumisu
05315b7ea5 fix(port/dwc2/usb_hc_dwc2): fix check typo 2024-10-17 09:21:31 +08:00
sakumisu
f1a1434047 chore(platform/usbh_lwip): remove Double quotation marks 2024-10-11 21:53:24 +08:00
sakumisu
a20e312b55 update(port/kinetis): update mcx glue for mcxa153/mcxc444 2024-10-11 20:02:39 +08:00
sakumisu
83b5d842c7 docs: fix some translations 2024-10-10 21:39:40 +08:00
sakumisu
e425b992be feat(port/kinetis): add kinetis usbip 2024-10-10 21:30:42 +08:00
HalfSweet
0b81f3b2a2 Update start.rst 2024-10-10 21:23:58 +08:00
HalfSweet
287eb130ac Update deploy-docs.yml 2024-10-10 21:23:58 +08:00
sakumisu
525884a00f feat(class/audio/usb_audio): add audio altsetting desc init macros 2024-09-30 16:46:58 +08:00
sakumisu
2c52445639 update(platform/none/usbh_lwip): remove freertos, use osal api 2024-09-28 14:37:36 +08:00
sakumisu
df888eb9bc update(class/wireless/usbh_rndis): reduce rndis control buffer 2024-09-28 14:32:13 +08:00
Derek Konigsberg
5a15f714f5 Reduce size of HID class request buffer
With the change from cherry-embedded#260, this buffer no longer needs to be so large.  It can be reduced to the save a lot of memory.
2024-09-28 00:27:38 +08:00
sakumisu
bb79408275 Create cppcheck.yml 2024-09-27 22:16:32 +08:00
sakumisu
2b6eebcbb2 fix(class/msc/usbh_msc): when device stalls by usbh_msc_get_maxlun, ingore error and set lun=0, refs:#259 2024-09-27 19:03:33 +08:00
sakumisu
ab59beebd4 update(class/hid/usbh_hid): export usbh_hid_get_report_descriptor api, refs:#260 2024-09-27 19:03:33 +08:00
sakumisu
c377747e67 docs: update rst 2024-09-27 19:03:33 +08:00
sakumisu
2f14ee7a7b update(port/dwc2/usb_dc_dwc2): enlarge CONFIG_USB_DWC2_TX1_FIFO_SIZE for video demo and export CONFIG_USB_DWC2_DMA_ENABLE 2024-09-27 19:03:33 +08:00
sakumisu
0d65bbc6ba fix(core/usbd_core): reset endpoint only for altsetting 0, refs:#258 2024-09-27 19:02:28 +08:00
sakumisu
76bbd09fed fix(port/dwc2/usb_dc_dwc2): set multi packet for iso in tx empty process, every transfer will reset this bits, so we need restore it. remove ununsed iso imcomplete isr 2024-09-26 21:22:36 +08:00
HalfSweet
a8ef0c4cac fix: action running permissions 2024-09-24 21:59:05 +08:00
HalfSweet
b461f4e2d1 Add issue template (#257) 2024-09-24 21:52:15 +08:00
HalfSweet
5fb7d4d0e9 Add Github Action for Documentation Builds (#256) 2024-09-24 20:14:31 +08:00
sakumisu
8cb95b04cf chore(cmake): fix cdc acm config name 2024-09-19 20:57:23 +08:00
sakumisu
df7ecdf019 docs: update memory usage 2024-09-19 20:57:05 +08:00
sakumisu
68bf529608 fix(class/msc/usbd_msc): fix warning and add check for CONFIG_USBDEV_MSC_MAX_BUFSIZE 2024-09-19 20:25:11 +08:00
sakumisu
02340e0f44 chore: static code analysis 2024-09-19 09:50:18 +08:00
CCHhui
171b36e766 fix(core/usbh_core): Fix raw_config_desc heap out of bounds 2024-09-16 22:48:35 +08:00
sakumisu
0371bb921c docs: update rst 2024-09-11 22:26:29 +08:00
sakumisu
7ec7891fe4 update(demo): set bNumConfigurations with zero in Device Qualifier Descriptor, we do not request other speed desc as default 2024-09-09 22:48:18 +08:00
sakumisu
da391c6cf9 docs: update rst framework 2024-09-08 22:12:35 +08:00
sakumisu
b56b67182a refactor(class/audio/usbh_audio): refactor getting audio control info 2024-09-08 22:12:29 +08:00
sakumisu
e6fde5efab fix(port/dwc2): fix dwc2 rx fifo size, remove divided by 4 2024-09-08 22:11:38 +08:00
sakumisu
0487af6900 fix(port/dwc2): reset dma burst then modify, clear HCINT intstatus first 2024-09-08 22:11:38 +08:00
wangyz1997
be2880a7e8 fix(port/dwc2): fix typo 2024-09-08 22:11:38 +08:00
sakumisu
97e2a38b4a chore(cmake): do not use env variable 2024-09-08 22:11:38 +08:00
sakumisu
a139a70782 update(usbh_core): add terminate char for raw_config_desc 2024-09-07 22:43:43 +08:00
sakumisu
cb6a0c2ad6 chore(cherrymp): add license 2024-09-07 22:42:27 +08:00
sakumisu
bacacdb32c update: remove uvc queue 2024-09-06 22:24:16 +08:00
sakumisu
0323ffb424 update(class/cdc): set cdc acm bFunctionProtocol to 0x00 2024-09-04 22:06:14 +08:00
sakumisu
89e93f6c93 chore(scons): fix missing libpath 2024-09-02 18:57:15 +08:00
sakumisu
1deab668ef fix(port/ehci/usb_glue_ma35d0): fix typo 2024-09-02 18:54:53 +08:00
sakumisu
fbe2e3f8a3 fix(class/msc/usbd_msc): fix missing return value 2024-09-02 18:54:11 +08:00
sakumisu
d03dfe43ca update(port/dwc2/usb_hc_dwc2): power enable at last for common with other host ip 2024-09-01 11:59:11 +08:00
sakumisu
e42e99e975 update(platform/usbh_lwip): check lwip min stack size 2024-08-31 21:01:36 +08:00
sakumisu
8a7979378d update(osal): add error log and assert when alloc fail, and stop working 2024-08-31 18:23:00 +08:00
sakumisu
a8a5d95f8f fix(platform/rtthread/usbh_dfs): fix mem free 2024-08-31 16:08:10 +08:00
sakumisu
02ac1db3ff docs: update logo 2024-08-30 20:35:35 +08:00
tyustli
0d561ea313 Update usb_dc_dwc2.c
According to DS, the status register is W1C, |= will read the register first, write 1 to the corresponding bit, then write the register, if there is more than one status, it will be cleared by mistake. I'm not sure if other IP dcd's have the same problem?
2024-08-29 09:43:11 +08:00
233 changed files with 12723 additions and 2026 deletions

85
.github/ISSUE_TEMPLATE/1-bug-report.yml vendored Normal file
View File

@@ -0,0 +1,85 @@
name: "🐞 上报bug / Bug report"
description: "提交bug以让改进软件功能 / Create a report to help us improve"
labels: ["peding"]
body:
- type: markdown
attributes:
value: |
感谢上报新的问题请填写以下信息以帮助我们更好地理解问题。请注意如果您不按模板填写issue那您的issue可能会被关闭或者删除
我们的工作语言是中文或者英文请使用这两种语言之一填写issue。
Thank you for reporting a new issue! Please fill in the following information to help us better understand the problem. Please note that if you do not fill in the issue according to the template, your issue may be closed or deleted!
Our working languages are Chinese or English, please use one of these two languages to fill in the issue.
- type: textarea
id: bug-description
attributes:
label: 描述一下这个bug / Describe the bug
description: 请使用简介并详细的语句来描述这个bug。 / A clear and concise description of what the bug is.
placeholder: 我准备……我想要……但是实际上它……了 / I am doing ... What I expect is ... What actually happening is ...
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: 复现步骤 / To Reproduce
description: 按照下面的步骤可以复现bug / Steps to reproduce the behavior
placeholder: 首先……然后……接着…… / Go to '...', Click on '....', Scroll down to '....'
validations:
required: true
- type: textarea
id: target
attributes:
label: 设备信息 / Target Device
description: 您使用的板子/芯片型号、使用的引脚、以及USB IP类型 / Your target board/chip model, the pins you used, and the type of USB IP you used
placeholder: |-
板子型号HPM5301EVKLite
引脚PA24 PA25
USB IP/
validations:
required: true
- type: textarea
id: log
attributes:
label: 日志 / Log
description: 请提供输出 log
placeholder: |-
[D/USB] EP0 send 18 bytes, 0 remained
[D/USB] EP0 recv out status
[D/USB] EP0 send 0 bytes, 0 remained
[D/USB] EP0 send 18 bytes, 0 remained
[D/USB] EP0 recv out status
validations:
required: true
- type: markdown
attributes:
value: |
以下的部分仅在移植的时候需要填写,如果不是移植问题,请忽略这部分。
The following section is only required when porting, if it is not a porting issue, please ignore this section.
- type: textarea
id: configure
attributes:
label: 配置 / Configuration
description: 请确认 USB 中断,时钟,引脚,寄存器地址是否正确,并截图 / Please confirm that the USB interrupt, clock, pin, and register address are correct, and provide a screenshot
- type: textarea
id: USBIrq
attributes:
label: USB中断 / USB Interrupt
description: 请确认是否能进入USB中断
- type: textarea
id: cache
attributes:
label: 缓存 / Cache
description: 芯片是否带有 cache功能是否做了 no cache 处理,并截图 / Whether the chip has a cache function, whether no cache processing is done, and provide a screenshot
- type: checkboxes
id: bussiness
attributes:
label: 商业 / Business
description: 是否流片并销售 / Whether it is mass-produced and sold
options:
- label: 是 / Yes

17
.github/workflows/cppcheck.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: Cppcheck action
on:
push:
pull_request:
jobs:
build:
name: cppcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: cppcheck
shell: bash
run: |
sudo apt install cppcheck
cppcheck --enable=warning,portability,performance --language=c --platform=unix32 --std=c99 --force . -i third_party/ -i class/template -i port/template/

28
.github/workflows/deploy-docs.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: Deploy docs
on:
push:
branches:
- master
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- uses: ammaraskar/sphinx-action@8.0.2
with:
docs-folder: "docs/"
- uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: docs/build/html

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[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
[submodule "third_party/nimble-1.6.0/nimble"]
path = third_party/nimble-1.6.0/nimble
url = https://github.com/sakumisu/mynewt-nimble.git

View File

@@ -1,10 +1,11 @@
cmake_minimum_required(VERSION 3.15)
if(DEFINED ENV{BL_SDK_BASE})
if(BL_SDK_BASE)
set(CONFIG_CHERRYUSB_DEVICE 1)
set(CONFIG_CHERRYUSB_DEVICE_CDC 1)
set(CONFIG_CHERRYUSB_DEVICE_CDC_ACM 1)
set(CONFIG_CHERRYUSB_DEVICE_HID 1)
set(CONFIG_CHERRYUSB_DEVICE_MSC 1)
set(CONFIG_CHERRYUSB_DEVICE_AUDIO 1)
set(CONFIG_CHERRYUSB_DEVICE_VIDEO 1)
set(CONFIG_CHERRYUSB_DEVICE_DCD "bl")
@@ -35,7 +36,7 @@ sdk_library_add_sources(${cherryusb_srcs})
sdk_library_add_sources(platform/none/usbh_lwip.c)
elseif(DEFINED ENV{HPM_SDK_BASE})
elseif(HPM_SDK_BASE)
set(CONFIG_CHERRYUSB_HOST 1)
set(CONFIG_CHERRYUSB_HOST_CDC_ACM 1)
set(CONFIG_CHERRYUSB_HOST_CDC_ECM 1)
@@ -76,10 +77,14 @@ set(ldfragments "osal/idf/linker.lf")
if(CONFIG_CHERRYUSB_HOST_CDC_ECM OR CONFIG_CHERRYUSB_HOST_CDC_RNDIS OR CONFIG_CHERRYUSB_HOST_CDC_NCM
OR CONFIG_CHERRYUSB_HOST_ASIX OR CONFIG_CHERRYUSB_HOST_RTL8152 OR CONFIG_CHERRYUSB_HOST_BL616)
list(APPEND cherryusb_srcs platform/none/usbh_lwip.c)
idf_component_get_property(lwip lwip COMPONENT_LIB)
target_compile_definitions(${lwip} PRIVATE "-DPBUF_POOL_BUFSIZE=1600")
endif()
idf_component_get_property(freertos_include freertos ORIG_INCLUDE_PATH)
idf_component_register(SRCS ${cherryusb_srcs}
INCLUDE_DIRS ${cherryusb_incs}
INCLUDE_DIRS ${cherryusb_incs} ${freertos_include}
PRIV_REQUIRES usb
LDFRAGMENTS ${ldfragments}
)

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

27
Kconfig
View File

@@ -38,6 +38,8 @@ if CHERRYUSB
bool "dwc2_gd"
config CHERRYUSB_DEVICE_DWC2_HC
bool "dwc2_hc"
config CHERRYUSB_DEVICE_DWC2_KENDRYTE
bool "dwc2_kendryte"
config CHERRYUSB_DEVICE_DWC2_CUSTOM
bool "dwc2_custom"
config CHERRYUSB_DEVICE_MUSB_ES
@@ -48,16 +50,24 @@ if CHERRYUSB
bool "musb_bk"
config CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_DEVICE_KINETIS_MCX
bool "kinetis_mcx"
config CHERRYUSB_DEVICE_KINETIS_MM32
bool "kinetis_mm32"
config CHERRYUSB_DEVICE_KINETIS_CUSTOM
bool "kinetis_custom"
config CHERRYUSB_DEVICE_CHIPIDEA_MCX
bool "chipidea_mcx"
config CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM
bool "chipidea_mcx"
bool "chipidea_custom"
config CHERRYUSB_DEVICE_BL
bool "bouffalo"
config CHERRYUSB_DEVICE_HPM
bool "hpm"
config CHERRYUSB_DEVICE_AIC
bool "aic"
config CHERRYUSB_DEVICE_RP2040
bool "rp2040"
config CHERRYUSB_DEVICE_CH32
bool "ch32"
config CHERRYUSB_DEVICE_PUSB2
@@ -185,6 +195,8 @@ if CHERRYUSB
bool "dwc2_esp"
config CHERRYUSB_HOST_DWC2_HC
bool "dwc2_hc"
config CHERRYUSB_HOST_DWC2_KENDRYTE
bool "dwc2_kendryte"
config CHERRYUSB_HOST_DWC2_CUSTOM
bool "dwc2_custom"
config CHERRYUSB_HOST_MUSB_ES
@@ -201,6 +213,14 @@ if CHERRYUSB
bool "xhci_phytium"
config CHERRYUSB_HOST_XHCI_CUSTOM
bool "xhci"
config CHERRYUSB_HOST_KINETIS_MCX
bool "kinetis_mcx"
config CHERRYUSB_HOST_KINETIS_MM32
bool "kinetis_mm32"
config CHERRYUSB_HOST_KINETIS_CUSTOM
bool "kinetis_custom"
config CHERRYUSB_HOST_RP2040
bool "rp2040"
endchoice
config CHERRYUSB_HOST_CDC_ACM
@@ -283,6 +303,11 @@ if CHERRYUSB
prompt "Enable usb pl2303 driver"
default n
config CHERRYUSB_HOST_AOA
bool
prompt "Enable usb aoa driver"
default n
config USBHOST_PLATFORM_CDC_ECM
bool

View File

@@ -1,8 +1,18 @@
# CherryUSB
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">CherryUSB</h1>
<p align="center">
<a href="https://github.com/cherry-embedded/CherryUSB/releases"><img src="https://img.shields.io/github/release/cherry-embedded/CherryUSB.svg"><a>
<a href="https://github.com/cherry-embedded/CherryUSB/blob/master/LICENSE"><img src="https://img.shields.io/github/license/cherry-embedded/CherryUSB.svg?style=flat-square"></a>
<a href="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml"><img src="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml/badge.svg"> </a>
<a href="https://discord.com/invite/wFfvrSAey8"><img src="https://img.shields.io/badge/Discord-blue?logo=discord&style=flat-square"> </a>
</p>
[中文版](./README_zh.md)
<p align="center">
<a href="./README_zh.md">中文</a>
|
<a href="./README.md">English</a>
</p>
CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP.
CherryUSB is a tiny and beautiful, high performance and portable USB host and device stack for embedded system with USB IP.
![CherryUSB](CherryUSB.svg)
@@ -22,7 +32,7 @@ In order to make it easier for users to learn USB basics, enumeration, driver lo
In order to facilitate the use of the USB interface and to take into account the fact that users have learned about uart and dma, the following advantages have been designed for the data sending and receiving class of interface:
- Equivalent to using uart tx dma/uart rx dma
- There is no limit to the length of send and receive, the user does not need to care about the USB packetization process (the porting driver does the packetization process)
- There is no limit to the length of send and receive, the user does not need to care about the USB packetization process (the porting driver does it)
### Easy to bring out USB performance
@@ -32,7 +42,7 @@ Taking into account USB performance issues and trying to achieve the theoretical
- Memory zero copy
- If IP has DMA then uses DMA mode (DMA with hardware packetization)
- Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
- Subcontracting function is handled in interrupt
- Packetization is handled in interrupt
## Directory Structure
@@ -75,13 +85,13 @@ CherryUSB Device Stack resource usage (GCC 10.2 with -O2):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|usbd_core.c | 3516 | 512(default) + 320 | 0 | 0 |
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|usbd_hid.c | 364 | 0 | 0 | 0 |
|usbd_audio.c | 1455 | 0 | 0 | 0 |
|usbd_video.c | 2494 | 0 | 84 | 0 |
|usbd_rndis.c | 2109 | 3340 | 76 | 0 |
|usbd_core.c | ~4400 | 512(default) + 320 | 0 | 0 |
|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 |
|usbd_msc.c | ~3800 | 128 + 512(default) | 16 | 0 |
|usbd_hid.c | ~360 | 0 | 0 | 0 |
|usbd_audio.c | ~1500 | 0 | 0 | 0 |
|usbd_video.c | ~2600 | 0 | 84 | 0 |
|usbd_rndis.c | ~2100 | 2 * 1580(default)+156+8 | 76 | 0 |
## Host Stack Overview
@@ -93,7 +103,7 @@ CherryUSB Host Stack has the following functions
- Automatic loading of supported Class drivers
- 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 and ehci now)
- 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 Human Interface Device (HID)
- Support Mass Storage Class (MSC)
@@ -103,6 +113,7 @@ CherryUSB Host Stack has the following functions
- Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm)
- Support Vendor class (serial, net, wifi)
- Support USB modeswitch
- Support Android Open Accessory
- Support multi host with the same USB IP
The CherryUSB Host stack also provides the lsusb function, which allows you to view information about all mounted devices, including those on external hubs, with the help of a shell plugin.
@@ -111,16 +122,17 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~1000 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~3700 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~3100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~3900 | 4096 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2500 | 2 * 1514 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_bluetooth.c | ~2300 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
|usbh_core.c | ~9000 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|usbh_hub.c | ~6000 | 32 + 4 * (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|usbh_cdc_acm.c | ~900 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2700 | 64 | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~1400 | 256 | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~3800 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~4100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~4200 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2200 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_cdc_ncm.c | ~3300 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1 | 0 |
|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affected by the following macros
@@ -148,7 +160,7 @@ Only standard and commercial USB IP are listed.
| IP | device | host | Support status |
|:----------------:|:----------:|:--------:|:--------------:|
| OHCI(intel) | none | OHCI | × |
| OHCI(intel) | none | OHCI | |
| EHCI(intel) | none | EHCI | √ |
| XHCI(intel) | none | XHCI | √ |
| UHCI(intel) | none | UHCI | × |
@@ -184,12 +196,13 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|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 | chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= 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 |
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
## Package Support
@@ -211,4 +224,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="100"/> <img src="docs/assets/hpmicro.jpg" width="100" height="100" /> <img src="docs/assets/eastsoft.jpg" width="100" height="100" /> <img src="docs/assets/rtthread.jpg" width="100" height="100" /> <img src="docs/assets/sophgo.jpg" width="100" height="100" /> <img src="docs/assets/phytium.jpg" width="100" height="100" /> <img src="docs/assets/thead.jpg" width="100" height="100" /> <img src="docs/assets/nuvoton.jpg" width="100" height="100" /> <img src="docs/assets/artinchip.jpg" width="100" height="100" /> <img src="docs/assets/bekencorp.jpg" width="100" height="100" />
<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" />

View File

@@ -1,8 +1,18 @@
# CherryUSB
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">CherryUSB</h1>
<p align="center">
<a href="https://github.com/cherry-embedded/CherryUSB/releases"><img src="https://img.shields.io/github/release/cherry-embedded/CherryUSB.svg"><a>
<a href="https://github.com/cherry-embedded/CherryUSB/blob/master/LICENSE"><img src="https://img.shields.io/github/license/cherry-embedded/CherryUSB.svg?style=flat-square"></a>
<a href="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml"><img src="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml/badge.svg"> </a>
<a href="https://discord.com/invite/wFfvrSAey8"><img src="https://img.shields.io/badge/Discord-blue?logo=discord&style=flat-square"> </a>
</p>
[English](./README.md)
<p align="center">
<a href="./README_zh.md">中文</a>
|
<a href="./README.md">English</a>
</p>
CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的 USB 主从协议栈。
CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的高性能 USB 主从协议栈。
![CherryUSB](CherryUSB.svg)
@@ -22,7 +32,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带
为了方便用户使用 USB 接口,考虑到用户学习过 uart 和 dma因此设计的数据收发类接口具备以下优点
- 等价于使用 uart tx dma/uart rx dma
- 收发长度没有限制,用户不需要关心 USB 分包过程porting 驱动做分包过程
- 收发长度没有限制,用户不需要关心 USB 分包过程(分包过程在 porting 中处理
### 易于发挥 USB 性能
@@ -32,7 +42,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带
- Memory zero copy
- IP 如果带 DMA 则使用 DMA 模式DMA 带硬件分包功能)
- 长度无限制,方便对接硬件 DMA 并且发挥 DMA 的优势
- 分包功能在中断中处理
- 分包过程在中断中执行
## 目录结构
@@ -75,13 +85,13 @@ CherryUSB Device 协议栈资源占用说明GCC 10.2 with -O2
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|usbd_core.c | 3516 | 512(default) + 320 | 0 | 0 |
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|usbd_hid.c | 364 | 0 | 0 | 0 |
|usbd_audio.c | 1455 | 0 | 0 | 0 |
|usbd_video.c | 2494 | 0 | 84 | 0 |
|usbd_rndis.c | 2109 | 3340 | 76 | 0 |
|usbd_core.c | ~4400 | 512(default) + 320 | 0 | 0 |
|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 |
|usbd_msc.c | ~3800 | 128 + 512(default) | 16 | 0 |
|usbd_hid.c | ~360 | 0 | 0 | 0 |
|usbd_audio.c | ~1500 | 0 | 0 | 0 |
|usbd_video.c | ~2600 | 0 | 84 | 0 |
|usbd_rndis.c | ~2100 | 2 * 1580(default)+156+8 | 76 | 0 |
## Host 协议栈简介
@@ -93,7 +103,7 @@ CherryUSB Host 协议栈当前实现以下功能:
- 自动加载支持的Class 驱动
- 支持阻塞式传输和异步传输
- 支持复合设备
- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,当前仅支持 dwc2ehci)
- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,仅支持 dwc2/ehci/xhci/rp2040)
- 支持 Communication Device Class (CDC_ACM, CDC_ECM)
- 支持 Human Interface Device (HID)
- 支持 Mass Storage Class (MSC)
@@ -103,6 +113,7 @@ CherryUSB Host 协议栈当前实现以下功能:
- 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能)
- 支持 Vendor 类 class (serial, net, wifi)
- 支持 USB modeswitch
- 支持 Android Open Accessory
- 支持相同 USB IP 的多主机
同时CherryUSB Host 协议栈还提供了 lsusb 的功能,借助 shell 插件可以查看所有挂载设备的信息,包括外部 hub 上的设备的信息。
@@ -111,16 +122,17 @@ CherryUSB Host 协议栈资源占用说明GCC 10.2 with -O2
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~1000 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~3700 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~3100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~3900 | 4096 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2500 | 2 * 1514 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_bluetooth.c | ~2300 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
|usbh_core.c | ~9000 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|usbh_hub.c | ~6000 | 32 + 4 * (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|usbh_cdc_acm.c | ~900 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2700 | 64 | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~1400 | 256 | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~3800 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~4100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~4200 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2200 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_cdc_ncm.c | ~3300 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1 | 0 |
|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
其中,`sizeof(struct usbh_hub)``sizeof(struct usbh_hubport)` 受以下宏影响:
@@ -148,7 +160,7 @@ x 受以下宏影响:
| IP | device | host | Support status |
|:----------------:|:----------:|:--------:|:--------------:|
| OHCI(intel) | none | OHCI | × |
| OHCI(intel) | none | OHCI | |
| EHCI(intel) | none | EHCI | √ |
| XHCI(intel) | none | XHCI | √ |
| UHCI(intel) | none | UHCI | × |
@@ -185,12 +197,13 @@ CherryUSB 快速入门、USB 基本概念API 手册Class 基本概念和
|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 | chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= 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 |
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
## 软件包支持
@@ -213,4 +226,4 @@ CherryUSB 微信群:与我联系后邀请加入
感谢以下企业支持(顺序不分先后)。
<img src="docs/assets/bouffalolab.jpg" width="100" height="100"/> <img src="docs/assets/hpmicro.jpg" width="100" height="100" /> <img src="docs/assets/eastsoft.jpg" width="100" height="100" /> <img src="docs/assets/rtthread.jpg" width="100" height="100" /> <img src="docs/assets/sophgo.jpg" width="100" height="100" /> <img src="docs/assets/phytium.jpg" width="100" height="100" /> <img src="docs/assets/thead.jpg" width="100" height="100" /> <img src="docs/assets/nuvoton.jpg" width="100" height="100" /> <img src="docs/assets/artinchip.jpg" width="100" height="100" /> <img src="docs/assets/bekencorp.jpg" width="100" height="100" />
<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" />

View File

@@ -1,18 +1,23 @@
from building import *
cwd = GetCurrentDir()
path = [cwd + '/common']
path = [cwd]
path += [cwd + '/common']
path += [cwd + '/core']
path += [cwd + '/class/hub']
path += [cwd + '/class/cdc']
path += [cwd + '/class/msc']
path += [cwd + '/class/hid']
path += [cwd + '/class/audio']
path += [cwd + '/class/video']
path += [cwd + '/class/wireless']
path += [cwd + '/class/midi']
path += [cwd + '/class/adb']
path += [cwd + '/class/dfu']
path += [cwd + '/class/midi']
path += [cwd + '/class/vendor/net']
path += [cwd + '/class/vendor/serial']
path += [cwd + '/class/vendor/wifi']
src = []
LIBS = []
@@ -45,6 +50,9 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_HC']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
src += Glob('port/dwc2/usb_glue_hc.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_KENDRYTE']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
src += Glob('port/dwc2/usb_glue_kendryte.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_CUSTOM']):
src += Glob('port/dwc2/usb_dc_dwc2.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_ES']):
@@ -58,6 +66,11 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
src += Glob('port/musb/usb_glue_bk.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM']):
src += Glob('port/musb/usb_dc_musb.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_KINETIS_MCX']):
src += Glob('port/kinetis/usb_dc_kinetis.c')
src += Glob('port/kinetis/usb_glue_mcx.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_KINETIS_CUSTOM']):
src += Glob('port/kinetis/usb_dc_kinetis.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX']):
src += Glob('port/chipidea/usb_dc_chipidea.c')
src += Glob('port/chipidea/usb_glue_mcx.c')
@@ -106,6 +119,8 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
src += Glob('demo/cdc_acm_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC']):
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']):
@@ -137,7 +152,6 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
# USB HOST
if GetDepend(['PKG_CHERRYUSB_HOST']):
path += [cwd + '/class/hub']
src += Glob('core/usbh_core.c')
src += Glob('class/hub/usbh_hub.c')
src += Glob('osal/usb_osal_rtthread.c')
@@ -172,6 +186,9 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
if GetDepend(['PKG_CHERRYUSB_HOST_DWC2_ESP']):
src += Glob('port/dwc2/usb_hc_dwc2.c')
src += Glob('port/dwc2/usb_glue_esp.c')
if GetDepend(['PKG_CHERRYUSB_HOST_DWC2_KENDRYTE']):
src += Glob('port/dwc2/usb_hc_dwc2.c')
src += Glob('port/dwc2/usb_glue_kendryte.c')
if GetDepend(['PKG_CHERRYUSB_HOST_DWC2_CUSTOM']):
src += Glob('port/dwc2/usb_hc_dwc2.c')
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_STANDARD']):
@@ -187,6 +204,11 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
src += Glob('port/musb/usb_glue_bk.c')
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_CUSTOM']):
src += Glob('port/musb/usb_hc_musb.c')
if GetDepend(['PKG_CHERRYUSB_HOST_KINETIS_MCX']):
src += Glob('port/kinetis/usb_hc_kinetis.c')
src += Glob('port/kinetis/usb_glue_mcx.c')
if GetDepend(['PKG_CHERRYUSB_HOST_KINETIS_CUSTOM']):
src += Glob('port/kinetis/usb_hc_kinetis.c')
if GetDepend(['PKG_CHERRYUSB_HOST_PUSB2']):
path += [cwd + '/port/pusb2/rt-thread']
src += Glob('port/pusb2/rt-thread/usb_hc_glue_phytium.c')
@@ -255,7 +277,7 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
src += Glob('platform/rtthread/usb_msh.c')
src += Glob('platform/rtthread/usb_check.c')
group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES)
group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], LIBS = LIBS, LIBPATH=LIBPATH, CPPPATH = path, CPPDEFINES = CPPDEFINES)
Return('group')

View File

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

View File

@@ -26,6 +26,7 @@
# set(CONFIG_CHERRYUSB_HOST_HCD "ehci_xxx")
list(APPEND cherryusb_incs
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/common
${CMAKE_CURRENT_LIST_DIR}/core
${CMAKE_CURRENT_LIST_DIR}/class/hub
@@ -37,9 +38,11 @@ ${CMAKE_CURRENT_LIST_DIR}/class/video
${CMAKE_CURRENT_LIST_DIR}/class/wireless
${CMAKE_CURRENT_LIST_DIR}/class/midi
${CMAKE_CURRENT_LIST_DIR}/class/adb
${CMAKE_CURRENT_LIST_DIR}/class/dfu
${CMAKE_CURRENT_LIST_DIR}/class/vendor/net
${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial
${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi
${CMAKE_CURRENT_LIST_DIR}/class/aoa
)
if(CONFIG_CHERRYUSB_DEVICE)
@@ -105,6 +108,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "chipidea_mcx")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_dc_chipidea.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_glue_mcx.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "kinetis_mcx")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_dc_kinetis.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_glue_mcx.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "hpm")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpm/usb_dc_hpm.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "bl")
@@ -112,6 +118,8 @@ if(CONFIG_CHERRYUSB_DEVICE)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "aic")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic_ll.c)
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "rp2040")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_dc_rp2040.c)
endif()
endif()
@@ -215,6 +223,9 @@ if(CONFIG_CHERRYUSB_HOST)
if(CONFIG_CHERRYUSB_HOST_BL616)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi/usbh_bl616.c)
endif()
if(CONFIG_CHERRYUSB_HOST_AOA)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/aoa/usbh_aoa.c)
endif()
if(DEFINED CONFIG_CHERRYUSB_HOST_HCD)
if("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_bouffalo")
@@ -260,6 +271,11 @@ if(CONFIG_CHERRYUSB_HOST)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "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_HCD}" STREQUAL "kinetis_mcx")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_hc_kinetis.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_glue_mcx.c)
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "rp2040")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c)
endif()
endif()
@@ -287,6 +303,10 @@ endif()
if(CONFIG_CHERRYMP)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/usbh_uvc_queue.c)
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp)
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool_osal_freertos.c)
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "rtthread")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool_osal_rtthread.c)
endif()
endif()

View File

@@ -17,11 +17,13 @@
/* Enable print with color */
#define CONFIG_USB_PRINTF_COLOR_ENABLE
/* data align size when use dma */
/* data align size when use dma or use dcache */
#ifndef CONFIG_USB_ALIGN_SIZE
#define CONFIG_USB_ALIGN_SIZE 4
#endif
//#define CONFIG_USB_DCACHE_ENABLE
/* attribute data into no cache ram */
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
@@ -46,6 +48,20 @@
/* Enable test mode */
// #define CONFIG_USBDEV_TEST_MODE
/* enable advance desc register api */
// CONFIG_USBDEV_ADVANCE_DESC
/* move ep0 setup handler from isr to thread */
// #define CONFIG_USBDEV_EP0_THREAD
#ifndef CONFIG_USBDEV_EP0_PRIO
#define CONFIG_USBDEV_EP0_PRIO 4
#endif
#ifndef CONFIG_USBDEV_EP0_STACKSIZE
#define CONFIG_USBDEV_EP0_STACKSIZE 2048
#endif
#ifndef CONFIG_USBDEV_MSC_MAX_LUN
#define CONFIG_USBDEV_MSC_MAX_LUN 1
#endif
@@ -208,6 +224,9 @@
#define CONFIG_USBDEV_EP_NUM 8
#endif
/* 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
@@ -218,7 +237,7 @@
// #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 (512 / 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)
@@ -227,6 +246,8 @@
// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_DMA_ENABLE
/* ---------------- MUSB Configuration ---------------- */
// #define CONFIG_USB_MUSB_SUNXI
@@ -266,9 +287,31 @@
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4)
// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
/* ---------------- MUSB Configuration ---------------- */
// #define CONFIG_USB_MUSB_SUNXI
/* ================ USB Dcache Configuration ==================*/
#ifdef CONFIG_USB_DCACHE_ENABLE
/* style 1*/
// void usb_dcache_clean(uintptr_t addr, uint32_t size);
// void usb_dcache_invalidate(uintptr_t addr, uint32_t size);
// void usb_dcache_flush(uintptr_t addr, uint32_t size);
/* style 2*/
// #define usb_dcache_clean(addr, size)
// #define usb_dcache_invalidate(addr, size)
// #define usb_dcache_flush(addr, size)
#endif
#ifndef usb_phyaddr2ramaddr
#define usb_phyaddr2ramaddr(addr) (addr)
#endif
#ifndef usb_ramaddr2phyaddr
#define usb_ramaddr2phyaddr(addr) (addr)
#endif
#endif

48
class/aoa/usb_aoa.h Normal file
View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USB_AOA_H
#define USB_AOA_H
//AOA 1.0
#define AOA_ACCESSORY_VENDOR_ID 0x18D1
#define AOA_ACCESSORY_PRODUCT_ID 0x2D00
#define AOA_ACCESSORY_ADB_PRODUCT_ID 0x2D01
//AOA 2.0
#define AOA_AUDIO_PRODUCT_ID 0x2D02
#define AOA_AUDIO_ADB_PRODUCT_ID 0x2D03
#define AOA_ACCESSORY_AUDIO_PRODUCT_ID 0x2D04
#define AOA_ACCESSORY_AUDIO_ADB_PRODUCT_ID 0x2D05
//AOA 1.0
#define AOA_ACCESSORY_GET_PROTOCOL 51
#define AOA_ACCESSORY_SEND_STRING 52
#define AOA_ACCESSORY_START 53
//AOA 2.0
#define AOA_ACCESSORY_REGISTER_HID 54
#define AOA_ACCESSORY_UNREGISTER_HID 55
#define AOA_ACCESSORY_SET_HID_REPORT_DESC 56
#define AOA_ACCESSORY_SEND_HID_EVENT 57
#define AOA_ACCESSORY_SET_AUDIO_MODE 58
#define AOA_ACCESSORY_STRING_MANUFACTURER 0
#define AOA_ACCESSORY_STRING_MODEL 1
#define AOA_ACCESSORY_STRING_DESCRIPTION 2
#define AOA_ACCESSORY_STRING_VERSION 3
#define AOA_ACCESSORY_STRING_URI 4
#define AOA_ACCESSORY_STRING_SERIAL 5
struct aoa_string_info {
char acc_manufacturer[64];
char acc_model[64];
char acc_description[64];
char acc_version[64];
char acc_uri[64];
char acc_serial[64];
};
#endif /* USB_AOA_H */

289
class/aoa/usbh_aoa.c Normal file
View File

@@ -0,0 +1,289 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbh_core.h"
#include "usbh_aoa.h"
#undef USB_DBG_TAG
#define USB_DBG_TAG "usbh_aoa"
#include "usb_log.h"
#define DEV_FORMAT "/dev/aoa"
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_aoa_buffer[128];
static struct usbh_aoa g_aoa_class;
int usbh_aoa_switch(struct usbh_hubport *hport, struct aoa_string_info *info)
{
struct usb_setup_packet *setup;
int ret;
setup = hport->setup;
if (setup == NULL) {
return -USB_ERR_INVAL;
}
USB_LOG_INFO("Try switch into aoa mode\r\n");
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_GET_PROTOCOL;
setup->wValue = 0;
setup->wIndex = 0;
setup->wLength = 2;
ret = usbh_control_transfer(hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
USB_LOG_INFO("AOA version: v%d.%d\r\n", g_aoa_buffer[0], g_aoa_buffer[1]);
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SEND_STRING;
setup->wValue = 0;
setup->wIndex = AOA_ACCESSORY_STRING_MANUFACTURER;
setup->wLength = strlen(info->acc_manufacturer) + 1;
memcpy(g_aoa_buffer, info->acc_manufacturer, strlen(info->acc_manufacturer));
ret = usbh_control_transfer(hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SEND_STRING;
setup->wValue = 0;
setup->wIndex = AOA_ACCESSORY_STRING_MODEL;
setup->wLength = strlen(info->acc_model) + 1;
memcpy(g_aoa_buffer, info->acc_model, strlen(info->acc_model));
ret = usbh_control_transfer(hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SEND_STRING;
setup->wValue = 0;
setup->wIndex = AOA_ACCESSORY_STRING_DESCRIPTION;
setup->wLength = strlen(info->acc_description) + 1;
memcpy(g_aoa_buffer, info->acc_description, strlen(info->acc_description));
ret = usbh_control_transfer(hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SEND_STRING;
setup->wValue = 0;
setup->wIndex = AOA_ACCESSORY_STRING_VERSION;
setup->wLength = strlen(info->acc_version) + 1;
memcpy(g_aoa_buffer, info->acc_version, strlen(info->acc_version));
ret = usbh_control_transfer(hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SEND_STRING;
setup->wValue = 0;
setup->wIndex = AOA_ACCESSORY_STRING_URI;
setup->wLength = strlen(info->acc_uri) + 1;
memcpy(g_aoa_buffer, info->acc_uri, strlen(info->acc_uri));
ret = usbh_control_transfer(hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SEND_STRING;
setup->wValue = 0;
setup->wIndex = AOA_ACCESSORY_STRING_SERIAL;
setup->wLength = strlen(info->acc_serial) + 1;
memcpy(g_aoa_buffer, info->acc_serial, strlen(info->acc_serial));
ret = usbh_control_transfer(hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_START;
setup->wValue = 0;
setup->wIndex = 0;
setup->wLength = 0;
ret = usbh_control_transfer(hport, setup, NULL);
if (ret < 0) {
return ret;
}
USB_LOG_INFO("Switch into aoa mode success, wait usb device restart...\r\n");
return 0;
}
int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *report, uint32_t report_len)
{
struct usb_setup_packet *setup;
int ret;
uint8_t len;
uint32_t offset;
if (!aoa_class || !aoa_class->hport) {
return -USB_ERR_INVAL;
}
setup = aoa_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_REGISTER_HID;
setup->wValue = id;
setup->wIndex = report_len;
setup->wLength = 0;
ret = usbh_control_transfer(aoa_class->hport, setup, NULL);
if (ret < 0) {
return ret;
}
offset = 0;
while (report_len > 0) {
len = report_len > 64 ? 64 : report_len;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SET_HID_REPORT_DESC;
setup->wValue = id;
setup->wIndex = offset;
setup->wLength = len;
memcpy(g_aoa_buffer, report + offset, len);
ret = usbh_control_transfer(aoa_class->hport, setup, g_aoa_buffer);
if (ret < 0) {
return ret;
}
offset += len;
report_len -= len;
}
return ret;
}
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;
}
setup = aoa_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = AOA_ACCESSORY_SEND_HID_EVENT;
setup->wValue = id;
setup->wIndex = 0;
setup->wLength = event_len;
memcpy(g_aoa_buffer, event, event_len);
return usbh_control_transfer(aoa_class->hport, setup, event);
}
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;
memset(aoa_class, 0, sizeof(struct usbh_aoa));
aoa_class->hport = hport;
aoa_class->intf = intf;
hport->config.intf[intf].priv = aoa_class;
for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
if (ep_desc->bEndpointAddress & 0x80) {
USBH_EP_INIT(aoa_class->bulkin, ep_desc);
} else {
USBH_EP_INIT(aoa_class->bulkout, ep_desc);
}
}
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register AOA Class:%s\r\n", hport->config.intf[intf].devname);
usbh_aoa_run(aoa_class);
return 0;
}
static int usbh_aoa_disconnect(struct usbh_hubport *hport, uint8_t intf)
{
int ret = 0;
struct usbh_aoa *aoa_class = (struct usbh_aoa *)hport->config.intf[intf].priv;
if (aoa_class) {
if (aoa_class->bulkin) {
usbh_kill_urb(&aoa_class->bulkin_urb);
}
if (aoa_class->bulkout) {
usbh_kill_urb(&aoa_class->bulkout_urb);
}
if (hport->config.intf[intf].devname[0] != '\0') {
USB_LOG_INFO("Unregister AOA Class:%s\r\n", hport->config.intf[intf].devname);
usbh_aoa_stop(aoa_class);
}
memset(aoa_class, 0, sizeof(struct usbh_aoa));
}
return ret;
}
__WEAK void usbh_aoa_run(struct usbh_aoa *aoa_class)
{
(void)aoa_class;
}
__WEAK void usbh_aoa_stop(struct usbh_aoa *aoa_class)
{
(void)aoa_class;
}
static const uint16_t aoa_id_table[][2] = {
{ AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_PRODUCT_ID },
{ AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_ADB_PRODUCT_ID },
{ AOA_ACCESSORY_VENDOR_ID, AOA_AUDIO_PRODUCT_ID },
{ AOA_ACCESSORY_VENDOR_ID, AOA_AUDIO_ADB_PRODUCT_ID },
{ AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_AUDIO_PRODUCT_ID },
{ AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_AUDIO_ADB_PRODUCT_ID },
{ 0, 0 },
};
const struct usbh_class_driver aoa_class_driver = {
.driver_name = "aoa",
.connect = usbh_aoa_connect,
.disconnect = usbh_aoa_disconnect
};
CLASS_INFO_DEFINE const struct usbh_class_info aoa_intf_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0xff,
.bInterfaceProtocol = 0x00,
.id_table = aoa_id_table,
.class_driver = &aoa_class_driver
};

40
class/aoa/usbh_aoa.h Normal file
View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBH_AOA_H
#define USBH_AOA_H
#include "usb_aoa.h"
struct usbh_aoa {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
struct usbh_urb bulkout_urb;
struct usbh_urb bulkin_urb;
uint8_t intf;
uint8_t minor;
void *user_data;
};
#ifdef __cplusplus
extern "C" {
#endif
int usbh_aoa_switch(struct usbh_hubport *hport, struct aoa_string_info *info);
int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *report, uint32_t report_len);
int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len);
void usbh_aoa_run(struct usbh_aoa *aoa_class);
void usbh_aoa_stop(struct usbh_aoa *aoa_class);
#ifdef __cplusplus
}
#endif
#endif /* USBH_AOA_H */

View File

@@ -132,11 +132,11 @@
#define AUDIO_FORMAT_ALAW 0x0004
#define AUDIO_FORMAT_MULAW 0x0005
#define AUDIO_V2_FORMAT_PCM 0x00000001
#define AUDIO_V2_FORMAT_PCM8 0x00000002
#define AUDIO_V2_FORMAT_IEEE_FLOAT 0x00000004
#define AUDIO_V2_FORMAT_ALAW 0x00000008
#define AUDIO_V2_FORMAT_MULAW 0x00000010
#define AUDIO_V2_FORMAT_PCM 0x00000001
#define AUDIO_V2_FORMAT_PCM8 0x00000002
#define AUDIO_V2_FORMAT_IEEE_FLOAT 0x00000004
#define AUDIO_V2_FORMAT_ALAW 0x00000008
#define AUDIO_V2_FORMAT_MULAW 0x00000010
/* bmChannelConfig: a bitmap field that indicates which spatial locations
* are occupied by the channels present in the cluster. The bit allocations
@@ -648,6 +648,18 @@ struct audio_cs_if_ac_feature_unit_descriptor {
#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + (ch + 1) * n)
struct audio_cs_if_ac_selector_unit_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bNrInPins;
uint8_t baSourceID[1];
uint8_t iSelector;
} __PACKED;
#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(n) (6 + n)
struct audio_cs_if_as_general_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
@@ -810,7 +822,120 @@ struct audio_cs_ep_ep_general_descriptor {
0x00, /* wLockDelay */ \
0x00
#define AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, bFeedbackEndpointAddress, ...) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
0x00, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
0x00, /* iInterface */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
0x01, /* bAlternateSetting */ \
0x02, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
0x00, /* iInterface */ \
0x07, /* bLength */ \
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \
bTerminalLink, /* bTerminalLink : Unit ID of the Output Terminal*/ \
0x01, /* bDelay */ \
WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag : AUDIO_FORMAT_PCM */ \
0x08 + PP_NARG(__VA_ARGS__), /* bLength */ \
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \
AUDIO_FORMAT_TYPE_I, /* bFormatType */ \
bNrChannels, /* bNrChannels */ \
bSubFrameSize, /* bSubFrameSize : Bytes per audio subframe */ \
bBitResolution, /* bBitResolution : bits per sample */ \
(PP_NARG(__VA_ARGS__)/3), /* bSamFreqType : only one frequency supported */ \
__VA_ARGS__, /* tSamFreq : Audio sampling frequency coded on 3 bytes */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
bEndpointAddress, /* bEndpointAddress : IN endpoint 1 */ \
0x05, /* bmAttributes */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
bInterval, /* bInterval : one packet per frame */ \
0x00, /* bRefresh */ \
bFeedbackEndpointAddress, /* bSynchAddress */ \
0x07, /* bLength */ \
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \
AUDIO_EP_CONTROL_SAMPLING_FEQ, /* bmAttributes AUDIO_SAMPLING_FREQ_CONTROL */ \
0x00, /* bLockDelayUnits */ \
0x00, /* wLockDelay */ \
0x00, \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
bFeedbackEndpointAddress, /* bFeedbackEndpointAddress Revise Dir to bEndpointAddress */ \
0x11, /* bmAttributes: TransferType=Isochronous SyncType=None EndpointType=Feedback */ \
WBVAL(4), /* XXXX wMaxPacketSize in Bytes */ \
bInterval, /* bInterval */ \
0x03, /* bRefresh, 8ms */ \
0x00 /* bSynchAddress */
#define AUDIO_AS_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07)
#define AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07 + 0x09)
#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
bAlternateSetting, /* bAlternateSetting */ \
0x01, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
0x00, /* iInterface */ \
0x07, /* bLength */ \
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \
bTerminalLink, /* bTerminalLink : Unit ID of the Output Terminal*/ \
0x01, /* bDelay */ \
WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag : AUDIO_FORMAT_PCM */ \
0x08 + PP_NARG(__VA_ARGS__), /* bLength */ \
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \
AUDIO_FORMAT_TYPE_I, /* bFormatType */ \
bNrChannels, /* bNrChannels */ \
bSubFrameSize, /* bSubFrameSize : Bytes per audio subframe */ \
bBitResolution, /* bBitResolution : bits per sample */ \
(PP_NARG(__VA_ARGS__)/3), /* bSamFreqType : only one frequency supported */ \
__VA_ARGS__, /* tSamFreq : Audio sampling frequency coded on 3 bytes */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
bEndpointAddress, /* bEndpointAddress : IN endpoint 1 */ \
bmAttributes, /* bmAttributes */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
bInterval, /* bInterval : one packet per frame */ \
0x00, /* bRefresh */ \
0x00, /* bSynchAddress */ \
0x07, /* bLength */ \
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \
AUDIO_EP_CONTROL_SAMPLING_FEQ, /* bmAttributes AUDIO_SAMPLING_FREQ_CONTROL */ \
0x00, /* bLockDelayUnits */ \
0x00, /* wLockDelay */ \
0x00
#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07)
#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
0x01, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
0x00 /* iInterface */
#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \
0x09, /* bLength */ \
@@ -1096,6 +1221,58 @@ struct audio_v2_control_range3_param_block {
0x00, /* wLockDelay */ \
0x00
#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
bAlternateSetting, /* bAlternateSetting */ \
0x01, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \
0x00, /* iInterface */ \
0x10, /* bLength */ \
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \
bTerminalLink, /* bTerminalLink : Unit ID of the Output or Input Terminal*/ \
0x00, /* bmControls */ \
AUDIO_FORMAT_TYPE_I, /* bFormatType : AUDIO_FORMAT_TYPE_I */ \
DBVAL(AUDIO_V2_FORMAT_PCM), /* bmFormats PCM */ \
bNrChannels, /* bNrChannels */ \
DBVAL(bmChannelConfig), /* bmChannelConfig */ \
0x00, /* iChannelNames */ \
0x06, /* bLength */ \
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \
AUDIO_FORMAT_TYPE_I, /* bFormatType */ \
bSubslotSize, /* bSubslotSize */ \
bBitResolution, /* bBitResolution */ \
0x07, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
bEndpointAddress, /* bEndpointAddress 3 out endpoint for Audio */ \
bmAttributes, /* bmAttributes */ \
WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (SampleRate * SlotByteSize * NumChannels) */ \
bInterval, /* bInterval */ \
0x08, /* bLength */ \
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \
0x00, /* bmAttributes */ \
0x00, /* bmControls */ \
0x00, /* bLockDelayUnits */ \
0x00, /* wLockDelay */ \
0x00
#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
0x01, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \
0x00 /* iInterface */
#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, bFeedbackEndpointAddress) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
@@ -1150,16 +1327,32 @@ struct audio_v2_control_range3_param_block {
bFeedbackEndpointAddress, /* bFeedbackEndpointAddress Revise Dir to bEndpointAddress */ \
0x11, /* bmAttributes: TransferType=Isochronous SyncType=None EndpointType=Feedback */ \
WBVAL(4), /* XXXX wMaxPacketSize in Bytes */ \
bInterval /* bInterval */ \
bInterval /* bInterval */
// clang-format on
#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08)
#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07)
#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08)
#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08)
#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07)
#define AUDIO_SAMPLE_FREQ_NUM(num) (uint8_t)(num), (uint8_t)((num >> 8))
#define AUDIO_SAMPLE_FREQ_3B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
#define AUDIO_SAMPLE_FREQ_4B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), \
(uint8_t)((frq >> 16)), (uint8_t)((frq >> 24))
/* format 10.14 */
#define AUDIO_FREQ_TO_FEEDBACK_FS(freq) ((freq << 10) / 1000)
#define AUDIO_FEEDBACK_TO_BUF_FS(buf, feedback) \
buf[0] = ((feedback << 4) & 0xFFU); \
buf[1] = (((feedback << 4) >> 8U) & 0xFFU); \
buf[2] = (((feedback << 4) >> 16U) & 0xFFU)
/* format 16.16 */
#define AUDIO_FREQ_TO_FEEDBACK_HS(freq) ((freq << 13) / 1000)
#define AUDIO_FEEDBACK_TO_BUF_HS(buf, feedback) \
buf[0] = (((feedback & 0x00001FFFu) << 3) & 0xFFu); \
buf[1] = ((((feedback & 0x00001FFFu) << 3) >> 8) & 0xFFu); \
buf[2] = (((feedback & 0x01FFE000u) >> 13) & 0xFFu); \
buf[3] = (((feedback & 0x01FFE000u) >> 21) & 0xFFu)
#endif /* USB_AUDIO_H */

View File

@@ -136,27 +136,26 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
memcpy(&volume, *data, *len);
if (volume < 0x8000) {
volume_db = volume / 256;
} else if (volume > 0x8000) {
volume_db = (0xffff - volume + 1) / -256;
} else {
volume_db = (volume - 0x10000) / 256;
}
volume_db += 128; /* 0 ~ 255 */
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%04x\r\n", ep, ch, volume);
USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
usbd_audio_set_volume(busid, ep, ch, volume_db);
break;
case AUDIO_REQUEST_GET_CUR:
volume_db = usbd_audio_get_volume(busid, ep, ch);
volume_db -= 128;
if (volume_db >= 0) {
volume = volume_db * 256;
} else {
volume = volume_db * 256 + 0xffff + 1;
volume = volume_db * 256 + 0x10000;
}
USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
memcpy(*data, &volume, 2);
*len = 2;
break;
case AUDIO_REQUEST_GET_MIN:
(*data)[0] = 0x00; /* -2560/256 dB */
(*data)[1] = 0xdb;
(*data)[0] = 0x00; /* -100 dB */
(*data)[1] = 0x9c;
*len = 2;
break;
case AUDIO_REQUEST_GET_MAX:
@@ -165,7 +164,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
*len = 2;
break;
case AUDIO_REQUEST_GET_RES:
(*data)[0] = 0x00; /* -256/256 dB */
(*data)[0] = 0x00; /* 1 dB */
(*data)[1] = 0x01;
*len = 2;
break;
@@ -178,22 +177,31 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
case AUDIO_REQUEST_CUR:
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
volume_db = usbd_audio_get_volume(busid, ep, ch);
volume = volume_db;
if (volume_db >= 0) {
volume = volume_db * 256;
} else {
volume = volume_db * 256 + 0x10000;
}
USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
memcpy(*data, &volume, 2);
*len = 2;
} else {
memcpy(&volume, *data, *len);
volume_db = volume;
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%02x\r\n", ep, ch, volume);
if (volume < 0x8000) {
volume_db = volume / 256;
} else {
volume_db = (volume - 0x10000) / 256;
}
USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
usbd_audio_set_volume(busid, ep, ch, volume_db);
}
break;
case AUDIO_REQUEST_RANGE:
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
*((uint16_t *)(*data + 0)) = 1;
*((uint16_t *)(*data + 2)) = 0;
*((uint16_t *)(*data + 4)) = 100;
*((uint16_t *)(*data + 6)) = 1;
*((uint16_t *)(*data + 2)) = 0x9c00; /* MIN -100 dB */
*((uint16_t *)(*data + 4)) = 0x0000; /* MAX 0 dB */
*((uint16_t *)(*data + 6)) = 0x100; /* RES 1 dB */
*len = 8;
} else {
}
@@ -312,12 +320,12 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid,
return intf;
}
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume)
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db)
{
(void)busid;
(void)ep;
(void)ch;
(void)volume;
(void)volume_db;
}
__WEAK int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch)

View File

@@ -27,7 +27,7 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid, struct usbd_interface
void usbd_audio_open(uint8_t busid, uint8_t intf);
void usbd_audio_close(uint8_t busid, uint8_t intf);
void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume);
void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db);
int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch);
void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute);
bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch);

View File

@@ -21,10 +21,6 @@
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
#ifndef CONFIG_USBHOST_MAX_AUDIO_CLASS
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 4
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_audio_buf[128];
static struct usbh_audio g_audio_class[CONFIG_USBHOST_MAX_AUDIO_CLASS];
@@ -32,11 +28,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_audio *usbh_audio_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_AUDIO_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_audio_class[devno], 0, sizeof(struct usbh_audio));
g_audio_class[devno].minor = devno;
return &g_audio_class[devno];
@@ -47,15 +43,15 @@ static struct usbh_audio *usbh_audio_class_alloc(void)
static void usbh_audio_class_free(struct usbh_audio *audio_class)
{
int devno = audio_class->minor;
uint8_t devno = audio_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(audio_class, 0, sizeof(struct usbh_audio));
}
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq)
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution)
{
struct usb_setup_packet *setup;
struct usb_endpoint_descriptor *ep_desc;
@@ -74,20 +70,24 @@ int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t s
return 0;
}
for (uint8_t i = 0; i < audio_class->module_num; i++) {
if (strcmp(name, audio_class->module[i].name) == 0) {
for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) {
for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) {
if (audio_class->module[i].altsetting[j].sampfreq[k] == samp_freq) {
intf = audio_class->module[i].data_intf;
altsetting = j;
goto freq_found;
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) {
intf = audio_class->as_msg_table[i].stream_intf;
for (uint8_t j = 1; j < audio_class->as_msg_table[i].num_of_altsetting; j++) {
if (audio_class->as_msg_table[i].as_format[j].bBitResolution == bitresolution) {
for (uint8_t k = 0; k < audio_class->as_msg_table[i].as_format[j].bSamFreqType; k++) {
uint32_t freq = 0;
memcpy(&freq, &audio_class->as_msg_table[i].as_format[j].tSamFreq[3 * k], 3);
if (freq == samp_freq) {
altsetting = j;
goto freq_found;
}
}
}
}
}
}
return -USB_ERR_NODEV;
freq_found:
@@ -105,16 +105,18 @@ freq_found:
ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_ENDPOINT;
setup->bRequest = AUDIO_REQUEST_SET_CUR;
setup->wValue = (AUDIO_EP_CONTROL_SAMPLING_FEQ << 8) | 0x00;
setup->wIndex = ep_desc->bEndpointAddress;
setup->wLength = 3;
if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].ep_attr & AUDIO_EP_CONTROL_SAMPLING_FEQ) {
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_ENDPOINT;
setup->bRequest = AUDIO_REQUEST_SET_CUR;
setup->wValue = (AUDIO_EP_CONTROL_SAMPLING_FEQ << 8) | 0x00;
setup->wIndex = ep_desc->bEndpointAddress;
setup->wLength = 3;
memcpy(g_audio_buf, &samp_freq, 3);
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
memcpy(g_audio_buf, &samp_freq, 3);
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
}
}
mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
@@ -127,7 +129,7 @@ freq_found:
USBH_EP_INIT(audio_class->isoout, ep_desc);
}
USB_LOG_INFO("Open audio module :%s, altsetting: %u\r\n", name, altsetting);
USB_LOG_INFO("Open audio stream :%s, altsetting: %u\r\n", name, altsetting);
audio_class->is_opened = true;
return ret;
}
@@ -145,9 +147,9 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
}
setup = audio_class->hport->setup;
for (size_t i = 0; i < audio_class->module_num; i++) {
if (strcmp(name, audio_class->module[i].name) == 0) {
intf = audio_class->module[i].data_intf;
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) {
intf = audio_class->as_msg_table[i].stream_intf;
}
}
@@ -155,7 +157,17 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
return -USB_ERR_NODEV;
}
USB_LOG_INFO("Close audio module :%s\r\n", name);
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = 0;
setup->wIndex = intf;
setup->wLength = 0;
ret = usbh_control_transfer(audio_class->hport, setup, NULL);
if (ret < 0) {
return ret;
}
USB_LOG_INFO("Close audio stream :%s\r\n", name);
audio_class->is_opened = false;
ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc;
@@ -169,52 +181,128 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
}
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = USB_REQUEST_SET_INTERFACE;
setup->wValue = 0;
setup->wIndex = intf;
setup->wLength = 0;
ret = usbh_control_transfer(audio_class->hport, setup, NULL);
return ret;
}
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume)
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db)
{
struct usb_setup_packet *setup;
int ret;
uint8_t intf = 0xff;
uint8_t feature_id = 0xff;
uint8_t intf;
uint16_t volume_hex;
int volume_min_db;
int volume_max_db;
if (!audio_class || !audio_class->hport) {
return -USB_ERR_INVAL;
}
if ((volume_db > 127) || (volume_db < -127)) {
return -USB_ERR_INVAL;
}
setup = audio_class->hport->setup;
for (size_t i = 0; i < audio_class->module_num; i++) {
if (strcmp(name, audio_class->module[i].name) == 0) {
intf = audio_class->ctrl_intf;
feature_id = audio_class->module[i].feature_unit_id;
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) {
feature_id = audio_class->as_msg_table[i].feature_terminal_id;
intf = audio_class->as_msg_table[i].stream_intf;
}
}
if (intf == 0xff) {
if (feature_id == 0xff) {
return -USB_ERR_NODEV;
}
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = AUDIO_REQUEST_GET_CUR;
setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch;
setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf;
setup->wLength = 2;
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
}
memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_cur, g_audio_buf, 2);
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = AUDIO_REQUEST_GET_MIN;
setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch;
setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf;
setup->wLength = 2;
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
}
memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min, g_audio_buf, 2);
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = AUDIO_REQUEST_GET_MAX;
setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch;
setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf;
setup->wLength = 2;
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
}
memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max, g_audio_buf, 2);
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = AUDIO_REQUEST_GET_RES;
setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch;
setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf;
setup->wLength = 2;
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
}
memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_res, g_audio_buf, 2);
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = AUDIO_REQUEST_SET_CUR;
setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch;
setup->wIndex = (feature_id << 8) | intf;
setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf;
setup->wLength = 2;
volume_hex = -0xDB00 / 100 * volume + 0xdb00;
if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min < 0x8000) {
volume_min_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min / 256;
} else {
volume_min_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min - 0x10000) / 256;
}
if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max < 0x8000) {
volume_max_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max / 256;
} else {
volume_max_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max - 0x10000) / 256;
}
USB_LOG_INFO("Get ch:%d dB range: %d dB ~ %d dB\r\n", volume_min_db, volume_max_db);
if (volume_db >= 0) {
volume_hex = volume_db * 256;
if (volume_hex > audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max) {
return -USB_ERR_RANGE;
}
} else {
volume_hex = volume_db * 256 + 0x10000;
if (volume_hex < audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min) {
return -USB_ERR_RANGE;
}
}
memcpy(g_audio_buf, &volume_hex, 2);
ret = usbh_control_transfer(audio_class->hport, setup, NULL);
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
}
audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_cur = volume_hex;
return ret;
}
@@ -222,34 +310,37 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_
{
struct usb_setup_packet *setup;
int ret;
uint8_t intf = 0xff;
uint8_t feature_id = 0xff;
uint8_t intf = 0xff;
if (!audio_class || !audio_class->hport) {
return -USB_ERR_INVAL;
}
setup = audio_class->hport->setup;
for (size_t i = 0; i < audio_class->module_num; i++) {
if (strcmp(name, audio_class->module[i].name) == 0) {
intf = audio_class->ctrl_intf;
feature_id = audio_class->module[i].feature_unit_id;
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) {
feature_id = audio_class->as_msg_table[i].feature_terminal_id;
intf = audio_class->as_msg_table[i].stream_intf;
}
}
if (intf == 0xff) {
if (feature_id == 0xff) {
return -USB_ERR_NODEV;
}
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = AUDIO_REQUEST_SET_CUR;
setup->wValue = (AUDIO_FU_CONTROL_MUTE << 8) | ch;
setup->wIndex = (feature_id << 8) | intf;
setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf;
setup->wLength = 1;
memcpy(g_audio_buf, &mute, 1);
ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf);
if (ret < 0) {
return ret;
}
audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].mute = mute;
return ret;
}
@@ -257,26 +348,28 @@ void usbh_audio_list_module(struct usbh_audio *audio_class)
{
USB_LOG_INFO("============= Audio module information ===================\r\n");
USB_LOG_RAW("bcdADC :%04x\r\n", audio_class->bcdADC);
USB_LOG_RAW("Num of modules :%u\r\n", audio_class->module_num);
USB_LOG_RAW("Num of altsettings:%u\r\n", audio_class->num_of_intf_altsettings);
USB_LOG_RAW("Num of audio stream :%u\r\n", audio_class->stream_intf_num);
for (uint8_t i = 0; i < audio_class->module_num; i++) {
USB_LOG_RAW(" module name :%s\r\n", audio_class->module[i].name);
USB_LOG_RAW(" module feature unit id :%d\r\n", audio_class->module[i].feature_unit_id);
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
USB_LOG_RAW("\tstream name :%s\r\n", audio_class->as_msg_table[i].stream_name);
USB_LOG_RAW("\tstream intf :%u\r\n", audio_class->as_msg_table[i].stream_intf);
USB_LOG_RAW("\tNum of altsetting :%u\r\n", audio_class->as_msg_table[i].num_of_altsetting);
for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) {
for (uint8_t j = 0; j < audio_class->as_msg_table[i].num_of_altsetting; j++) {
if (j == 0) {
USB_LOG_RAW(" Ingore altsetting 0\r\n");
USB_LOG_RAW("\t\tIngore altsetting 0\r\n");
continue;
}
USB_LOG_RAW(" Altsetting %u\r\n", j);
USB_LOG_RAW(" module channels :%u\r\n", audio_class->module[i].altsetting[j].channels);
//USB_LOG_RAW(" module format_type :%u\r\n",audio_class->module[i].altsetting[j].format_type);
USB_LOG_RAW(" module bitresolution :%u\r\n", audio_class->module[i].altsetting[j].bitresolution);
USB_LOG_RAW(" module sampfreq num :%u\r\n", audio_class->module[i].altsetting[j].sampfreq_num);
USB_LOG_RAW("\t\tAltsetting :%u\r\n", j);
USB_LOG_RAW("\t\t\tbNrChannels :%u\r\n", audio_class->as_msg_table[i].as_format[j].bNrChannels);
USB_LOG_RAW("\t\t\tbBitResolution :%u\r\n", audio_class->as_msg_table[i].as_format[j].bBitResolution);
USB_LOG_RAW("\t\t\tbSamFreqType :%u\r\n", audio_class->as_msg_table[i].as_format[j].bSamFreqType);
for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) {
USB_LOG_RAW(" module sampfreq :%d hz\r\n", audio_class->module[i].altsetting[j].sampfreq[k]);
for (uint8_t k = 0; k < audio_class->as_msg_table[i].as_format[j].bSamFreqType; k++) {
uint32_t freq = 0;
memcpy(&freq, &audio_class->as_msg_table[i].as_format[j].tSamFreq[3 * k], 3);
USB_LOG_RAW("\t\t\t\tSampleFreq :%u\r\n", freq);
}
}
}
@@ -287,14 +380,14 @@ void usbh_audio_list_module(struct usbh_audio *audio_class)
static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
{
int ret;
uint8_t cur_iface = 0xff;
uint8_t cur_iface_count = 0xff;
uint8_t cur_alt_setting = 0xff;
uint8_t cur_iface = 0;
uint8_t cur_iface_count = 0;
uint8_t cur_alt_setting = 0;
uint8_t input_offset = 0;
uint8_t output_offset = 0;
uint8_t feature_unit_offset = 0;
uint8_t format_offset = 0;
uint8_t *p;
struct usbh_audio_ac_msg ac_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS];
struct usbh_audio *audio_class = usbh_audio_class_alloc();
if (audio_class == NULL) {
@@ -304,8 +397,6 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
audio_class->hport = hport;
audio_class->ctrl_intf = intf;
audio_class->num_of_intf_altsettings = hport->config.intf[intf + 1].altsetting_num;
hport->config.intf[intf].priv = audio_class;
p = hport->raw_config_desc;
@@ -331,72 +422,49 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
case AUDIO_CONTROL_INPUT_TERMINAL: {
struct audio_cs_if_ac_input_terminal_descriptor *desc = (struct audio_cs_if_ac_input_terminal_descriptor *)p;
audio_class->module[input_offset].input_terminal_id = desc->bTerminalID;
audio_class->module[input_offset].input_terminal_type = desc->wTerminalType;
audio_class->module[input_offset].input_channel_config = desc->wChannelConfig;
if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) {
audio_class->module[input_offset].terminal_link_id = desc->bTerminalID;
}
if (desc->wTerminalType == AUDIO_INTERM_MIC) {
audio_class->module[input_offset].name = "mic";
}
memcpy(&ac_msg_table[input_offset].ac_input, desc, sizeof(struct audio_cs_if_ac_input_terminal_descriptor));
input_offset++;
} break;
break;
case AUDIO_CONTROL_OUTPUT_TERMINAL: {
struct audio_cs_if_ac_output_terminal_descriptor *desc = (struct audio_cs_if_ac_output_terminal_descriptor *)p;
audio_class->module[output_offset].output_terminal_id = desc->bTerminalID;
audio_class->module[output_offset].output_terminal_type = desc->wTerminalType;
if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) {
audio_class->module[output_offset].terminal_link_id = desc->bTerminalID;
}
if (desc->wTerminalType == AUDIO_OUTTERM_SPEAKER) {
audio_class->module[output_offset].name = "speaker";
}
memcpy(&ac_msg_table[output_offset].ac_output, desc, sizeof(struct audio_cs_if_ac_output_terminal_descriptor));
output_offset++;
} break;
case AUDIO_CONTROL_FEATURE_UNIT: {
struct audio_cs_if_ac_feature_unit_descriptor *desc = (struct audio_cs_if_ac_feature_unit_descriptor *)p;
audio_class->module[feature_unit_offset].feature_unit_id = desc->bUnitID;
audio_class->module[feature_unit_offset].feature_unit_controlsize = desc->bControlSize;
for (uint8_t j = 0; j < desc->bControlSize; j++) {
audio_class->module[feature_unit_offset].feature_unit_controls[j] = p[6 + j];
}
memcpy(&ac_msg_table[feature_unit_offset].ac_feature_unit, desc, desc->bLength);
feature_unit_offset++;
} break;
case AUDIO_CONTROL_PROCESSING_UNIT:
default:
USB_LOG_ERR("Do not support %02x subtype\r\n", p[DESC_bDescriptorSubType]);
return -USB_ERR_NOTSUPP;
}
} else if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) {
switch (p[DESC_bDescriptorSubType]) {
case AUDIO_STREAMING_GENERAL: {
struct audio_cs_if_as_general_descriptor *desc = (struct audio_cs_if_as_general_descriptor *)p;
break;
/* all altsetting have the same general */
audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].stream_intf = cur_iface;
memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_general, desc, sizeof(struct audio_cs_if_as_general_descriptor));
} break;
case AUDIO_STREAMING_FORMAT_TYPE: {
struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p;
audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].num_of_altsetting = (cur_alt_setting + 1);
memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_format[cur_alt_setting], desc, desc->bLength);
} break;
default:
break;
}
} else if ((cur_iface < (audio_class->ctrl_intf + cur_iface_count)) && (cur_iface > audio_class->ctrl_intf)) {
switch (p[DESC_bDescriptorSubType]) {
case AUDIO_STREAMING_GENERAL:
break;
case AUDIO_STREAMING_FORMAT_TYPE: {
struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p;
audio_class->module[format_offset].data_intf = cur_iface;
audio_class->module[format_offset].altsetting[cur_alt_setting].channels = desc->bNrChannels;
audio_class->module[format_offset].altsetting[cur_alt_setting].format_type = desc->bFormatType;
audio_class->module[format_offset].altsetting[cur_alt_setting].bitresolution = desc->bBitResolution;
audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq_num = desc->bSamFreqType;
for (uint8_t j = 0; j < desc->bSamFreqType; j++) {
audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq[j] = (uint32_t)(p[10 + j * 3] << 16) |
(uint32_t)(p[9 + j * 3] << 8) |
(uint32_t)(p[8 + j * 3] << 0);
}
if (cur_alt_setting == (hport->config.intf[intf + 1].altsetting_num - 1)) {
format_offset++;
}
} break;
default:
break;
}
break;
case AUDIO_ENDPOINT_DESCRIPTOR_TYPE:
if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) {
if (p[DESC_bDescriptorSubType] == AUDIO_ENDPOINT_GENERAL) {
struct audio_cs_ep_ep_general_descriptor *desc = (struct audio_cs_ep_ep_general_descriptor *)p;
audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].ep_attr = desc->bmAttributes;
}
}
break;
@@ -407,16 +475,98 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
p += p[DESC_bLength];
}
if ((input_offset != output_offset) && (input_offset != feature_unit_offset) && (input_offset != format_offset)) {
if ((input_offset != output_offset) && (input_offset != feature_unit_offset)) {
USB_LOG_ERR("Audio control descriptor is invalid\r\n");
return -USB_ERR_INVAL;
}
audio_class->module_num = input_offset;
if (cur_iface_count == 0xff) {
USB_LOG_ERR("Audio descriptor must have iad descriptor\r\n");
return -USB_ERR_INVAL;
}
for (size_t i = 0; i < audio_class->module_num; i++) {
ret = usbh_audio_close(audio_class, audio_class->module[i].name);
audio_class->stream_intf_num = input_offset;
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
/* Search 0x0101 in input or output desc */
for (uint8_t streamidx = 0; streamidx < audio_class->stream_intf_num; streamidx++) {
if (audio_class->as_msg_table[i].as_general.bTerminalLink == ac_msg_table[streamidx].ac_input.bTerminalID) {
/* INPUT --> FEATURE UNIT --> OUTPUT */
audio_class->as_msg_table[i].input_terminal_id = ac_msg_table[streamidx].ac_input.bTerminalID;
/* Search input terminal id in feature desc */
for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) {
if (ac_msg_table[streamidx].ac_input.bTerminalID == ac_msg_table[featureidx].ac_feature_unit.bSourceID) {
audio_class->as_msg_table[i].feature_terminal_id = ac_msg_table[featureidx].ac_feature_unit.bUnitID;
/* Search feature unit id in output desc */
for (uint8_t outputid = 0; outputid < audio_class->stream_intf_num; outputid++) {
if (ac_msg_table[featureidx].ac_feature_unit.bUnitID == ac_msg_table[outputid].ac_output.bSourceID) {
audio_class->as_msg_table[i].output_terminal_id = ac_msg_table[outputid].ac_output.bTerminalID;
switch (ac_msg_table[outputid].ac_output.wTerminalType) {
case AUDIO_OUTTERM_SPEAKER:
audio_class->as_msg_table[i].stream_name = "speaker";
break;
case AUDIO_OUTTERM_HEADPHONES:
audio_class->as_msg_table[i].stream_name = "headphoens";
break;
case AUDIO_OUTTERM_HEADDISPLAY:
audio_class->as_msg_table[i].stream_name = "headdisplay";
break;
default:
audio_class->as_msg_table[i].stream_name = "unknown";
break;
}
break;
}
}
break;
}
}
} else if (audio_class->as_msg_table[i].as_general.bTerminalLink == ac_msg_table[streamidx].ac_output.bTerminalID) {
/* OUTPUT --> FEATURE UNIT --> INPUT */
audio_class->as_msg_table[i].output_terminal_id = ac_msg_table[streamidx].ac_output.bTerminalID;
/* Search output terminal id in feature desc */
for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) {
if (ac_msg_table[streamidx].ac_output.bSourceID == ac_msg_table[featureidx].ac_feature_unit.bUnitID) {
audio_class->as_msg_table[i].feature_terminal_id = ac_msg_table[featureidx].ac_feature_unit.bUnitID;
/* Search feature unit id in input desc */
for (uint8_t inputid = 0; inputid < audio_class->stream_intf_num; inputid++) {
if (ac_msg_table[featureidx].ac_feature_unit.bSourceID == ac_msg_table[inputid].ac_input.bTerminalID) {
audio_class->as_msg_table[i].input_terminal_id = ac_msg_table[inputid].ac_input.bTerminalID;
switch (ac_msg_table[inputid].ac_input.wTerminalType) {
case AUDIO_INTERM_MIC:
audio_class->as_msg_table[i].stream_name = "mic";
break;
default:
audio_class->as_msg_table[i].stream_name = "unknown";
break;
}
break;
}
}
break;
}
}
}
}
}
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
if (audio_class->as_msg_table[i].stream_name == NULL) {
USB_LOG_ERR("Audio stream search fail\r\n");
return -USB_ERR_NODEV;
}
}
for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) {
ret = usbh_audio_close(audio_class, audio_class->as_msg_table[i].stream_name);
if (ret < 0) {
USB_LOG_ERR("Fail to close audio module :%s\r\n", audio_class->module[i].name);
USB_LOG_ERR("Fail to close audio stream :%s\r\n", audio_class->as_msg_table[i].stream_name);
return ret;
}
}
@@ -492,18 +642,18 @@ const struct usbh_class_driver audio_streaming_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info audio_ctrl_intf_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
.class = USB_DEVICE_CLASS_AUDIO,
.subclass = AUDIO_SUBCLASS_AUDIOCONTROL,
.protocol = 0x00,
.bInterfaceClass = USB_DEVICE_CLASS_AUDIO,
.bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOCONTROL,
.bInterfaceProtocol = 0x00,
.id_table = NULL,
.class_driver = &audio_ctrl_class_driver
};
CLASS_INFO_DEFINE const struct usbh_class_info audio_streaming_intf_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
.class = USB_DEVICE_CLASS_AUDIO,
.subclass = AUDIO_SUBCLASS_AUDIOSTREAMING,
.protocol = 0x00,
.bInterfaceClass = USB_DEVICE_CLASS_AUDIO,
.bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOSTREAMING,
.bInterfaceProtocol = 0x00,
.id_table = NULL,
.class_driver = &audio_streaming_class_driver
};

View File

@@ -8,34 +8,31 @@
#include "usb_audio.h"
struct usbh_audio_format_type {
uint8_t channels;
uint8_t format_type;
uint8_t bitresolution;
uint8_t sampfreq_num;
uint32_t sampfreq[3];
#ifndef CONFIG_USBHOST_AUDIO_MAX_STREAMS
#define CONFIG_USBHOST_AUDIO_MAX_STREAMS 3
#endif
struct usbh_audio_ac_msg {
struct audio_cs_if_ac_input_terminal_descriptor ac_input;
struct audio_cs_if_ac_feature_unit_descriptor ac_feature_unit;
struct audio_cs_if_ac_output_terminal_descriptor ac_output;
};
/**
* bSourceID in feature_unit = input_terminal_id
* bSourceID in output_terminal = feature_unit_id
* terminal_link_id = input_terminal_id or output_terminal_id (if input_terminal_type or output_terminal_type is 0x0101)
*
*
*/
struct usbh_audio_module {
const char *name;
uint8_t data_intf;
struct usbh_audio_as_msg {
const char *stream_name;
uint8_t stream_intf;
uint8_t input_terminal_id;
uint16_t input_terminal_type;
uint16_t input_channel_config;
uint8_t feature_terminal_id;
uint8_t output_terminal_id;
uint16_t output_terminal_type;
uint8_t feature_unit_id;
uint8_t feature_unit_controlsize;
uint8_t feature_unit_controls[8];
uint8_t terminal_link_id;
struct usbh_audio_format_type altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS];
uint8_t ep_attr;
uint8_t num_of_altsetting;
uint16_t volume_min;
uint16_t volume_max;
uint16_t volume_res;
uint16_t volume_cur;
bool mute;
struct audio_cs_if_as_general_descriptor as_general;
struct audio_cs_if_as_format_type_descriptor as_format[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS];
};
struct usbh_audio {
@@ -50,9 +47,8 @@ struct usbh_audio {
bool is_opened;
uint16_t bcdADC;
uint8_t bInCollection;
uint8_t num_of_intf_altsettings;
struct usbh_audio_module module[2];
uint8_t module_num;
uint8_t stream_intf_num;
struct usbh_audio_as_msg as_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS];
void *user_data;
};
@@ -61,9 +57,9 @@ struct usbh_audio {
extern "C" {
#endif
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq);
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution);
int usbh_audio_close(struct usbh_audio *audio_class, const char *name);
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume);
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db);
int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute);
void usbh_audio_run(struct usbh_audio *audio_class);

View File

@@ -421,7 +421,7 @@ struct cdc_ncm_ndp16 {
0x02, /* bInterfaceCount */ \
USB_DEVICE_CLASS_CDC, /* bFunctionClass */ \
CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \
CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bFunctionProtocol */ \
CDC_COMMON_PROTOCOL_NONE, /* bFunctionProtocol */ \
0x00, /* iFunction */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
@@ -430,7 +430,7 @@ struct cdc_ncm_ndp16 {
0x01, /* bNumEndpoints */ \
USB_DEVICE_CLASS_CDC, /* bInterfaceClass */ \
CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \
CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bInterfaceProtocol */ \
CDC_COMMON_PROTOCOL_NONE, /* bInterfaceProtocol */ \
str_idx, /* iInterface */ \
0x05, /* bLength */ \
CDC_CS_INTERFACE, /* bDescriptorType */ \
@@ -489,8 +489,8 @@ struct cdc_ncm_ndp16 {
bFirstInterface, /* bFirstInterface */ \
0x02, /* bInterfaceCount */ \
USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \
CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \
0x01, /* bFunctionSubClass */ \
0x03, /* bFunctionProtocol */ \
0x00, /* iFunction */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
@@ -498,8 +498,8 @@ struct cdc_ncm_ndp16 {
0x00, /* bAlternateSetting */ \
0x01, /* bNumEndpoints */ \
USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \
CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \
0x01, /* bInterfaceSubClass */ \
0x03, /* bInterfaceProtocol */ \
str_idx, /* iInterface */ \
0x05, /* bLength */ \
CDC_CS_INTERFACE, /* bDescriptorType */ \
@@ -524,7 +524,7 @@ struct cdc_ncm_ndp16 {
int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \
0x08, 0x00, /* wMaxPacketSize */ \
0x10, /* bInterval */ \
0x05, /* bInterval */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
@@ -596,7 +596,7 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \
0x10, 0x00, /* wMaxPacketSize */ \
0x10, /* bInterval */ \
0x05, /* bInterval */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \

View File

@@ -7,17 +7,21 @@
#include "usbd_cdc_ecm.h"
#define CDC_ECM_OUT_EP_IDX 0
#define CDC_ECM_IN_EP_IDX 1
#define CDC_ECM_INT_EP_IDX 2
#define CDC_ECM_IN_EP_IDX 1
#define CDC_ECM_INT_EP_IDX 2
/* Ethernet Maximum Segment size, typically 1514 bytes */
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1536U
/* Describe EndPoints configuration */
static struct usbd_endpoint cdc_ecm_ep_data[3];
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
#endif
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16];
volatile uint8_t *g_cdc_ecm_rx_data_buffer = NULL;
volatile uint32_t g_cdc_ecm_rx_data_length = 0;
volatile uint32_t g_cdc_ecm_tx_data_length = 0;
@@ -68,8 +72,10 @@ void usbd_cdc_ecm_send_notify(uint8_t notifycode, uint8_t value, uint32_t *speed
break;
}
if (bytes2send) {
usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send);
if (usb_device_is_configured(0)) {
if (bytes2send) {
usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send);
}
}
}
@@ -93,11 +99,11 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
* bit3 Broadcast
* bit4 Multicast
*/
if (g_current_net_status == 0) {
g_current_net_status = 1;
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL);
}
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
g_connect_speed_table[0] = 100000000; /* 100 Mbps */
g_connect_speed_table[1] = 100000000; /* 100 Mbps */
usbd_cdc_ecm_set_connect(true, g_connect_speed_table);
#endif
break;
default:
USB_LOG_WRN("Unhandled CDC ECM Class bRequest 0x%02x\r\n", setup->bRequest);
@@ -117,10 +123,11 @@ void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
g_current_net_status = 0;
g_cdc_ecm_rx_data_length = 0;
g_cdc_ecm_tx_data_length = 0;
g_cdc_ecm_rx_data_buffer = NULL;
break;
case USBD_EVENT_CONFIGURED:
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
#endif
break;
default:
@@ -132,14 +139,8 @@ void cdc_ecm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
(void)busid;
g_cdc_ecm_rx_data_length += nbytes;
if (nbytes < usbd_get_ep_mps(0, ep)) {
g_cdc_ecm_rx_data_buffer = g_cdc_ecm_rx_buffer;
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
} else {
usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(0, ep));
}
g_cdc_ecm_rx_data_length = nbytes;
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_data_length);
}
void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
@@ -150,6 +151,7 @@ void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
/* send zlp */
usbd_ep_start_write(0, ep, NULL, 0);
} else {
usbd_cdc_ecm_data_send_done(g_cdc_ecm_tx_data_length);
g_cdc_ecm_tx_data_length = 0;
}
}
@@ -160,14 +162,20 @@ void cdc_ecm_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
(void)ep;
(void)nbytes;
if (g_current_net_status == 1) {
g_current_net_status = 2;
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, g_connect_speed_table);
if (g_current_net_status == 2) {
g_current_net_status = 3;
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE, 0, g_connect_speed_table);
} else {
g_current_net_status = 0;
}
}
int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len)
{
if (!usb_device_is_configured(0)) {
return -USB_ERR_NODEV;
}
if (g_cdc_ecm_tx_data_length > 0) {
return -USB_ERR_BUSY;
}
@@ -175,14 +183,17 @@ int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len)
g_cdc_ecm_tx_data_length = len;
USB_LOG_DBG("txlen:%d\r\n", g_cdc_ecm_tx_data_length);
return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, g_cdc_ecm_tx_data_length);
return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, len);
}
void usbd_cdc_ecm_start_read_next(void)
int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len)
{
if (!usb_device_is_configured(0)) {
return -USB_ERR_NODEV;
}
g_cdc_ecm_rx_data_length = 0;
g_cdc_ecm_rx_data_buffer = NULL;
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, g_cdc_ecm_rx_buffer, usbd_get_ep_mps(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
return usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, buf, len);
}
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
@@ -190,19 +201,19 @@ struct pbuf *usbd_cdc_ecm_eth_rx(void)
{
struct pbuf *p;
if (g_cdc_ecm_rx_data_buffer == NULL) {
if (g_cdc_ecm_rx_data_length == 0) {
return NULL;
}
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_data_length, PBUF_POOL);
if (p == NULL) {
usbd_cdc_ecm_start_read_next();
usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
return NULL;
}
usb_memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
p->len = g_cdc_ecm_rx_data_length;
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_data_length);
usbd_cdc_ecm_start_read_next();
usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
return p;
}
@@ -250,13 +261,24 @@ struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const
return intf;
}
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2])
void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2])
{
memcpy(g_connect_speed_table, speed, 8);
if (connect) {
g_current_net_status = 2;
memcpy(g_connect_speed_table, speed, 8);
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL);
} else {
g_current_net_status = 1;
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_DISCONNECTED, NULL);
}
}
__WEAK void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len)
__WEAK void usbd_cdc_ecm_data_recv_done(uint32_t len)
{
(void)len;
}
__WEAK void usbd_cdc_ecm_data_send_done(uint32_t len)
{
(void)buf;
(void)len;
}

View File

@@ -12,21 +12,15 @@
extern "C" {
#endif
/* Ethernet Maximum Segment size, typically 1514 bytes */
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U
/* Init cdc ecm interface driver */
struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const uint8_t int_ep, const uint8_t out_ep, const uint8_t in_ep);
/* Setup request command callback api */
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2]);
void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2]);
/* Api for eth only without any net stack */
uint8_t *usbd_cdc_ecm_get_tx_buffer(void);
void usbd_cdc_ecm_send_done(void);
void usbd_cdc_ecm_data_recv_done(uint32_t len);
void usbd_cdc_ecm_data_send_done(uint32_t len);
int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len);
void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len);
void usbd_cdc_ecm_start_read_next(void);
int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len);
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
#include "lwip/netif.h"

View File

@@ -19,11 +19,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_cdc_acm_class[devno], 0, sizeof(struct usbh_cdc_acm));
g_cdc_acm_class[devno].minor = devno;
return &g_cdc_acm_class[devno];
@@ -34,10 +34,10 @@ static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void)
static void usbh_cdc_acm_class_free(struct usbh_cdc_acm *cdc_acm_class)
{
int devno = cdc_acm_class->minor;
uint8_t devno = cdc_acm_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
}
@@ -266,19 +266,19 @@ const struct usbh_class_driver cdc_data_class_driver = {
};
CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_CDC,
.subclass = CDC_ABSTRACT_CONTROL_MODEL,
.protocol = CDC_COMMON_PROTOCOL_AT_COMMANDS,
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
.bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
.bInterfaceProtocol = 0x00,
.id_table = NULL,
.class_driver = &cdc_acm_class_driver
};
CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
.class = USB_DEVICE_CLASS_CDC_DATA,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = USB_DEVICE_CLASS_CDC_DATA,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = NULL,
.class_driver = &cdc_data_class_driver
};

View File

@@ -231,12 +231,12 @@ static int usbh_cdc_ecm_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
void usbh_cdc_ecm_rx_thread(void *argument)
void usbh_cdc_ecm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_cdc_ecm_rx_length;
int ret;
(void)argument;
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create cdc ecm rx thread\r\n");
// clang-format off
find_class:
@@ -323,9 +323,9 @@ const struct usbh_class_driver cdc_ecm_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info cdc_ecm_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_CDC,
.subclass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL,
.protocol = CDC_COMMON_PROTOCOL_NONE,
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
.bInterfaceSubClass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL,
.bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE,
.id_table = NULL,
.class_driver = &cdc_ecm_class_driver
};

View File

@@ -41,7 +41,7 @@ void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class);
uint8_t *usbh_cdc_ecm_get_eth_txbuf(void);
int usbh_cdc_ecm_eth_output(uint32_t buflen);
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ecm_rx_thread(void *argument);
void usbh_cdc_ecm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}

View File

@@ -48,7 +48,7 @@ static int usbh_cdc_ncm_get_ntb_parameters(struct usbh_cdc_ncm *cdc_ncm_class, s
setup->wLength = 28;
ret = usbh_control_transfer(cdc_ncm_class->hport, setup, g_cdc_ncm_buf);
if (ret < 0) {
if (ret < 8) {
return ret;
}
@@ -62,12 +62,12 @@ static void print_ntb_parameters(struct cdc_ncm_ntb_parameters *param)
USB_LOG_RAW("wLength: 0x%02x \r\n", param->wLength);
USB_LOG_RAW("bmNtbFormatsSupported: %s \r\n", param->bmNtbFormatsSupported ? "NTB16" : "NTB32");
USB_LOG_RAW("dwNtbInMaxSize: 0x%04x \r\n", param->dwNtbInMaxSize);
USB_LOG_RAW("dwNtbInMaxSize: 0x%08lx \r\n", param->dwNtbInMaxSize);
USB_LOG_RAW("wNdbInDivisor: 0x%02x \r\n", param->wNdbInDivisor);
USB_LOG_RAW("wNdbInPayloadRemainder: 0x%02x \r\n", param->wNdbInPayloadRemainder);
USB_LOG_RAW("wNdbInAlignment: 0x%02x \r\n", param->wNdbInAlignment);
USB_LOG_RAW("dwNtbOutMaxSize: 0x%04x \r\n", param->dwNtbOutMaxSize);
USB_LOG_RAW("dwNtbOutMaxSize: 0x%08lx \r\n", param->dwNtbOutMaxSize);
USB_LOG_RAW("wNdbOutDivisor: 0x%02x \r\n", param->wNdbOutDivisor);
USB_LOG_RAW("wNdbOutPayloadRemainder: 0x%02x \r\n", param->wNdbOutPayloadRemainder);
USB_LOG_RAW("wNdbOutAlignment: 0x%02x \r\n", param->wNdbOutAlignment);
@@ -249,7 +249,7 @@ static int usbh_cdc_ncm_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
void usbh_cdc_ncm_rx_thread(void *argument)
void usbh_cdc_ncm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_cdc_ncm_rx_length;
int ret;
@@ -259,7 +259,7 @@ void usbh_cdc_ncm_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
(void)argument;
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
// clang-format off
find_class:
@@ -403,9 +403,9 @@ const struct usbh_class_driver cdc_ncm_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info cdc_ncm_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_CDC,
.subclass = CDC_NETWORK_CONTROL_MODEL,
.protocol = CDC_COMMON_PROTOCOL_NONE,
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
.bInterfaceSubClass = CDC_NETWORK_CONTROL_MODEL,
.bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE,
.id_table = NULL,
.class_driver = &cdc_ncm_class_driver
};

View File

@@ -45,7 +45,7 @@ void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class);
uint8_t *usbh_cdc_ncm_get_eth_txbuf(void);
int usbh_cdc_ncm_eth_output(uint32_t buflen);
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ncm_rx_thread(void *argument);
void usbh_cdc_ncm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}

View File

@@ -191,11 +191,11 @@
#define HID_MOUSE_INPUT_REPORT_BUTTON3 (1 << 2)
#define HID_MOUSE_INPUT_REPORT_BUTTON_MASK (7)
#define HID_MOUSE_INPUT_BUTTON_LEFT (1 << 0)
#define HID_MOUSE_INPUT_BUTTON_RIGHT (1 << 1)
#define HID_MOUSE_INPUT_BUTTON_MIDDLE (1 << 2)
#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
#define HID_MOUSE_INPUT_BUTTON_FORWARD (1 << 4)
#define HID_MOUSE_INPUT_BUTTON_LEFT (1 << 0)
#define HID_MOUSE_INPUT_BUTTON_RIGHT (1 << 1)
#define HID_MOUSE_INPUT_BUTTON_MIDDLE (1 << 2)
#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
#define HID_MOUSE_INPUT_BUTTON_FORWARD (1 << 4)
/* Joystick input report (4 bytes) (HID D.1) */
#define HID_JS_INPUT_REPORT_HATSWITCH_SHIFT (0)
@@ -241,14 +241,14 @@
#define HID_DESKTOP_USAGE_UNDEFINED 0x00 /* Undefined */
#define HID_DESKTOP_USAGE_POINTER 0x01 /* Pointer */
#define HID_DESKTOP_USAGE_MOUSE 0x02 /* Mouse */
/* 0x03 Reserved */
/* 0x03 Reserved */
#define HID_DESKTOP_USAGE_JOYSTICK 0x04 /* Joystick */
#define HID_DESKTOP_USAGE_GAMEPAD 0x05 /* Game Pad */
#define HID_DESKTOP_USAGE_KEYBOARD 0x06 /* Keyboard */
#define HID_DESKTOP_USAGE_KEYPAD 0x07 /* Keypad */
#define HID_DESKTOP_USAGE_MULTIAXIS 0x08 /* Multi-axis Controller */
#define HID_DESKTOP_USAGE_TABLET 0x09 /* Tablet PC System Controls */
/* 0x0a-2f Reserved */
/* 0x0a-2f Reserved */
#define HID_DESKTOP_USAGE_X 0x30 /* X */
#define HID_DESKTOP_USAGE_Y 0x31 /* Y */
#define HID_DESKTOP_USAGE_Z 0x32 /* Z */
@@ -264,7 +264,7 @@
#define HID_DESKTOP_USAGE_MOTION 0x3c /* Motion Wakeup */
#define HID_DESKTOP_USAGE_START 0x3d /* Start */
#define HID_DESKTOP_USAGE_SELECT 0x3e /* Select */
/* 0x3f Reserved */
/* 0x3f Reserved */
#define HID_DESKTOP_USAGE_VX 0x40 /* Vx */
#define HID_DESKTOP_USAGE_VY 0x41 /* Vy */
#define HID_DESKTOP_USAGE_VZ 0x42 /* Vz */
@@ -274,7 +274,7 @@
#define HID_DESKTOP_USAGE_VNO 0x46 /* Vno */
#define HID_DESKTOP_USAGE_FEATURE 0x47 /* Feature Notification */
#define HID_DESKTOP_USAGE_RESOLUTION 0x48 /* Resolution Multiplier */
/* 0x49-7f Reserved */
/* 0x49-7f Reserved */
#define HID_DESKTOP_USAGE_CONTROL 0x80 /* System Control */
#define HID_DESKTOP_USAGE_POWERDOWN 0x81 /* System Power Down */
#define HID_DESKTOP_USAGE_SLEEP 0x82 /* System Sleep */
@@ -295,7 +295,7 @@
#define HID_DESKTOP_USAGE_DPAD_DOWN 0x91 /* D-pad Down */
#define HID_DESKTOP_USAGE_DPAD_RIGHT 0x92 /* D-pad Right */
#define HID_DESKTOP_USAGE_DPAD_LEFT 0x93 /* D-pad Left */
/* 0x94-9f Reserved */
/* 0x94-9f Reserved */
#define HID_DESKTOP_USAGE_DOCK 0xa0 /* System Dock */
#define HID_DESKTOP_USAGE_UNDOCK 0xa1 /* System Undock */
#define HID_DESKTOP_USAGE_SETUP 0xa2 /* System Setup */
@@ -305,7 +305,7 @@
#define HID_DESKTOP_USAGE_APP_DEBUG_BREAK 0xa6 /* Application Debugger Break */
#define HID_DESKTOP_USAGE_MUTE 0xa7 /* System Speaker Mute */
#define HID_DESKTOP_USAGE_HIBERNATE 0xa8 /* System Hibernate */
/* 0xa9-af Reserved */
/* 0xa9-af Reserved */
#define HID_DESKTOP_USAGE_DISPLAY_INVERT 0xb0 /* System Display Invert */
#define HID_DESKTOP_USAGE_DISPALY_INTERNAL 0xb1 /* System Display Internal */
#define HID_DESKTOP_USAGE_DISPLAY_EXTERNAL 0xb2 /* System Display External */
@@ -314,7 +314,7 @@
#define HID_DESKTOP_USAGE_DISPLAY_TOGGLE 0xb5 /* System Display Toggle Int/Ext */
#define HID_DESKTOP_USAGE_DISPLAY_SWAP 0xb6 /* System Display Swap */
#define HID_DESKTOP_USAGE_ 0xb7 /* System Display LCD Autoscale */
/* 0xb8-ffff Reserved */
/* 0xb8-ffff Reserved */
/* Keyboard usage IDs (HuT 10) */
#define HID_KBD_USAGE_NONE 0x00 /* Reserved (no event indicated) */
@@ -529,16 +529,16 @@
/* HID Report Definitions */
struct usb_hid_class_subdescriptor {
uint8_t bDescriptorType;/* Class descriptor type (See 7.1) */
uint16_t wDescriptorLength;/* Size of the report descriptor */
uint8_t bDescriptorType; /* Class descriptor type (See 7.1) */
uint16_t wDescriptorLength; /* Size of the report descriptor */
} __PACKED;
struct usb_hid_descriptor {
uint8_t bLength; /* Size of the HID descriptor */
uint8_t bDescriptorType;/* HID descriptor type */
uint16_t bcdHID;/* HID class specification release */
uint8_t bCountryCode;/* Country code */
uint8_t bNumDescriptors;/* Number of descriptors (>=1) */
uint8_t bLength; /* Size of the HID descriptor */
uint8_t bDescriptorType; /* HID descriptor type */
uint16_t bcdHID; /* HID class specification release */
uint8_t bCountryCode; /* Country code */
uint8_t bNumDescriptors; /* Number of descriptors (>=1) */
/*
* Specification says at least one Class Descriptor needs to
@@ -550,11 +550,10 @@ struct usb_hid_descriptor {
/* Standard Reports *********************************************************/
/* Keyboard input report (8 bytes) (HID B.1) */
struct usb_hid_kbd_report
{
uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
uint8_t reserved;
uint8_t key[6]; /* Keycode 1-6 */
struct usb_hid_kbd_report {
uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
uint8_t reserved;
uint8_t key[6]; /* Keycode 1-6 */
};
/* Keyboard output report (1 byte) (HID B.1),
@@ -562,22 +561,109 @@ struct usb_hid_kbd_report
*/
/* Mouse input report (HID B.2) */
struct usb_hid_mouse_report
{
uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
int8_t xdisp; /* X displacement */
int8_t ydisp; /* y displacement */
struct usb_hid_mouse_report {
uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
int8_t xdisp; /* X displacement */
int8_t ydisp; /* y displacement */
/* Device specific additional bytes may follow */
uint8_t wdisp; /* Wheel displacement */
uint8_t wdisp; /* Wheel displacement */
};
/* Joystick input report (1 bytes) (HID D.1) */
struct usb_hid_js_report
{
int8_t xpos; /* X position */
int8_t ypos; /* X position */
uint8_t buttons; /* See USBHID_JSIN_* definitions */
uint8_t throttle; /* Throttle */
struct usb_hid_js_report {
int8_t xpos; /* X position */
int8_t ypos; /* X position */
uint8_t buttons; /* See USBHID_JSIN_* definitions */
uint8_t throttle; /* Throttle */
};
// clang-format off
#define HID_MOUSE_DESCRIPTOR_LEN (9 + 9 + 7)
#define HID_MOUSE_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
0x09, /* bLength: Interface Descriptor size */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
0x00, /* bAlternateSetting: Alternate setting */ \
0x01, /* bNumEndpoints */ \
0x03, /* bInterfaceClass: HID */ \
bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
0x00, /* iInterface: Index of string descriptor */ \
0x09, /* bLength: HID Descriptor size */ \
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \
0x11, /* bcdHID: HID Class Spec release number */ \
0x01, \
0x00, /* bCountryCode: Hardware target country */ \
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \
0x22, /* bDescriptorType */ \
WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
0x07, /* bLength: Endpoint Descriptor size */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
int_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
0x03, /* bmAttributes: Interrupt endpoint */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
bInterval /* bInterval: Polling Interval */
#define HID_KEYBOARD_DESCRIPTOR_LEN (9 + 9 + 7)
#define HID_KEYBOARD_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
0x09, /* bLength: Interface Descriptor size */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
0x00, /* bAlternateSetting: Alternate setting */ \
0x01, /* bNumEndpoints */ \
0x03, /* bInterfaceClass: HID */ \
bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
0x00, /* iInterface: Index of string descriptor */ \
0x09, /* bLength: HID Descriptor size */ \
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \
0x11, /* bcdHID: HID Class Spec release number */ \
0x01, \
0x00, /* bCountryCode: Hardware target country */ \
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \
0x22, /* bDescriptorType */ \
WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
0x07, /* bLength: Endpoint Descriptor size */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
int_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
0x03, /* bmAttributes: Interrupt endpoint */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
bInterval /* bInterval: Polling Interval */
#define HID_CUSTOM_INOUT_DESCRIPTOR_LEN (9 + 9 + 7 + 7)
#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, in_ep, out_ep,wMaxPacketSize, bInterval) \
0x09, /* bLength: Interface Descriptor size */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
0x00, /* bAlternateSetting: Alternate setting */ \
0x02, /* bNumEndpoints */ \
0x03, /* bInterfaceClass: HID */ \
bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
0x00, /* iInterface: Index of string descriptor */ \
0x09, /* bLength: HID Descriptor size */ \
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \
0x11, /* bcdHID: HID Class Spec release number */ \
0x01, \
0x00, /* bCountryCode: Hardware target country */ \
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \
0x22, /* bDescriptorType */ \
WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
0x07, /* bLength: Endpoint Descriptor size */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
in_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
0x03, /* bmAttributes: Interrupt endpoint */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
bInterval, /* bInterval: Polling Interval */ \
0x07, /* bLength: Endpoint Descriptor size */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
out_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
0x03, /* bmAttributes: Interrupt endpoint */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
bInterval /* bInterval: Polling Interval */
// clang-format on
#endif /* USB_HID_H */

View File

@@ -20,18 +20,18 @@
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(256, CONFIG_USB_ALIGN_SIZE)];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS];
static uint32_t g_devinuse = 0;
static struct usbh_hid *usbh_hid_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_HID_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_hid_class[devno], 0, sizeof(struct usbh_hid));
g_hid_class[devno].minor = devno;
return &g_hid_class[devno];
@@ -42,18 +42,17 @@ static struct usbh_hid *usbh_hid_class_alloc(void)
static void usbh_hid_class_free(struct usbh_hid *hid_class)
{
int devno = hid_class->minor;
uint8_t devno = hid_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(hid_class, 0, sizeof(struct usbh_hid));
}
static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer)
int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer, uint32_t buflen)
{
struct usb_setup_packet *setup;
int ret;
if (!hid_class || !hid_class->hport) {
return -USB_ERR_INVAL;
@@ -64,14 +63,9 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = HID_DESCRIPTOR_TYPE_HID_REPORT << 8;
setup->wIndex = hid_class->intf;
setup->wLength = hid_class->report_size;
setup->wLength = buflen;
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
if (ret < 0) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
return ret;
return usbh_control_transfer(hid_class->hport, setup, buffer);
}
int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration)
@@ -109,7 +103,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
setup->wLength = 1;
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
if (ret < 0) {
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
@@ -169,7 +163,7 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
setup->wLength = buflen;
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
if (ret < 0) {
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
@@ -215,11 +209,6 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
}
hid_class->report_size = desc->subdesc[0].wDescriptorLength;
if (hid_class->report_size > sizeof(g_hid_buf[hid_class->minor])) {
USB_LOG_ERR("HID report descriptor too large\r\n");
return -USB_ERR_INVAL;
}
found = true;
goto found;
}
@@ -247,7 +236,8 @@ found:
USB_LOG_WRN("Do not support set idle\r\n");
}
ret = usbh_hid_get_report_descriptor(hid_class, hid_class->report_desc);
/* We read report desc but do nothing (because of too much memory usage for parsing report desc, parsed by users) */
ret = usbh_hid_get_report_descriptor(hid_class, g_hid_buf[hid_class->minor], MIN(sizeof(g_hid_buf[hid_class->minor]), hid_class->report_size));
if (ret < 0) {
return ret;
}
@@ -313,9 +303,9 @@ const struct usbh_class_driver hid_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info hid_custom_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
.class = USB_DEVICE_CLASS_HID,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = USB_DEVICE_CLASS_HID,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = NULL,
.class_driver = &hid_class_driver
};

View File

@@ -15,7 +15,6 @@ struct usbh_hid {
struct usbh_urb intin_urb; /* INTR IN urb */
struct usbh_urb intout_urb; /* INTR OUT urb */
uint8_t report_desc[256];
uint16_t report_size;
uint8_t protocol;
@@ -29,6 +28,7 @@ struct usbh_hid {
extern "C" {
#endif
int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer, uint32_t buflen);
int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration);
int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer);
int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen);

View File

@@ -33,11 +33,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_hub *usbh_hub_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_EXTHUBS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_hub_class[devno], 0, sizeof(struct usbh_hub));
g_hub_class[devno].index = EXTHUB_FIRST_INDEX + devno;
return &g_hub_class[devno];
@@ -48,10 +48,10 @@ static struct usbh_hub *usbh_hub_class_alloc(void)
static void usbh_hub_class_free(struct usbh_hub *hub_class)
{
int devno = hub_class->index - EXTHUB_FIRST_INDEX;
uint8_t devno = hub_class->index - EXTHUB_FIRST_INDEX;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(hub_class, 0, sizeof(struct usbh_hub));
}
@@ -648,12 +648,12 @@ static void usbh_hub_events(struct usbh_hub *hub)
}
}
static void usbh_hub_thread(void *argument)
static void usbh_hub_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
struct usbh_hub *hub;
int ret = 0;
struct usbh_bus *bus = (struct usbh_bus *)argument;
struct usbh_bus *bus = (struct usbh_bus *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
usb_hc_init(bus);
while (1) {
@@ -734,9 +734,9 @@ const struct usbh_class_driver hub_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info hub_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
.class = USB_DEVICE_CLASS_HUB,
.subclass = 0,
.protocol = 0,
.bInterfaceClass = USB_DEVICE_CLASS_HUB,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.id_table = NULL,
.class_driver = &hub_class_driver
};

View File

@@ -60,7 +60,7 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_priv {
} g_usbd_msc[CONFIG_USBDEV_MAX_BUS];
#ifdef CONFIG_USBDEV_MSC_THREAD
static void usbdev_msc_thread(void *argument);
static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#endif
static void usdb_msc_set_max_lun(uint8_t busid)
@@ -109,7 +109,7 @@ void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg)
if (g_usbd_msc[busid].usbd_msc_mq == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_mq\r\n");
}
g_usbd_msc[busid].usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, (void *)busid);
g_usbd_msc[busid].usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, (void *)(uint32_t)busid);
if (g_usbd_msc[busid].usbd_msc_thread == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_thread\r\n");
}
@@ -537,6 +537,7 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
g_usbd_msc[busid].stage = MSC_DATA_IN;
#if defined(CONFIG_USBDEV_MSC_THREAD)
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
return true;
#elif defined(CONFIG_USBDEV_MSC_POLLING)
chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
return true;
@@ -574,6 +575,7 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
g_usbd_msc[busid].stage = MSC_DATA_IN;
#if defined(CONFIG_USBDEV_MSC_THREAD)
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
return true;
#elif defined(CONFIG_USBDEV_MSC_POLLING)
chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
return true;
@@ -909,11 +911,11 @@ void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
}
#if defined(CONFIG_USBDEV_MSC_THREAD)
static void usbdev_msc_thread(void *argument)
static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uintptr_t event;
int ret;
uint8_t busid = (uint8_t)argument;
uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
while (1) {
ret = usb_osal_mq_recv(g_usbd_msc[busid].usbd_msc_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
@@ -975,9 +977,9 @@ struct usbd_interface *usbd_msc_init_intf(uint8_t busid, struct usbd_interface *
for (uint8_t i = 0u; i <= g_usbd_msc[busid].max_lun; i++) {
usbd_msc_get_cap(busid, i, &g_usbd_msc[busid].scsi_blk_nbr[i], &g_usbd_msc[busid].scsi_blk_size[i]);
if (g_usbd_msc[busid].scsi_blk_size[i] > CONFIG_USBDEV_MSC_MAX_BUFSIZE) {
USB_LOG_ERR("msc block buffer overflow\r\n");
return NULL;
if (CONFIG_USBDEV_MSC_MAX_BUFSIZE % g_usbd_msc[busid].scsi_blk_size[i]) {
USB_LOG_ERR("CONFIG_USBDEV_MSC_MAX_BUFSIZE must be a multiple of block size\r\n");
while(1){}
}
}

View File

@@ -13,8 +13,11 @@
#define DEV_FORMAT "/dev/sd%c"
#define MSC_INQUIRY_TIMEOUT 500
#ifndef CONFIG_USBHOST_MSC_READY_CHECK_TIMES
#define CONFIG_USBHOST_MSC_READY_CHECK_TIMES 10
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_cbw_csw[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
static struct usbh_msc g_msc_class[CONFIG_USBHOST_MAX_MSC_CLASS];
@@ -23,11 +26,11 @@ static struct usbh_msc_modeswitch_config *g_msc_modeswitch_config = NULL;
static struct usbh_msc *usbh_msc_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_MSC_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_msc_class[devno], 0, sizeof(struct usbh_msc));
g_msc_class[devno].sdchar = 'a' + devno;
return &g_msc_class[devno];
@@ -38,10 +41,10 @@ static struct usbh_msc *usbh_msc_class_alloc(void)
static void usbh_msc_class_free(struct usbh_msc *msc_class)
{
int devno = msc_class->sdchar - 'a';
uint8_t devno = msc_class->sdchar - 'a';
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(msc_class, 0, sizeof(struct usbh_msc));
}
@@ -131,7 +134,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
/* Send the CBW */
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, timeout);
if (nbytes < 0) {
USB_LOG_ERR("cbw transfer error\r\n");
USB_LOG_ERR("cbw transfer error: %d\r\n", nbytes);
goto __err_exit;
}
@@ -150,7 +153,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
}
if (nbytes < 0) {
USB_LOG_ERR("msc data transfer error\r\n");
USB_LOG_ERR("msc data transfer error: %d\r\n", nbytes);
goto __err_exit;
}
}
@@ -159,7 +162,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
memset(csw, 0, USB_SIZEOF_MSC_CSW);
nbytes = usbh_msc_bulk_in_transfer(msc_class, (uint8_t *)csw, USB_SIZEOF_MSC_CSW, timeout);
if (nbytes < 0) {
USB_LOG_ERR("csw transfer error\r\n");
USB_LOG_ERR("csw transfer error: %d\r\n", nbytes);
goto __err_exit;
}
@@ -184,14 +187,14 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
cbw->bCBLength = SCSICMD_TESTUNITREADY_SIZEOF;
cbw->CB[0] = SCSI_CMD_TESTUNITREADY;
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], NULL, CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
@@ -199,7 +202,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -209,7 +212,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
cbw->CB[0] = SCSI_CMD_REQUESTSENSE;
cbw->CB[4] = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
@@ -217,7 +220,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -227,7 +230,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
cbw->CB[0] = SCSI_CMD_INQUIRY;
cbw->CB[4] = SCSIRESP_INQUIRY_SIZEOF;
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
@@ -235,7 +238,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
struct CBW *cbw;
/* Construct the CBW */
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -244,7 +247,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
cbw->bCBLength = SCSICMD_READCAPACITY10_SIZEOF;
cbw->CB[0] = SCSI_CMD_READCAPACITY10;
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
}
static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message)
@@ -252,18 +255,18 @@ static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t
struct CBW *cbw;
/* Construct the CBW */
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memcpy(g_msc_buf[msc_class->sdchar - 'a'], message, 31);
memcpy(g_msc_cbw_csw[msc_class->sdchar - 'a'], message, 31);
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], NULL, CONFIG_USBHOST_MSC_TIMEOUT);
}
static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;
int ret;
struct usbh_msc_modeswitch_config *config;
int ret;
struct usbh_msc *msc_class = usbh_msc_class_alloc();
if (msc_class == NULL) {
@@ -278,7 +281,12 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
ret = usbh_msc_get_maxlun(msc_class, g_msc_buf[msc_class->sdchar - 'a']);
if (ret < 0) {
return ret;
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;
} else {
return ret;
}
}
USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[msc_class->sdchar - 'a'][0] + 1);
@@ -310,34 +318,6 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
}
}
ret = usbh_msc_scsi_testunitready(msc_class);
if (ret < 0) {
ret = usbh_msc_scsi_requestsense(msc_class);
if (ret < 0) {
USB_LOG_ERR("Fail to scsi_testunitready\r\n");
return ret;
}
}
ret = usbh_msc_scsi_inquiry(msc_class);
if (ret < 0) {
USB_LOG_ERR("Fail to scsi_inquiry\r\n");
return ret;
}
ret = usbh_msc_scsi_readcapacity10(msc_class);
if (ret < 0) {
USB_LOG_ERR("Fail to scsi_readcapacity10\r\n");
return ret;
}
if (msc_class->blocksize > 0) {
USB_LOG_INFO("Capacity info:\r\n");
USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize);
} else {
USB_LOG_ERR("Invalid block size\r\n");
return -USB_ERR_RANGE;
}
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
USB_LOG_INFO("Register MSC Class:%s\r\n", hport->config.intf[intf].devname);
@@ -372,13 +352,52 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
int usbh_msc_scsi_init(struct usbh_msc *msc_class)
{
int ret;
uint16_t cnt;
cnt = 0;
while (usbh_msc_scsi_testunitready(msc_class) < 0) {
USB_LOG_WRN("Device not ready, try again...\r\n");
ret = usbh_msc_scsi_requestsense(msc_class);
if (ret < 0) {
USB_LOG_ERR("Fail to scsi_testunitready\r\n");
}
cnt++;
if (cnt > CONFIG_USBHOST_MSC_READY_CHECK_TIMES) {
return -USB_ERR_NODEV;
}
}
ret = usbh_msc_scsi_inquiry(msc_class);
if (ret < 0) {
USB_LOG_ERR("Fail to scsi_inquiry\r\n");
return ret;
}
ret = usbh_msc_scsi_readcapacity10(msc_class);
if (ret < 0) {
USB_LOG_ERR("Fail to scsi_readcapacity10\r\n");
return ret;
}
if (msc_class->blocksize > 0) {
USB_LOG_INFO("Capacity info:\r\n");
USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize);
} else {
USB_LOG_ERR("Invalid block size\r\n");
return -USB_ERR_RANGE;
}
return 0;
}
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
{
struct CBW *cbw;
/* Construct the CBW */
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -389,7 +408,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
SET_BE32(&cbw->CB[2], start_sector);
SET_BE16(&cbw->CB[7], nsectors);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
}
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
@@ -397,7 +416,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
struct CBW *cbw;
/* Construct the CBW */
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
cbw->dSignature = MSC_CBW_Signature;
@@ -409,7 +428,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
SET_BE32(&cbw->CB[2], start_sector);
SET_BE16(&cbw->CB[7], nsectors);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
}
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
@@ -439,9 +458,9 @@ const struct usbh_class_driver msc_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info msc_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_MASS_STORAGE,
.subclass = MSC_SUBCLASS_SCSI,
.protocol = MSC_PROTOCOL_BULK_ONLY,
.bInterfaceClass = USB_DEVICE_CLASS_MASS_STORAGE,
.bInterfaceSubClass = MSC_SUBCLASS_SCSI,
.bInterfaceProtocol = MSC_PROTOCOL_BULK_ONLY,
.id_table = NULL,
.class_driver = &msc_class_driver
};

View File

@@ -32,6 +32,7 @@ struct usbh_msc_modeswitch_config {
};
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config);
int usbh_msc_scsi_init(struct usbh_msc *msc_class);
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);

View File

@@ -9,11 +9,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_xxx *usbh_xxx_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_CUSTOM_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_xxx_class[devno], 0, sizeof(struct usbh_xxx));
g_xxx_class[devno].minor = devno;
return &g_xxx_class[devno];
@@ -24,10 +24,10 @@ static struct usbh_xxx *usbh_xxx_class_alloc(void)
static void usbh_xxx_class_free(struct usbh_xxx *xxx_class)
{
int devno = xxx_class->minor;
uint8_t devno = xxx_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(xxx_class, 0, sizeof(struct usbh_xxx));
}
@@ -89,9 +89,9 @@ static const struct usbh_class_driver xxx_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info xxx_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = 0,
.subclass = 0,
.protocol = 0,
.bInterfaceClass = 0,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.id_table = NULL,
.class_driver = &xxx_class_driver
};

View File

@@ -70,7 +70,7 @@ static int usbh_asix_read_cmd(struct usbh_asix *asix_class,
setup->wLength = size;
ret = usbh_control_transfer(asix_class->hport, setup, g_asix_buf);
if (ret < 0) {
if (ret < 8) {
return ret;
}
memcpy(data, g_asix_buf, ret - 8);
@@ -98,9 +98,12 @@ static int usbh_asix_write_cmd(struct usbh_asix *asix_class,
setup->wIndex = index;
setup->wLength = size;
memcpy(g_asix_buf, data, size);
return usbh_control_transfer(asix_class->hport, setup, g_asix_buf);
if (data && size) {
memcpy(g_asix_buf, data, size);
return usbh_control_transfer(asix_class->hport, setup, g_asix_buf);
} else {
return usbh_control_transfer(asix_class->hport, setup, NULL);
}
}
static int usbh_asix_mdio_write(struct usbh_asix *asix_class, int phy_id, int loc, int val)
@@ -667,7 +670,7 @@ int usbh_asix_get_connect_status(struct usbh_asix *asix_class)
return 0;
}
void usbh_asix_rx_thread(void *argument)
void usbh_asix_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_asix_rx_length;
int ret;
@@ -680,7 +683,7 @@ void usbh_asix_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
(void)argument;
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create asix rx thread\r\n");
// clang-format off
find_class:
@@ -814,9 +817,9 @@ static const struct usbh_class_driver asix_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info asix_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = asix_id_table,
.class_driver = &asix_class_driver
};

View File

@@ -168,7 +168,7 @@ void usbh_asix_stop(struct usbh_asix *asix_class);
uint8_t *usbh_asix_get_eth_txbuf(void);
int usbh_asix_eth_output(uint32_t buflen);
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_asix_rx_thread(void *argument);
void usbh_asix_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}

View File

@@ -961,7 +961,7 @@ static int usbh_rtl8152_read_regs(struct usbh_rtl8152 *rtl8152_class,
setup->wLength = size;
ret = usbh_control_transfer(rtl8152_class->hport, setup, g_rtl8152_buf);
if (ret < 0) {
if (ret < 8) {
return ret;
}
memcpy(data, g_rtl8152_buf, ret - 8);
@@ -997,9 +997,10 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si
{
uint16_t limit = 64;
int ret = 0;
uint8_t *buf = data;
/* both size and indix must be 4 bytes align */
if ((size & 3) || !size || (index & 3) || !data)
if ((size & 3) || !size || (index & 3) || !buf)
return -USB_ERR_INVAL;
if ((uint32_t)index + (uint32_t)size > 0xffff)
@@ -1007,20 +1008,20 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si
while (size) {
if (size > limit) {
ret = usbh_rtl8152_read_regs(tp, index, type, limit, data);
ret = usbh_rtl8152_read_regs(tp, index, type, limit, buf);
if (ret < 0)
break;
index += limit;
data += limit;
buf += limit;
size -= limit;
} else {
ret = usbh_rtl8152_read_regs(tp, index, type, size, data);
ret = usbh_rtl8152_read_regs(tp, index, type, size, buf);
if (ret < 0)
break;
index += size;
data += size;
buf += size;
size = 0;
break;
}
@@ -1035,9 +1036,10 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b
int ret;
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) || !data)
if ((size & 3) || !size || (index & 3) || !buf)
return -USB_ERR_INVAL;
if ((uint32_t)index + (uint32_t)size > 0xffff)
@@ -1050,12 +1052,12 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b
/* Split the first DWORD if the byte_en is not 0xff */
if (byen != BYTE_EN_DWORD) {
ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, data);
ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, buf);
if (ret < 0)
goto error1;
index += 4;
data += 4;
buf += 4;
size -= 4;
}
@@ -1070,22 +1072,22 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b
if (size > limit) {
ret = usbh_rtl8152_write_regs(tp, index,
type | BYTE_EN_DWORD,
limit, data);
limit, buf);
if (ret < 0)
goto error1;
index += limit;
data += limit;
buf += limit;
size -= limit;
} else {
ret = usbh_rtl8152_write_regs(tp, index,
type | BYTE_EN_DWORD,
size, data);
size, buf);
if (ret < 0)
goto error1;
index += size;
data += size;
buf += size;
size = 0;
break;
}
@@ -1093,7 +1095,7 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b
/* Set the last DWORD */
if (byen != BYTE_EN_DWORD)
ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, data);
ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, buf);
}
error1:
@@ -2128,7 +2130,7 @@ static int usbh_rtl8152_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
void usbh_rtl8152_rx_thread(void *argument)
void usbh_rtl8152_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_rtl8152_rx_length;
int ret;
@@ -2140,7 +2142,7 @@ void usbh_rtl8152_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
(void)argument;
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
// clang-format off
find_class:
@@ -2270,9 +2272,9 @@ static const struct usbh_class_driver rtl8152_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info rtl8152_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = rtl_id_table,
.class_driver = &rtl8152_class_driver
};

View File

@@ -59,7 +59,7 @@ void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class);
uint8_t *usbh_rtl8152_get_eth_txbuf(void);
int usbh_rtl8152_eth_output(uint32_t buflen);
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_rtl8152_rx_thread(void *argument);
void usbh_rtl8152_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}

View File

@@ -17,11 +17,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_ch34x *usbh_ch34x_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_ch34x_class[devno], 0, sizeof(struct usbh_ch34x));
g_ch34x_class[devno].minor = devno;
return &g_ch34x_class[devno];
@@ -32,10 +32,10 @@ static struct usbh_ch34x *usbh_ch34x_class_alloc(void)
static void usbh_ch34x_class_free(struct usbh_ch34x *ch34x_class)
{
int devno = ch34x_class->minor;
uint8_t devno = ch34x_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(ch34x_class, 0, sizeof(struct usbh_ch34x));
}
@@ -370,9 +370,9 @@ const struct usbh_class_driver ch34x_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = ch34x_id_table,
.class_driver = &ch34x_class_driver
};

View File

@@ -17,11 +17,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_cp210x *usbh_cp210x_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_cp210x_class[devno], 0, sizeof(struct usbh_cp210x));
g_cp210x_class[devno].minor = devno;
return &g_cp210x_class[devno];
@@ -32,10 +32,10 @@ static struct usbh_cp210x *usbh_cp210x_class_alloc(void)
static void usbh_cp210x_class_free(struct usbh_cp210x *cp210x_class)
{
int devno = cp210x_class->minor;
uint8_t devno = cp210x_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(cp210x_class, 0, sizeof(struct usbh_cp210x));
}
@@ -319,9 +319,9 @@ const struct usbh_class_driver cp210x_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = cp210x_id_table,
.class_driver = &cp210x_class_driver
};

View File

@@ -17,11 +17,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_ftdi *usbh_ftdi_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_FTDI_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_ftdi_class[devno], 0, sizeof(struct usbh_ftdi));
g_ftdi_class[devno].minor = devno;
return &g_ftdi_class[devno];
@@ -32,10 +32,10 @@ static struct usbh_ftdi *usbh_ftdi_class_alloc(void)
static void usbh_ftdi_class_free(struct usbh_ftdi *ftdi_class)
{
int devno = ftdi_class->minor;
uint8_t devno = ftdi_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(ftdi_class, 0, sizeof(struct usbh_ftdi));
}
@@ -392,9 +392,9 @@ const struct usbh_class_driver ftdi_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = ftdi_id_table,
.class_driver = &ftdi_class_driver
};

View File

@@ -25,11 +25,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_pl2303 *usbh_pl2303_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_PL2303_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_pl2303_class[devno], 0, sizeof(struct usbh_pl2303));
g_pl2303_class[devno].minor = devno;
return &g_pl2303_class[devno];
@@ -40,10 +40,10 @@ static struct usbh_pl2303 *usbh_pl2303_class_alloc(void)
static void usbh_pl2303_class_free(struct usbh_pl2303 *pl2303_class)
{
int devno = pl2303_class->minor;
uint8_t devno = pl2303_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(pl2303_class, 0, sizeof(struct usbh_pl2303));
}
@@ -440,9 +440,9 @@ const struct usbh_class_driver pl2303_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info pl2303_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = pl2303_id_table,
.class_driver = &pl2303_class_driver
};

View File

@@ -347,7 +347,7 @@ static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
void usbh_bl616_rx_thread(void *argument)
void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
usb_data_t *usb_hdr;
@@ -356,7 +356,7 @@ void usbh_bl616_rx_thread(void *argument)
rnm_scan_ind_msg_t *scanmsg;
uint8_t *data;
(void)argument;
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create bl616 wifi rx thread\r\n");
while (1) {
@@ -504,9 +504,9 @@ static const struct usbh_class_driver bl616_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info bl616_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = bl616_id_table,
.class_driver = &bl616_class_driver
};

View File

@@ -205,7 +205,7 @@ void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t
uint8_t *usbh_bl616_get_eth_txbuf(void);
int usbh_bl616_eth_output(uint32_t buflen);
void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_bl616_rx_thread(void *argument);
void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
void usbh_bl616_run(struct usbh_bl616 *bl616_class);
void usbh_bl616_stop(struct usbh_bl616 *bl616_class);

View File

@@ -15,11 +15,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_xbox *usbh_xbox_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_XBOX_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_xbox_class[devno], 0, sizeof(struct usbh_xbox));
g_xbox_class[devno].minor = devno;
return &g_xbox_class[devno];
@@ -30,10 +30,10 @@ static struct usbh_xbox *usbh_xbox_class_alloc(void)
static void usbh_xbox_class_free(struct usbh_xbox *xbox_class)
{
int devno = xbox_class->minor;
uint8_t devno = xbox_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(xbox_class, 0, sizeof(struct usbh_xbox));
}
@@ -220,9 +220,9 @@ static const uint16_t xbox_id_table[][2] = {
CLASS_INFO_DEFINE const struct usbh_class_info xbox_custom_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_VEND_SPECIFIC,
.subclass = 0x5d,
.protocol = 0x01,
.bInterfaceClass = USB_DEVICE_CLASS_VEND_SPECIFIC,
.bInterfaceSubClass = 0x5d,
.bInterfaceProtocol = 0x01,
.id_table = xbox_id_table,
.class_driver = &xbox_class_driver
};

View File

@@ -18,6 +18,20 @@ struct usbd_video_priv {
uint8_t power_mode;
uint8_t error_code;
struct video_entity_info info[3];
uint8_t *ep_buf0;
uint8_t *ep_buf1;
bool ep_buf0_ready;
bool ep_buf1_ready;
uint32_t ep_buf0_len;
uint32_t ep_buf1_len;
uint8_t ep_buf_idx;
bool stream_finish;
uint32_t max_packets;
uint8_t *stream_buf;
uint32_t stream_len;
uint32_t stream_offset;
uint8_t stream_frameid;
uint32_t stream_headerlen;
} g_usbd_video[CONFIG_USBDEV_MAX_BUS];
static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
@@ -671,7 +685,7 @@ static int video_class_interface_request_handler(uint8_t busid, struct usb_setup
} else {
return usbd_video_control_unit_terminal_request_handler(busid, setup, data, len); /* Unit and Terminal Requests */
}
} else if (intf_num == 1) { /* Video Stream Inteface */
} else if (intf_num == 1) { /* Video Stream Inteface */
return usbd_video_stream_request_handler(busid, setup, data, len); /* Interface Stream Requests */
}
return -1;
@@ -700,7 +714,7 @@ static void video_notify_handler(uint8_t busid, uint8_t event, void *arg)
}
}
void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize)
static void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize)
{
g_usbd_video[busid].probe.hintUnion.bmHint = 0x01;
g_usbd_video[busid].probe.hintUnion1.bmHint = 0;
@@ -737,9 +751,47 @@ void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameIn
g_usbd_video[busid].commit.bPreferedVersion = 0;
g_usbd_video[busid].commit.bMinVersion = 0;
g_usbd_video[busid].commit.bMaxVersion = 0;
g_usbd_video[busid].stream_frameid = 0;
g_usbd_video[busid].stream_headerlen = 2;
}
struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface *intf,
static uint32_t usbd_video_prepare_ep_buf_data(uint8_t busid, uint32_t remain, uint8_t *ep_buf)
{
struct video_payload_header *header;
uint32_t len;
uint32_t offset;
len = MIN(remain, (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen) * g_usbd_video[busid].max_packets);
offset = 0;
while (len > 0) {
header = (struct video_payload_header *)&ep_buf[offset];
header->bHeaderLength = g_usbd_video[busid].stream_headerlen;
header->headerInfoUnion.bmheaderInfo = 0;
header->headerInfoUnion.headerInfoBits.endOfHeader = 1;
header->headerInfoUnion.headerInfoBits.endOfFrame = 0;
header->headerInfoUnion.headerInfoBits.frameIdentifier = g_usbd_video[busid].stream_frameid;
uint32_t len2 = MIN(len, g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen);
usb_memcpy(&ep_buf[offset + g_usbd_video[busid].stream_headerlen],
&g_usbd_video[busid].stream_buf[g_usbd_video[busid].stream_offset],
len2);
g_usbd_video[busid].stream_offset += len2;
len -= len2;
offset += (len2 + g_usbd_video[busid].stream_headerlen);
if (g_usbd_video[busid].stream_offset == g_usbd_video[busid].stream_len) {
header->headerInfoUnion.headerInfoBits.endOfFrame = 1;
}
}
return offset;
}
struct usbd_interface *usbd_video_init_intf(uint8_t busid,
struct usbd_interface *intf,
uint32_t dwFrameInterval,
uint32_t dwMaxVideoFrameSize,
uint32_t dwMaxPayloadTransferSize)
@@ -763,28 +815,70 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface
return intf;
}
uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len)
bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep)
{
uint32_t packets;
uint32_t last_packet_size;
uint32_t picture_pos = 0;
static uint8_t uvc_header[2] = { 0x02, 0x80 };
uint32_t remain;
packets = (input_len + (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2) ) / (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2);
last_packet_size = input_len - ((packets - 1) * (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2));
for (size_t i = 0; i < packets; i++) {
output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i] = uvc_header[0];
output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i + 1] = uvc_header[1];
if (i == (packets - 1)) {
memcpy(&output[2 + g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i], &input[picture_pos], last_packet_size);
output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i + 1] |= (1 << 1);
} else {
memcpy(&output[2 + g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i], &input[picture_pos], g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2);
picture_pos += g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2;
if (g_usbd_video[busid].ep_buf1_ready && (g_usbd_video[busid].ep_buf_idx == 0)) { /* callback: buf1 ready and buf0 was sent */
g_usbd_video[busid].ep_buf0_ready = false;
g_usbd_video[busid].ep_buf_idx = 1;
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf1, g_usbd_video[busid].ep_buf1_len);
} else if (g_usbd_video[busid].ep_buf0_ready && (g_usbd_video[busid].ep_buf_idx == 1)) { /* callback: buf0 ready and buf1 was sent */
g_usbd_video[busid].ep_buf1_ready = false;
g_usbd_video[busid].ep_buf_idx = 0;
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len);
} else {
if (g_usbd_video[busid].stream_finish) {
return true;
}
}
uvc_header[1] ^= 1;
*out_len = (input_len + 2 * packets);
return packets;
}
if (!g_usbd_video[busid].ep_buf0_ready) {
remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset;
if (remain == 0) {
g_usbd_video[busid].stream_frameid ^= 1;
g_usbd_video[busid].stream_finish = true;
} else {
g_usbd_video[busid].ep_buf0_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf0);
g_usbd_video[busid].ep_buf0_ready = true;
if (!g_usbd_video[busid].ep_buf1_ready) {
g_usbd_video[busid].ep_buf_idx = 0;
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len);
}
}
}
if (!g_usbd_video[busid].ep_buf1_ready) {
remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset;
if (remain == 0) {
g_usbd_video[busid].stream_frameid ^= 1;
g_usbd_video[busid].stream_finish = true;
} else {
g_usbd_video[busid].ep_buf1_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf1);
g_usbd_video[busid].ep_buf1_ready = true;
}
}
return false;
}
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len)
{
if ((usb_device_is_configured(busid) == 0) || (stream_len == 0)) {
return -1;
}
g_usbd_video[busid].ep_buf0 = ep_buf0;
g_usbd_video[busid].ep_buf1 = ep_buf1;
g_usbd_video[busid].ep_buf0_ready = false;
g_usbd_video[busid].ep_buf1_ready = false;
g_usbd_video[busid].ep_buf_idx = 0;
g_usbd_video[busid].stream_finish = false;
g_usbd_video[busid].max_packets = ep_bufsize / g_usbd_video[busid].probe.dwMaxPayloadTransferSize;
g_usbd_video[busid].stream_buf = stream_buf;
g_usbd_video[busid].stream_len = stream_len;
g_usbd_video[busid].stream_offset = 0;
usbd_video_stream_split_transfer(busid, ep);
return 0;
}

View File

@@ -20,7 +20,9 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface
void usbd_video_open(uint8_t busid, uint8_t intf);
void usbd_video_close(uint8_t busid, uint8_t intf);
uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len);
bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep);
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len);
#ifdef __cplusplus
}

View File

@@ -34,11 +34,11 @@ static uint32_t g_devinuse = 0;
static struct usbh_video *usbh_video_class_alloc(void)
{
int devno;
uint8_t devno;
for (devno = 0; devno < CONFIG_USBHOST_MAX_VIDEO_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
if ((g_devinuse & (1U << devno)) == 0) {
g_devinuse |= (1U << devno);
memset(&g_video_class[devno], 0, sizeof(struct usbh_video));
g_video_class[devno].minor = devno;
return &g_video_class[devno];
@@ -49,10 +49,10 @@ static struct usbh_video *usbh_video_class_alloc(void)
static void usbh_video_class_free(struct usbh_video *video_class)
{
int devno = video_class->minor;
uint8_t devno = video_class->minor;
if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
if (devno < 32) {
g_devinuse &= ~(1U << devno);
}
memset(video_class, 0, sizeof(struct usbh_video));
}
@@ -531,18 +531,18 @@ const struct usbh_class_driver video_streaming_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info video_ctrl_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_VIDEO,
.subclass = VIDEO_SC_VIDEOCONTROL,
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
.bInterfaceClass = USB_DEVICE_CLASS_VIDEO,
.bInterfaceSubClass = VIDEO_SC_VIDEOCONTROL,
.bInterfaceProtocol = VIDEO_PC_PROTOCOL_UNDEFINED,
.id_table = NULL,
.class_driver = &video_ctrl_class_driver
};
CLASS_INFO_DEFINE const struct usbh_class_info video_streaming_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_VIDEO,
.subclass = VIDEO_SC_VIDEOSTREAMING,
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
.bInterfaceClass = USB_DEVICE_CLASS_VIDEO,
.bInterfaceSubClass = VIDEO_SC_VIDEOSTREAMING,
.bInterfaceProtocol = VIDEO_PC_PROTOCOL_UNDEFINED,
.id_table = NULL,
.class_driver = &video_streaming_class_driver
};

View File

@@ -37,14 +37,17 @@ struct usbd_rndis_priv {
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
#endif
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8];
volatile uint8_t *g_rndis_rx_data_buffer;
volatile uint32_t g_rndis_rx_data_length;
volatile uint32_t g_rndis_rx_total_length;
volatile uint32_t g_rndis_tx_data_length;
/* RNDIS options list */
@@ -447,12 +450,14 @@ static void rndis_notify_handler(uint8_t busid, uint8_t event, void *arg)
switch (event) {
case USBD_EVENT_RESET:
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
break;
case USBD_EVENT_CONFIGURED:
g_rndis_rx_data_length = 0;
g_rndis_tx_data_length = 0;
break;
case USBD_EVENT_CONFIGURED:
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_CONNECTED;
usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
#endif
break;
default:
@@ -467,10 +472,9 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
(void)busid;
(void)ep;
hdr = (rndis_data_packet_t *)g_rndis_rx_buffer;
g_rndis_rx_data_buffer = g_rndis_rx_buffer;
hdr = (rndis_data_packet_t *)g_rndis_rx_data_buffer;
if ((hdr->MessageType != REMOTE_NDIS_PACKET_MSG) || (nbytes < hdr->MessageLength)) {
usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
usbd_rndis_start_read((uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_total_length);
return;
}
@@ -478,7 +482,7 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
g_rndis_rx_data_buffer += hdr->DataOffset + sizeof(rndis_generic_msg_t);
g_rndis_rx_data_length = hdr->DataLength;
usbd_rndis_data_recv_done();
usbd_rndis_data_recv_done(g_rndis_rx_data_length);
}
void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
@@ -489,6 +493,7 @@ void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
/* send zlp */
usbd_ep_start_write(0, ep, NULL, 0);
} else {
usbd_rndis_data_send_done(g_rndis_tx_data_length);
g_rndis_tx_data_length = 0;
}
}
@@ -502,6 +507,34 @@ void rndis_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
//USB_LOG_DBG("len:%d\r\n", nbytes);
}
int usbd_rndis_start_write(uint8_t *buf, uint32_t len)
{
if (!usb_device_is_configured(0)) {
return -USB_ERR_NODEV;
}
if (g_rndis_tx_data_length > 0) {
return -USB_ERR_BUSY;
}
g_rndis_tx_data_length = len;
USB_LOG_DBG("txlen:%d\r\n", g_rndis_tx_data_length);
return usbd_ep_start_write(0, rndis_ep_data[RNDIS_IN_EP_IDX].ep_addr, buf, len);
}
int usbd_rndis_start_read(uint8_t *buf, uint32_t len)
{
if (!usb_device_is_configured(0)) {
return -USB_ERR_NODEV;
}
g_rndis_rx_data_buffer = buf;
g_rndis_rx_total_length = len;
g_rndis_rx_data_length = 0;
return usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, buf, len);
}
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
#include <lwip/pbuf.h>
@@ -514,15 +547,14 @@ struct pbuf *usbd_rndis_eth_rx(void)
}
p = pbuf_alloc(PBUF_RAW, g_rndis_rx_data_length, PBUF_POOL);
if (p == NULL) {
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
return NULL;
}
usb_memcpy(p->payload, (uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
p->len = g_rndis_rx_data_length;
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_data_length);
g_rndis_rx_data_length = 0;
usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
return p;
}
@@ -592,3 +624,18 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
return intf;
}
void usbd_rndis_set_connect(bool connect)
{
g_usbd_rndis.link_status = connect ? NDIS_MEDIA_STATE_CONNECTED : NDIS_MEDIA_STATE_DISCONNECTED;
}
__WEAK void usbd_rndis_data_recv_done(uint32_t len)
{
(void)len;
}
__WEAK void usbd_rndis_data_send_done(uint32_t len)
{
(void)len;
}

View File

@@ -18,7 +18,12 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
const uint8_t in_ep,
const uint8_t int_ep, uint8_t mac[6]);
void usbd_rndis_data_recv_done(void);
void usbd_rndis_set_connect(bool connect);
void usbd_rndis_data_recv_done(uint32_t len);
void usbd_rndis_data_send_done(uint32_t len);
int usbd_rndis_start_write(uint8_t *buf, uint32_t len);
int usbd_rndis_start_read(uint8_t *buf, uint32_t len);
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
struct pbuf *usbd_rndis_eth_rx(void);

View File

@@ -189,7 +189,7 @@ int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen)
return ret;
}
void usbh_bluetooth_hci_rx_thread(void *argument)
void usbh_bluetooth_hci_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
uint32_t ep_mps;
@@ -271,7 +271,7 @@ int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen)
return ret;
}
void usbh_bluetooth_hci_evt_rx_thread(void *argument)
void usbh_bluetooth_hci_evt_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
uint32_t ep_mps;
@@ -320,7 +320,7 @@ delete :
// clang-format on
}
void usbh_bluetooth_hci_acl_rx_thread(void *argument)
void usbh_bluetooth_hci_acl_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
uint32_t ep_mps;
@@ -393,18 +393,18 @@ static const uint16_t bluetooth_id_table[][2] = {
CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_h4_nrf_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.class = 0xff,
.subclass = 0x00,
.protocol = 0x00,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = bluetooth_id_table,
.class_driver = &bluetooth_class_driver
};
#else
CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_WIRELESS,
.subclass = 0x01,
.protocol = 0x01,
.bInterfaceClass = USB_DEVICE_CLASS_WIRELESS,
.bInterfaceSubClass = 0x01,
.bInterfaceProtocol = 0x01,
.id_table = NULL,
.class_driver = &bluetooth_class_driver
};

View File

@@ -40,10 +40,10 @@ extern "C" {
int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen);
void usbh_bluetooth_hci_read_callback(uint8_t *data, uint32_t len);
#ifdef CONFIG_USBHOST_BLUETOOTH_HCI_H4
void usbh_bluetooth_hci_rx_thread(void *argument);
void usbh_bluetooth_hci_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#else
void usbh_bluetooth_hci_evt_rx_thread(void *argument);
void usbh_bluetooth_hci_acl_rx_thread(void *argument);
void usbh_bluetooth_hci_evt_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
void usbh_bluetooth_hci_acl_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#endif
void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class);

View File

@@ -13,7 +13,7 @@
#define DEV_FORMAT "/dev/rndis"
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[4096];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[512];
#define CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE 1514
#define CONFIG_USBHOST_RNDIS_ETH_MSG_SIZE (CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE + 44)
@@ -80,7 +80,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE;
setup->wValue = 0;
setup->wIndex = 0;
setup->wLength = 4096;
setup->wLength = sizeof(g_rndis_buf);
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp);
if (ret < 0) {
@@ -90,8 +90,8 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
rndis_class->max_transfer_pkts = resp->MaxPacketsPerTransfer;
rndis_class->max_transfer_size = resp->MaxTransferSize;
USB_LOG_INFO("MaxPacketsPerTransfer:%d\r\n", resp->MaxPacketsPerTransfer);
USB_LOG_INFO("MaxTransferSize:%d\r\n", resp->MaxTransferSize);
USB_LOG_INFO("MaxPacketsPerTransfer:%ld\r\n", resp->MaxPacketsPerTransfer);
USB_LOG_INFO("MaxTransferSize:%ld\r\n", resp->MaxTransferSize);
return ret;
}
@@ -138,7 +138,7 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid,
setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE;
setup->wValue = 0;
setup->wIndex = 0;
setup->wLength = 4096;
setup->wLength = sizeof(g_rndis_buf);
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp);
if (ret < 0) {
@@ -195,7 +195,7 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t
setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE;
setup->wValue = 0;
setup->wIndex = 0;
setup->wLength = 4096;
setup->wLength = sizeof(g_rndis_buf);
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp);
if (ret < 0) {
@@ -262,7 +262,7 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class)
setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE;
setup->wValue = 0;
setup->wIndex = 0;
setup->wLength = 4096;
setup->wLength = sizeof(g_rndis_buf);
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp);
if (ret < 0) {
@@ -278,8 +278,8 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
struct usb_endpoint_descriptor *ep_desc;
int ret;
uint32_t *oid_support_list;
unsigned int oid = 0;
unsigned int oid_num = 0;
uint32_t oid = 0;
uint32_t oid_num = 0;
uint32_t data_len;
uint8_t tmp_buffer[512];
uint8_t data[32];
@@ -319,7 +319,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
oid_num = (data_len / 4);
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%d\r\n", oid_num);
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%ld\r\n", oid_num);
oid_support_list = (uint32_t *)tmp_buffer;
@@ -380,21 +380,21 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
}
break;
default:
USB_LOG_WRN("Ignore rndis query iod:%08x\r\n", oid);
USB_LOG_WRN("Ignore rndis query iod:%08lx\r\n", oid);
continue;
}
USB_LOG_INFO("rndis query iod:%08x success\r\n", oid);
USB_LOG_INFO("rndis query iod:%08lx success\r\n", oid);
}
uint32_t packet_filter = 0x0f;
usbh_rndis_set_msg_transfer(rndis_class, OID_GEN_CURRENT_PACKET_FILTER, (uint8_t *)&packet_filter, 4);
ret = usbh_rndis_set_msg_transfer(rndis_class, OID_GEN_CURRENT_PACKET_FILTER, (uint8_t *)&packet_filter, 4);
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 };
usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6);
ret = usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6);
if (ret < 0) {
return ret;
}
@@ -414,7 +414,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
usbh_rndis_run(rndis_class);
return ret;
query_errorout:
USB_LOG_ERR("rndis query iod:%08x error\r\n", oid);
USB_LOG_ERR("rndis query iod:%08lx error\r\n", oid);
return ret;
}
@@ -448,7 +448,7 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
return ret;
}
void usbh_rndis_rx_thread(void *argument)
void usbh_rndis_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uint32_t g_rndis_rx_length;
int ret;
@@ -461,7 +461,7 @@ void usbh_rndis_rx_thread(void *argument)
uint32_t transfer_size = (16 * 1024);
#endif
(void)argument;
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create rndis rx thread\r\n");
// clang-format off
@@ -501,7 +501,7 @@ find_class:
uint32_t total_len = g_rndis_rx_length;
while (g_rndis_rx_length > 0) {
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_length);
USB_LOG_DBG("rxlen:%ld\r\n", g_rndis_rx_length);
pmsg = (rndis_data_packet_t *)(g_rndis_rx_buffer + pmg_offset);
@@ -523,7 +523,7 @@ find_class:
g_rndis_rx_length = 0;
}
} else {
USB_LOG_ERR("offset:%d,remain:%d,total:%d\r\n", pmg_offset, g_rndis_rx_length, total_len);
USB_LOG_ERR("offset:%ld,remain:%ld,total:%ld\r\n", pmg_offset, g_rndis_rx_length, total_len);
g_rndis_rx_length = 0;
USB_LOG_ERR("Error rndis packet message\r\n");
}
@@ -600,9 +600,9 @@ static const struct usbh_class_driver rndis_class_driver = {
CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_WIRELESS,
.subclass = 0x01,
.protocol = 0x03,
.bInterfaceClass = USB_DEVICE_CLASS_WIRELESS,
.bInterfaceSubClass = 0x01,
.bInterfaceProtocol = 0x03,
.id_table = NULL,
.class_driver = &rndis_class_driver
};

View File

@@ -46,7 +46,7 @@ void usbh_rndis_stop(struct usbh_rndis *rndis_class);
uint8_t *usbh_rndis_get_eth_txbuf(void);
int usbh_rndis_eth_output(uint32_t buflen);
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_rndis_rx_thread(void *argument);
void usbh_rndis_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
#ifdef __cplusplus
}

View File

@@ -136,7 +136,7 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
*/
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len);
/* usb dcd irq callback */
/* usb dcd irq callback, called by user */
/**
* @brief Usb connect irq callback.
@@ -194,6 +194,9 @@ void usbd_event_ep_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode);
#endif
/* called by user */
void USBD_IRQHandler(uint8_t busid);
#ifdef __cplusplus
}
#endif

19
common/usb_dcache.h Normal file
View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USB_DCACHE_H
#define USB_DCACHE_H
#ifdef CONFIG_USB_DCACHE_ENABLE
#if CONFIG_USB_ALIGN_SIZE % 32
#error "CONFIG_USB_ALIGN_SIZE must be multiple of 32"
#endif
#else
#define usb_dcache_clean(addr, size)
#define usb_dcache_invalidate(addr, size)
#define usb_dcache_flush(addr, size)
#endif
#endif /* USB_DCACHE_H */

View File

@@ -108,6 +108,9 @@ int usbh_submit_urb(struct usbh_urb *urb);
*/
int usbh_kill_urb(struct usbh_urb *urb);
/* called by user */
void USBH_IRQHandler(uint8_t busid);
#ifdef __cplusplus
}
#endif

View File

@@ -86,10 +86,12 @@ void usb_assert(const char *filename, int linenum);
static inline void usb_hexdump(const void *ptr, uint32_t buflen)
{
unsigned char *buf = (unsigned char *)ptr;
uint32_t i, j;
unsigned int i, j;
(void)buf;
for (i = 0; i < buflen; i += 16) {
CONFIG_USB_PRINTF("%08X:", i);
CONFIG_USB_PRINTF("%08x:", i);
for (j = 0; j < 16; j++)
if (i + j < buflen) {

View File

@@ -10,13 +10,21 @@
#include <string.h>
#include <stdbool.h>
#ifdef __INCLUDE_NUTTX_CONFIG_H
#define CONFIG_USB_OSAL_THREAD_SET_ARGV int argc, char **argv
#define CONFIG_USB_OSAL_THREAD_GET_ARGV ((uintptr_t)strtoul(argv[1], NULL, 16))
#else
#define CONFIG_USB_OSAL_THREAD_SET_ARGV void *argument
#define CONFIG_USB_OSAL_THREAD_GET_ARGV ((uintptr_t)argument)
#endif
#define USB_OSAL_WAITING_FOREVER (0xFFFFFFFFU)
typedef void *usb_osal_thread_t;
typedef void *usb_osal_sem_t;
typedef void *usb_osal_mutex_t;
typedef void *usb_osal_mq_t;
typedef void (*usb_thread_entry_t)(void *argument);
typedef void (*usb_thread_entry_t)(CONFIG_USB_OSAL_THREAD_SET_ARGV);
typedef void (*usb_timer_handler_t)(void *argument);
struct usb_osal_timer {
usb_timer_handler_t handler;

41
common/usb_otg.h Normal file
View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USB_OTG_H
#define USB_OTG_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief usb otg controller hardware or gpio id simulator init.
*
* @return On success will return 0, and others indicate fail.
*/
int usb_otg_init(uint8_t busid);
/**
* @brief usb otg controller hardware or gpio id simulator deinit.
*
* @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);
#ifdef __cplusplus
}
#endif
#endif /* USB_OTG_H */

View File

@@ -207,4 +207,12 @@
#define USB_ALIGN_UP(size, align) (((size) + (align)-1) & ~((align)-1))
#ifndef usb_phyaddr2ramaddr
#define usb_phyaddr2ramaddr(addr) (addr)
#endif
#ifndef usb_ramaddr2phyaddr
#define usb_ramaddr2phyaddr(addr) (addr)
#endif
#endif /* USB_UTIL_H */

View File

@@ -15,7 +15,7 @@
#undef CHERRYUSB_VERSION_STR
#endif
#define CHERRYUSB_VERSION 0x010400
#define CHERRYUSB_VERSION_STR "v1.4.0"
#define CHERRYUSB_VERSION 0x010403
#define CHERRYUSB_VERSION_STR "v1.4.3"
#endif

View File

@@ -4,6 +4,17 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#ifdef CONFIG_USBDEV_EP0_THREAD
#include "usb_osal.h"
#define USB_EP0_STATE_SETUP 0
#define USB_EP0_STATE_IN 1
#define USB_EP0_STATE_OUT 2
#endif
#undef USB_DBG_TAG
#define USB_DBG_TAG "usbd_core"
#include "usb_log.h"
/* general descriptor field offsets */
#define DESC_bLength 0 /** Length offset */
@@ -62,8 +73,13 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
#endif
#ifdef CONFIG_USBDEV_TEST_MODE
bool test_req;
#endif
#ifdef CONFIG_USBDEV_EP0_THREAD
usb_osal_mq_t usbd_ep0_mq;
usb_osal_thread_t usbd_ep0_thread;
#endif
struct usbd_interface *intf[16];
uint8_t intf_altsetting[16];
uint8_t intf_offset;
struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM];
@@ -98,6 +114,7 @@ static bool is_device_configured(uint8_t busid)
* This function sets endpoint configuration according to one specified in USB
* endpoint descriptor and then enables it for data transfers.
*
* @param [in] busid busid
* @param [in] ep Endpoint descriptor byte array
*
* @return true if successfully configured and enabled
@@ -125,6 +142,7 @@ static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descripto
* This function cancels transfers that are associated with endpoint and
* disabled endpoint itself.
*
* @param [in] busid busid
* @param [in] ep Endpoint descriptor byte array
*
* @return true if successfully deconfigured and disabled
@@ -144,6 +162,7 @@ static bool usbd_reset_endpoint(uint8_t busid, const struct usb_endpoint_descrip
* This function parses the list of installed USB descriptors and attempts
* to find the specified USB descriptor.
*
* @param [in] busid busid
* @param [in] type_index Type and index of the descriptor
* @param [out] data Descriptor data
* @param [out] len Descriptor length
@@ -370,6 +389,7 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
* index and alternate setting by parsing the installed USB descriptor list.
* A configuration index of 0 unconfigures the device.
*
* @param [in] busid busid
* @param [in] config_index Configuration index
* @param [in] alt_setting Alternate setting number
*
@@ -426,8 +446,8 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t
}
/* skip to next descriptor */
p += p[DESC_bLength];
current_desc_len += p[DESC_bLength];
p += p[DESC_bLength];
if (current_desc_len >= desc_len && desc_len) {
break;
}
@@ -439,6 +459,7 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t
/**
* @brief set USB interface
*
* @param [in] busid busid
* @param [in] iface Interface index
* @param [in] alt_setting Alternate setting number
*
@@ -489,10 +510,11 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
if (cur_iface == iface) {
ep_desc = (struct usb_endpoint_descriptor *)p;
if (cur_alt_setting != alt_setting) {
if (alt_setting == 0) {
ret = usbd_reset_endpoint(busid, ep_desc);
} else {
} else if (cur_alt_setting == alt_setting) {
ret = usbd_set_endpoint(busid, ep_desc);
} else {
}
}
@@ -503,8 +525,8 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
}
/* skip to next descriptor */
p += p[DESC_bLength];
current_desc_len += p[DESC_bLength];
p += p[DESC_bLength];
if (current_desc_len >= desc_len && desc_len) {
break;
}
@@ -518,6 +540,7 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
/**
* @brief handle a standard device request
*
* @param [in] busid busid
* @param [in] setup The setup packet
* @param [in,out] data Data buffer
* @param [in,out] len Pointer to data length
@@ -613,6 +636,7 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
/**
* @brief handle a standard interface request
*
* @param [in] busid busid
* @param [in] setup The setup packet
* @param [in,out] data Data buffer
* @param [in,out] len Pointer to data length
@@ -674,8 +698,8 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
}
/* skip to next descriptor */
p += p[DESC_bLength];
current_desc_len += p[DESC_bLength];
p += p[DESC_bLength];
if (current_desc_len >= desc_len && desc_len) {
break;
}
@@ -699,11 +723,12 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
ret = false;
break;
case USB_REQUEST_GET_INTERFACE:
(*data)[0] = 0;
(*data)[0] = g_usbd_core[busid].intf_altsetting[intf_num];
*len = 1;
break;
case USB_REQUEST_SET_INTERFACE:
g_usbd_core[busid].intf_altsetting[intf_num] = LO_BYTE(setup->wValue);
usbd_set_interface(busid, setup->wIndex, setup->wValue);
*len = 0;
break;
@@ -719,6 +744,7 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
/**
* @brief handle a standard endpoint request
*
* @param [in] busid busid
* @param [in] setup The setup packet
* @param [in,out] data Data buffer
* @param [in,out] len Pointer to data length
@@ -783,6 +809,7 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet
/**
* @brief handle standard requests (list in chapter 9)
*
* @param [in] busid busid
* @param [in] setup The setup packet
* @param [in,out] data Data buffer
* @param [in,out] len Pointer to data length
@@ -826,8 +853,7 @@ static int usbd_standard_request_handler(uint8_t busid, struct usb_setup_packet
/**
* @brief handler for class requests
*
* If a custom request handler was installed, this handler is called first.
*
* @param [in] busid busid
* @param [in] setup The setup packet
* @param [in,out] data Data buffer
* @param [in,out] len Pointer to data length
@@ -859,8 +885,7 @@ static int usbd_class_request_handler(uint8_t busid, struct usb_setup_packet *se
/**
* @brief handler for vendor requests
*
* If a custom request handler was installed, this handler is called first.
*
* @param [in] busid busid
* @param [in] setup The setup packet
* @param [in,out] data Data buffer
* @param [in,out] len Pointer to data length
@@ -1002,6 +1027,7 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
/**
* @brief handle setup request( standard/class/vendor/other)
*
* @param [in] busid busid
* @param [in] setup The setup packet
* @param [in,out] data Data buffer
* @param [in,out] len Pointer to data length
@@ -1112,12 +1138,10 @@ void usbd_event_reset_handler(uint8_t busid)
g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESET);
}
void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_setup_packet *setup)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
uint8_t *buf;
memcpy(setup, psetup, 8);
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
usbd_print_setup(setup);
#endif
@@ -1163,7 +1187,7 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
#ifdef CONFIG_USBDEV_EP0_INDATA_NO_COPY
g_usbd_core[busid].ep0_data_buf = buf;
#else
memcpy(g_usbd_core[busid].ep0_data_buf, buf, g_usbd_core[busid].ep0_data_buf_residue);
usb_memcpy(g_usbd_core[busid].ep0_data_buf, buf, g_usbd_core[busid].ep0_data_buf_residue);
#endif
} else {
/* use memcpy(*data, xxx, len); has copied into ep0 buffer, we do nothing */
@@ -1182,7 +1206,20 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
}
}
void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
memcpy(setup, psetup, 8);
#ifdef CONFIG_USBDEV_EP0_THREAD
usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_SETUP);
#else
__usbd_event_ep0_setup_complete_handler(busid, setup);
#endif
}
static void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
@@ -1223,11 +1260,12 @@ void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
}
}
void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
(void)ep;
(void)setup;
if (nbytes > 0) {
g_usbd_core[busid].ep0_data_buf += nbytes;
@@ -1236,6 +1274,9 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, 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);
#else
/* Received all, send data to handler */
g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
@@ -1245,6 +1286,7 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
/*Send status to host*/
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
#endif
} else {
/* Start reading the remain data */
usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
@@ -1383,6 +1425,47 @@ int usbd_send_remote_wakeup(uint8_t busid)
}
}
#ifdef CONFIG_USBDEV_EP0_THREAD
static void usbdev_ep0_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uintptr_t event;
int ret;
uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
while (1) {
ret = usb_osal_mq_recv(g_usbd_core[busid].usbd_ep0_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
if (ret < 0) {
continue;
}
USB_LOG_DBG("event:%d\r\n", event);
switch (event) {
case USB_EP0_STATE_SETUP:
__usbd_event_ep0_setup_complete_handler(busid, setup);
break;
case USB_EP0_STATE_IN:
// do nothing
break;
case USB_EP0_STATE_OUT:
/* Received all, send data to handler */
g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
usbd_ep_set_stall(busid, USB_CONTROL_IN_EP0);
continue;
}
/*Send status to host*/
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
break;
default:
break;
}
}
}
#endif
int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
{
int ret;
@@ -1397,6 +1480,21 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
bus = &g_usbdev_bus[busid];
bus->reg_base = reg_base;
#ifdef CONFIG_USBDEV_EP0_THREAD
g_usbd_core[busid].usbd_ep0_mq = usb_osal_mq_create(1);
if (g_usbd_core[busid].usbd_ep0_mq == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_mq\r\n");
while (1) {
}
}
g_usbd_core[busid].usbd_ep0_thread = usb_osal_thread_create("usbd_ep0", CONFIG_USBDEV_EP0_STACKSIZE, CONFIG_USBDEV_EP0_PRIO, usbdev_ep0_thread, (void *)(uint32_t)busid);
if (g_usbd_core[busid].usbd_ep0_thread == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_thread\r\n");
while (1) {
}
}
#endif
g_usbd_core[busid].event_handler = event_handler;
ret = usb_dc_init(busid);
usbd_class_event_notify_handler(busid, USBD_EVENT_INIT, NULL);
@@ -1406,9 +1504,24 @@ 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) {
}
}
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);
}
#endif
return 0;
}

View File

@@ -93,19 +93,22 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
struct usbh_class_info *index = NULL;
for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) {
if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->class == class)) {
if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->bInterfaceClass == class)) {
continue;
}
if ((index->match_flags & USB_CLASS_MATCH_INTF_SUBCLASS) && !(index->subclass == subclass)) {
if ((index->match_flags & USB_CLASS_MATCH_INTF_SUBCLASS) && !(index->bInterfaceSubClass == subclass)) {
continue;
}
if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->protocol == protocol)) {
if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) {
continue;
}
if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) {
/* scan id table */
uint32_t i;
for (i = 0; index->id_table[i][0] && index->id_table[i][0] != vid && index->id_table[i][1] != pid; i++) {
for (i = 0; index->id_table[i][0]; i++) {
if (index->id_table[i][0] == vid && index->id_table[i][1] == pid) {
break;
}
}
/* do not match, continue next */
if (!index->id_table[i][0]) {
@@ -321,6 +324,17 @@ static void usbh_print_hubport_info(struct usbh_hubport *hport)
}
}
static void usbh_print_setup(struct usb_setup_packet *setup)
{
USB_LOG_DBG("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);
}
static int usbh_get_default_mps(int speed)
{
switch (speed) {
@@ -486,7 +500,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
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);
hport->raw_config_desc = usb_osal_malloc(wTotalLength + 1);
if (hport->raw_config_desc == NULL) {
ret = -USB_ERR_NOMEM;
USB_LOG_ERR("No memory to alloc for raw_config_desc\r\n");
@@ -495,6 +509,8 @@ int usbh_enumerate(struct usbh_hubport *hport)
config_value = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bConfigurationValue;
memcpy(hport->raw_config_desc, ep0_request_buffer[hport->bus->busid], wTotalLength);
hport->raw_config_desc[wTotalLength] = '\0';
#ifdef CONFIG_USBHOST_GET_STRING_DESC
uint8_t string_buffer[128];
@@ -649,6 +665,12 @@ 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) {
}
}
bus = &g_usbhost_bus[busid];
usbh_hub_deinitialize(bus);
@@ -663,10 +685,16 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
struct usbh_urb *urb;
int ret;
if (!hport || !setup) {
return -USB_ERR_INVAL;
}
urb = &hport->ep0_urb;
usb_osal_mutex_take(hport->mutex);
usbh_print_setup(setup);
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) {
@@ -823,6 +851,42 @@ static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *
}
}
static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port)
{
struct usbh_hubport *hport;
struct usbh_hub *hub_next;
if (hub->index == hub_index) {
hport = &hub->child[hub_port - 1];
if (hport->connected) {
return hport;
} else {
return NULL;
}
} else {
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) {
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) {
hport = usbh_list_all_hubport(hub_next, hub_index, hub_port);
if (hport) {
return hport;
}
}
}
}
}
}
}
}
return NULL;
}
void *usbh_find_class_instance(const char *devname)
{
usb_slist_t *bus_list;
@@ -847,6 +911,23 @@ void *usbh_find_class_instance(const char *devname)
return NULL;
}
struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port)
{
struct usbh_hub *hub;
struct usbh_bus *bus;
struct usbh_hubport *hport;
size_t flags;
flags = usb_osal_enter_critical_section();
bus = &g_usbhost_bus[busid];
hub = &bus->hcd.roothub;
hport = usbh_list_all_hubport(hub, hub_index, hub_port);
usb_osal_leave_critical_section(flags);
return hport;
}
int lsusb(int argc, char **argv)
{
usb_slist_t *bus_list;

View File

@@ -21,6 +21,7 @@
#include "usb_osal.h"
#include "usbh_hub.h"
#include "usb_memcpy.h"
#include "usb_dcache.h"
#include "usb_version.h"
#ifdef __cplusplus
@@ -61,9 +62,9 @@ extern "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. */
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;
};
@@ -275,6 +276,7 @@ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsett
int usbh_initialize(uint8_t busid, uintptr_t reg_base);
int usbh_deinitialize(uint8_t busid);
void *usbh_find_class_instance(const char *devname);
struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port);
int lsusb(int argc, char **argv);

137
core/usbotg_core.c Normal file
View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbotg_core.h"
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];
static void usbotg_host_initialize(uint8_t busid)
{
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);
}
}
static void usbotg_device_initialize(uint8_t busid)
{
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);
}
}
static void usbotg_rolechange_thread(void *argument)
{
uint8_t busid = (uint8_t)(uintptr_t)argument;
usb_otg_init(busid);
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) {
usbotg_host_initialize(busid);
} else if (usbotg_get_current_mode(busid) == 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))
{
char thread_name[32] = { 0 };
if (busid >= CONFIG_USBHOST_MAX_BUS) {
USB_LOG_ERR("bus overflow\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);
}
}
return 0;
}
int usbotg_deinitialize(uint8_t busid, uint32_t reg_base)
{
if (g_usbotg_core[busid].usbd_initialized) {
g_usbotg_core[busid].usbd_initialized = false;
usbd_deinitialize(busid);
}
if (g_usbotg_core[busid].usbh_initialized) {
g_usbotg_core[busid].usbh_initialized = false;
usbh_deinitialize(busid);
}
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)
{
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) {
USBH_IRQHandler(busid);
} else if (usbotg_get_current_mode(busid) == USBOTG_MODE_DEVICE) {
USBD_IRQHandler(busid);
}
}

34
core/usbotg_core.h Normal file
View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBOTG_CORE_H
#define USBOTG_CORE_H
#ifdef __cplusplus
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);
/* called by user */
void usbotg_trigger_role_change(uint8_t busid);
#ifdef __cplusplus
}
#endif
#endif /* USBOTG_CORE_H */

View File

@@ -108,6 +108,70 @@ struct usb_msosv1_descriptor msosv1_desc = {
.comp_id_property = WINUSB_IFx_WCIDProperties,
};
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS)
};
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 */
"CherryADB", /* Product */
"CherryADB2024", /* 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 msc_bootuf2_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,
.msosv1_descriptor = &msosv1_desc
};
#else
/*!< global descriptor */
static const uint8_t adb_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
@@ -171,15 +235,16 @@ static const uint8_t adb_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -222,7 +287,14 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base)
}
}
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &adb_descriptor);
#else
usbd_desc_register(busid, adb_descriptor);
#endif
#ifndef CONFIG_USBDEV_ADVANCE_DESC
usbd_msosv1_desc_register(busid, &msosv1_desc);
#endif
usbd_add_interface(busid, usbd_adb_init_intf(busid, &intf0, WINUSB_IN_EP, WINUSB_OUT_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);
}

View File

@@ -68,6 +68,73 @@
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
#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, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID),
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ))
};
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 UAC 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 audio_v1_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
const uint8_t audio_v1_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -125,12 +192,12 @@ const uint8_t audio_v1_descriptor[] = {
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'1', 0x00, /* wcChar3 */
'0', 0x00, /* wcChar4 */
'3', 0x00, /* wcChar5 */
'1', 0x00, /* wcChar6 */
'0', 0x00, /* wcChar7 */
'0', 0x00, /* wcChar8 */
'2', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'0' + IN_CHANNEL_NUM, 0x00, /* wcChar9 */
#ifdef CONFIG_USB_HS
///////////////////////////////////////
@@ -144,11 +211,12 @@ const uint8_t audio_v1_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
volatile bool tx_flag = 0;
volatile bool ep_tx_busy_flag = false;
@@ -214,7 +282,11 @@ struct audio_entity_info audio_entity_table[] = {
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &audio_v1_descriptor);
#else
usbd_desc_register(busid, audio_v1_descriptor);
#endif
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 1));
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 1));
usbd_add_endpoint(busid, &audio_in_ep);

View File

@@ -6,19 +6,24 @@
#include "usbd_core.h"
#include "usbd_audio.h"
#define USING_FEEDBACK 0
#define USBD_VID 0xffff
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#ifdef CONFIG_USB_HS
#define EP_INTERVAL 0x04
#define EP_INTERVAL 0x04
#define FEEDBACK_ENDP_PACKET_SIZE 0x04
#else
#define EP_INTERVAL 0x01
#define EP_INTERVAL 0x01
#define FEEDBACK_ENDP_PACKET_SIZE 0x03
#endif
#define AUDIO_IN_EP 0x81
#define AUDIO_OUT_EP 0x02
#define AUDIO_OUT_FEEDBACK_EP 0x83
#define AUDIO_IN_FU_ID 0x02
#define AUDIO_OUT_FU_ID 0x05
@@ -38,6 +43,7 @@
/* 16bit(2 Bytes) 双声道(Mono:2) */
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_MIC_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * 2) / 1000))
#if USING_FEEDBACK == 0
#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \
AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
@@ -48,6 +54,18 @@
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \
AUDIO_AS_DESCRIPTOR_INIT_LEN(1))
#else
#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \
AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(1))
#endif
#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
@@ -57,6 +75,84 @@
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
#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, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02),
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
#if USING_FEEDBACK == 0
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
#else
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,
EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
#endif
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ))
};
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 UAC 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 audio_v1_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
const uint8_t audio_v1_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -67,8 +163,13 @@ const uint8_t audio_v1_descriptor[] = {
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
#if USING_FEEDBACK == 0
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
#else
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,
EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
#endif
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
///////////////////////////////////////
@@ -120,13 +221,17 @@ const uint8_t audio_v1_descriptor[] = {
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'1', 0x00, /* wcChar3 */
'0', 0x00, /* wcChar4 */
'3', 0x00, /* wcChar5 */
'1', 0x00, /* wcChar6 */
'0', 0x00, /* wcChar7 */
'0', 0x00, /* wcChar8 */
'2', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
#if USING_FEEDBACK == 0
'1', 0x00, /* wcChar9 */
#else
'2', 0x00, /* wcChar9 */
#endif
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
@@ -139,14 +244,16 @@ const uint8_t audio_v1_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
volatile bool tx_flag = 0;
volatile bool rx_flag = 0;
@@ -183,6 +290,9 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
rx_flag = 1;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
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);
printf("OPEN1\r\n");
} else {
tx_flag = 1;
@@ -215,6 +325,16 @@ void usbd_audio_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
ep_tx_busy_flag = false;
}
#if USING_FEEDBACK == 1
void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
}
#endif
static struct usbd_endpoint audio_in_ep = {
.ep_cb = usbd_audio_in_callback,
.ep_addr = AUDIO_IN_EP
@@ -225,6 +345,13 @@ static struct usbd_endpoint audio_out_ep = {
.ep_addr = AUDIO_OUT_EP
};
#if USING_FEEDBACK == 1
static struct usbd_endpoint audio_out_feedback_ep = {
.ep_cb = usbd_audio_iso_out_feedback_callback,
.ep_addr = AUDIO_OUT_FEEDBACK_EP
};
#endif
struct usbd_interface intf0;
struct usbd_interface intf1;
struct usbd_interface intf2;
@@ -240,13 +367,19 @@ struct audio_entity_info audio_entity_table[] = {
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &audio_v1_descriptor);
#else
usbd_desc_register(busid, audio_v1_descriptor);
#endif
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 2));
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 2));
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0100, audio_entity_table, 2));
usbd_add_endpoint(busid, &audio_in_ep);
usbd_add_endpoint(busid, &audio_out_ep);
#if USING_FEEDBACK == 1
usbd_add_endpoint(busid, &audio_out_feedback_ep);
#endif
usbd_initialize(busid, reg_base, usbd_event_handler);
}

View File

@@ -72,6 +72,74 @@
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00),
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, 0x01, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, INPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x03, 0x01, 0x0000),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
};
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 UAC 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 audio_v2_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
const uint8_t audio_v2_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -149,11 +217,12 @@ const uint8_t audio_v2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static const uint8_t mic_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(1),
@@ -162,7 +231,10 @@ static const uint8_t mic_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_4B(0x00)
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
volatile bool tx_flag = 0;
volatile bool ep_tx_busy_flag = false;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -210,6 +282,7 @@ void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sam
void usbd_audio_iso_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
ep_tx_busy_flag = false;
}
static struct usbd_endpoint audio_in_ep = {
@@ -231,7 +304,11 @@ struct audio_entity_info audio_entity_table[] = {
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &audio_v2_descriptor);
#else
usbd_desc_register(busid, audio_v2_descriptor);
#endif
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2));
usbd_add_endpoint(busid, &audio_in_ep);
@@ -242,5 +319,13 @@ void audio_v2_init(uint8_t busid, uintptr_t reg_base)
void audio_v2_test(uint8_t busid)
{
if (tx_flag) {
memset(write_buffer, 'a', AUDIO_IN_PACKET);
ep_tx_busy_flag = true;
usbd_ep_start_write(busid, AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
while (ep_tx_busy_flag) {
if (tx_flag == false) {
break;
}
}
}
}

View File

@@ -114,6 +114,79 @@
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00),
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
};
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 UAC 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 audio_v2_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
uint8_t audio_v2_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -196,11 +269,12 @@ uint8_t audio_v2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static const uint8_t speaker_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(5),
@@ -233,6 +307,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
volatile bool tx_flag = 0;
volatile bool rx_flag = 0;
volatile bool ep_tx_busy_flag = false;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -293,20 +368,6 @@ void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sam
}
}
void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
{
uint16_t packet_size = 0;
if (ep == AUDIO_OUT_EP) {
packet_size = ((sampling_freq * 2 * OUT_CHANNEL_NUM) / 1000);
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 11] = packet_size;
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 10] = packet_size >> 8;
} else if (ep == AUDIO_IN_EP) {
packet_size = ((sampling_freq * 2 * IN_CHANNEL_NUM) / 1000);
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 11] = packet_size;
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 10] = packet_size >> 8;
}
}
void usbd_audio_iso_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
@@ -348,7 +409,11 @@ struct audio_entity_info audio_entity_table[] = {
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &audio_v2_descriptor);
#else
usbd_desc_register(busid, audio_v2_descriptor);
#endif
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4));
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 4));
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0200, audio_entity_table, 4));
@@ -361,6 +426,14 @@ void audio_v2_init(uint8_t busid, uintptr_t reg_base)
void audio_v2_test(uint8_t busid)
{
if (tx_flag) {
memset(write_buffer, 'a', AUDIO_IN_PACKET);
ep_tx_busy_flag = true;
usbd_ep_start_write(busid, AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
while (ep_tx_busy_flag) {
if (tx_flag == false) {
break;
}
}
}
if (rx_flag) {
}

View File

@@ -6,18 +6,23 @@
#include "usbd_core.h"
#include "usbd_audio.h"
#define USING_FEEDBACK 0
#define USBD_VID 0xffff
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#ifdef CONFIG_USB_HS
#define EP_INTERVAL 0x04
#define EP_INTERVAL 0x04
#define FEEDBACK_ENDP_PACKET_SIZE 0x04
#else
#define EP_INTERVAL 0x01
#define EP_INTERVAL 0x01
#define FEEDBACK_ENDP_PACKET_SIZE 0x03
#endif
#define AUDIO_OUT_EP 0x01
#define AUDIO_OUT_EP 0x01
#define AUDIO_OUT_FEEDBACK_EP 0x82
#define AUDIO_OUT_CLOCK_ID 0x01
#define AUDIO_OUT_FU_ID 0x03
@@ -58,6 +63,7 @@
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
#if USING_FEEDBACK == 0
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
@@ -65,6 +71,15 @@
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
#else
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN)
#endif
#define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
@@ -72,6 +87,78 @@
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00),
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
#if USING_FEEDBACK == 0
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
#else
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
#endif
};
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 UAC 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 audio_v2_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
const uint8_t audio_v2_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -80,7 +167,11 @@ const uint8_t audio_v2_descriptor[] = {
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
#if USING_FEEDBACK == 0
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
#else
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
#endif
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
@@ -136,7 +227,11 @@ const uint8_t audio_v2_descriptor[] = {
'1', 0x00, /* wcChar6 */
'0', 0x00, /* wcChar7 */
'0', 0x00, /* wcChar8 */
'3', 0x00, /* wcChar9 */
#if USING_FEEDBACK == 0
'3', 0x00, /* wcChar9 */
#else
'4', 0x00, /* wcChar9 */
#endif
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
@@ -149,11 +244,12 @@ const uint8_t audio_v2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static const uint8_t default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(5),
@@ -175,6 +271,7 @@ static const uint8_t default_sampling_freq_table[] = {
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
volatile bool rx_flag = 0;
@@ -208,6 +305,14 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
rx_flag = 1;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
#ifdef CONFIG_USB_HS
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
#else
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
#endif
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
USB_LOG_RAW("OPEN\r\n");
}
@@ -230,11 +335,33 @@ void usbd_audio_iso_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
}
#if USING_FEEDBACK == 1
void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
#ifdef CONFIG_USB_HS
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
#else
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
#endif
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
}
#endif
static struct usbd_endpoint audio_out_ep = {
.ep_cb = usbd_audio_iso_out_callback,
.ep_addr = AUDIO_OUT_EP
};
#if USING_FEEDBACK == 1
static struct usbd_endpoint audio_out_feedback_ep = {
.ep_cb = usbd_audio_iso_out_feedback_callback,
.ep_addr = AUDIO_OUT_FEEDBACK_EP
};
#endif
struct usbd_interface intf0;
struct usbd_interface intf1;
@@ -249,11 +376,17 @@ struct audio_entity_info audio_entity_table[] = {
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &audio_v2_descriptor);
#else
usbd_desc_register(busid, audio_v2_descriptor);
#endif
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2));
usbd_add_endpoint(busid, &audio_out_ep);
#if USING_FEEDBACK == 1
usbd_add_endpoint(busid, &audio_out_feedback_ep);
#endif
usbd_initialize(busid, reg_base, usbd_event_handler);
}

View File

@@ -23,6 +23,69 @@
#define MSC_MAX_MPS 64
#endif
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_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 UF2 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 msc_bootuf2_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
const uint8_t msc_bootuf2_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -95,11 +158,12 @@ const uint8_t msc_bootuf2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -151,7 +215,11 @@ static struct usbd_interface intf0;
void msc_bootuf2_init(uint8_t busid, uintptr_t reg_base)
{
boot2uf2_flash_init();
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &msc_bootuf2_descriptor);
#else
usbd_desc_register(busid, msc_bootuf2_descriptor);
#endif
usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);

View File

@@ -43,6 +43,101 @@
#define MSC_MAX_MPS 64
#endif
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 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),
MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x03, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
};
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 MSC HID 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_acm_hid_msc_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
const uint8_t cdc_acm_hid_msc_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -147,11 +242,12 @@ const uint8_t cdc_acm_hid_msc_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -303,8 +399,11 @@ struct usbd_interface intf3;
void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &cdc_acm_hid_msc_descriptor);
#else
usbd_desc_register(busid, cdc_acm_hid_msc_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);
@@ -332,14 +431,15 @@ void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
*/
void hid_mouse_test(uint8_t busid)
{
if(usb_device_is_configured(busid) == false) {
return;
}
/*!< move mouse pointer */
mouse_cfg.x += 10;
mouse_cfg.y = 0;
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
if (ret < 0) {
return;
}
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
while (hid_state == HID_STATE_BUSY) {
}
}

View File

@@ -54,11 +54,11 @@ static const uint8_t device_quality_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
};
@@ -169,11 +169,11 @@ static const uint8_t cdc_msc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00

View File

@@ -37,8 +37,74 @@
#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, 0x08, 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),
CDC_ACM_DESCRIPTOR_INIT(0x02, CDC_INT_EP2, CDC_OUT_EP2, CDC_IN_EP2, CDC_MAX_MPS, 0x02),
CDC_ACM_DESCRIPTOR_INIT(0x04, CDC_INT_EP3, CDC_OUT_EP3, CDC_IN_EP3, CDC_MAX_MPS, 0x02),
CDC_ACM_DESCRIPTOR_INIT(0x06, CDC_INT_EP4, CDC_OUT_EP4, CDC_IN_EP4, 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 MULTI 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_multi_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[] = {
static const uint8_t cdc_multi_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x08, 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),
@@ -109,15 +175,16 @@ static const uint8_t cdc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[4][2048];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[4][2048];
@@ -225,8 +292,11 @@ struct usbd_interface intf7;
void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, cdc_descriptor);
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &cdc_multi_descriptor);
#else
usbd_desc_register(busid, cdc_multi_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_ep1);

View File

@@ -25,6 +25,69 @@
#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),
@@ -94,15 +157,16 @@ static const uint8_t cdc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -181,7 +245,11 @@ void cdc_acm_init(uint8_t busid, uintptr_t reg_base)
memcpy(&write_buffer[0], data, 10);
memset(&write_buffer[10], 'a', 2038);
#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);

View File

@@ -6,6 +6,10 @@
#include "usbd_core.h"
#include "usbd_cdc_ecm.h"
#ifndef CONFIG_USBDEV_CDC_ECM_USING_LWIP
#error "Please enable CONFIG_USBDEV_CDC_ECM_USING_LWIP for this demo"
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02
@@ -30,6 +34,69 @@
/* str idx = 4 is for mac address: aa:bb:cc:dd:ee:ff*/
#define CDC_ECM_MAC_STRING_INDEX 4
#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_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_ETH_STATISTICS_BITMAP, CONFIG_CDC_ECM_ETH_MAX_SEGSZE, 0, 0, CDC_ECM_MAC_STRING_INDEX)
};
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 ECM 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_ecm_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_ecm_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
@@ -120,15 +187,16 @@ static const uint8_t cdc_ecm_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
@@ -222,12 +290,12 @@ void cdc_ecm_lwip_init(void)
while (!netif_is_up(netif)) {
}
// while (dhserv_init(&dhcp_config)) {}
while (dhserv_init(&dhcp_config)) {}
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
}
void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len)
void usbd_cdc_ecm_data_recv_done(uint32_t len)
{
}
@@ -273,7 +341,11 @@ void cdc_ecm_init(uint8_t busid, uintptr_t reg_base)
{
cdc_ecm_lwip_init();
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &cdc_ecm_descriptor);
#else
usbd_desc_register(busid, cdc_ecm_descriptor);
#endif
usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf0, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf1, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);

View File

@@ -6,6 +6,10 @@
#include "usbd_core.h"
#include "usbd_rndis.h"
#ifndef CONFIG_USBDEV_RNDIS_USING_LWIP
#error "Please enable CONFIG_USBDEV_RNDIS_USING_LWIP for this demo"
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02
@@ -25,8 +29,71 @@
#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_RNDIS_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 RNDIS 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_rndis_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[] = {
static const uint8_t cdc_rndis_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_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
@@ -96,15 +163,16 @@ static const uint8_t cdc_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
@@ -170,7 +238,7 @@ rt_err_t rt_usbd_rndis_eth_tx(rt_device_t dev, struct pbuf *p)
return usbd_rndis_eth_tx(p);
}
void usbd_rndis_data_recv_done(void)
void usbd_rndis_data_recv_done(uint32_t len)
{
eth_device_ready(&rndis_dev);
}
@@ -258,12 +326,12 @@ void rndis_lwip_init(void)
while (!netif_is_up(netif)) {
}
// while (dhserv_init(&dhcp_config)) {}
while (dhserv_init(&dhcp_config)) {}
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
}
void usbd_rndis_data_recv_done(void)
void usbd_rndis_data_recv_done(uint32_t len)
{
}
@@ -311,7 +379,11 @@ void cdc_rndis_init(uint8_t busid, uintptr_t reg_base)
#else
rndis_lwip_init();
#endif
usbd_desc_register(busid, cdc_descriptor);
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &cdc_rndis_descriptor);
#else
usbd_desc_register(busid, cdc_rndis_descriptor);
#endif
usbd_add_interface(busid, usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
usbd_initialize(busid, reg_base, usbd_event_handler);

View File

@@ -15,6 +15,69 @@
#define USB_CONFIG_SIZE (9 + 9 + 9)
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
DFU_DESCRIPTOR_INIT()
};
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 DFU 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 dfu_flash_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
const uint8_t dfu_flash_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -136,11 +199,12 @@ const uint8_t dfu_flash_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -171,7 +235,11 @@ struct usbd_interface intf0;
void dfu_flash_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &dfu_flash_descriptor);
#else
usbd_desc_register(busid, dfu_flash_descriptor);
#endif
usbd_add_interface(busid, usbd_dfu_init_intf(&intf0));
usbd_initialize(busid, reg_base, usbd_event_handler);
}

View File

@@ -39,6 +39,103 @@
/*!< custom hid report descriptor size */
#define HID_CUSTOM_REPORT_DESC_SIZE 38
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/************** Descriptor of Custom interface *****************/
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Custom HID ********************/
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Custom in endpoint ********************/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HIDRAW_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
WBVAL(HIDRAW_IN_EP_SIZE), /* wMaxPacketSize: 4 Byte max */
HIDRAW_IN_INTERVAL, /* bInterval: Polling Interval */
/******************** Descriptor of Custom out endpoint ********************/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HIDRAW_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
WBVAL(HIDRAW_OUT_EP_SIZE), /* wMaxPacketSize: 4 Byte max */
HIDRAW_OUT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 73 */
};
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 HID 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 hid_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 hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
@@ -146,11 +243,12 @@ static const uint8_t hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
/*!< custom hid report descriptor */
static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
@@ -274,7 +372,11 @@ struct usbd_interface intf0;
void hid_custom_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &hid_descriptor);
#else
usbd_desc_register(busid, hid_descriptor);
#endif
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &custom_in_ep);
usbd_add_endpoint(busid, &custom_out_ep);

View File

@@ -18,6 +18,101 @@
#define USB_HID_CONFIG_DESC_SIZ 34
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
};
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 HID 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 hid_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
static const uint8_t hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -122,11 +217,12 @@ static const uint8_t hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
/* USB HID device Configuration Descriptor */
static uint8_t hid_desc[9] __ALIGN_END = {
@@ -223,7 +319,11 @@ struct usbd_interface intf0;
void hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &hid_descriptor);
#else
usbd_desc_register(busid, hid_descriptor);
#endif
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
@@ -236,12 +336,13 @@ void hid_keyboard_test(uint8_t busid)
{
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy(write_buffer, sendbuffer, 8);
int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
if (ret < 0) {
if(usb_device_is_configured(busid) == false) {
return;
}
memcpy(write_buffer, sendbuffer, 8);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
while (hid_state == HID_STATE_BUSY) {
}
}

View File

@@ -21,6 +21,101 @@
/*!< report descriptor size */
#define HID_MOUSE_REPORT_DESC_SIZE 74
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
};
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 HID 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 hid_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 */
const uint8_t hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
@@ -126,11 +221,12 @@ const uint8_t hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -241,7 +337,11 @@ struct usbd_interface intf0;
void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &hid_descriptor);
#else
usbd_desc_register(busid, hid_descriptor);
#endif
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
@@ -304,14 +404,15 @@ void draw_circle(uint8_t *buf)
/* https://cps-check.com/cn/polling-rate-check */
void hid_mouse_test(uint8_t busid)
{
if(usb_device_is_configured(busid) == false) {
return;
}
int counter = 0;
while (counter < 1000) {
draw_circle((uint8_t *)&mouse_cfg);
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
if (ret < 0) {
return;
}
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
while (hid_state == HID_STATE_BUSY) {
}

View File

@@ -21,6 +21,101 @@
/*!< report descriptor size */
#define HID_MOUSE_REPORT_DESC_SIZE 74
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
};
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 HID 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 hid_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 */
const uint8_t hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
@@ -126,11 +221,12 @@ const uint8_t hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
@@ -241,7 +337,11 @@ static struct usbd_interface intf0;
void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &hid_descriptor);
#else
usbd_desc_register(busid, hid_descriptor);
#endif
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
@@ -307,6 +407,10 @@ void hid_mouse_test(uint8_t busid)
static uint32_t count = 1000;
int ret;
if(usb_device_is_configured(busid) == false) {
return;
}
// if (gpio_read_pin(GPIO_PIN) == 1) {
// ret = usbd_send_remote_wakeup(busid);
// if (ret < 0) {
@@ -317,11 +421,8 @@ void hid_mouse_test(uint8_t busid)
while (count) {
draw_circle((uint8_t *)&mouse_cfg);
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
if (ret < 0) {
return;
}
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
while (hid_state == HID_STATE_BUSY) {
}

View File

@@ -22,6 +22,118 @@
#define MIDI_EP_MPS 64
#endif
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, 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),
// Standard AC Interface Descriptor
0x09,
0x04,
0x00,
0x00,
0x00,
0x01,
0x01,
0x00,
0x00,
// Class-specific AC Interface Descriptor
0x09,
0x24,
0x01,
0x00,
0x01,
0x09,
0x00,
0x01,
0x01,
// MIDIStreaming Interface Descriptors
0x09,
0x04,
0x01,
0x00,
0x02,
0x01,
0x03,
0x00,
0x00,
// Class-Specific MS Interface Header Descriptor
0x07,
0x24,
0x01,
0x00,
0x01,
WBVAL(65),
// MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x01),
// MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x02),
// MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x03, 0x02),
// MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x04, 0x01),
MIDI_JACK_DESCRIPTOR_INIT(0x01),
// OUT endpoint descriptor
0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
0x05, 0x25, 0x01, 0x01, 0x01,
// IN endpoint descriptor
0x09, 0x05, MIDI_IN_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
0x05, 0x25, 0x01, 0x01, 0x03
};
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 MIDI 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 midi_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
const uint8_t midi_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -141,15 +253,16 @@ const uint8_t midi_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[MIDI_EP_MPS];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[MIDI_EP_MPS];
@@ -204,7 +317,11 @@ struct usbd_endpoint midi_in_ep = {
void midi_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &midi_descriptor);
#else
usbd_desc_register(busid, midi_descriptor);
#endif
usbd_add_interface(busid, &intf0);
usbd_add_interface(busid, &intf1);
usbd_add_endpoint(busid, &midi_out_ep);

View File

@@ -22,6 +22,69 @@
#define MSC_MAX_MPS 64
#endif
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_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 MSC 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 msc_ram_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
const uint8_t msc_ram_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -94,11 +157,12 @@ const uint8_t msc_ram_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -158,7 +222,11 @@ static struct usbd_interface intf0;
void msc_ram_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &msc_ram_descriptor);
#else
usbd_desc_register(busid, msc_ram_descriptor);
#endif
usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);

View File

@@ -58,10 +58,10 @@ void usbh_cdc_acm_callback(void *arg, int nbytes)
}
}
static void usbh_cdc_acm_thread(void *argument)
static void usbh_cdc_acm_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)argument;
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
/* test with only one buffer, if you have more cdc acm class, modify by yourself */
#if TEST_USBH_CDC_SPEED
@@ -133,10 +133,10 @@ void usbh_hid_callback(void *arg, int nbytes)
}
}
static void usbh_hid_thread(void *argument)
static void usbh_hid_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
struct usbh_hid *hid_class = (struct usbh_hid *)argument;
struct usbh_hid *hid_class = (struct usbh_hid *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
;
/* test with only one buffer, if you have more hid class, modify by yourself */
@@ -222,13 +222,18 @@ unmount:
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t partition_table[512];
static void usbh_msc_thread(void *argument)
static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
struct usbh_msc *msc_class = (struct usbh_msc *)argument;
struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
/* test with only one buffer, if you have more msc class, modify by yourself */
#if 1
#if TEST_USBH_MSC_FATFS == 0
ret = usbh_msc_scsi_init(msc_class);
if (ret < 0) {
USB_LOG_RAW("scsi_init error,ret:%d\r\n", ret);
goto delete;
}
/* get the partition table */
ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
if (ret < 0) {
@@ -242,11 +247,10 @@ static void usbh_msc_thread(void *argument)
USB_LOG_RAW("%02x ", partition_table[i]);
}
USB_LOG_RAW("\r\n");
#endif
#if TEST_USBH_MSC_FATFS
#else
usb_msc_fatfs_test();
#endif
// clang-format off
delete:
usb_osal_thread_delete(NULL);
@@ -254,38 +258,38 @@ delete:
}
#endif
#if TEST_USBH_CDC_ACM
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
{
#if TEST_USBH_CDC_ACM
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class);
#endif
}
void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
{
}
#endif
#if TEST_USBH_HID
void usbh_hid_run(struct usbh_hid *hid_class)
{
#if TEST_USBH_HID
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
#endif
}
void usbh_hid_stop(struct usbh_hid *hid_class)
{
}
#endif
#if TEST_USBH_MSC
void usbh_msc_run(struct usbh_msc *msc_class)
{
#if TEST_USBH_MSC
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
#endif
}
void usbh_msc_stop(struct usbh_msc *msc_class)
{
}
#endif
#if TEST_USBH_AUDIO
#error "commercial charge"
@@ -294,3 +298,26 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
#if TEST_USBH_VIDEO
#error "commercial charge"
#endif
#if 0
#include "usbh_aoa.h"
static struct aoa_string_info deviceinfo = {
.acc_manufacturer = "CherryUSB",
.acc_model = "CherryUSB",
.acc_description = "Android Open Accessory CherryUSB",
.acc_version = "1.0",
.acc_uri = "http://developer.android.com/tools/adk/index.html",
.acc_serial = "CherryUSB"
};
int aoa_switch(int argc, char **argv)
{
struct usbh_hubport *hport = usbh_find_hubport(0, 1, 1);
usbh_aoa_switch(hport, &deviceinfo);
return 0;
}
SHELL_CMD_EXPORT_ALIAS(aoa_switch, aoa_switch, aoa_switch);
#endif

View File

@@ -9,6 +9,8 @@
#include "usbd_hid.h"
#include "cherryusb_mjpeg.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x86
@@ -101,6 +103,120 @@
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
#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, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x06, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01),
VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
AUDIO_AC_DESCRIPTOR_INIT(0x02, 0x03, AUDIO_AC_SIZ, 0x00, 0x03, 0x04),
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
AUDIO_AS_DESCRIPTOR_INIT(0x03, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
AUDIO_AS_DESCRIPTOR_INIT(0x04, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x05, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
};
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 UVC UAC HID 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 video_audio_hid_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
const uint8_t video_audio_hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x06, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -224,11 +340,12 @@ const uint8_t video_audio_hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
@@ -267,7 +384,7 @@ static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_read_buffer[AUDIO_OUT_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_write_buffer[AUDIO_IN_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
volatile bool video_tx_flag = 0;
volatile bool audio_tx_flag = 0;
@@ -331,8 +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)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
video_iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
video_iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -418,7 +537,11 @@ struct audio_entity_info audio_entity_table[] = {
void composite_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &video_audio_hid_descriptor);
#else
usbd_desc_register(busid, video_audio_hid_descriptor);
#endif
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_endpoint(busid, &video_in_ep);
@@ -458,56 +581,30 @@ void hid_keyboard_test(uint8_t busid)
{
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy(hid_write_buffer, sendbuffer, 8);
int ret = usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8);
if (ret < 0) {
if(usb_device_is_configured(busid) == false) {
return;
}
memcpy(hid_write_buffer, sendbuffer, 8);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8);
while (hid_state == HID_STATE_BUSY) {
}
}
void video_test(uint8_t busid)
{
uint32_t out_len;
uint32_t packets;
memset(video_packet_buffer, 0, sizeof(video_packet_buffer));
(void)packets;
memset(video_packet_buffer, 0, 40 * 1024);
while (1) {
if (video_tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), video_packet_buffer, &out_len);
#if 1
video_iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, video_packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[0][0], &video_packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
while (video_iso_tx_busy) {
if (video_tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
video_iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (video_iso_tx_busy) {
if (video_tx_flag == 0) {
break;
}
}
} else {
video_iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (video_iso_tx_busy) {
if (video_tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -7,6 +7,8 @@
#include "usbd_video.h"
#include "cherryusb_h264.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -48,6 +50,77 @@
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#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, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
VIDEO_VS_FORMAT_H264_DESCRIPTOR_INIT(0x01, 0x01),
VIDEO_VS_FRAME_H264_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01)
};
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 UVC 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 video_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
const uint8_t video_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -129,11 +202,12 @@ const uint8_t video_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
volatile bool tx_flag = 0;
volatile bool iso_tx_busy = false;
@@ -180,8 +254,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)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -194,7 +270,11 @@ struct usbd_interface intf1;
void video_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &video_descriptor);
#else
usbd_desc_register(busid, video_descriptor);
#endif
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_endpoint(busid, &video_in_ep);
@@ -202,7 +282,7 @@ void video_init(uint8_t busid, uintptr_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][40 * 1024];
void video_test(uint8_t busid)
{
@@ -210,40 +290,16 @@ void video_test(uint8_t busid)
uint32_t packets;
(void)packets;
memset(packet_buffer, 0, 40 * 1024);
memset(packet_buffer, 0, sizeof(packet_buffer));
while (1) {
if (tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264), packet_buffer, &out_len);
#if 1
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264));
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
} else {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -7,6 +7,8 @@
#include "usbd_video.h"
#include "cherryusb_mjpeg.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -34,7 +36,7 @@
#define MAX_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS)
#define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT * 2)
#define VS_HEADER_SIZ (unsigned int)(VIDEO_SIZEOF_VS_INPUT_HEADER_DESC(1,1) + VIDEO_SIZEOF_VS_FORMAT_MJPEG_DESC + VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(1))
#define VS_HEADER_SIZ (unsigned int)(VIDEO_SIZEOF_VS_INPUT_HEADER_DESC(1, 1) + VIDEO_SIZEOF_VS_FORMAT_MJPEG_DESC + VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(1))
#define USB_VIDEO_DESC_SIZ (unsigned long)(9 + \
VIDEO_VC_NOEP_DESCRIPTOR_LEN + \
@@ -48,6 +50,77 @@
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#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, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01),
VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01)
};
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 UVC 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 video_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
const uint8_t video_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -129,11 +202,12 @@ const uint8_t video_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
volatile bool tx_flag = 0;
volatile bool iso_tx_busy = false;
@@ -180,8 +254,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)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -194,7 +270,11 @@ struct usbd_interface intf1;
void video_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &video_descriptor);
#else
usbd_desc_register(busid, video_descriptor);
#endif
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_endpoint(busid, &video_in_ep);
@@ -202,48 +282,21 @@ void video_init(uint8_t busid, uintptr_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
void video_test(uint8_t busid)
{
uint32_t out_len;
uint32_t packets;
memset(packet_buffer, 0, sizeof(packet_buffer));
(void)packets;
memset(packet_buffer, 0, 40 * 1024);
while (1) {
if (tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), packet_buffer, &out_len);
#if 1
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
} else {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -7,6 +7,8 @@
#include "usbd_video.h"
#include "cherryusb_yuyv.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -49,6 +51,79 @@
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#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, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, 0x01, VIDEO_GUID_YUY2),
VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
VIDEO_VS_COLOR_MATCHING_DESCRIPTOR_INIT(),
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
};
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 UVC 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 video_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
const uint8_t video_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -131,11 +206,12 @@ const uint8_t video_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
volatile bool tx_flag = 0;
volatile bool iso_tx_busy = false;
@@ -182,8 +258,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)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -196,7 +274,11 @@ struct usbd_interface intf1;
void video_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &video_descriptor);
#else
usbd_desc_register(busid, video_descriptor);
#endif
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
usbd_add_endpoint(busid, &video_in_ep);
@@ -204,48 +286,21 @@ void video_init(uint8_t busid, uintptr_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
void video_test(uint8_t busid)
{
uint32_t out_len;
uint32_t packets;
memset(packet_buffer, 0, sizeof(packet_buffer));
(void)packets;
memset(packet_buffer, 0, 40 * 1024);
while (1) {
if (tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv), packet_buffer, &out_len);
#if 1
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv));
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
} else {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -149,6 +149,105 @@ struct usb_bos_descriptor bos_desc = {
.string_len = USBD_BOS_WTOTALLENGTH
};
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00)
};
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 WEBUSB HID 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 webusb_hid_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,
.msosv2_descriptor = &msosv2_desc,
.webusb_url_descriptor = &webusb_url_desc,
.bos_descriptor = &bos_desc
};
#else
static const uint8_t webusb_hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -207,7 +306,7 @@ static const uint8_t webusb_hid_descriptor[] = {
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x26, /* bLength */
0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
@@ -219,14 +318,17 @@ static const uint8_t webusb_hid_descriptor[] = {
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'H', 0x00, /* wcChar10 */
'I', 0x00, /* wcChar11 */
'D', 0x00, /* wcChar12 */
' ', 0x00, /* wcChar13 */
'D', 0x00, /* wcChar14 */
'E', 0x00, /* wcChar15 */
'M', 0x00, /* wcChar16 */
'O', 0x00, /* wcChar17 */
'W', 0x00, /* wcChar10 */
'E', 0x00, /* wcChar11 */
'B', 0x00, /* wcChar12 */
'U', 0x00, /* wcChar13 */
'S', 0x00, /* wcChar14 */
'B', 0x00, /* wcChar15 */
' ', 0x00, /* wcChar16 */
'D', 0x00, /* wcChar17 */
'E', 0x00, /* wcChar18 */
'M', 0x00, /* wcChar19 */
'O', 0x00, /* wcChar20 */
///////////////////////////////////////
/// string3 descriptor
///////////////////////////////////////
@@ -254,11 +356,12 @@ static const uint8_t webusb_hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
/* USB HID device Configuration Descriptor */
static uint8_t hid_desc[9] __ALIGN_END = {
@@ -355,10 +458,16 @@ static struct usbd_interface intf0;
void webusb_hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &webusb_hid_descriptor);
#else
usbd_desc_register(busid, webusb_hid_descriptor);
#endif
#ifndef CONFIG_USBDEV_ADVANCE_DESC
usbd_bos_desc_register(busid, &bos_desc);
usbd_msosv2_desc_register(busid, &msosv2_desc);
usbd_webusb_desc_register(busid, &webusb_url_desc);
#endif
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
@@ -371,12 +480,13 @@ void hid_keyboard_test(uint8_t busid)
{
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy(write_buffer, sendbuffer, 8);
int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
if (ret < 0) {
if(usb_device_is_configured(busid) == false) {
return;
}
memcpy(write_buffer, sendbuffer, 8);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
while (hid_state == HID_STATE_BUSY) {
}
}

View File

@@ -188,6 +188,79 @@ struct usb_msosv1_descriptor msosv1_desc = {
#define WINUSB_EP_MPS 64
#endif
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04),
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00),
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00),
#if DOUBLE_WINUSB == 1
USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05),
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00),
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00),
#endif
};
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 WINUSB DEMO", /* Product */
"2022123456", /* Serial Number */
"CherryUSB WINUSB DEMO 1", /* STRING4 */
"CherryUSB WINUSB DEMO 2", /* STRING5 */
};
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 > 5) {
return NULL;
}
return string_descriptors[index];
}
const struct usb_descriptor winusb_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,
.msosv1_descriptor = &msosv1_desc
};
#else
const uint8_t winusb_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -252,12 +325,12 @@ const uint8_t winusb_descriptor[] = {
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'1', 0x00, /* wcChar3 */
'0', 0x00, /* wcChar4 */
'3', 0x00, /* wcChar5 */
'1', 0x00, /* wcChar6 */
'0', 0x00, /* wcChar7 */
'0', 0x00, /* wcChar8 */
'0', 0x00, /* wcChar9 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
///////////////////////////////////////
/// string4 descriptor
///////////////////////////////////////
@@ -322,15 +395,16 @@ const uint8_t winusb_descriptor[] = {
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -446,8 +520,14 @@ struct usbd_interface intf1;
void winusb_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &winusb_descriptor);
#else
usbd_desc_register(busid, winusb_descriptor);
#endif
#ifndef CONFIG_USBDEV_ADVANCE_DESC
usbd_msosv1_desc_register(busid, &msosv1_desc);
#endif
usbd_add_interface(busid, &intf0);
usbd_add_endpoint(busid, &winusb_out_ep1);
usbd_add_endpoint(busid, &winusb_in_ep1);

View File

@@ -145,6 +145,89 @@ __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
#endif
};
struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = USBD_WINUSB_VENDOR_CODE,
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
};
struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = USBD_BOS_WTOTALLENGTH
};
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
};
static const uint8_t config_descriptor[] = {
/* Configuration 0 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/* Interface 0 */
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
/* Endpoint OUT 2 */
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
/* Endpoint IN 1 */
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, WINUSB_EP_MPS, 0x00)
};
static const uint8_t device_quality_descriptor[] = {
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x10,
0x02,
0x00,
0x00,
0x00,
0x40,
0x00,
0x00,
};
static const char *string_descriptors[] = {
(const char[]){ 0x09, 0x04 }, /* Langid */
"CherryUSB", /* Manufacturer */
"CherryUSB WINUSB 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 winusbv2_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,
.msosv2_descriptor = &msosv2_desc,
.bos_descriptor = &bos_desc
};
#else
const uint8_t winusbv2_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
/* Configuration 0 */
@@ -170,7 +253,9 @@ const uint8_t winusbv2_descriptor[] = {
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
/* String 2 (Product) */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
@@ -194,21 +279,21 @@ const uint8_t winusbv2_descriptor[] = {
'E', 0x00, /* wcChar18 */
'M', 0x00, /* wcChar19 */
'O', 0x00, /* wcChar20 */
/* String 3 (Serial Number) */
0x1A, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'0', 0, // wcChar0
'1', 0, // wcChar1
'2', 0, // wcChar2
'3', 0, // wcChar3
'4', 0, // wcChar4
'5', 0, // wcChar5
'A', 0, // wcChar6
'B', 0, // wcChar7
'C', 0, // wcChar8
'D', 0, // wcChar9
'E', 0, // wcChar10
'F', 0, // wcChar11
///////////////////////////////////////
/// 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 */
0x0a,
@@ -219,12 +304,13 @@ const uint8_t winusbv2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
/* End */
0x00
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -248,6 +334,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
ep_tx_busy_flag = false;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
@@ -283,6 +370,30 @@ void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
}
}
void usbd_cdc_acm_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
// for (int i = 0; i < 100; i++) {
// printf("%02x ", read_buffer[i]);
// }
// printf("\r\n");
usbd_ep_start_write(busid, CDC_IN_EP, read_buffer, nbytes);
/* setup next out ep read transfer */
usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
}
void usbd_cdc_acm_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", 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;
}
}
struct usbd_endpoint winusb_out_ep1 = {
.ep_addr = WINUSB_OUT_EP,
.ep_cb = usbd_winusb_out
@@ -295,35 +406,29 @@ struct usbd_endpoint winusb_in_ep1 = {
static struct usbd_endpoint cdc_out_ep = {
.ep_addr = CDC_OUT_EP,
.ep_cb = NULL
.ep_cb = usbd_cdc_acm_out
};
static struct usbd_endpoint cdc_in_ep = {
.ep_addr = CDC_IN_EP,
.ep_cb = NULL
.ep_cb = usbd_cdc_acm_in
};
struct usbd_interface winusb_intf;
struct usbd_interface intf1;
struct usbd_interface intf2;
struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = USBD_WINUSB_VENDOR_CODE,
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
};
struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = USBD_BOS_WTOTALLENGTH
};
void winusbv2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &winusbv2_descriptor);
#else
usbd_desc_register(busid, winusbv2_descriptor);
#endif
#ifndef CONFIG_USBDEV_ADVANCE_DESC
usbd_bos_desc_register(busid, &bos_desc);
usbd_msosv2_desc_register(busid, &msosv2_desc);
#endif
/*!< winusb */
usbd_add_interface(busid, &winusb_intf);
usbd_add_endpoint(busid, &winusb_out_ep1);
@@ -336,4 +441,26 @@ void winusbv2_init(uint8_t busid, uintptr_t reg_base)
usbd_add_endpoint(busid, &cdc_in_ep);
usbd_initialize(busid, reg_base, usbd_event_handler);
}
volatile uint8_t dtr_enable = 0;
void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
{
if (dtr) {
dtr_enable = 1;
} else {
dtr_enable = 0;
}
}
void cdc_acm_data_send_with_dtr_test(uint8_t busid)
{
if (dtr_enable) {
memset(&write_buffer[10], 'a', 2038);
ep_tx_busy_flag = true;
usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048);
while (ep_tx_busy_flag) {
}
}
}

View File

@@ -151,6 +151,119 @@ __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
#endif
};
struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = USBD_WINUSB_VENDOR_CODE,
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
};
struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = USBD_BOS_WTOTALLENGTH
};
#ifdef CONFIG_USBDEV_ADVANCE_DESC
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
};
static const uint8_t config_descriptor[] = {
/* Configuration 0 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/* Interface 0 */
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
/* Endpoint OUT 2 */
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
/* Endpoint IN 1 */
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
};
static const uint8_t device_quality_descriptor[] = {
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x10,
0x02,
0x00,
0x00,
0x00,
0x40,
0x00,
0x00,
};
static const char *string_descriptors[] = {
(const char[]){ 0x09, 0x04 }, /* Langid */
"CherryUSB", /* Manufacturer */
"CherryUSB WINUSB 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 winusbv2_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,
.msosv2_descriptor = &msosv2_desc,
.bos_descriptor = &bos_desc
};
#else
const uint8_t winusbv2_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
/* Configuration 0 */
@@ -206,7 +319,9 @@ const uint8_t winusbv2_descriptor[] = {
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
/* String 2 (Product) */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
@@ -230,21 +345,21 @@ const uint8_t winusbv2_descriptor[] = {
'E', 0x00, /* wcChar18 */
'M', 0x00, /* wcChar19 */
'O', 0x00, /* wcChar20 */
/* String 3 (Serial Number) */
0x1A, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'0', 0, // wcChar0
'1', 0, // wcChar1
'2', 0, // wcChar2
'3', 0, // wcChar3
'4', 0, // wcChar4
'5', 0, // wcChar5
'A', 0, // wcChar6
'B', 0, // wcChar7
'C', 0, // wcChar8
'D', 0, // wcChar9
'E', 0, // wcChar10
'F', 0, // wcChar11
///////////////////////////////////////
/// 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 */
0x0a,
@@ -255,12 +370,13 @@ const uint8_t winusbv2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
/* End */
0x00
};
#endif
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
@@ -411,23 +527,17 @@ static struct usbd_endpoint hid_in_ep = {
struct usbd_interface winusb_intf;
struct usbd_interface intf1;
struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = USBD_WINUSB_VENDOR_CODE,
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
};
struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = USBD_BOS_WTOTALLENGTH
};
void winusbv2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &winusbv2_descriptor);
#else
usbd_desc_register(busid, winusbv2_descriptor);
#endif
#ifndef CONFIG_USBDEV_ADVANCE_DESC
usbd_bos_desc_register(busid, &bos_desc);
usbd_msosv2_desc_register(busid, &msosv2_desc);
#endif
/*!< winusb */
usbd_add_interface(busid, &winusb_intf);
usbd_add_endpoint(busid, &winusb_out_ep1);

1
docs/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*build

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