61 Commits

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

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

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

1
.gitignore vendored
View File

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

View File

@@ -56,7 +56,6 @@ elseif(ESP_PLATFORM)
OR CONFIG_CHERRYUSB_HOST_CDC_NCM
OR CONFIG_CHERRYUSB_HOST_ASIX
OR CONFIG_CHERRYUSB_HOST_RTL8152
OR CONFIG_CHERRYUSB_HOST_BL616
)
idf_component_get_property(lwip lwip COMPONENT_LIB)
target_compile_definitions(${lwip} PRIVATE "-DPBUF_POOL_BUFSIZE=1600")
@@ -64,6 +63,14 @@ elseif(ESP_PLATFORM)
idf_component_get_property(freertos_include freertos ORIG_INCLUDE_PATH)
if(CONFIG_CHERRYUSB_HOST_MSC)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_fatfs.c)
endif()
set(priv_req esp_mm esp_netif esp_timer fatfs)
if(${IDF_VERSION_MAJOR} LESS 6)
list(APPEND priv_req usb)
endif()
idf_component_register(
SRCS
${cherryusb_srcs}
@@ -71,7 +78,7 @@ elseif(ESP_PLATFORM)
${cherryusb_incs}
${freertos_include}
PRIV_REQUIRES
usb esp_mm esp_netif esp_timer
${priv_req}
LDFRAGMENTS
${ldfragments}
)
@@ -81,7 +88,7 @@ elseif(ESP_PLATFORM)
# 强制链接器不删除符号
if(CONFIG_CHERRYUSB_HOST_CDC_ACM)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u cdc_acm_class_info")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u cdc_acm_none_class_info")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u cdc_data_class_info")
endif()
if(CONFIG_CHERRYUSB_HOST_HID)
@@ -187,7 +194,6 @@ elseif(HPM_SDK_BASE)
set(CONFIG_CHERRYUSB_HOST_CP210X 1)
set(CONFIG_CHERRYUSB_HOST_FTDI 1)
set(CONFIG_CHERRYUSB_HOST_PL2303 1)
set(CONFIG_CHERRYUSB_HOST_BL616 1)
set(CONFIG_CHERRYUSB_DEVICE_HPM 1)
set(CONFIG_CHERRYUSB_HOST_EHCI_HPM 1)

View File

@@ -118,6 +118,7 @@ if CHERRYUSB
config CHERRYUSB_DEVICE_CDC_NCM
bool
prompt "Enable usb cdc ncm device"
depends on !IDF_CMAKE
default n
config CHERRYUSB_DEVICE_MTP
@@ -219,13 +220,16 @@ if CHERRYUSB
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
bool
prompt "winusbv1"
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2
bool
prompt "winusbv2"
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
bool
prompt "winusbv2_cdc"
depends on CHERRYUSB_DEVICE_CDC_ACM
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
config CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID
bool
prompt "winusbv2_hid"
prompt "webusb_hid"
depends on CHERRYUSB_DEVICE_HID
endchoice
endif
@@ -338,6 +342,7 @@ if CHERRYUSB
config CHERRYUSB_HOST_BLUETOOTH
bool
prompt "Enable usb bluetooth driver"
depends on !IDF_CMAKE
default n
config CHERRYUSB_HOST_ASIX

View File

@@ -230,13 +230,16 @@ if RT_USING_CHERRYUSB
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
bool
prompt "winusbv1"
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2
bool
prompt "winusbv2"
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
bool
prompt "winusbv2_cdc"
depends on RT_CHERRYUSB_DEVICE_CDC_ACM
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
config RT_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID
bool
prompt "winusbv2_hid"
prompt "webusb_hid"
depends on RT_CHERRYUSB_DEVICE_HID
config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB
bool

View File

@@ -229,13 +229,16 @@ if PKG_USING_CHERRYUSB
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
bool
prompt "winusbv1"
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2
bool
prompt "winusbv2"
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
bool
prompt "winusbv2_cdc"
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID
bool
prompt "winusbv2_hid"
prompt "webusb_hid"
depends on PKG_CHERRYUSB_DEVICE_HID
config PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB
bool
@@ -465,12 +468,14 @@ if PKG_USING_CHERRYUSB
choice
prompt "Version"
default PKG_USING_CHERRYUSB_V010502
default PKG_USING_CHERRYUSB_V010503
help
Select the package version
config PKG_USING_CHERRYUSB_LATEST_VERSION
bool "latest"
config PKG_USING_CHERRYUSB_V010502
bool "v1.5.3"
config PKG_USING_CHERRYUSB_V010502
bool "v1.5.2"
config PKG_USING_CHERRYUSB_V010501
@@ -490,6 +495,7 @@ if PKG_USING_CHERRYUSB
config PKG_CHERRYUSB_VER
string
default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION
default "v1.5.3" if PKG_USING_CHERRYUSB_V010503
default "v1.5.2" if PKG_USING_CHERRYUSB_V010502
default "v1.5.1" if PKG_USING_CHERRYUSB_V010501
default "v1.5.0" if PKG_USING_CHERRYUSB_V010500

View File

@@ -197,7 +197,7 @@ TODO
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |

View File

@@ -197,7 +197,7 @@ TODO
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |

View File

@@ -166,10 +166,12 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
src += Glob('demo/cdc_acm_hid_msc_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1']):
src += Glob('demo/winusb1.0_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2']):
src += Glob('demo/winusb2.0_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC']):
src += Glob('demo/winusb2.0_cdc_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID']):
src += Glob('demo/winusb2.0_hid_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID']):
src += Glob('demo/webusb_hid_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB']):
src += Glob('demo/adb/usbd_adb_template.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV']):

View File

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

View File

@@ -246,9 +246,6 @@ if(CONFIG_CHERRYUSB_HOST)
if(CONFIG_CHERRYUSB_HOST_PL2303)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_pl2303.c)
endif()
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()
@@ -258,7 +255,6 @@ if(CONFIG_CHERRYUSB_HOST)
OR CONFIG_CHERRYUSB_HOST_CDC_NCM
OR CONFIG_CHERRYUSB_HOST_ASIX
OR CONFIG_CHERRYUSB_HOST_RTL8152
OR CONFIG_CHERRYUSB_HOST_BL616
)
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_net.c)
@@ -340,6 +336,10 @@ if(CONFIG_CHERRYUSB_HOST)
endif()
endif()
if(CONFIG_CHERRYUSB_DEVICE AND CONFIG_CHERRYUSB_HOST)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/core/usbotg_core.c)
endif()
if(DEFINED CONFIG_CHERRYUSB_OSAL)
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_freertos.c)

View File

@@ -301,6 +301,7 @@
/* ---------------- MUSB Configuration ---------------- */
#define CONFIG_USB_MUSB_PIPE_NUM 8
// #define CONFIG_USB_MUSB_SUNXI
// #define CONFIG_USB_MUSB_WITHOUT_MULTIPOINT
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
* the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
@@ -317,4 +318,7 @@
#define usb_ramaddr2phyaddr(addr) (addr)
#endif
/* Enable OTG support, only support hpmicro now */
// #define CONFIG_USB_OTG_ENABLE
#endif

View File

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

View File

@@ -88,18 +88,6 @@
#define AUDIO_ENDPOINT_UNDEFINED 0x00U
#define AUDIO_ENDPOINT_GENERAL 0x01U
/* Feature Unit Control Bits */
#define AUDIO_CONTROL_MUTE 0x0001
#define AUDIO_CONTROL_VOLUME 0x0002
#define AUDIO_CONTROL_BASS 0x0004
#define AUDIO_CONTROL_MID 0x0008
#define AUDIO_CONTROL_TREBLE 0x0010
#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040
#define AUDIO_CONTROL_DEALY 0x0080
#define AUDIO_CONTROL_BASS_BOOST 0x0100
#define AUDIO_CONTROL_LOUDNESS 0x0200
/* Encoder Type Codes */
#define AUDIO_ENCODER_UNDEF 0x00
#define AUDIO_ENCODER_OTHER 0x01
@@ -245,22 +233,34 @@
#define AUDIO_FU_CONTROL_OVERFLOW 0x0f
#define AUDIO_FU_CONTROL_LATENCY 0x10
#define AUDIO_V2_FU_CONTROL_UNDEF 0x00
#define AUDIO_V2_FU_CONTROL_MUTE (0x03 << 0)
#define AUDIO_V2_FU_CONTROL_VOLUME (0x03 << 2)
#define AUDIO_V2_FU_CONTROL_BASS (0x03 << 4)
#define AUDIO_V2_FU_CONTROL_MID (0x03 << 6)
#define AUDIO_V2_FU_CONTROL_TREBLE (0x03 << 8)
#define AUDIO_V2_FU_CONTROL_EQUALIZER (0x03 << 10)
#define AUDIO_V2_FU_CONTROL_AGC (0x03 << 12)
#define AUDIO_V2_FU_CONTROL_DELAY (0x03 << 14)
#define AUDIO_V2_FU_CONTROL_BASS_BOOST (0x03 << 16)
#define AUDIO_V2_FU_CONTROL_LOUDNESS (0x03 << 18)
#define AUDIO_V2_FU_CONTROL_INP_GAIN (0x03 << 20)
#define AUDIO_V2_FU_CONTROL_INP_GAIN_PAD (0x03 << 22)
#define AUDIO_V2_FU_CONTROL_PHASE_INVERT (0x03 << 24)
#define AUDIO_V2_FU_CONTROL_UNDERFLOW (0x03 << 26)
#define AUDIO_V2_FU_CONTROL_OVERFLOW (0x03 << 28)
/* Feature Unit Control Bits */
#define AUDIO_CONTROL_MUTE 0x0001
#define AUDIO_CONTROL_VOLUME 0x0002
#define AUDIO_CONTROL_BASS 0x0004
#define AUDIO_CONTROL_MID 0x0008
#define AUDIO_CONTROL_TREBLE 0x0010
#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040
#define AUDIO_CONTROL_DEALY 0x0080
#define AUDIO_CONTROL_BASS_BOOST 0x0100
#define AUDIO_CONTROL_LOUDNESS 0x0200
#define AUDIO_V2_CONTROL_UNDEF 0x00
#define AUDIO_V2_CONTROL_MUTE (0x03 << 0)
#define AUDIO_V2_CONTROL_VOLUME (0x03 << 2)
#define AUDIO_V2_CONTROL_BASS (0x03 << 4)
#define AUDIO_V2_CONTROL_MID (0x03 << 6)
#define AUDIO_V2_CONTROL_TREBLE (0x03 << 8)
#define AUDIO_V2_CONTROL_EQUALIZER (0x03 << 10)
#define AUDIO_V2_CONTROL_AGC (0x03 << 12)
#define AUDIO_V2_CONTROL_DELAY (0x03 << 14)
#define AUDIO_V2_CONTROL_BASS_BOOST (0x03 << 16)
#define AUDIO_V2_CONTROL_LOUDNESS (0x03 << 18)
#define AUDIO_V2_CONTROL_INP_GAIN (0x03 << 20)
#define AUDIO_V2_CONTROL_INP_GAIN_PAD (0x03 << 22)
#define AUDIO_V2_CONTROL_PHASE_INVERT (0x03 << 24)
#define AUDIO_V2_CONTROL_UNDERFLOW (0x03 << 26)
#define AUDIO_V2_CONTROL_OVERFLOW (0x03 << 28)
/* Parametric Equalizer Section Effect Unit Control Selectors */
#define AUDIO_PE_CONTROL_UNDEF 0x00
@@ -605,7 +605,7 @@ struct audio_cs_if_ac_header_descriptor {
uint8_t baInterfaceNr[];
} __PACKED;
#define AUDIO_SIZEOF_AC_HEADER_DESC(n) (8 + n)
#define AUDIO_SIZEOF_AC_HEADER_DESC(bInCollection) (8 + (bInCollection))
struct audio_cs_if_ac_input_terminal_descriptor {
uint8_t bLength;
@@ -646,7 +646,7 @@ struct audio_cs_if_ac_feature_unit_descriptor {
uint8_t iFeature;
} __PACKED;
#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + (ch + 1) * n)
#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(bNrChannels, bControlSize) (7 + ((bNrChannels) + 1) * (bControlSize))
struct audio_cs_if_ac_selector_unit_descriptor {
uint8_t bLength;
@@ -658,7 +658,7 @@ struct audio_cs_if_ac_selector_unit_descriptor {
uint8_t iSelector;
} __PACKED;
#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(n) (6 + n)
#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(bNrInPins) (6 + (bNrInPins))
struct audio_cs_if_as_general_descriptor {
uint8_t bLength;
@@ -683,7 +683,7 @@ struct audio_cs_if_as_format_type_descriptor {
uint8_t tSamFreq[3];
} __PACKED;
#define AUDIO_SIZEOF_FORMAT_TYPE_DESC(n) (8 + 3 * n)
#define AUDIO_SIZEOF_FORMAT_TYPE_DESC(bSamFreqType) (8 + 3 * (bSamFreqType))
struct audio_ep_descriptor {
uint8_t bLength;
@@ -738,7 +738,7 @@ struct audio_cs_ep_ep_general_descriptor {
PP_NARG(__VA_ARGS__), /* bInCollection */ \
__VA_ARGS__ /* baInterfaceNr */
#define AUDIO_AC_DESCRIPTOR_INIT_LEN(n) (0x08 + 0x09 + 0x08 + n)
#define AUDIO_AC_DESCRIPTOR_LEN(bInCollection) (0x08 + 0x09 + 0x08 + bInCollection)
#define AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(bTerminalID, wTerminalType, bNrChannels, wChannelConfig) \
0x0C, /* bLength */ \
@@ -880,8 +880,8 @@ struct audio_cs_ep_ep_general_descriptor {
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_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07)
#define AUDIO_AS_FEEDBACK_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07 + 0x09)
#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \
0x09, /* bLength */ \
@@ -924,9 +924,9 @@ struct audio_cs_ep_ep_general_descriptor {
0x00, /* wLockDelay */ \
0x00
#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07)
#define AUDIO_AS_ALTSETTING_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07)
#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \
#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
@@ -937,19 +937,6 @@ struct audio_cs_ep_ep_general_descriptor {
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
0x00 /* iInterface */
#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
bNumEndpoints, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_MIDISTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
0x00 /* iInterface */
#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT_LEN 0x09
struct audio_v2_channel_cluster_descriptor {
uint8_t bNrChannels;
uint32_t bmChannelConfig;
@@ -993,7 +980,7 @@ struct audio_v2_cs_if_ac_clock_selector_descriptor {
uint8_t iClockSelector;
} __PACKED;
#define AUDIO_SIZEOF_AC_CLOCK_SELECTOR_DESC(n) (7 + n)
#define AUDIO_SIZEOF_AC_CLOCK_SELECTOR_DESC(bNrInPins) (7 + (bNrInPins))
struct audio_v2_cs_if_ac_clock_multiplier_descriptor {
uint8_t bLength;
@@ -1005,7 +992,7 @@ struct audio_v2_cs_if_ac_clock_multiplier_descriptor {
uint8_t iClockMultiplier;
} __PACKED;
#define AUDIO_SIZEOF_AC_CLOCK_MULTIPLIER_DESC() (7)
#define AUDIO_SIZEOF_AC_CLOCK_MULTIPLIER_DESC (7)
struct audio_v2_cs_if_ac_input_terminal_descriptor {
uint8_t bLength;
@@ -1049,7 +1036,7 @@ struct audio_v2_cs_if_ac_feature_unit_descriptor {
uint8_t iFeature;
} __PACKED;
#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(ch) (6 + (ch + 1) * 4)
#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(bNrChannels) (6 + ((bNrChannels) + 1) * 4)
struct audio_v2_cs_if_as_general_descriptor {
uint8_t bLength;
@@ -1124,7 +1111,7 @@ struct audio_v2_control_range3_param_block {
WBVAL(wTotalLength), /* wTotalLength */ \
bmControls /* bmControls */ \
#define AUDIO_V2_AC_DESCRIPTOR_INIT_LEN (0x08 + 0x09 + 0x09)
#define AUDIO_V2_AC_DESCRIPTOR_LEN (0x08 + 0x09 + 0x09)
#define AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(bClockID, bmAttributes, bmControls) \
0x08, /* bLength */ \
@@ -1262,7 +1249,7 @@ struct audio_v2_control_range3_param_block {
0x00, /* wLockDelay */ \
0x00
#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \
#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
@@ -1331,9 +1318,10 @@ struct audio_v2_control_range3_param_block {
// clang-format on
#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_V2_AS_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08)
#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_LEN (0x09)
#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08)
#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_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))

View File

@@ -551,10 +551,9 @@ struct cdc_ncm_ndp16 {
#define DBVAL_BE(x) ((x >> 24) & 0xFF), ((x >> 16) & 0xFF), ((x >> 8) & 0xFF), (x & 0xFF)
/*Length of template descriptor: 71 bytes*/
#define CDC_ECM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 7 + 9 + 7 + 7)
#define CDC_ECM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 7 + 9 + 7 + 7)
// clang-format off
#define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, \
eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) \
#define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \
/* Interface Associate */ \
0x08, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
@@ -587,10 +586,10 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */\
CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype */\
str_idx, /* Device's MAC string index */\
DBVAL_BE(eth_statistics), /* Ethernet statistics (bitmap) */\
WBVAL(wMaxSegmentSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
WBVAL(wNumberMCFilters), /* wNumberMCFilters: the number of multicast filters */\
bNumberPowerFilters, /* bNumberPowerFilters: the number of wakeup power filters */\
DBVAL_BE(0x00000000), /* Ethernet statistics (bitmap) */\
WBVAL(1514), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
WBVAL(0), /* wNumberMCFilters: the number of multicast filters */ \
0, /* bNumberPowerFilters: the number of wakeup power filters */ \
0x07, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
int_ep, /* bEndpointAddress */ \
@@ -621,10 +620,9 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
// clang-format on
/*Length of template descriptor: 77 bytes*/
#define CDC_NCM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 7 + 7)
#define CDC_NCM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 7 + 7)
// clang-format off
#define CDC_NCM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, \
eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) \
#define CDC_NCM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \
/* Interface Associate */ \
0x08, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
@@ -657,10 +655,10 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */\
CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype */\
str_idx, /* Device's MAC string index */\
DBVAL_BE(eth_statistics), /* Ethernet statistics (bitmap) */\
WBVAL(wMaxPacketSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
WBVAL(wNumberMCFilters), /* wNumberMCFilters: the number of multicast filters */\
bNumberPowerFilters, /* bNumberPowerFilters: the number of wakeup power filters */\
DBVAL_BE(0x00000000), /* Ethernet statistics (bitmap) */\
WBVAL(1514), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
WBVAL(0), /* wNumberMCFilters: the number of multicast filters */ \
0, /* bNumberPowerFilters: the number of wakeup power filters */ \
0x06, \
CDC_CS_INTERFACE, \
CDC_FUNC_DESC_NCM, \

View File

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

View File

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

View File

@@ -634,7 +634,7 @@ struct usb_hid_js_report {
#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) \
#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, out_ep, in_ep, wMaxPacketSize, bInterval) \
0x09, /* bLength: Interface Descriptor size */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
@@ -654,13 +654,13 @@ struct usb_hid_js_report {
WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
0x07, /* bLength: Endpoint Descriptor size */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
in_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
out_ep, /* bEndpointAddress: Endpoint Address (OUT) */ \
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) */ \
in_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
0x03, /* bmAttributes: Interrupt endpoint */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
bInterval /* bInterval: Polling Interval */

View File

@@ -106,7 +106,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
memcpy(buffer, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1));
return ret;
}
@@ -148,7 +148,7 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol)
if (ret < 8) {
return ret;
}
memcpy(protocol, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
memcpy(protocol, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1));
return ret;
}
@@ -190,7 +190,7 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, buflen));
memcpy(buffer, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, buflen));
return ret;
}

View File

@@ -373,6 +373,11 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5);
}
if (hub->nports > CONFIG_USBHOST_MAX_EHPORTS) {
USB_LOG_ERR("Hub nports %u overflow\r\n", hub->nports);
return -USB_ERR_NOMEM;
}
for (uint8_t port = 0; port < hub->nports; port++) {
hub->child[port].port = port + 1;
hub->child[port].parent = hub;
@@ -665,7 +670,9 @@ static void usbh_hub_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
if (ret < 0) {
continue;
}
usb_osal_mutex_take(bus->mutex);
usbh_hub_events(hub);
usb_osal_mutex_give(bus->mutex);
}
}
@@ -695,6 +702,12 @@ int usbh_hub_initialize(struct usbh_bus *bus)
return -1;
}
bus->mutex = usb_osal_mutex_create();
if (bus->mutex == NULL) {
USB_LOG_ERR("Failed to create bus mutex\r\n");
return -1;
}
snprintf(thread_name, 32, "usbh_hub%u", bus->busid);
bus->hub_thread = usb_osal_thread_create(thread_name, CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbh_hub_thread, bus);
if (bus->hub_thread == NULL) {
@@ -708,8 +721,8 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
{
struct usbh_hubport *hport;
struct usbh_hub *hub;
size_t flags;
usb_osal_mutex_take(bus->mutex);
hub = &bus->hcd.roothub;
for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
@@ -717,15 +730,13 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
usbh_hubport_release(hport);
}
flags = usb_osal_enter_critical_section();
usb_hc_deinit(bus);
usb_osal_leave_critical_section(flags);
usb_osal_mq_delete(bus->hub_mq);
usb_osal_thread_delete(bus->hub_thread);
usb_osal_mq_delete(bus->hub_mq);
usb_osal_mutex_give(bus->mutex);
usb_osal_mutex_delete(bus->mutex);
return 0;
}

View File

@@ -6,6 +6,8 @@
#ifndef USB_MIDI_H
#define USB_MIDI_H
#include "usb_audio.h"
/* bDescriptorSubType */
#define MIDI_VC_HEADER_DESCRIPTOR_SUBTYPE 0x01U
#define MIDI_MS_HEADER_DESCRIPTOR_SUBTYPE 0x01U
@@ -201,6 +203,19 @@ struct midi_cs_ep_ms_general_descriptor {
#define MIDI_SIZEOF_MS_GENERAL_DESC(n) (4 + n)
// clang-format off
#define MIDI_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bInterfaceNumber, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
bNumEndpoints, /* bNumEndpoints */ \
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
AUDIO_SUBCLASS_MIDISTREAMING, /* bInterfaceSubClass */ \
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
0x00 /* iInterface */
#define MIDI_STANDARD_DESCRIPTOR_LEN 0x09
#define MIDI_CS_HEADER_DESCRIPTOR_INIT(wTotalLength) \
0x07, /* bLength */ \
USB_CS_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \

View File

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

0
class/vendor/wifi/.gitkeep vendored Normal file
View File

View File

@@ -1,6 +0,0 @@
# BL616 USB WIFI
Usbwifi firmware please contact bouffalolab. You can purchase a module in the following ways:
- https://iot.mi.com/moduleBrowser.html
- https://docs.ai-thinker.com/ai_m61

View File

@@ -1,513 +0,0 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbh_core.h"
#include "usbh_bl616.h"
#undef USB_DBG_TAG
#define USB_DBG_TAG "usbh_bl616"
#include "usb_log.h"
#define DEV_FORMAT "/dev/wifi/bl616"
#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
#define ARR_ELE_6(e) (e)[0], (e)[1], (e)[2], (e)[3], (e)[4], (e)[5]
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_tx_buffer[2048 + 512];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_rx_buffer[2048 + 512];
static struct usbh_bl616 g_bl616_class;
static const char *auth_to_str(uint8_t auth)
{
const char *table[RNM_WIFI_AUTH_MAX] = {
[RNM_WIFI_AUTH_UNKNOWN] = "UNKNOWN",
[RNM_WIFI_AUTH_OPEN] = "OPEN",
[RNM_WIFI_AUTH_WEP] = "WEP",
[RNM_WIFI_AUTH_WPA_PSK] = "WPA-PSK",
[RNM_WIFI_AUTH_WPA2_PSK] = "WPA2-PSK",
[RNM_WIFI_AUTH_WPA_WPA2_PSK] = "WPA2-PSK/WPA-PSK",
[RNM_WIFI_AUTH_WPA_ENTERPRISE] = "WPA-ENT",
[RNM_WIFI_AUTH_WPA3_SAE] = "WPA3-SAE",
[RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE] = "WPA2-PSK/WPA3-SAE",
};
if (auth < RNM_WIFI_AUTH_MAX)
return table[auth];
else
return table[RNM_WIFI_AUTH_UNKNOWN];
}
static const char *cipher_to_str(uint8_t cipher)
{
const char *table[RNM_WIFI_CIPHER_MAX] = {
[RNM_WIFI_CIPHER_UNKNOWN] = "UNKNOWN",
[RNM_WIFI_CIPHER_NONE] = "NONE",
[RNM_WIFI_CIPHER_WEP] = "WEP",
[RNM_WIFI_CIPHER_AES] = "AES",
[RNM_WIFI_CIPHER_TKIP] = "TKIP",
[RNM_WIFI_CIPHER_TKIP_AES] = "TKIP/AES",
};
if (cipher < RNM_WIFI_CIPHER_MAX)
return table[cipher];
else
return table[RNM_WIFI_CIPHER_UNKNOWN];
}
static int parse_get_mac_rsp_msg(struct usbh_bl616 *bl616_class, void *buf, int buf_len)
{
usb_data_t *usb_hdr = buf;
rnm_mac_addr_ind_msg_t *rsp = buf + sizeof(usb_data_t);
if (buf_len != sizeof(usb_data_t) + sizeof(rnm_mac_addr_ind_msg_t)) {
return -1;
}
if (usb_hdr->type != USBWIFI_DATA_TYPE_CMD || usb_hdr->length != sizeof(rnm_mac_addr_ind_msg_t)) {
return -1;
}
if (rsp->hdr.cmd != BFLB_CMD_GET_MAC_ADDR || !(rsp->hdr.flags & RNM_MSG_FLAG_ACK)) {
return -1;
}
memcpy(bl616_class->sta_mac, rsp->sta_mac, 6);
memcpy(bl616_class->ap_mac, rsp->ap_mac, 6);
return 0;
}
static int usbh_bl616_bulk_in_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
{
int ret;
struct usbh_urb *urb = &bl616_class->bulkin_urb;
usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkin, buffer, buflen, timeout, NULL, NULL);
ret = usbh_submit_urb(urb);
if (ret == 0) {
ret = urb->actual_length;
}
return ret;
}
static int usbh_bl616_bulk_out_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
{
int ret;
struct usbh_urb *urb = &bl616_class->bulkout_urb;
usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkout, buffer, buflen, timeout, NULL, NULL);
ret = usbh_submit_urb(urb);
if (ret == 0) {
ret = urb->actual_length;
}
return ret;
}
static int usbh_bl616_get_wifi_mac(struct usbh_bl616 *bl616_class)
{
int ret;
uint32_t msg_len;
usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
rnm_base_msg_t *rnm_msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
memset(usb_hdr, 0, sizeof(usb_data_t));
memset(rnm_msg, 0, sizeof(rnm_base_msg_t));
usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
usb_hdr->length = sizeof(rnm_base_msg_t);
usb_hdr->payload_offset = sizeof(usb_data_t);
rnm_msg->cmd = BFLB_CMD_GET_MAC_ADDR;
msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
ret = usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
if (ret < 0) {
return ret;
}
ret = usbh_bl616_bulk_in_transfer(bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), 500);
if (ret < 0) {
return ret;
}
ret = parse_get_mac_rsp_msg(bl616_class, g_bl616_rx_buffer, ret);
return ret;
}
static int usbh_bl616_wifi_open(struct usbh_bl616 *bl616_class)
{
uint32_t msg_len;
usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
memset(usb_hdr, 0, sizeof(usb_data_t));
memset(msg, 0, sizeof(rnm_base_msg_t));
usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
usb_hdr->length = sizeof(rnm_base_msg_t);
usb_hdr->payload_offset = sizeof(usb_data_t);
msg->cmd = BFLB_CMD_HELLO;
msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
}
static int usbh_bl616_wifi_close(struct usbh_bl616 *bl616_class)
{
uint32_t msg_len;
usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
memset(usb_hdr, 0, sizeof(usb_data_t));
memset(msg, 0, sizeof(rnm_base_msg_t));
usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
usb_hdr->length = sizeof(rnm_base_msg_t);
usb_hdr->payload_offset = sizeof(usb_data_t);
msg->cmd = BFLB_CMD_UNLOAD_DRV;
msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500);
}
int usbh_bl616_wifi_sta_connect(const char *ssid,
const int ssid_len,
const char *password,
const int pwd_len)
{
uint32_t msg_len;
usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
rnm_sta_connect_msg_t *msg = (rnm_sta_connect_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
memset(usb_hdr, 0, sizeof(usb_data_t));
memset(msg, 0, sizeof(rnm_sta_connect_msg_t));
usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
usb_hdr->length = sizeof(rnm_sta_connect_msg_t);
usb_hdr->payload_offset = sizeof(usb_data_t);
msg->hdr.cmd = BFLB_CMD_STA_CONNECT;
msg->hdr.msg_id = 0x0001;
msg->hdr.session_id = 0x0002;
msg->ssid_len = ssid_len;
memcpy(msg->ssid, ssid, ssid_len);
if (password) {
memcpy(msg->password, password, pwd_len);
}
msg_len = sizeof(usb_data_t) + sizeof(rnm_sta_connect_msg_t);
return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
}
int usbh_bl616_wifi_sta_disconnect(void)
{
uint32_t msg_len;
usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
memset(usb_hdr, 0, sizeof(usb_data_t));
memset(msg, 0, sizeof(rnm_base_msg_t));
usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
usb_hdr->length = sizeof(rnm_base_msg_t);
usb_hdr->payload_offset = sizeof(usb_data_t);
msg->cmd = BFLB_CMD_STA_DISCONNECT;
msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
}
int usbh_bl616_get_wifi_scan_result(void)
{
uint32_t msg_len;
usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
memset(usb_hdr, 0, sizeof(usb_data_t));
memset(msg, 0, sizeof(rnm_base_msg_t));
usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
usb_hdr->length = sizeof(rnm_base_msg_t);
usb_hdr->payload_offset = sizeof(usb_data_t);
msg->cmd = BFLB_CMD_SCAN_RESULTS;
msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
}
int usbh_bl616_wifi_scan(void)
{
int ret;
uint32_t msg_len;
usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t));
memset(usb_hdr, 0, sizeof(usb_data_t));
memset(msg, 0, sizeof(rnm_base_msg_t));
usb_hdr->type = USBWIFI_DATA_TYPE_CMD;
usb_hdr->length = sizeof(rnm_base_msg_t);
usb_hdr->payload_offset = sizeof(usb_data_t);
msg->cmd = BFLB_CMD_SCAN;
msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t);
ret = usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500);
if (ret < 0) {
return ret;
}
usb_osal_msleep(500);
return usbh_bl616_get_wifi_scan_result();
}
static int usbh_bl616_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;
int ret = 0;
struct usbh_bl616 *bl616_class = &g_bl616_class;
memset(bl616_class, 0, sizeof(struct usbh_bl616));
bl616_class->hport = hport;
bl616_class->intf = intf;
hport->config.intf[intf].priv = bl616_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(bl616_class->bulkin, ep_desc);
} else {
USBH_EP_INIT(bl616_class->bulkout, ep_desc);
}
}
usbh_bl616_get_wifi_mac(bl616_class);
usbh_bl616_wifi_close(bl616_class);
usbh_bl616_wifi_open(bl616_class);
USB_LOG_INFO("BL616 WIFI STA MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
bl616_class->sta_mac[0],
bl616_class->sta_mac[1],
bl616_class->sta_mac[2],
bl616_class->sta_mac[3],
bl616_class->sta_mac[4],
bl616_class->sta_mac[5]);
USB_LOG_INFO("BL616 WIFI AP MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
bl616_class->ap_mac[0],
bl616_class->ap_mac[1],
bl616_class->ap_mac[2],
bl616_class->ap_mac[3],
bl616_class->ap_mac[4],
bl616_class->ap_mac[5]);
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
USB_LOG_INFO("Register BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname);
usbh_bl616_run(bl616_class);
return ret;
}
static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf)
{
int ret = 0;
struct usbh_bl616 *bl616_class = (struct usbh_bl616 *)hport->config.intf[intf].priv;
if (bl616_class) {
if (bl616_class->bulkin) {
usbh_kill_urb(&bl616_class->bulkin_urb);
}
if (bl616_class->bulkout) {
usbh_kill_urb(&bl616_class->bulkout_urb);
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname);
usbh_bl616_stop(bl616_class);
}
memset(bl616_class, 0, sizeof(struct usbh_bl616));
}
return ret;
}
void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
usb_data_t *usb_hdr;
rnm_base_msg_t *msg;
rnm_sta_ip_update_ind_msg_t *ipmsg;
rnm_scan_ind_msg_t *scanmsg;
uint8_t *data;
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
USB_LOG_INFO("Create bl616 wifi rx thread\r\n");
while (1) {
ret = usbh_bl616_bulk_in_transfer(&g_bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), USB_OSAL_WAITING_FOREVER);
if (ret < 0) {
break;
}
usb_hdr = (usb_data_t *)g_bl616_rx_buffer;
if (usb_hdr->type == USBWIFI_DATA_TYPE_CMD) {
msg = (rnm_base_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
switch (msg->cmd) {
case BFLB_CMD_STA_CONNECTED_IND:
USB_LOG_INFO("AP connected\n");
g_bl616_class.connect_status = true;
usbh_bl616_sta_connect_callback();
break;
case BFLB_CMD_STA_DISCONNECTED_IND:
if (g_bl616_class.connect_status == true) {
g_bl616_class.connect_status = false;
USB_LOG_INFO("AP disconnected\n");
usbh_bl616_sta_disconnect_callback();
}
break;
case BFLB_CMD_STA_IP_UPDATE_IND:
ipmsg = (rnm_sta_ip_update_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
USB_LOG_INFO("WIFI IP update\r\n");
USB_LOG_INFO("WIFI IPv4 Address : %d:%d:%d:%d\r\n",
ipmsg->ip4_addr[0],
ipmsg->ip4_addr[1],
ipmsg->ip4_addr[2],
ipmsg->ip4_addr[3]);
USB_LOG_INFO("WIFI IPv4 Mask : %d:%d:%d:%d\r\n",
ipmsg->ip4_mask[0],
ipmsg->ip4_mask[1],
ipmsg->ip4_mask[2],
ipmsg->ip4_mask[3]);
USB_LOG_INFO("WIFI IPv4 Gateway : %d:%d:%d:%d\r\n\r\n",
ipmsg->ip4_gw[0],
ipmsg->ip4_gw[1],
ipmsg->ip4_gw[2],
ipmsg->ip4_gw[3]);
g_bl616_class.mode = BL_MODE_STA;
usbh_bl616_sta_update_ip(ipmsg->ip4_addr, ipmsg->ip4_mask, ipmsg->ip4_gw);
break;
case BFLB_CMD_SCAN_RESULTS:
scanmsg = (rnm_scan_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
USB_LOG_INFO("WIFI scan result:\r\n");
for (uint32_t i = 0; i < scanmsg->num; ++i) {
struct bf1b_wifi_scan_record *r = &scanmsg->records[i];
USB_LOG_INFO("BSSID " MAC_FMT ", channel %u, rssi %d, auth %s, cipher %s, SSID %s\r\n",
ARR_ELE_6(r->bssid), r->channel, r->rssi,
auth_to_str(r->auth_mode), cipher_to_str(r->cipher), r->ssid);
}
break;
default:
break;
}
} else if (usb_hdr->type == USBWIFI_DATA_TYPE_PKT) {
data = (uint8_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset);
usbh_bl616_eth_input(data, usb_hdr->length);
} else {
}
}
USB_LOG_INFO("Delete bl616 wifi rx thread\r\n");
usb_osal_thread_delete(NULL);
}
uint8_t *usbh_bl616_get_eth_txbuf(void)
{
return (g_bl616_tx_buffer + sizeof(usb_data_t));
}
int usbh_bl616_eth_output(uint32_t buflen)
{
usb_data_t *usb_hdr;
uint32_t txlen;
if (g_bl616_class.connect_status == false) {
return -USB_ERR_NOTCONN;
}
usb_hdr = (usb_data_t *)g_bl616_tx_buffer;
memset(usb_hdr, 0, sizeof(usb_data_t));
usb_hdr->type = USBWIFI_DATA_TYPE_PKT;
usb_hdr->length = buflen;
usb_hdr->payload_offset = sizeof(usb_data_t);
txlen = buflen + sizeof(usb_data_t);
if (!(txlen % USB_GET_MAXPACKETSIZE(g_bl616_class.bulkout->wMaxPacketSize))) {
txlen += 1;
}
USB_LOG_DBG("txlen:%d\r\n", txlen);
usbh_bulk_urb_fill(&g_bl616_class.bulkout_urb, g_bl616_class.hport, g_bl616_class.bulkout, g_bl616_tx_buffer, txlen, USB_OSAL_WAITING_FOREVER, NULL, NULL);
return usbh_submit_urb(&g_bl616_class.bulkout_urb);
}
int wifi_sta_connect(int argc, char **argv)
{
if (argc < 3) {
USB_LOG_ERR("Usage: %s <ssid> <password>\r\n", argv[0]);
return -1;
}
usbh_bl616_wifi_sta_connect(argv[1], strlen(argv[1]), argv[2], strlen(argv[2]));
return 0;
}
int wifi_scan(int argc, char **argv)
{
(void)argc;
(void)argv;
usbh_bl616_wifi_scan();
return 0;
}
__WEAK void usbh_bl616_run(struct usbh_bl616 *bl616_class)
{
(void)bl616_class;
}
__WEAK void usbh_bl616_stop(struct usbh_bl616 *bl616_class)
{
(void)bl616_class;
}
static const uint16_t bl616_id_table[][2] = {
{ 0x349b, 0x616f },
{ 0, 0 },
};
static const struct usbh_class_driver bl616_class_driver = {
.driver_name = "bl616_wifi",
.connect = usbh_bl616_connect,
.disconnect = usbh_bl616_disconnect
};
CLASS_INFO_DEFINE const struct usbh_class_info bl616_class_info = {
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
.bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.id_table = bl616_id_table,
.class_driver = &bl616_class_driver
};

View File

@@ -1,220 +0,0 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBH_BL616_H
#define USBH_BL616_H
#define USBWIFI_DATA_TYPE_CMD 0xA55A
#define USBWIFI_DATA_TYPE_PKT 0x6996
#define USB_DATA_FLAG_AP_PKT (1u << 0)
typedef enum {
BFLB_CMD_REBOOT = 0,
BFLB_CMD_RESET,
BFLB_CMD_HELLO,
BFLB_CMD_PING,
BFLB_CMD_GET_MAC_ADDR,
// Scan
BFLB_CMD_SCAN,
BFLB_CMD_SCAN_RESULTS,
// STA
BFLB_CMD_STA_CONNECT,
BFLB_CMD_STA_DISCONNECT,
BFLB_CMD_STA_CONNECTED_IND,
BFLB_CMD_STA_DISCONNECTED_IND,
BFLB_CMD_STA_IP_UPDATE_IND,
BFLB_CMD_STA_SET_AUTO_RECONNECT,
BFLB_CMD_STA_GET_LINK_STATUS,
// AP
BFLB_CMD_AP_START,
BFLB_CMD_AP_STOP,
BFLB_CMD_AP_STARTED_IND,
BFLB_CMD_AP_STOPPED_IND,
BFLB_CMD_AP_GET_STA_LIST,
// Monitor
BFLB_CMD_MONITOR_START,
BFLB_CMD_MONITOR_STOP,
BFLB_CMD_MONITOR_SET_CHANNEL,
BFLB_CMD_MONITOR_GET_CHANNEL,
BFLB_CMD_SET_LPM_MODE,
// OTA
BFLB_CMD_GET_DEV_VERSION,
BFLB_CMD_OTA,
BFLB_CMD_EXT,
BFLB_CMD_USER_EXT,
BFLB_CMD_UNLOAD_DRV,
BFLB_CMD_MAX,
} bflb_cmd_t;
typedef enum {
STATUS_OK,
STATUS_NOMEM = 128,
STATUS_INVALID_INPUT,
STATUS_INVALID_MODE,
STATUS_ERR_UNSPECIFIED,
STATUS_NOT_IMPLEMENTED,
} cmd_status_t;
typedef enum {
RNM_WIFI_AUTH_UNKNOWN = 0,
RNM_WIFI_AUTH_OPEN,
RNM_WIFI_AUTH_WEP,
RNM_WIFI_AUTH_WPA_PSK,
RNM_WIFI_AUTH_WPA2_PSK,
RNM_WIFI_AUTH_WPA_WPA2_PSK,
RNM_WIFI_AUTH_WPA_ENTERPRISE,
RNM_WIFI_AUTH_WPA3_SAE,
RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE,
RNM_WIFI_AUTH_MAX,
} rnm_wifi_auth_mode_t;
typedef enum {
RNM_WIFI_CIPHER_UNKNOWN = 0,
RNM_WIFI_CIPHER_NONE,
RNM_WIFI_CIPHER_WEP,
RNM_WIFI_CIPHER_AES,
RNM_WIFI_CIPHER_TKIP,
RNM_WIFI_CIPHER_TKIP_AES,
RNM_WIFI_CIPHER_MAX,
} rnm_wifi_cipher_t;
/* common header */
typedef struct {
uint16_t cmd;
// flag ACK is used by server to indicate a response to client
#define RNM_MSG_FLAG_ACK (1 << 0)
// flag TRANSPARENT is never transfered to peer but used locally
#define RNM_MSG_FLAG_TRANSPARENT (1 << 1)
// flag ASYNC is used by server to notify client events such as STA_CONNECTED
#define RNM_MSG_FLAG_ASYNC (1 << 2)
uint16_t flags;
uint16_t status;
uint16_t msg_id;
uint16_t session_id;
uint16_t msg_id_replying;
} rnm_base_msg_t;
typedef struct {
rnm_base_msg_t hdr;
} rnm_ack_msg_t;
typedef struct {
rnm_base_msg_t hdr;
uint8_t sta_mac[6];
uint8_t ap_mac[6];
} rnm_mac_addr_ind_msg_t;
typedef struct {
rnm_base_msg_t hdr;
uint16_t ssid_len;
uint8_t ssid[32];
uint8_t password[64];
} rnm_sta_connect_msg_t;
typedef struct {
rnm_base_msg_t hdr;
uint8_t ip4_addr[4];
uint8_t ip4_mask[4];
uint8_t ip4_gw[4];
uint8_t ip4_dns1[4];
uint8_t ip4_dns2[4];
uint8_t gw_mac[6];
} rnm_sta_ip_update_ind_msg_t;
struct bf1b_wifi_scan_record {
uint8_t bssid[6];
// TODO use compressed SSID encoding to save room
uint8_t ssid[32 + 1];
uint16_t channel;
int8_t rssi;
uint8_t auth_mode;
uint8_t cipher;
} __PACKED;
typedef struct {
rnm_base_msg_t hdr;
uint16_t num;
struct bf1b_wifi_scan_record records[];
} rnm_scan_ind_msg_t;
typedef enum {
BL_MODE_NONE,
BL_MODE_STA, // card is STA
BL_MODE_AP, // card is AP
BL_MODE_STA_AP, // card is STA&AP
BL_MODE_SNIFFER, // card is sniffer
BL_MODE_MAX,
} bl_wifi_mode_t;
typedef struct {
uint16_t type;
uint16_t length;
uint16_t flags;
uint16_t payload_offset;
uint32_t rsvd[8];
uint8_t payload[];
} __attribute__((aligned(4))) usb_data_t;
struct usbh_bl616 {
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 sta_mac[6];
uint8_t ap_mac[6];
uint8_t mode;
bool connect_status;
void *user_data;
};
#ifdef __cplusplus
extern "C" {
#endif
int usbh_bl616_wifi_sta_connect(const char *ssid,
const int ssid_len,
const char *password,
const int pwd_len);
int usbh_bl616_wifi_sta_disconnect(void);
int usbh_bl616_wifi_scan(void);
void usbh_bl616_sta_connect_callback(void);
void usbh_bl616_sta_disconnect_callback(void);
void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4]);
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(CONFIG_USB_OSAL_THREAD_SET_ARGV);
void usbh_bl616_run(struct usbh_bl616 *bl616_class);
void usbh_bl616_stop(struct usbh_bl616 *bl616_class);
int wifi_sta_connect(int argc, char **argv);
int wifi_scan(int argc, char **argv);
#ifdef __cplusplus
}
#endif
#endif /* USBH_BL616_H */

View File

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

View File

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

View File

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

View File

@@ -556,7 +556,7 @@ struct usb_bos_header_descriptor {
} __PACKED;
/* BOS Capability platform Descriptor */
struct usb_bos_capability_platform_descriptor {
struct usb_bos_capability_platform_common_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
@@ -564,16 +564,26 @@ struct usb_bos_capability_platform_descriptor {
uint8_t PlatformCapabilityUUID[16];
} __PACKED;
/* BOS Capability MS OS Descriptors version 2 */
struct usb_bos_capability_msosv2_descriptor {
/* Microsoft OS 2.0 Platform Capability Descriptor
* See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/
* microsoft-defined-usb-descriptors
* Adapted from the source:
* https://github.com/sowbug/weblight/blob/master/firmware/webusb.c
* (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c
*/
struct usb_bos_capability_platform_winusb_descriptor {
struct usb_bos_capability_platform_common_descriptor common;
uint32_t dwWindowsVersion;
uint16_t wMSOSDescriptorSetTotalLength;
uint8_t bVendorCode;
uint8_t bAltEnumCode;
} __PACKED;
/* BOS Capability webusb */
struct usb_bos_capability_webusb_descriptor {
/* WebUSB Platform Capability Descriptor:
* https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
*/
struct usb_bos_capability_platform_webusb_descriptor {
struct usb_bos_capability_platform_common_descriptor common;
uint16_t bcdVersion;
uint8_t bVendorCode;
uint8_t iLandingPage;
@@ -587,26 +597,6 @@ struct usb_bos_capability_extension_descriptor {
uint32_t bmAttributes;
} __PACKED;
/* Microsoft OS 2.0 Platform Capability Descriptor
* See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/
* microsoft-defined-usb-descriptors
* Adapted from the source:
* https://github.com/sowbug/weblight/blob/master/firmware/webusb.c
* (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c
*/
struct usb_bos_capability_platform_msosv2_descriptor {
struct usb_bos_capability_platform_descriptor platform_msos;
struct usb_bos_capability_msosv2_descriptor data_msosv2;
} __PACKED;
/* WebUSB Platform Capability Descriptor:
* https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
*/
struct usb_bos_capability_platform_webusb_descriptor {
struct usb_bos_capability_platform_descriptor platform_webusb;
struct usb_bos_capability_webusb_descriptor data_webusb;
} __PACKED;
struct usb_webusb_url_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
@@ -625,18 +615,12 @@ struct usb_bos_descriptor {
uint32_t string_len;
};
/* USB Device Capability Descriptor */
struct usb_device_capability_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
} __PACKED;
/** USB descriptor header */
struct usb_desc_header {
uint8_t bLength; /**< descriptor length */
uint8_t bDescriptorType; /**< descriptor type */
};
// clang-format off
#define USB_DEVICE_DESCRIPTOR_INIT(bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct, bcdDevice, bNumConfigurations) \
0x12, /* bLength */ \
@@ -705,7 +689,7 @@ struct usb_desc_header {
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
bInterval /* bInterval */
#define USB_IAD_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \
#define USB_IAD_DESCRIPTOR_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \
0x08, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
bFirstInterface, /* bFirstInterface */ \
@@ -716,9 +700,145 @@ struct usb_desc_header {
0x00 /* iFunction */
#define USB_LANGID_INIT(id) \
0x04, /* bLength */ \
0x04, /* bLength */ \
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \
WBVAL(id) /* wLangID0 */
#define USB_BOS_HEADER_DESCRIPTOR_INIT(wTotalLength, bNumDeviceCaps) \
0x05, /* bLength */ \
USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE, /* bDescriptorType */\
WBVAL(wTotalLength), /* wTotalLength */ \
bNumDeviceCaps /* bNumDeviceCaps */
#define USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_INIT(bVendorCode, iLandingPage) \
0x18, /* bLength */ \
USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, /* bDescriptorType */ \
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ \
0x00, /* bReserved */ \
0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, /* PlatformCapabilityUUID */ \
0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65, \
WBVAL(0x0100), /* bcdVersion */ \
bVendorCode, /* bVendorCode */ \
iLandingPage /* iLandingPage */
#define USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(bVendorCode, wMSOSDescriptorSetTotalLength) \
0x1C, /* bLength */ \
USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, /* bDescriptorType */ \
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ \
0x00, /* bReserved */ \
0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, /* PlatformCapabilityUUID */ \
0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F, \
DBVAL(0x06030000), /* dwWindowsVersion */ \
WBVAL(wMSOSDescriptorSetTotalLength), /* wMSOSDescriptorSetTotalLength */ \
bVendorCode, /* bVendorCode */ \
0x00 /* bAltEnumCode */
#define USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_LEN 24
#define USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN 28
#define USB_MSOSV1_STRING_DESCRIPTOR_INIT(vendor_code) \
0x12, /* bLength */ \
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \
'M', 0, /* bString[0] */ \
'S', 0, /* bString[1] */ \
'F', 0, /* bString[2] */ \
'T', 0, /* bString[3] */ \
'1', 0, /* bString[4] */ \
'0', 0, /* bString[5] */ \
'0', 0, /* bString[6] */ \
vendor_code, /* bMS_VendorCode */ \
0x00 /* bPad */
#define USB_MSOSV1_COMP_ID_HEADER_DESCRIPTOR_INIT(bCount) \
DBVAL((sizeof(struct usb_msosv1_compat_id_header_descriptor) + sizeof(struct usb_msosv1_comp_id_function_descriptor) * bCount)), /* dwLength */ \
WBVAL(0x0100), /* bcdVersion */ \
WBVAL(0x0004), /* wIndex */ \
bCount, /* bCount */ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved[7] */
#define USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(bFirstInterfaceNumber) \
bFirstInterfaceNumber, /* bFirstInterfaceNumber */\
0x01, /* reserved1 */ \
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* compatibleID[8] */ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved2[6] */
#define USB_MSOSV1_COMP_ID_FUNCTION_MTP_DESCRIPTOR_INIT(bFirstInterfaceNumber)\
bFirstInterfaceNumber, /* bFirstInterfaceNumber */\
0x01, /* reserved1 */ \
'M', 'T', 'P', 'U', 'S', 'B', 0x00, 0x00, /* compatibleID[8] */ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved2[6] */
#define USB_MSOSV1_COMP_ID_FUNCTION_ADB_DESCRIPTOR_INIT(bFirstInterfaceNumber)\
bFirstInterfaceNumber, * bFirstInterfaceNumber */\
0x01, /* reserved1 */ \
'A', 'D', 'B', 0x00, 0x00, 0x00, 0x00, 0x00, /* compatibleID[8] */ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */ \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved2[6] */
#define USB_MSOSV1_COMP_ID_DESCRIPTOR_LEN(bCount) \
(sizeof(struct usb_msosv1_compat_id_header_descriptor) + sizeof(struct usb_msosv1_comp_id_function_descriptor) * (bCount))
#define USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(wDescriptorSetTotalLength) \
WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */ \
WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */ \
DBVAL(0x06030000), /* dwWindowsVersion */ \
WBVAL(wDescriptorSetTotalLength) /* wDescriptorSetTotalLength */
#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_INIT() \
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ \
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ \
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ \
0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ \
WBVAL(132), /* wLength */ \
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ \
WBVAL(WINUSB_PROP_DATA_TYPE_REG_SZ), /* wPropertyDataType */ \
WBVAL(42), /* wPropertyNameLength bPropertyName: "DeviceInterfaceGUID" */ \
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, \
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, \
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, \
WBVAL(80), /* wPropertyDataLength */ \
'{', 0, \
'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, \
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, \
'4', 0, '6', 0, '6', 0, '3', 0, '-', 0, \
'A', 0, 'A', 0, '3', 0, '6', 0, '-', \
0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, \
'}', 0, 0, 0, 0, 0
#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_LEN \
(WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132)
#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(bFirstInterfaceNumber) \
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */ \
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */ \
bFirstInterfaceNumber, /* bFirstInterface*/ \
0, /* bReserved */ \
WBVAL((WINUSB_FUNCTION_SUBSET_HEADER_SIZE + WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132)), /* wSubsetLength */\
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ \
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ \
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ \
0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ \
WBVAL(132), /* wLength */ \
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ \
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */ \
WBVAL(42), /* wPropertyNameLength bPropertyName: "DeviceInterfaceGUID" */ \
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, \
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, \
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, \
WBVAL(80), /* wPropertyDataLength */ \
'{', 0, \
'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, \
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, \
'4', 0, '6', 0, '6', 0, '3', 0, '-', 0, \
'A', 0, 'A', 0, '3', 0, '6', 0, '-', \
0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, \
'}', 0, 0, 0, 0, 0
#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN \
(WINUSB_FUNCTION_SUBSET_HEADER_SIZE + WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132)
// clang-format on
#endif /* USB_DEF_H */

View File

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

View File

@@ -185,8 +185,8 @@
(field)[3] = (uint8_t)((value) >> 0); \
} while (0)
#define WBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF)
#define DBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF), ((x >> 16) & 0xFF), ((x >> 24) & 0xFF)
#define WBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF)
#define DBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF), (((x) >> 24) & 0xFF)
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__, PP_RSEQ_N())

View File

@@ -15,7 +15,7 @@
#undef CHERRYUSB_VERSION_STR
#endif
#define CHERRYUSB_VERSION 0x010502
#define CHERRYUSB_VERSION_STR "v1.5.2"
#define CHERRYUSB_VERSION 0x010503
#define CHERRYUSB_VERSION_STR "v1.5.3"
#endif

View File

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

View File

@@ -56,6 +56,7 @@ enum usbd_event_type {
typedef int (*usbd_request_handler)(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len);
typedef void (*usbd_endpoint_callback)(uint8_t busid, uint8_t ep, uint32_t nbytes);
typedef void (*usbd_notify_handler)(uint8_t busid, uint8_t event, void *arg);
typedef void (*usbd_event_handler_t)(uint8_t busid, uint8_t event);
struct usbd_endpoint {
uint8_t ep_addr;
@@ -115,7 +116,7 @@ bool usb_device_is_suspend(uint8_t busid);
int usbd_send_remote_wakeup(uint8_t busid);
uint8_t usbd_get_ep0_next_state(uint8_t busid);
int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event));
int usbd_initialize(uint8_t busid, uintptr_t reg_base, usbd_event_handler_t event_handler);
int usbd_deinitialize(uint8_t busid);
#ifdef __cplusplus

View File

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

View File

@@ -33,6 +33,7 @@ extern "C" {
#define USB_CLASS_MATCH_INTF_CLASS 0x0004
#define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008
#define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010
#define USB_CLASS_MATCH_INTF_NUM 0x0020
#define USB_CLASS_MATCH_VID_PID (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT)
#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i))
@@ -60,11 +61,14 @@ extern "C" {
USB_GET_MULT(ep_desc->wMaxPacketSize)); \
} while (0)
typedef void (*usbh_event_handler_t)(uint8_t busid, uint8_t hub_index, uint8_t hub_port, uint8_t intf, uint8_t event);
struct usbh_class_info {
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
uint8_t bInterfaceClass; /* Base device class code */
uint8_t bInterfaceSubClass; /* Sub-class, depends on base class. Eg. */
uint8_t bInterfaceProtocol; /* Protocol, depends on base class. Eg. */
uint8_t bInterfaceNumber; /* Interface number */
const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */
const struct usbh_class_driver *class_driver;
};
@@ -150,7 +154,7 @@ struct usbh_devaddr_map {
* alloctab[3]:addr from 96~127
*
*/
uint8_t next; /* Next device address */
uint8_t last; /* Last device address */
uint32_t alloctab[4]; /* Bit allocation table */
};
@@ -168,6 +172,8 @@ struct usbh_bus {
struct usbh_devaddr_map devgen;
usb_osal_thread_t hub_thread;
usb_osal_mq_t hub_mq;
usb_osal_mutex_t mutex;
usbh_event_handler_t event_handler;
};
static inline void usbh_control_urb_fill(struct usbh_urb *urb,
@@ -278,6 +284,7 @@ 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);
uint8_t usbh_get_hport_active_config_index(struct usbh_hubport *hport);
int lsusb(int argc, char **argv);

View File

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

View File

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

View File

@@ -288,7 +288,7 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base)
/* shell_init() must be called in-task */
if (0 != shell_init(false)) {
/* shell failed to be initialized */
printf("Failed to initialize shell\r\n");
USB_LOG_RAW("Failed to initialize shell\r\n");
for (;;) {
;
}

View File

@@ -24,11 +24,11 @@
/* AUDIO Class Config */
#define AUDIO_FREQ 16000U
#define IN_CHANNEL_NUM 1
#define IN_CHANNEL_NUM 2
#if IN_CHANNEL_NUM == 1
#define INPUT_CTRL 0x03, 0x03
#define INPUT_CH_ENABLE 0x0000
#define INPUT_CH_ENABLE 0x0001
#elif IN_CHANNEL_NUM == 2
#define INPUT_CTRL 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x0003
@@ -56,12 +56,12 @@
/* 16bit(2 Bytes) 单声道(Mono:1) */
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * 2 * IN_CHANNEL_NUM) / 1000))
#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \
AUDIO_AC_DESCRIPTOR_INIT_LEN(1) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_AS_DESCRIPTOR_INIT_LEN(1))
#define USB_CONFIG_SIZE (unsigned long)(9 + \
AUDIO_AC_DESCRIPTOR_LEN(1) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_AS_DESCRIPTOR_LEN(1))
#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(1) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
@@ -74,7 +74,7 @@ static const uint8_t device_descriptor[] = {
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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),
@@ -137,7 +137,7 @@ const struct usb_descriptor audio_v1_descriptor = {
#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),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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),
@@ -301,6 +301,8 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC

View File

@@ -21,13 +21,69 @@
#define FEEDBACK_ENDP_PACKET_SIZE 0x03
#endif
#define AUDIO_IN_EP 0x81
#define AUDIO_OUT_EP 0x02
#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
#define IN_CHANNEL_NUM 2
#if IN_CHANNEL_NUM == 1
#define INPUT_CTRL 0x03, 0x03
#define INPUT_CH_ENABLE 0x0001
#elif IN_CHANNEL_NUM == 2
#define INPUT_CTRL 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x0003
#elif IN_CHANNEL_NUM == 3
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x0007
#elif IN_CHANNEL_NUM == 4
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x000f
#elif IN_CHANNEL_NUM == 5
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x001f
#elif IN_CHANNEL_NUM == 6
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x003F
#elif IN_CHANNEL_NUM == 7
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x007f
#elif IN_CHANNEL_NUM == 8
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define INPUT_CH_ENABLE 0x00ff
#endif
#define OUT_CHANNEL_NUM 2
#if OUT_CHANNEL_NUM == 1
#define OUTPUT_CTRL 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x0001
#elif OUT_CHANNEL_NUM == 2
#define OUTPUT_CTRL 0x03, 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x0003
#elif OUT_CHANNEL_NUM == 3
#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x0007
#elif OUT_CHANNEL_NUM == 4
#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x000f
#elif OUT_CHANNEL_NUM == 5
#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x001f
#elif OUT_CHANNEL_NUM == 6
#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x003F
#elif OUT_CHANNEL_NUM == 7
#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x007f
#elif OUT_CHANNEL_NUM == 8
#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
#define OUTPUT_CH_ENABLE 0x00ff
#endif
/* AUDIO Class Config */
#define AUDIO_SPEAKER_FREQ 16000U
#define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u
@@ -44,27 +100,27 @@
#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 + \
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_DESCRIPTOR_INIT_LEN(1))
#define USB_CONFIG_SIZE (unsigned long)(9 + \
AUDIO_AC_DESCRIPTOR_LEN(2) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_AS_DESCRIPTOR_LEN(1) + \
AUDIO_AS_DESCRIPTOR_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))
#define USB_CONFIG_SIZE (unsigned long)(9 + \
AUDIO_AC_DESCRIPTOR_LEN(2) + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_AS_DESCRIPTOR_LEN(1) + \
AUDIO_AS_FEEDBACK_DESCRIPTOR_LEN(1))
#endif
#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) + \
@@ -81,23 +137,23 @@ static const uint8_t device_descriptor[] = {
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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),
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_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x04, 0x01, OUTPUT_CTRL),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID),
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 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)),
#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,
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, 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)),
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, 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[] = {
@@ -155,23 +211,23 @@ const struct usb_descriptor audio_v1_descriptor = {
#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),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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),
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_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE),
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x04, 0x01, OUTPUT_CTRL),
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID),
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 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)),
#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,
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, 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)),
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, 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)),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
@@ -230,7 +286,7 @@ const uint8_t audio_v1_descriptor[] = {
#if USING_FEEDBACK == 0
'1', 0x00, /* wcChar9 */
#else
'2', 0x00, /* wcChar9 */
'2', 0x00, /* wcChar9 */
#endif
#ifdef CONFIG_USB_HS
///////////////////////////////////////
@@ -297,11 +353,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value); /* uac1 can only use 10.14 */
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
#endif
printf("OPEN1\r\n");
USB_LOG_INFO("OPEN1\r\n");
} else {
tx_flag = 1;
ep_tx_busy_flag = false;
printf("OPEN2\r\n");
USB_LOG_INFO("OPEN2\r\n");
}
}
@@ -309,11 +365,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
{
if (intf == 1) {
rx_flag = 0;
printf("CLOSE1\r\n");
USB_LOG_INFO("CLOSE1\r\n");
} else {
tx_flag = 0;
ep_tx_busy_flag = false;
printf("CLOSE2\r\n");
USB_LOG_INFO("CLOSE2\r\n");
}
}
@@ -393,6 +449,8 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC

View File

@@ -22,17 +22,17 @@
#define AUDIO_IN_CLOCK_ID 0x01
#define AUDIO_IN_FU_ID 0x03
#define AUDIO_IN_MAX_FREQ 16000
#define HALF_WORD_BYTES 2 //2 half word (one channel)
#define SAMPLE_BITS 16 //16 bit per channel
#define AUDIO_IN_MAX_FREQ 96000
#define AUDIO_MIC_FRAME_SIZE_BYTE 2u
#define AUDIO_MIC_RESOLUTION_BIT 16u
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME)
#define IN_CHANNEL_NUM 2
#if IN_CHANNEL_NUM == 1
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define INPUT_CH_ENABLE 0x00000000
#define INPUT_CH_ENABLE 0x00000001
#elif IN_CHANNEL_NUM == 2
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define INPUT_CH_ENABLE 0x00000003
@@ -56,15 +56,15 @@
#define INPUT_CH_ENABLE 0x000000ff
#endif
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * IN_CHANNEL_NUM) / 1000))
#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(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
#define USB_CONFIG_SIZE (9 + \
AUDIO_V2_AC_DESCRIPTOR_LEN + \
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_DESCRIPTOR_LEN)
#define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
@@ -78,13 +78,13 @@ static const uint8_t device_descriptor[] = {
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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)
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x02, INPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 0x0000),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
};
static const uint8_t device_quality_descriptor[] = {
@@ -142,13 +142,13 @@ const struct usb_descriptor audio_v2_descriptor = {
#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),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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),
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x02, INPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 0x0000),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
@@ -225,10 +225,22 @@ const uint8_t audio_v2_descriptor[] = {
#endif
static const uint8_t mic_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(1),
AUDIO_SAMPLE_FREQ_NUM(5),
AUDIO_SAMPLE_FREQ_4B(8000),
AUDIO_SAMPLE_FREQ_4B(8000),
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(16000),
AUDIO_SAMPLE_FREQ_4B(16000),
AUDIO_SAMPLE_FREQ_4B(0x00)
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(32000),
AUDIO_SAMPLE_FREQ_4B(32000),
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(48000),
AUDIO_SAMPLE_FREQ_4B(48000),
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(96000),
AUDIO_SAMPLE_FREQ_4B(96000),
AUDIO_SAMPLE_FREQ_4B(0x00),
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
@@ -323,6 +335,8 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC

View File

@@ -30,19 +30,21 @@
#define AUDIO_IN_CLOCK_ID 0x05
#define AUDIO_IN_FU_ID 0x07
#define AUDIO_OUT_MAX_FREQ 96000
#define AUDIO_IN_MAX_FREQ 16000
#define AUDIO_OUT_MAX_FREQ 96000
#define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u
#define AUDIO_SPEAKER_RESOLUTION_BIT 16u
#define HALF_WORD_BYTES 2 //2 half word (one channel)
#define SAMPLE_BITS 16 //16 bit per channel
#define AUDIO_IN_MAX_FREQ 96000
#define AUDIO_MIC_FRAME_SIZE_BYTE 2u
#define AUDIO_MIC_RESOLUTION_BIT 16u
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME)
#define IN_CHANNEL_NUM 2
#if IN_CHANNEL_NUM == 1
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define INPUT_CH_ENABLE 0x00000000
#define INPUT_CH_ENABLE 0x00000001
#elif IN_CHANNEL_NUM == 2
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define INPUT_CH_ENABLE 0x00000003
@@ -70,7 +72,7 @@
#if OUT_CHANNEL_NUM == 1
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define OUTPUT_CH_ENABLE 0x00000000
#define OUTPUT_CH_ENABLE 0x00000001
#elif OUT_CHANNEL_NUM == 2
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define OUTPUT_CH_ENABLE 0x00000003
@@ -95,35 +97,35 @@
#endif
/* AudioFreq * DataSize (2 bytes) * NumChannels */
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * AUDIO_SPEAKER_FRAME_SIZE_BYTE * OUT_CHANNEL_NUM) / 1000))
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * IN_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 + \
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_SIZEOF_AC_CLOCK_SOURCE_DESC + \
AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_DESCRIPTOR_INIT_LEN + \
AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
#define USB_CONFIG_SIZE (9 + \
AUDIO_V2_AC_DESCRIPTOR_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_SIZEOF_AC_CLOCK_SOURCE_DESC + \
AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_DESCRIPTOR_LEN + \
AUDIO_V2_AS_DESCRIPTOR_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_SIZEOF_AC_CLOCK_SOURCE_DESC + \
AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN + \
AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
#define USB_CONFIG_SIZE (9 + \
AUDIO_V2_AC_DESCRIPTOR_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_SIZEOF_AC_CLOCK_SOURCE_DESC + \
AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN + \
AUDIO_V2_AS_DESCRIPTOR_LEN)
#endif
#define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \
@@ -142,22 +144,22 @@ static const uint8_t device_descriptor[] = {
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, 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, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 0x0000),
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x06, INPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 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),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, 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, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
#endif
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)
AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
};
static const uint8_t device_quality_descriptor[] = {
@@ -215,22 +217,22 @@ const struct usb_descriptor audio_v2_descriptor = {
#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),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, 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, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 0x0000),
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03),
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x06, INPUT_CTRL),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 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),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, 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, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
#endif
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),
AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
@@ -330,9 +332,21 @@ static const uint8_t speaker_default_sampling_freq_table[] = {
};
static const uint8_t mic_default_sampling_freq_table[] = {
AUDIO_SAMPLE_FREQ_NUM(1),
AUDIO_SAMPLE_FREQ_NUM(5),
AUDIO_SAMPLE_FREQ_4B(8000),
AUDIO_SAMPLE_FREQ_4B(8000),
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(16000),
AUDIO_SAMPLE_FREQ_4B(16000),
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(32000),
AUDIO_SAMPLE_FREQ_4B(32000),
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(48000),
AUDIO_SAMPLE_FREQ_4B(48000),
AUDIO_SAMPLE_FREQ_4B(0x00),
AUDIO_SAMPLE_FREQ_4B(96000),
AUDIO_SAMPLE_FREQ_4B(96000),
AUDIO_SAMPLE_FREQ_4B(0x00)
};
@@ -501,6 +515,8 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC

View File

@@ -31,13 +31,13 @@
#define HALF_WORD_BYTES 2 //2 half word (one channel)
#define SAMPLE_BITS 16 //16 bit per channel
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME)
#define OUT_CHANNEL_NUM 2
#if OUT_CHANNEL_NUM == 1
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define OUTPUT_CH_ENABLE 0x00000000
#define OUTPUT_CH_ENABLE 0x00000001
#elif OUT_CHANNEL_NUM == 2
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
#define OUTPUT_CH_ENABLE 0x00000003
@@ -64,21 +64,21 @@
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_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 + \
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_DESCRIPTOR_INIT_LEN)
#define USB_CONFIG_SIZE (9 + \
AUDIO_V2_AC_DESCRIPTOR_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_DESCRIPTOR_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)
#define USB_CONFIG_SIZE (9 + \
AUDIO_V2_AC_DESCRIPTOR_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_LEN)
#endif
#define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \
@@ -93,12 +93,12 @@ static const uint8_t device_descriptor[] = {
};
static const uint8_t config_descriptor[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, 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),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 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
@@ -161,12 +161,12 @@ const struct usb_descriptor audio_v2_descriptor = {
#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),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 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_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, 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),
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 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
@@ -397,6 +397,8 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too.
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC

View File

@@ -52,37 +52,7 @@ 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 */
HID_MOUSE_DESCRIPTOR_INIT(0x03, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
};
static const uint8_t device_quality_descriptor[] = {
@@ -143,37 +113,7 @@ const uint8_t cdc_acm_hid_msc_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 */
HID_MOUSE_DESCRIPTOR_INIT(0x03, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////

View File

@@ -205,4 +205,28 @@ void cdc_acm_chardev_init(uint8_t busid, uintptr_t reg_base)
#endif
usbd_cdc_acm_serial_init(busid, CDC_IN_EP, CDC_OUT_EP);
usbd_initialize(busid, reg_base, usbd_event_handler);
}
}
static int cdc_acm_enter(int argc, char **argv)
{
(void)argc;
(void)argv;
finsh_set_device("usb-acm0");
rt_console_set_device("usb-acm0");
return 0;
}
MSH_CMD_EXPORT(cdc_acm_enter, cdc_acm_enter);
static int cdc_acm_exit(int argc, char **argv)
{
(void)argc;
(void)argv;
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
return 0;
}
MSH_CMD_EXPORT(cdc_acm_exit, cdc_acm_exit);

View File

@@ -29,14 +29,9 @@
#define CDC_MAX_MPS 64
#endif
#define CDC_ECM_ETH_STATISTICS_BITMAP 0x00000000
/* str idx = 4 is for mac address: aa:bb:cc:dd:ee:ff*/
#define CDC_ECM_MAC_STRING_INDEX 4
/* Ethernet Maximum Segment size, typically 1514 bytes */
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U
#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)
@@ -44,7 +39,7 @@ static const uint8_t device_descriptor[] = {
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)
CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_MAC_STRING_INDEX)
};
static const uint8_t device_quality_descriptor[] = {
@@ -68,6 +63,7 @@ static const char *string_descriptors[] = {
"CherryUSB", /* Manufacturer */
"CherryUSB CDC ECM DEMO", /* Product */
"2022123456", /* Serial Number */
"aabbccddeeff", /* ecm mac address */
};
static const uint8_t *device_descriptor_callback(uint8_t speed)
@@ -104,7 +100,7 @@ const struct usb_descriptor cdc_ecm_descriptor = {
static const uint8_t cdc_ecm_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_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),
CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_MAC_STRING_INDEX),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////

View File

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

View File

@@ -8,25 +8,8 @@
#include "usbd_core.h"
#include "usbd_hid.h"
/*!< hidraw in endpoint */
#define HIDRAW_IN_EP 0x81
#ifdef CONFIG_USB_HS
#define HIDRAW_IN_EP_SIZE 1024
#define HIDRAW_IN_INTERVAL 4
#else
#define HIDRAW_IN_EP_SIZE 64
#define HIDRAW_IN_INTERVAL 10
#endif
/*!< hidraw out endpoint */
#define HIDRAW_OUT_EP 0x02
#ifdef CONFIG_USB_HS
#define HIDRAW_OUT_EP_SIZE 1024
#define HIDRAW_OUT_EP_INTERVAL 4
#else
#define HIDRAW_OUT_EP_SIZE 64
#define HIDRAW_OUT_EP_INTERVAL 10
#endif
#define HIDRAW_IN_EP 0x81
#define HIDRAW_OUT_EP 0x02
#define USBD_VID 0xffff
#define USBD_PID 0xffff
@@ -34,53 +17,27 @@
#define USBD_LANGID_STRING 1033
/*!< config descriptor size */
#define USB_HID_CONFIG_DESC_SIZ (9 + 9 + 9 + 7 + 7)
#define USB_CONFIG_SIZE (9 + 9 + 9 + 7 + 7)
/*!< custom hid report descriptor size */
#define HID_CUSTOM_REPORT_DESC_SIZE 38
#ifdef CONFIG_USB_HS
#define HID_MAX_MPS 1024
#define HIDRAW_IN_INTERVAL 1
#else
#define HID_MAX_MPS 64
#define HIDRAW_IN_INTERVAL 1
#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, 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 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_CUSTOM_INOUT_DESCRIPTOR_INIT(0x00, 0x01, HID_CUSTOM_REPORT_DESC_SIZE, HIDRAW_OUT_EP, HIDRAW_IN_EP, HID_MAX_MPS, HIDRAW_IN_INTERVAL),
};
static const uint8_t device_quality_descriptor[] = {
@@ -139,42 +96,8 @@ const struct usb_descriptor hid_descriptor = {
/*!< global descriptor */
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),
/************** 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 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_CUSTOM_INOUT_DESCRIPTOR_INIT(0x00, 0x01, HID_CUSTOM_REPORT_DESC_SIZE, HIDRAW_OUT_EP, HIDRAW_IN_EP, HID_MAX_MPS, HIDRAW_IN_INTERVAL),
/*
* string0 descriptor
*/
@@ -261,16 +184,16 @@ static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
0x09, 0x02, /* USAGE (Vendor Usage 1) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0xff, /*LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x96, 0xff, 0x03, /* REPORT_COUNT (63) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
/* <___________________________________________________> */
0x85, 0x01, /* REPORT ID (0x01) */
0x09, 0x03, /* USAGE (Vendor Usage 1) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x96, 0xff, 0x03, /* REPORT_COUNT (63) */
0x96, 0xff, 0x03, /* REPORT_COUNT (63) */
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */
@@ -299,8 +222,8 @@ static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
#endif
};
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[HIDRAW_OUT_EP_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t send_buffer[HIDRAW_IN_EP_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[HID_MAX_MPS];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t send_buffer[HID_MAX_MPS];
#define HID_STATE_IDLE 0
#define HID_STATE_BUSY 1
@@ -311,27 +234,27 @@ static volatile uint8_t custom_state;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
/* setup first out ep read transfer */
usbd_ep_start_read(busid, HIDRAW_OUT_EP, read_buffer, HIDRAW_OUT_EP_SIZE);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
/* setup first out ep read transfer */
usbd_ep_start_read(busid, HIDRAW_OUT_EP, read_buffer, HID_MAX_MPS);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
default:
break;
}
}
@@ -346,7 +269,7 @@ static void usbd_hid_custom_in_callback(uint8_t busid, uint8_t ep, uint32_t nbyt
static void usbd_hid_custom_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
usbd_ep_start_read(busid, ep, read_buffer, HIDRAW_IN_EP_SIZE);
usbd_ep_start_read(busid, ep, read_buffer, HID_MAX_MPS);
read_buffer[0] = 0x02; /* IN: report id */
usbd_ep_start_write(busid, HIDRAW_IN_EP, read_buffer, nbytes);
}

View File

@@ -15,7 +15,7 @@
#define HID_INT_EP_SIZE 8
#define HID_INT_EP_INTERVAL 10
#define USB_HID_CONFIG_DESC_SIZ 34
#define USB_CONFIG_SIZE 34
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
#ifdef CONFIG_USBDEV_ADVANCE_DESC
@@ -24,40 +24,8 @@ static const uint8_t device_descriptor[] = {
};
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 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
};
static const uint8_t device_quality_descriptor[] = {
@@ -115,40 +83,8 @@ const struct usb_descriptor hid_descriptor = {
#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),
/************** 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_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////

View File

@@ -17,7 +17,7 @@
#define USBD_LANGID_STRING 1033
/*!< config descriptor size */
#define USB_HID_CONFIG_DESC_SIZ 34
#define USB_CONFIG_SIZE 34
/*!< report descriptor size */
#define HID_MOUSE_REPORT_DESC_SIZE 74
@@ -27,40 +27,8 @@ static const uint8_t device_descriptor[] = {
};
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 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
};
static const uint8_t device_quality_descriptor[] = {
@@ -119,40 +87,8 @@ const struct usb_descriptor hid_descriptor = {
/*!< global descriptor */
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),
/************** 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 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////

View File

@@ -17,7 +17,7 @@
#define USBD_LANGID_STRING 1033
/*!< config descriptor size */
#define USB_HID_CONFIG_DESC_SIZ 34
#define USB_CONFIG_SIZE 34
/*!< report descriptor size */
#define HID_MOUSE_REPORT_DESC_SIZE 74
@@ -27,40 +27,8 @@ static const uint8_t device_descriptor[] = {
};
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 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
};
static const uint8_t device_quality_descriptor[] = {
@@ -119,40 +87,8 @@ const struct usb_descriptor hid_descriptor = {
/*!< global descriptor */
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_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 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////

View File

@@ -14,7 +14,13 @@
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#define USB_CONFIG_SIZE (9 + 9 + 9 + 9 + 7 + MIDI_SIZEOF_JACK_DESC + 9 + 5 + 9 + 5)
#define AUDIO_AC_SIZ AUDIO_SIZEOF_AC_HEADER_DESC(1)
#define AUDIO_MS_SIZ (7 + MIDI_SIZEOF_JACK_DESC + 9 + 5 + 9 + 5)
#define USB_CONFIG_SIZE (unsigned long)(9 + \
AUDIO_AC_DESCRIPTOR_LEN(1) + \
MIDI_STANDARD_DESCRIPTOR_LEN + \
AUDIO_MS_SIZ)
#ifdef CONFIG_USB_HS
#define MIDI_EP_MPS 512
@@ -29,48 +35,9 @@ static const uint8_t device_descriptor[] = {
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),
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
MIDI_STANDARD_DESCRIPTOR_INIT(0x01, 0x02),
MIDI_CS_HEADER_DESCRIPTOR_INIT(AUDIO_MS_SIZ),
MIDI_JACK_DESCRIPTOR_INIT(0x01),
// OUT endpoint descriptor
0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
@@ -137,48 +104,9 @@ const struct usb_descriptor midi_descriptor = {
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),
// 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),
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
MIDI_STANDARD_DESCRIPTOR_INIT(0x01, 0x02),
MIDI_CS_HEADER_DESCRIPTOR_INIT(AUDIO_MS_SIZ),
MIDI_JACK_DESCRIPTOR_INIT(0x01),
// OUT endpoint descriptor
0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
@@ -186,8 +114,7 @@ const uint8_t midi_descriptor[] = {
// IN endpoint descriptor
0x09, 0x05, MIDI_IN_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
0x05, 0x25, 0x01, 0x01, 0x03,
0x05, 0x25, 0x01, 0x01, 0x03
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////

View File

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

BIN
demo/mongoose/mongoose.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

View File

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

View File

@@ -236,7 +236,7 @@ int usb_msc_fatfs_test()
while (write_size > 0) {
res_sd = f_write(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum);
if (res_sd != FR_OK) {
printf("Write file failed, cause: %s\n", res_sd);
USB_LOG_RAW("Write file failed, cause: %s\n", res_sd);
goto unmount;
}
write_size -= BUF_SIZE;
@@ -262,7 +262,7 @@ int usb_msc_fatfs_test()
while (write_size > 0) {
res_sd = f_read(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum);
if (res_sd != FR_OK) {
printf("Read file failed, cause: %s\n", res_sd);
USB_LOG_RAW("Read file failed, cause: %s\n", res_sd);
goto unmount;
}
write_size -= BUF_SIZE;

182
demo/usbh_bl616_wifi_cli.c Normal file
View File

@@ -0,0 +1,182 @@
#include "usbh_core.h"
#include "usbh_cdc_acm.h"
#include "shell.h"
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[8 * 1024];
int wifi_scan(int argc, char **argv)
{
struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
uint32_t len;
int ret;
if (cdc_acm_class == NULL) {
printf("cdc acm class not found\r\n");
return -1;
}
len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_scan\r\n");
ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
if (ret < 0) {
printf("wifi scan failed1, ret:%d\r\n", ret);
return -1;
}
ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
if (ret < 0) {
printf("wifi scan failed2, ret:%d\r\n", ret);
return -1;
}
cdc_buffer[ret] = '\0';
printf("%s\r\n", cdc_buffer);
return 0;
}
CSH_CMD_EXPORT(wifi_scan, wifi_scan);
int wifi_scan_result(int argc, char **argv)
{
struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
uint32_t len;
int ret;
if (cdc_acm_class == NULL) {
printf("cdc acm class not found\r\n");
return -1;
}
len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_scan_result {\"offset\":0, \"count\":0}\r\n");
ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
if (ret < 0) {
printf("wifi scan failed1, ret:%d\r\n", ret);
return -1;
}
ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
if (ret < 0) {
printf("wifi scan failed2, ret:%d\r\n", ret);
return -1;
}
cdc_buffer[ret] = '\0';
printf("%s\r\n", cdc_buffer);
return 0;
}
CSH_CMD_EXPORT(wifi_scan_result, wifi_scan_result);
int wifi_connect(int argc, char **argv)
{
struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
uint32_t len;
int ret;
if (cdc_acm_class == NULL) {
printf("cdc acm class not found\r\n");
return -1;
}
if (argc < 3) {
printf("please input correct command: wifi_connect ssid password\r\n");
return -1;
}
len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_connect {\"ssid\":\"%s\", \"password\":\"%s\"}\r\n", argv[1], argv[2]);
ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
if (ret < 0) {
printf("wifi connect failed1, ret:%d\r\n", ret);
return -1;
}
ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
if (ret < 0) {
printf("wifi connect failed2, ret:%d\r\n", ret);
return -1;
}
cdc_buffer[ret] = '\0';
printf("%s\r\n", cdc_buffer);
return 0;
}
CSH_CMD_EXPORT(wifi_connect, wifi_connect);
int wifi_disconnect(int argc, char **argv)
{
struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
uint32_t len;
int ret;
if (cdc_acm_class == NULL) {
printf("cdc acm class not found\r\n");
return -1;
}
len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_disconnect\r\n");
ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
if (ret < 0) {
printf("wifi disconnect failed1, ret:%d\r\n", ret);
return -1;
}
ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
if (ret < 0) {
printf("wifi disconnect failed2, ret:%d\r\n", ret);
return -1;
}
cdc_buffer[ret] = '\0';
printf("%s\r\n", cdc_buffer);
return 0;
}
CSH_CMD_EXPORT(wifi_disconnect, wifi_disconnect);
int wifi_status(int argc, char **argv)
{
struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
uint32_t len;
int ret;
if (cdc_acm_class == NULL) {
printf("cdc acm class not found\r\n");
return -1;
}
len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_status\r\n");
ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
if (ret < 0) {
printf("wifi status failed1, ret:%d\r\n", ret);
return -1;
}
ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
if (ret < 0) {
printf("wifi status failed2, ret:%d\r\n", ret);
return -1;
}
cdc_buffer[ret] = '\0';
printf("%s\r\n", cdc_buffer);
return 0;
}
CSH_CMD_EXPORT(wifi_status, wifi_status);
int wifi_version(int argc, char **argv)
{
struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0");
uint32_t len;
int ret;
if (cdc_acm_class == NULL) {
printf("cdc acm class not found\r\n");
return -1;
}
len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "sys_version\r\n");
ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000);
if (ret < 0) {
printf("wifi status failed1, ret:%d\r\n", ret);
return -1;
}
ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000);
if (ret < 0) {
printf("wifi status failed2, ret:%d\r\n", ret);
return -1;
}
cdc_buffer[ret] = '\0';
printf("%s\r\n", cdc_buffer);
return 0;
}
CSH_CMD_EXPORT(wifi_version, wifi_version);

View File

@@ -46,15 +46,15 @@
VS_HEADER_SIZ + \
9 + \
7 + \
AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \
AUDIO_AC_DESCRIPTOR_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_DESCRIPTOR_INIT_LEN(1) + \
AUDIO_AS_DESCRIPTOR_LEN(1) + \
AUDIO_AS_DESCRIPTOR_LEN(1) + \
25)
#define USBD_VID 0xffff
@@ -130,38 +130,7 @@ static const uint8_t config_descriptor[] = {
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 */
HID_KEYBOARD_DESCRIPTOR_INIT(0x05, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
};
static const uint8_t device_quality_descriptor[] = {
@@ -469,11 +438,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
audio_rx_flag = 1;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, AUDIO_OUT_EP, audio_read_buffer, AUDIO_OUT_PACKET);
printf("OPEN1\r\n");
USB_LOG_RAW("OPEN1\r\n");
} else if (intf == 4) {
audio_tx_flag = 1;
audio_iso_tx_busy = false;
printf("OPEN2\r\n");
USB_LOG_RAW("OPEN2\r\n");
}
}
@@ -481,11 +450,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
{
if (intf == 3) {
audio_rx_flag = 0;
printf("CLOSE1\r\n");
USB_LOG_RAW("CLOSE1\r\n");
} else if (intf == 4) {
audio_tx_flag = 0;
audio_iso_tx_busy = false;
printf("CLOSE2\r\n");
USB_LOG_RAW("CLOSE2\r\n");
}
}

View File

@@ -6,6 +6,52 @@
#include "usbd_core.h"
#include "usbd_hid.h"
#define WEBUSB_VENDOR_CODE (0x22)
#define WINUSB_VENDOR_CODE (0x21)
#define URL_DESCRIPTOR_LENGTH (3 + 36)
#define WEBUSB_INTF_NUM 0x01
#define WEBUSB_URL_STRINGS \
'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', \
'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '/', 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B',
const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
URL_DESCRIPTOR_LENGTH,
WEBUSB_URL_TYPE,
WEBUSB_URL_SCHEME_HTTPS,
WEBUSB_URL_STRINGS
};
const uint8_t WINUSB_WCIDDescriptor[] = {
USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN),
USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(WEBUSB_INTF_NUM),
};
__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_LEN + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 2),
USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_INIT(WEBUSB_VENDOR_CODE, 0x01),
USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)),
};
struct usb_webusb_descriptor webusb_url_desc = {
.vendor_code = WEBUSB_VENDOR_CODE,
.string = USBD_WebUSBURLDescriptor,
.string_len = URL_DESCRIPTOR_LENGTH
};
struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = WINUSB_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
.compat_id_len = sizeof(WINUSB_WCIDDescriptor),
};
struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = sizeof(USBD_BinaryObjectStoreDescriptor)
};
#define USBD_VID 0xffff
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
@@ -15,181 +61,18 @@
#define HID_INT_EP_SIZE 8
#define HID_INT_EP_INTERVAL 10
#define USB_HID_CONFIG_DESC_SIZ (34 + 9)
#define USB_CONFIG_SIZE (34 + 9)
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
#define USBD_WEBUSB_VENDOR_CODE (0x22)
#define USBD_WINUSB_VENDOR_CODE (0x21)
#define USBD_WINUSB_DESC_SET_LEN (0xB2)
#define URL_DESCRIPTOR_LENGTH (3 + 36)
#define USBD_WEBUSB_INTF_NUM 0x01
#define WEBUSB_URL_STRINGS \
'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', \
'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '/', 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B',
const uint8_t USBD_WinUSBDescriptorSetDescriptor[USBD_WINUSB_DESC_SET_LEN] = {
// Microsoft OS 2.0 描述符集标头
0x0A, 0x00, // Descriptor size (10 bytes)
0x00, 0x00, // MS OS 2.0 descriptor set header
0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000)
USBD_WINUSB_DESC_SET_LEN, 0x00, // Size, MS OS 2.0 descriptor set
// Microsoft OS 2.0 配置子集标头
0x08, 0x00, // wLength
0x01, 0x00, // wDescriptorType
0x00, // 适用于配置 1
0x00, // bReserved
0XA8, 0X00, // Size, MS OS 2.0 configuration subset
// Microsoft OS 2.0 功能子集头
0x08, 0x00, // Descriptor size (8 bytes)
0x02, 0x00, // MS OS 2.0 function subset header
USBD_WEBUSB_INTF_NUM, // bFirstInterface
0x00, // 必须设置为 0
0xA0, 0x00,
// Microsoft OS 2.0 兼容 ID 描述符
// 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容
0x14, 0x00, // wLength 20
0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// Microsoft OS 2.0 注册表属性描述符
// 注册表属性分配设备接口 GUID
0x84, 0x00, //wLength: 132
0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9)
0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15)
0x2a, 0x00, //wPropertyNameLength:
//bPropertyName: “DeviceInterfaceGUID”
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00,
0x00, 0x00,
0x50, 0x00, // wPropertyDataLength
//bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
'{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00,
'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00,
'9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00,
'8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
};
const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
URL_DESCRIPTOR_LENGTH,
WEBUSB_URL_TYPE,
WEBUSB_URL_SCHEME_HTTPS,
WEBUSB_URL_STRINGS
};
#define USBD_BOS_WTOTALLENGTH 0x39
#define LANDING_PAGE 0x01
uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = {
// BOS描述符
0x05, // bLength 固长为5
0x0F, // bDescriptorType 固定为15
USBD_BOS_WTOTALLENGTH, 0x00, // wTotalLength BOS描述符的总大小
0x02, // bNumDeviceCaps BOS描述符中独立设备功能特性描述符的数量
// WebUSB 平台功能描述符
0x18, // Descriptor size (24 bytes)
0x10, // Descriptor type (Device Capability) 设备功能描述符
0x05, // Capability type (Platform) 平台描述符
0x00, // Reserved
// WebUSB Platform Capability ID (3408b638-09a9-47a0-8bfd-a0768815b665)
// 平台功能 UUID 将此标识为WebUSB 平台功能描述符,它提供有关设备的基本信息
0x38, 0xB6, 0x08, 0x34,
0xA9, 0x09,
0xA0, 0x47,
0x8B, 0xFD,
0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
0x00, 0x01, // WebUSB version 1.0
USBD_WEBUSB_VENDOR_CODE, // Vendor-assigned WebUSB request code
LANDING_PAGE, // Landing page
// Microsoft 平台功能描述符
// 标头
0x1C, // Descriptor size (28 bytes)
0x10, // Descriptor type (Device Capability)
0x05, // Capability type (Platform)
0x00, // Reserved
0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
0x89, 0x45, 0xC7, 0x4C,
0x9C, 0xD2, 0x65, 0x9D,
0x9E, 0x64, 0x8A, 0x9F,
// 描述符集信息结构
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 * dwWindowsVersion 最低兼容 Windows 版本 */
USBD_WINUSB_DESC_SET_LEN, 0X00, /* wDescriptorSetTotalLength */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0X00 /* bAltEnumCode */
};
struct usb_webusb_descriptor webusb_url_desc = {
.vendor_code = USBD_WEBUSB_VENDOR_CODE,
.string = USBD_WebUSBURLDescriptor,
.string_len = URL_DESCRIPTOR_LENGTH
};
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, 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)
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00)
};
static const uint8_t device_quality_descriptor[] = {
@@ -250,41 +133,9 @@ const struct usb_descriptor webusb_hid_descriptor = {
#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),
/************** 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),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
@@ -480,7 +331,7 @@ void hid_keyboard_test(uint8_t busid)
{
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
if(usb_device_is_configured(busid) == false) {
if (usb_device_is_configured(busid) == false) {
return;
}

View File

@@ -4,161 +4,106 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc_acm.h"
#define WCID_VENDOR_CODE 0x17
#define WINUSB_VENDOR_CODE 0x17
#define DOUBLE_WINUSB 0
#define WINUSB_NUM 1
__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
///////////////////////////////////////
/// MS OS string descriptor
///////////////////////////////////////
0x12, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
/* MSFT100 */
'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
'1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */
WCID_VENDOR_CODE, /* bVendorCode */
0x00, /* bReserved */
const uint8_t WCID_StringDescriptor_MSOS[18] = {
USB_MSOSV1_STRING_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE)
};
#if DOUBLE_WINUSB == 0
__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
///////////////////////////////////////
/// WCID descriptor
///////////////////////////////////////
0x28, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x04, 0x00, /* wIndex */
0x01, /* bCount */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
///////////////////////////////////////
/// WCID function descriptor
///////////////////////////////////////
0x00, /* bFirstInterfaceNumber */
0x01, /* bReserved */
/* WINUSB */
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
/* */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
const uint8_t WINUSB_WCIDDescriptor[] = {
USB_MSOSV1_COMP_ID_HEADER_DESCRIPTOR_INIT(WINUSB_NUM),
USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(0),
#if WINUSB_NUM == 2
USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(1),
#endif
};
#else
__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[64] __ALIGN_END = {
const uint8_t WINUSB_IF0_WCIDProperties[142] = {
///////////////////////////////////////
/// WCID descriptor
/// WCID property descriptor
///////////////////////////////////////
0x40, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x04, 0x00, /* wIndex */
0x02, /* bCount */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
0x8e, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// WCID function descriptor
/// registry propter descriptor
///////////////////////////////////////
0x00, /* bFirstInterfaceNumber */
0x01, /* bReserved */
/* WINUSB */
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
/* */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
0x84, 0x00, 0x00, 0x00, /* dwSize */
0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
0x28, 0x00, /* wPropertyNameLength */
/* DeviceInterfaceGUID */
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
/* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
'{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
'5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
'4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
'8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
'-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
'6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
};
#if WINUSB_NUM == 2
#define WINUSB_IF1_WCID_PROPERTIES_SIZE (142)
const uint8_t WINUSB_IF1_WCIDProperties[142] = {
///////////////////////////////////////
/// WCID property descriptor
///////////////////////////////////////
0x8e, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// WCID function descriptor
/// registry propter descriptor
///////////////////////////////////////
0x01, /* bFirstInterfaceNumber */
0x01, /* bReserved */
/* WINUSB */
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
/* */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
0x84, 0x00, 0x00, 0x00, /* dwSize */
0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
0x28, 0x00, /* wPropertyNameLength */
/* DeviceInterfaceGUID */
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
/* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
'{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
'5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
'4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
'8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
'-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
'6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
};
#endif
__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties [142] __ALIGN_END = {
///////////////////////////////////////
/// WCID property descriptor
///////////////////////////////////////
0x8e, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// registry propter descriptor
///////////////////////////////////////
0x84, 0x00, 0x00, 0x00, /* dwSize */
0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
0x28, 0x00, /* wPropertyNameLength */
/* DeviceInterfaceGUID */
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
/* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
'{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
'5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
'4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
'8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
'-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
'6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
};
#define WINUSB_IF1_WCID_PROPERTIES_SIZE (142)
__ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = {
///////////////////////////////////////
/// WCID property descriptor
///////////////////////////////////////
0x8e, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// registry propter descriptor
///////////////////////////////////////
0x84, 0x00, 0x00, 0x00, /* dwSize */
0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
0x28, 0x00, /* wPropertyNameLength */
/* DeviceInterfaceGUID */
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
/* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
'{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
'5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
'4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
'8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
'-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
'6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
};
const uint8_t *WINUSB_IFx_WCIDProperties[] = {
WINUSB_IF0_WCIDProperties,
#if DOUBLE_WINUSB == 1
#if WINUSB_NUM == 2
WINUSB_IF1_WCIDProperties,
#endif
};
struct usb_msosv1_descriptor msosv1_desc = {
.string = WCID_StringDescriptor_MSOS,
.vendor_code = WCID_VENDOR_CODE,
.vendor_code = WINUSB_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
.comp_id_property = WINUSB_IFx_WCIDProperties,
};
@@ -166,20 +111,20 @@ struct usb_msosv1_descriptor msosv1_desc = {
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02
#define USBD_VID 0xefff
#define USBD_VID 0xFFFE
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#if DOUBLE_WINUSB == 0
#if WINUSB_NUM == 1
#define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
#define INTF_NUM 1
#define INTF_NUM 1
#else
#define WINUSB_IN_EP2 0x83
#define WINUSB_OUT_EP2 0x04
#define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 7 + 7)
#define INTF_NUM 2
#define INTF_NUM 2
#endif
#ifdef CONFIG_USB_HS
@@ -198,7 +143,7 @@ static const uint8_t config_descriptor[] = {
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
#if WINUSB_NUM == 2
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),
@@ -253,7 +198,7 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
return string_descriptors[index];
}
const struct usb_descriptor winusb_descriptor = {
const struct usb_descriptor winusbv1_descriptor = {
.device_descriptor_callback = device_descriptor_callback,
.config_descriptor_callback = config_descriptor_callback,
.device_quality_descriptor_callback = device_quality_descriptor_callback,
@@ -261,13 +206,13 @@ const struct usb_descriptor winusb_descriptor = {
.msosv1_descriptor = &msosv1_desc
};
#else
const uint8_t winusb_descriptor[] = {
const uint8_t winusbv1_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),
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
#if WINUSB_NUM == 2
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),
@@ -428,7 +373,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);
#if DOUBLE_WINUSB == 1
#if WINUSB_NUM == 2
usbd_ep_start_read(busid, WINUSB_OUT_EP2, read_buffer, 2048);
#endif
break;
@@ -478,7 +423,7 @@ struct usbd_endpoint winusb_in_ep1 = {
struct usbd_interface intf0;
#if DOUBLE_WINUSB == 1
#if WINUSB_NUM == 2
void usbd_winusb_out2(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
@@ -518,12 +463,12 @@ struct usbd_interface intf1;
#endif
void winusb_init(uint8_t busid, uintptr_t reg_base)
void winusbv1_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &winusb_descriptor);
usbd_desc_register(busid, &winusbv1_descriptor);
#else
usbd_desc_register(busid, winusb_descriptor);
usbd_desc_register(busid, winusbv1_descriptor);
#endif
#ifndef CONFIG_USBDEV_ADVANCE_DESC
usbd_msosv1_desc_register(busid, &msosv1_desc);
@@ -531,7 +476,7 @@ void winusb_init(uint8_t busid, uintptr_t reg_base)
usbd_add_interface(busid, &intf0);
usbd_add_endpoint(busid, &winusb_out_ep1);
usbd_add_endpoint(busid, &winusb_in_ep1);
#if DOUBLE_WINUSB == 1
#if WINUSB_NUM == 2
usbd_add_interface(busid, &intf1);
usbd_add_endpoint(busid, &winusb_out_ep2);
usbd_add_endpoint(busid, &winusb_in_ep2);

View File

@@ -6,6 +6,29 @@
#include "usbd_core.h"
#include "usbd_cdc_acm.h"
#define WINUSB_VENDOR_CODE 0x17
const uint8_t WINUSB_WCIDDescriptor[] = {
USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN),
USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(0x00),
};
__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 1),
USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)),
};
const struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = WINUSB_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
.compat_id_len = sizeof(WINUSB_WCIDDescriptor),
};
const struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = sizeof(USBD_BinaryObjectStoreDescriptor),
};
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02
@@ -27,135 +50,6 @@
#define WINUSB_EP_MPS 64
#endif
#define USBD_WINUSB_VENDOR_CODE 0x20
#define USBD_WEBUSB_ENABLE 0
#define USBD_BULK_ENABLE 1
#define USBD_WINUSB_ENABLE 1
/* WinUSB Microsoft OS 2.0 descriptor sizes */
#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
#define FUNCTION_SUBSET_LEN 160
#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
#if (USBD_WEBUSB_ENABLE)
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
0, // bFirstInterface USBD_WINUSB_IF_NUM
0, // bReserved
WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId
0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
WBVAL(42), // wPropertyNameLength
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), // wPropertyDataLength
'{', 0,
'9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
'9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
'4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
'9', 0, '3', 0, '3', 0, 'B', 0, '-',
0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
'}', 0, 0, 0, 0, 0
#endif
#if USBD_BULK_ENABLE
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
0, /* bFirstInterface USBD_BULK_IF_NUM*/
0, /* bReserved */
WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/
0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
WBVAL(42), /* wPropertyNameLength */
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), /* wPropertyDataLength */
'{', 0,
'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
'4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
'A', 0, 'A', 0, '3', 0, '6', 0, '-',
0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
'}', 0, 0, 0, 0, 0
#endif
};
#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
#define USBD_WEBUSB_DESC_LEN 24
#define USBD_WINUSB_DESC_LEN 28
#define USBD_BOS_WTOTALLENGTH (0x05 + \
USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
0x05, /* bLength */
0x0f, /* bDescriptorType */
WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */
#if (USBD_WEBUSB_ENABLE)
USBD_WEBUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */
0xA9, 0x09, 0xA0, 0x47,
0x8B, 0xFD, 0xA0, 0x76,
0x88, 0x15, 0xB6, 0x65,
WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0, /* iLandingPage */
#endif
#if (USBD_WINUSB_ENABLE)
USBD_WINUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
0x89, 0x45, 0xC7, 0x4C,
0x9C, 0xD2, 0x65, 0x9D,
0x9E, 0x64, 0x8A, 0x9F,
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0, /* bAltEnumCode */
#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)
@@ -219,7 +113,7 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
return string_descriptors[index];
}
const struct usb_descriptor winusbv2_descriptor = {
const struct usb_descriptor winusbv2_cdc_descriptor = {
.device_descriptor_callback = device_descriptor_callback,
.config_descriptor_callback = config_descriptor_callback,
.device_quality_descriptor_callback = device_quality_descriptor_callback,
@@ -228,7 +122,7 @@ const struct usb_descriptor winusbv2_descriptor = {
.bos_descriptor = &bos_desc
};
#else
const uint8_t winusbv2_descriptor[] = {
const uint8_t winusbv2_cdc_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
/* Configuration 0 */
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
@@ -418,12 +312,12 @@ struct usbd_interface winusb_intf;
struct usbd_interface intf1;
struct usbd_interface intf2;
void winusbv2_init(uint8_t busid, uintptr_t reg_base)
void winusbv2_cdc_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &winusbv2_descriptor);
usbd_desc_register(busid, &winusbv2_cdc_descriptor);
#else
usbd_desc_register(busid, winusbv2_descriptor);
usbd_desc_register(busid, winusbv2_cdc_descriptor);
#endif
#ifndef CONFIG_USBDEV_ADVANCE_DESC
usbd_bos_desc_register(busid, &bos_desc);

View File

@@ -1,550 +0,0 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_hid.h"
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02
/*!< endpoint address */
#define HID_INT_EP 0x83
#define HID_INT_EP_SIZE 4
#define HID_INT_EP_INTERVAL 10
#define USBD_VID 0xFFFE
#define USBD_PID 0xFFFF
#define USBD_MAX_POWER 500
#define USBD_LANGID_STRING 1033
#define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 9 + 7)
#define INTF_NUM 2
/*!< config descriptor size */
#define USB_HID_CONFIG_DESC_SIZ 34
/*!< report descriptor size */
#define HID_MOUSE_REPORT_DESC_SIZE 74
#ifdef CONFIG_USB_HS
#define WINUSB_EP_MPS 512
#else
#define WINUSB_EP_MPS 64
#endif
#define USBD_WINUSB_VENDOR_CODE 0x20
#define USBD_WEBUSB_ENABLE 0
#define USBD_BULK_ENABLE 1
#define USBD_WINUSB_ENABLE 1
/* WinUSB Microsoft OS 2.0 descriptor sizes */
#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
#define FUNCTION_SUBSET_LEN 160
#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
#if (USBD_WEBUSB_ENABLE)
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
0, // bFirstInterface USBD_WINUSB_IF_NUM
0, // bReserved
WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId
0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
WBVAL(42), // wPropertyNameLength
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), // wPropertyDataLength
'{', 0,
'9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
'9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
'4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
'9', 0, '3', 0, '3', 0, 'B', 0, '-',
0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
'}', 0, 0, 0, 0, 0
#endif
#if USBD_BULK_ENABLE
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
0, /* bFirstInterface USBD_BULK_IF_NUM*/
0, /* bReserved */
WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/
0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
WBVAL(42), /* wPropertyNameLength */
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), /* wPropertyDataLength */
'{', 0,
'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
'4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
'A', 0, 'A', 0, '3', 0, '6', 0, '-',
0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
'}', 0, 0, 0, 0, 0
#endif
};
#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
#define USBD_WEBUSB_DESC_LEN 24
#define USBD_WINUSB_DESC_LEN 28
#define USBD_BOS_WTOTALLENGTH (0x05 + \
USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
0x05, /* bLength */
0x0f, /* bDescriptorType */
WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */
#if (USBD_WEBUSB_ENABLE)
USBD_WEBUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */
0xA9, 0x09, 0xA0, 0x47,
0x8B, 0xFD, 0xA0, 0x76,
0x88, 0x15, 0xB6, 0x65,
WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0, /* iLandingPage */
#endif
#if (USBD_WINUSB_ENABLE)
USBD_WINUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
0x89, 0x45, 0xC7, 0x4C,
0x9C, 0xD2, 0x65, 0x9D,
0x9E, 0x64, 0x8A, 0x9F,
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0, /* bAltEnumCode */
#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 */
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 */
/* String 0 (LANGID) */
USB_LANGID_INIT(USBD_LANGID_STRING),
/* String 1 (Manufacturer) */
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'W', 0x00, /* wcChar10 */
'I', 0x00, /* wcChar11 */
'N', 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
///////////////////////////////////////
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,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x10,
0x02,
0x00,
0x00,
0x00,
0x40,
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];
volatile bool ep_tx_busy_flag = false;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
ep_tx_busy_flag = false;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
void usbd_winusb_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
// for (int i = 0; i < 100; i++) {
// printf("%02x ", read_buffer[i]);
// }
// printf("\r\n");
usbd_ep_start_write(busid, WINUSB_IN_EP, read_buffer, nbytes);
/* setup next out ep read transfer */
usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
}
void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, WINUSB_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
};
struct usbd_endpoint winusb_in_ep1 = {
.ep_addr = WINUSB_IN_EP,
.ep_cb = usbd_winusb_in
};
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xA1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xA1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x01, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38,
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7F, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (2)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xC0, 0x09,
0x3c, 0x05,
0xff, 0x09,
0x01, 0x15,
0x00, 0x25,
0x01, 0x75,
0x01, 0x95,
0x02, 0xb1,
0x22, 0x75,
0x06, 0x95,
0x01, 0xb1,
0x01, 0xc0 // END_COLLECTION
};
/*!< mouse report struct */
struct hid_mouse {
uint8_t buttons;
int8_t x;
int8_t y;
int8_t wheel;
};
/*!< mouse report */
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg;
#define HID_STATE_IDLE 0
#define HID_STATE_BUSY 1
/*!< hid state ! Data can be sent only when state is idle */
static volatile uint8_t hid_state = HID_STATE_IDLE;
/* function ------------------------------------------------------------------*/
static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
hid_state = HID_STATE_IDLE;
}
/*!< endpoint call back */
static struct usbd_endpoint hid_in_ep = {
.ep_cb = usbd_hid_int_callback,
.ep_addr = HID_INT_EP
};
struct usbd_interface winusb_intf;
struct usbd_interface intf1;
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);
usbd_add_endpoint(busid, &winusb_in_ep1);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf1, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
usbd_initialize(busid, reg_base, usbd_event_handler);
}

416
demo/winusb2.0_template.c Normal file
View File

@@ -0,0 +1,416 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#define WINUSB_VENDOR_CODE 0x17
#define WINUSB_NUM 1
// note that if device is composite device, you should use USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT
const uint8_t WINUSB_WCIDDescriptor[] = {
#if WINUSB_NUM == 1
USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_LEN),
USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_INIT(),
#else
USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + WINUSB_NUM * USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN),
USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(0x00),
USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(0x01),
#endif
};
const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 1),
USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)),
};
const struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = WINUSB_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
.compat_id_len = sizeof(WINUSB_WCIDDescriptor),
};
const struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = sizeof(USBD_BinaryObjectStoreDescriptor),
};
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02
#define USBD_VID 0xFFFE
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#if WINUSB_NUM == 1
#define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
#define INTF_NUM 1
#else
#define WINUSB_IN_EP2 0x83
#define WINUSB_OUT_EP2 0x04
#define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 7 + 7)
#define INTF_NUM 2
#endif
#ifdef CONFIG_USB_HS
#define WINUSB_EP_MPS 512
#else
#define WINUSB_EP_MPS 64
#endif
#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, 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 WINUSB_NUM == 2
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 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, 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),
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 WINUSB_NUM == 2
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
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
///////////////////////////////////////
/// string1 descriptor
///////////////////////////////////////
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x2C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'W', 0x00, /* wcChar10 */
'I', 0x00, /* wcChar11 */
'N', 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
///////////////////////////////////////
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'1', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
///////////////////////////////////////
/// string4 descriptor
///////////////////////////////////////
0x30, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'W', 0x00, /* wcChar10 */
'I', 0x00, /* wcChar11 */
'N', 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 */
' ', 0x00, /* wcChar16 */
'1', 0x00, /* wcChar21 */
///////////////////////////////////////
/// string5 descriptor
///////////////////////////////////////
0x30, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'W', 0x00, /* wcChar10 */
'I', 0x00, /* wcChar11 */
'N', 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 */
' ', 0x00, /* wcChar16 */
'2', 0x00, /* wcChar21 */
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
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];
volatile bool ep_tx_busy_flag = false;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
ep_tx_busy_flag = false;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
#if WINUSB_NUM == 2
usbd_ep_start_read(busid, WINUSB_OUT_EP2, read_buffer, 2048);
#endif
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
void usbd_winusb_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
// for (int i = 0; i < 100; i++) {
// printf("%02x ", read_buffer[i]);
// }
// printf("\r\n");
usbd_ep_start_write(busid, WINUSB_IN_EP, read_buffer, nbytes);
/* setup next out ep read transfer */
usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
}
void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
if ((nbytes % WINUSB_EP_MPS) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, WINUSB_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
};
struct usbd_endpoint winusb_in_ep1 = {
.ep_addr = WINUSB_IN_EP,
.ep_cb = usbd_winusb_in
};
struct usbd_interface intf0;
#if WINUSB_NUM == 2
void usbd_winusb_out2(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
// for (int i = 0; i < 100; i++) {
// printf("%02x ", read_buffer[i]);
// }
// printf("\r\n");
usbd_ep_start_write(busid, WINUSB_IN_EP2, read_buffer, nbytes);
/* setup next out ep read transfer */
usbd_ep_start_read(busid, WINUSB_OUT_EP2, read_buffer, 2048);
}
void usbd_winusb_in2(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, WINUSB_IN_EP2, NULL, 0);
} else {
ep_tx_busy_flag = false;
}
}
struct usbd_endpoint winusb_out_ep2 = {
.ep_addr = WINUSB_OUT_EP2,
.ep_cb = usbd_winusb_out2
};
struct usbd_endpoint winusb_in_ep2 = {
.ep_addr = WINUSB_IN_EP2,
.ep_cb = usbd_winusb_in2
};
struct usbd_interface intf1;
#endif
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
usbd_add_interface(busid, &intf0);
usbd_add_endpoint(busid, &winusb_out_ep1);
usbd_add_endpoint(busid, &winusb_in_ep1);
#if WINUSB_NUM == 2
usbd_add_interface(busid, &intf1);
usbd_add_endpoint(busid, &winusb_out_ep2);
usbd_add_endpoint(busid, &winusb_in_ep2);
#endif
usbd_initialize(busid, reg_base, usbd_event_handler);
}

View File

@@ -6,8 +6,8 @@ project = 'CherryUSB'
copyright = '2022 ~ 2025, sakumisu'
author = 'sakumisu'
release = '1.5.2'
version = '1.5.2'
release = '1.5.3'
version = '1.5.3'
# -- General configuration

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

View File

@@ -0,0 +1,15 @@
OTG 功能的使用
=========================
如果需要使用 OTG 功能,首先使用的芯片需要支持 ID 检测功能,然后使能 ``CONFIG_USB_OTG_ENABLE`` 宏,将之前的例程中 ``usbh_initialize`` 或者 ``usbh_initialize``
替换成 ``usbotg_initialize`` 即可。
ID 检测电路根据不同的 USB 接口类型有所不同,常见的有 micro-USB 和 USB-C 两种接口类型。
- 如果是 micro-USB 接口,则将 ID 线连接到芯片的 ID 引脚,并使能 ID 功能即可。
- 如果是 USB-C 接口,由于没有 ID 引脚,则需要借助 CC 电路转换成 ID 然后连接到芯片的 ID 引脚常见电路图如下所示DNP 表示不焊接):
.. figure:: img/otg.png
.. note:: 除 ID 引脚以外,还需要增加 VBUS 输出开关控制,当工作在 host 时,开启 VBUS 供电,当工作在 device 时,关闭 VBUS 供电。

View File

@@ -1,2 +1,7 @@
usbd_audiov1
===============
在使用 UAC1.0 时,需要注意以下几点:
- 在使用windows 时当修改描述符任意参数时必须同步修改字符串描述符并且卸载驱动否则windows会认为设备未更改继续使用旧的驱动导致无法识别设备。Linux 不受此限制。
- QQ 群文件中下载 RemoveGhostDev64.exe 可以自动删除所有 USB 注册的驱动信息,无需第一步

View File

@@ -1,2 +1,9 @@
usbd_audiov2
===============
在使用 UAC2.0 时,需要注意以下几点:
- 在使用windows 时当修改描述符任意参数时必须同步修改字符串描述符并且卸载驱动否则windows会认为设备未更改继续使用旧的驱动导致无法识别设备。Linux 不受此限制。
- QQ 群文件中下载 RemoveGhostDev64.exe 可以自动删除所有 USB 注册的驱动信息,无需第一步
- windows 10 uac2.0 功能不完善,请使用 windows 11 测试uac2.0 功能。Linux 不受此限制
- windows 中设置的采样率表范围在多通道时通道数大于2计算有误比如设置 8K~96K那么实际是大于等于8K 小于96K而非小于等于96K。Linux 不受此限制

View File

@@ -1,19 +1,42 @@
usbd_winusb
===============
本节主要介绍 winusb 驱动。winusb 是 windows 为了让用户友好的访问 USB 自定义类设备提供的一套通用驱动,其实本质就是 CDC ACM。
WINUSB 版本根据 USB 版本分为 V1/V2 版本V2 版本需要包含 BOS 描述符V1 版本不需要。V2 版本需要在设备描述符中设置为 USB2.1 的版本号。
本节主要介绍 winusb 驱动。winusb 是 windows 为了让用户友好的访问 USB 自定义类设备提供的一套通用驱动,其实本质就是 CDC ACM,只不过没有设置波特率的命令
WINUSB 版本根据 USB 版本分为 V1/V2 版本V2 版本需要包含 BOS 描述符V1 版本不需要。 **V2 版本需要在设备描述符中设置为 USB2.1 的版本号**
.. note:: 更换 winusb 描述符任意配置可能会枚举成功但是无法识别设备,需要删除 计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\usbflags 下所有注册表项,重新插拔设备后生效。
- V1 版本注册描述符
.. code-block:: C
const struct usb_descriptor winusbv1_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
};
OR
usbd_msosv1_desc_register(busid, &msosv1_desc);
- V2 版本注册描述符
.. code-block:: C
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,
};
OR
usbd_bos_desc_register(busid, &bos_desc);
usbd_msosv2_desc_register(busid, &msosv2_desc);
@@ -29,4 +52,4 @@ WINUSB 版本根据 USB 版本分为 V1/V2 版本V2 版本需要包含 BOS
/* Endpoint IN 1 */
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
- 其余操作与 CDC ACM 相同,不再赘述
- 读写操作与 CDC ACM 相同,不再赘述

View File

@@ -44,10 +44,9 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
**其他相关链接**
- **CherryUSB 大纲** https://www.bilibili.com/video/BV1st4y1H7K2
- **CherryUSB 从机协议栈视频教程** https://www.bilibili.com/video/BV1Ef4y1t73d
- **CherryUSB 腾讯会议** https://www.bilibili.com/video/BV16x421y7mM
- **github** https://github.com/sakumisu/CherryUSB
- **视频教程** https://www.bilibili.com/cheese/play/ss707687201
- **github** https://github.com/sakumisu/CherryUSB
- **CherryUSB原理性分析和应用实践-汉斯期刊** https://www.hanspub.org/journal/paperinformation?paperid=126903
.. toctree::
:maxdepth: 1
@@ -57,10 +56,9 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
quick_start/demo
quick_start/transplant
quick_start/rtthread
quick_start/esp
q&a
opensource
share
quick_start/q&a
quick_start/share
quick_start/opensource
.. toctree::
:maxdepth: 1
@@ -116,6 +114,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
demo/usbh_wifi
demo/usbd_vendor
demo/usbh_vendor
demo/usb_otg
.. toctree::
:maxdepth: 1

View File

@@ -29,6 +29,21 @@
- esp32p4一个 USB2.0 内置全速 PHY 芯片,一个 USB2.0 内置高速 PHY 芯片,支持主从机。
- 默认 demo 采用组件库安装的形式,在 https://components.espressif.com/ 中搜索 cherryusb 即可
ESP-Registry 可以参考官方文档,推荐使用 vscode + esp-idf 的开发环境。
- ctrl + shift + p 选择 ESP-IDF 欢迎界面,然后选择 Component mananger
.. figure:: img/esp1.png
- 找到 cherryusb 并安装
.. figure:: img/esp2.png
- 打开 menuconfig并打开 cherryusb 的配置,根据实际情况选择主机或者从机模式
.. figure:: img/esp3.png
.. figure:: img/esp4.png
基于飞腾派系列芯片(官方 SDK 支持)
-----------------------------------
@@ -150,21 +165,6 @@ USB Device 移植要点
.. figure:: img/stm32_8.png
- 如果使用 dwc2 ip需要增加 **dwc2/usb_glue_st.c** 文件,并在 `usb_config.h` 中实现以下宏:
.. code-block:: C
// 以下细节如有出入,请对照 stm32xxx.h 文件修改
// 需要根据硬件实际的 fifo 深度进行修改,默认是最基础的配置
#define CONFIG_USBDEV_EP_NUM 6
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1012 - 16 * 6)
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
- 如果使用 fsdev ipV1.5.0 开始需要增加 **fsdev/usb_glue_st.c**`usb_config.h` 中实现以下宏,具体数值不同芯片不一样:
.. code-block:: C

View File

@@ -1,17 +0,0 @@
基于 ESP-Registry 开发指南
===========================
ESP-Registry 可以参考官方文档,推荐使用 vscode + esp-idf 的开发环境。
- ctrl + shift + p 选择 ESP-IDF 欢迎界面,然后选择 Component mananger
.. figure:: img/esp1.png
- 找到 cherryusb 并安装
.. figure:: img/esp2.png
- 打开 menuconfig并打开 cherryusb 的配置,根据实际情况选择主机或者从机模式
.. figure:: img/esp3.png
.. figure:: img/esp4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -46,16 +46,52 @@ GD IP 采用 DWC2但是读取的硬件参数都是 0我也不懂为什么
USB_OTG_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
USB_OTG_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
除此之外可能存在其他未知 BUG请自行测试。
开启 USB_LOG_DBG 后无法枚举
----------------------------------------------------------------
有且仅有商业性 IP 开启后可以枚举,其余 IP 禁止开启,否则无法枚举。懂得都懂。
USB3 CV测试用哪个版本
------------------------------
1.4.3 版本及以上
Ep addr XXX fifo overflow
------------------------------
.. figure:: img/question1.png
该错误表示该端点默认设置的 fifo 空间不够用,需要增大 fifo 空间,通常见于 DWC2/MUSB IP。FIFO 设置参考相关的 glue 文件。
Ep addr XXX overflow
------------------------------
该 IP 硬件上没有这么多端点, 请更换 IP or 减少端点使用。并且默认 demo 不做双向功能,考虑到不是所有的 IP 都支持,因此默认是 81 02 这样的而不是 81 01
如果支持,自行修改。某些 IP 双向端点可能会占用相同的硬件信息,不一定能同时使用,自行检查。
.. figure:: img/question2.png
该错误表示该 IP 硬件上没有这么多端点, 请更换 IP or 减少端点使用。
当然也可以修改为双向端点,考虑到不是所有的 IP 都支持双向端点,因此默认 demo 不做双向功能,举例默认是 81 02 这样的而不是 81 01如果支持自行修改。某些 IP 双向端点可能会占用相同的硬件信息,不一定能同时使用,自行检查。
This dwc2 version does not support dma mode, so stop working
----------------------------------------------------------------
该 DWC2 版本不支持 dma 模式,禁止使用。
该 DWC2 版本不支持 dma 模式,禁止使用。不使用 DMA 模式会频繁触发 NAK 中断大概几十us一次CPU 占用率过高。
OTG 有哪些芯片支持
------------------------------
当前主线仅 HPM 芯片支持 OTG 功能,通过 ID 引脚自动切换主从模式,其他芯片请使用手动切换模式 OR 自行实现添加 ID 识别的驱动。
PC 识别的 COM 口如何更改名称
----------------------------------------------------------------
这是微软对 CDC ACM 的驱动问题,无法修改,如需修改,请联系微软并缴纳费用+编写驱动后即可更改。
connect 和 disconnect event 不触发
----------------------------------------------------------------
当前仅 hpm 芯片支持 connect 和 disconnect 事件,其他芯片请使用 USB 检测 vbus 电路。DWC2 IP 支持但是由于需要占用引脚并且大多是log 口,然后不同使能的配置也不一样,因此不做支持。
__has_include 报错
------------------------------------------------------------------
@@ -78,6 +114,7 @@ Failed to enable port
USB_ERR_NAK 说明
----------------------------------------------------------------
USB_ERR_NAK 只存在于 DWC2 buffer dma 模式DWC2 在 buffer dma模式下对于中断传输不支持硬件处理 NAK 中断,因此需要软件处理,导致 NAK 中断非常多,建议搭配定时器使用。
DWC2 scatter/gather dma 模式下全部由硬件处理,但是不支持 split 传输。总结, **半斤 IP**
@@ -85,14 +122,3 @@ USB host 连接 USB 网卡问题
----------------------------------------------------------------
表现为能识别网卡并且分配到 IP 地址,但是无法 ping 通,这是因为网卡自身需要开启自动拨号,通常需要使用 AT 口设置。具体为 EC20/ML307 等模块。
PC 识别的 COM 口如何更改名称
----------------------------------------------------------------
这是微软对 CDC ACM 的驱动问题,无法修改,如需修改,请联系微软并缴纳费用即可更改。
connect 和 disconnect event 不触发
----------------------------------------------------------------
当前仅 hpm 芯片支持 connect 和 disconnect 事件,其他芯片请使用 USB 检测 vbus 电路。DWC2 IP 支持但是由于需要占用引脚并且大多是log 口,
然后不同使能的配置也不一样,因此不做支持。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

View File

@@ -88,6 +88,13 @@ USB Host ASIX 网卡
.. figure:: img/usbhost_ax88772_1.png
.. figure:: img/usbhost_ax88772_2.png
USB Host RNDIS 网卡
-----------------------
演示 USB Host 驱动手机,手机开启 USB 共享网络即可使用 RNDIS 。
.. figure:: img/usbhost_rndis.png
USB Host WIFI
-----------------------

View File

@@ -29,9 +29,11 @@ ZLP顾名思义零长度数据包也就是数据长度为0 的短包。
--------------------
从机接收:接收的长度与设置的长度相等;接收的最后一个包为短包。
从机发送:发送的长度与设置的长度相等,如果发送的长度是 EP MPS 的整数倍,需要再发送一个 ZLP仅限 control 和 bulk 传输)。
从机发送:发送的长度与设置的长度相等,如果发送的长度是 EP MPS 的整数倍, **通常** 需要再发送一个 ZLP仅限 control 和 bulk 传输)。
.. note:: 对于从机接收,并且是 bulk 传输,接收长度通常设计为 EP MPS以下三种情况可以修改为多个 EP MPS: 固定长度;自定义协议并携带长度(例如 MSC; 主机手动发送 ZLP 或者短包(例如 RNDIS
.. note:: 对于从机发送,并且是 bulk 传输,发送长度没有限制,但是如果是 EP MPS 整数倍,通常需要发送 ZLP。自定义协议则不需要发送 ZLP例如 MSC。
主机接收:同从机接收
主机发送:发送的长度与设置的长度相等
.. note:: 对于从机接收,并且是 bulk 传输,接收长度通常设计为 EP MPS以下三种情况可以修改为多个 EP MPS: 固定长度;自定义协议并携带长度(例如 MSC; 主机手动发送 ZLP 或者短包(例如 RNDIS

View File

@@ -148,4 +148,18 @@ v1.5.2
- musb 对于标准的 IP 结构采用独立 EP 控制寄存器组,不使用 EPIDX 寄存器去控制
- 删除所有 CONFIG_USBDEV_EP_NUM & CONFIG_USBHOST_PIPE_NUM不再使用因为 IP 本身会携带这些信息,或者厂家 SDK 提供了对应的宏
- CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 默认使用 2 减少内存,只有 UVC 和UAC 使用(商业收费),所以不需要开很大
- urb interval 从 u8 改 u32最大支持 2^15 * 125us
- urb interval 从 u8 改 u32最大支持 2^15 * 125us
v1.5.3
----------------------
- 增加 mongoose demo
- **从机支持自定义 ep0 mps仅支持商业性 IP**
- 主机增加 UVC bulk支持 **接口号匹配驱动功能** **主机分配地址功能改成循环自增模式** ,重构 lsusb 命令
- 主机控制传输增加 retry 机制,部分 device 通信不稳定retry 次数参考 linux
- **主机 rndis 驱动增加非标 02/02/ff 接口驱动匹配**
- musb IP 关闭 multipoint feature 支持
- hpmicro、chipidea dcache 支持
- idf host msc 支持
- otg 框架重构,当前 port 仅支持 hpmicro
- CI 编译功能,支持 hpmicro/espressif/bouffalolab

View File

@@ -1,4 +1,4 @@
version: "1.5.2"
version: "1.5.3"
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
tags:
- usb

View File

@@ -28,7 +28,12 @@
// #define CONFIG_USB_DCACHE_ENABLE
/* attribute data into no cache ram */
/* attribute data into no cache ram
* DRAM_DMA_ALIGNED_ATTR was introduced in IDF 5.3. If not defined, it falls back to DMA_ATTR
*/
#ifndef DRAM_DMA_ALIGNED_ATTR
#define DRAM_DMA_ALIGNED_ATTR DMA_ATTR
#endif
#define USB_NOCACHE_RAM_SECTION DRAM_DMA_ALIGNED_ATTR
/* use usb_memcpy default for high performance but cost more flash memory.
@@ -144,9 +149,6 @@
#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
#endif
#define CONFIG_USBDEV_RNDIS_USING_LWIP
#define CONFIG_USBDEV_CDC_ECM_USING_LWIP
/* ================ USB HOST Stack Configuration ================== */
#define CONFIG_USBHOST_MAX_RHPORTS 1

View File

@@ -1,165 +0,0 @@
/*
* Copyright (c) 2022, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __rtems__
#include "usb_osal.h"
#include "usb_errno.h"
#include <rtems.h>
#define SYS_USB_MBOX_SIZE (sizeof(void *))
usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args)
{
rtems_id id = 0;
rtems_status_code res;
res = rtems_task_create(
rtems_build_name(name[0], name[1], name[2], name[3]),
prio,
stack_size,
RTEMS_PREEMPT,
0,
&id);
if (res != RTEMS_SUCCESSFUL) {
return NULL;
}
res = rtems_task_start(id, (rtems_task_entry)entry, (rtems_task_argument)args);
if (res != RTEMS_SUCCESSFUL) {
rtems_task_delete(id);
return NULL;
}
return (usb_osal_thread_t)id;
}
void usb_osal_thread_delete(usb_osal_thread_t thread)
{
rtems_task_delete(thread);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
rtems_id semaphore = 0;
rtems_status_code ret = rtems_semaphore_create(
rtems_build_name('U', 'S', 'B', 's'),
initial_count,
RTEMS_COUNTING_SEMAPHORE,
0,
&semaphore);
return semaphore;
}
void usb_osal_sem_delete(usb_osal_sem_t sem)
{
rtems_semaphore_delete(sem);
}
int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
{
rtems_status_code status;
status = rtems_semaphore_obtain(sem, RTEMS_WAIT, timeout);
return status == RTEMS_SUCCESSFUL ? 0 : -USB_ERR_TIMEOUT;
}
int usb_osal_sem_give(usb_osal_sem_t sem)
{
rtems_status_code status = rtems_semaphore_release(sem);
return (status == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
usb_osal_mutex_t usb_osal_mutex_create(void)
{
rtems_id mutex;
rtems_status_code ret = rtems_semaphore_create(
rtems_build_name('U', 'S', 'B', 'm'),
1,
RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_LOCAL,
0,
&mutex);
return mutex;
}
void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
{
rtems_semaphore_delete(mutex);
}
int usb_osal_mutex_take(usb_osal_mutex_t mutex)
{
return (rtems_semaphore_obtain(mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
int usb_osal_mutex_give(usb_osal_mutex_t mutex)
{
return (rtems_semaphore_release(mutex) == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
{
rtems_status_code ret;
rtems_id mailbox = 0;
ret = rtems_message_queue_create(
rtems_build_name('U', 'S', 'B', 'q'),
max_msgs,
SYS_USB_MBOX_SIZE,
RTEMS_DEFAULT_ATTRIBUTES,
&mailbox);
return mailbox;
}
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
{
rtems_status_code ret;
ret = rtems_message_queue_send(mq, &addr, SYS_USB_MBOX_SIZE);
return (ret == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
{
size_t size;
rtems_status_code sc;
sc = rtems_message_queue_receive(
mq,
addr,
&size,
RTEMS_WAIT,
timeout);
return (sc == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
uint32_t usb_osal_enter_critical_section(void)
{
rtems_interrupt_level pval;
#if RTEMS_SMP
rtems_recursive_mutex_lock(&sys_arch_lock);
#else
rtems_interrupt_disable(pval);
#endif
return pval;
}
void usb_osal_leave_critical_section(size_t flag)
{
#if RTEMS_SMP
rtems_recursive_mutex_unlock(&sys_arch_lock);
#else
rtems_interrupt_enable(flag);
#endif
}
void usb_osal_msleep(uint32_t delay)
{
rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(delay));
}
#endif

View File

@@ -9,35 +9,23 @@
#include "usb_log.h"
#include "tx_api.h"
/* create bytepool in tx_application_define
*
* tx_byte_pool_create(&usb_byte_pool, "usb byte pool", memory_area, 65536);
*/
extern TX_BYTE_POOL usb_byte_pool; // define usb_byte_pool and call usb_osal_init first
extern TX_BYTE_POOL usb_byte_pool;
usb_osal_mq_t usb_osal_mq;
usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args)
{
CHAR *pointer = TX_NULL;
TX_THREAD *thread_ptr = TX_NULL;
tx_byte_allocate(&usb_byte_pool, (VOID **)&thread_ptr, sizeof(TX_THREAD), TX_NO_WAIT);
tx_byte_allocate(&usb_byte_pool, (VOID **)&thread_ptr, USB_ALIGN_UP(sizeof(TX_THREAD), 4) + stack_size, TX_NO_WAIT);
if (thread_ptr == TX_NULL) {
USB_LOG_ERR("Create thread %s failed\r\n", name);
while (1) {
}
}
tx_byte_allocate(&usb_byte_pool, (VOID **)&pointer, stack_size, TX_NO_WAIT);
if (pointer == TX_NULL) {
USB_LOG_ERR("Create thread %s failed\r\n", name);
while (1) {
}
}
tx_thread_create(thread_ptr, (CHAR *)name, (VOID(*)(ULONG))entry, (uintptr_t)args,
pointer, stack_size,
((CHAR *)thread_ptr + USB_ALIGN_UP(sizeof(TX_THREAD), 4)), stack_size,
prio, prio, TX_NO_TIME_SLICE, TX_AUTO_START);
return (usb_osal_thread_t)thread_ptr;
@@ -45,27 +33,17 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size,
void usb_osal_thread_delete(usb_osal_thread_t thread)
{
TX_THREAD *thread_ptr = NULL;
if (thread == NULL) {
/* Call the tx_thread_identify to get the control block pointer of the
currently executing thread. */
thread_ptr = tx_thread_identify();
thread = tx_thread_identify();
/* Check if the current running thread pointer is not NULL */
if (thread_ptr != NULL) {
/* Call the tx_thread_terminate to terminates the specified application
thread regardless of whether the thread is suspended or not. A thread
may call this service to terminate itself. */
tx_thread_terminate(thread_ptr);
tx_byte_release(thread_ptr->tx_thread_stack_start);
tx_byte_release(thread_ptr);
}
usb_osal_mq_send(usb_osal_mq, (uintptr_t)thread);
tx_thread_terminate(thread);
return;
}
tx_thread_terminate(thread);
tx_byte_release(thread_ptr->tx_thread_stack_start);
tx_thread_delete(thread);
tx_byte_release(thread);
}
@@ -86,7 +64,6 @@ usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
TX_SEMAPHORE *sem_ptr = TX_NULL;
tx_byte_allocate(&usb_byte_pool, (VOID **)&sem_ptr, sizeof(TX_SEMAPHORE), TX_NO_WAIT);
if (sem_ptr == TX_NULL) {
USB_LOG_ERR("Create semaphore failed\r\n");
while (1) {
@@ -121,7 +98,7 @@ int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
int usb_osal_sem_give(usb_osal_sem_t sem)
{
return (int)tx_semaphore_put((TX_SEMAPHORE *)sem);
return (tx_semaphore_put((TX_SEMAPHORE *)sem) == TX_SUCCESS) ? 0 : -USB_ERR_INVAL;
}
void usb_osal_sem_reset(usb_osal_sem_t sem)
@@ -134,14 +111,13 @@ usb_osal_mutex_t usb_osal_mutex_create(void)
TX_MUTEX *mutex_ptr = TX_NULL;
tx_byte_allocate(&usb_byte_pool, (VOID **)&mutex_ptr, sizeof(TX_MUTEX), TX_NO_WAIT);
if (mutex_ptr == TX_NULL) {
USB_LOG_ERR("Create mutex failed\r\n");
while (1) {
}
}
tx_mutex_create(mutex_ptr, "usbh_mutx", TX_INHERIT);
tx_mutex_create(mutex_ptr, "usbh_mutex", TX_INHERIT);
return (usb_osal_mutex_t)mutex_ptr;
}
@@ -169,38 +145,27 @@ int usb_osal_mutex_take(usb_osal_mutex_t mutex)
int usb_osal_mutex_give(usb_osal_mutex_t mutex)
{
return (int)(tx_mutex_put((TX_MUTEX *)mutex) == TX_SUCCESS) ? 0 : -USB_ERR_INVAL;
return (tx_mutex_put((TX_MUTEX *)mutex) == TX_SUCCESS) ? 0 : -USB_ERR_INVAL;
}
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
{
CHAR *pointer = TX_NULL;
TX_QUEUE *queue_ptr = TX_NULL;
tx_byte_allocate(&usb_byte_pool, (VOID **)&queue_ptr, sizeof(TX_QUEUE), TX_NO_WAIT);
tx_byte_allocate(&usb_byte_pool, (VOID **)&queue_ptr, USB_ALIGN_UP(sizeof(TX_QUEUE), 4) + sizeof(uintptr_t) * max_msgs, TX_NO_WAIT);
if (queue_ptr == TX_NULL) {
USB_LOG_ERR("Create TX_QUEUE failed\r\n");
while (1) {
}
}
tx_byte_allocate(&usb_byte_pool, (VOID **)&pointer, sizeof(uintptr_t) * max_msgs, TX_NO_WAIT);
if (pointer == TX_NULL) {
USB_LOG_ERR("Create mq failed\r\n");
while (1) {
}
}
tx_queue_create(queue_ptr, "usbh_mq", sizeof(uintptr_t) / 4, pointer, sizeof(uintptr_t) * max_msgs);
tx_queue_create(queue_ptr, "usbh_mq", sizeof(uintptr_t) / 4, (CHAR *)queue_ptr + USB_ALIGN_UP(sizeof(TX_QUEUE), 4), sizeof(uintptr_t) * max_msgs);
return (usb_osal_mq_t)queue_ptr;
}
void usb_osal_mq_delete(usb_osal_mq_t mq)
{
tx_queue_delete((TX_QUEUE *)mq);
tx_byte_release(((TX_QUEUE *)mq)->tx_queue_start);
tx_byte_release(mq);
}
@@ -231,7 +196,6 @@ struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_
struct usb_osal_timer *timer;
tx_byte_allocate(&usb_byte_pool, (VOID **)&timer, sizeof(struct usb_osal_timer), TX_NO_WAIT);
if (timer == TX_NULL) {
USB_LOG_ERR("Create usb_osal_timer failed\r\n");
while (1) {
@@ -240,7 +204,6 @@ struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_
memset(timer, 0, sizeof(struct usb_osal_timer));
tx_byte_allocate(&usb_byte_pool, (VOID **)&timer_ptr, sizeof(TX_TIMER), TX_NO_WAIT);
if (timer_ptr == TX_NULL) {
USB_LOG_ERR("Create TX_TIMER failed\r\n");
while (1) {
@@ -269,8 +232,8 @@ void usb_osal_timer_start(struct usb_osal_timer *timer)
{
if (tx_timer_change((TX_TIMER *)timer->timer, timer->timeout_ms, timer->is_period ? timer->timeout_ms : 0) == TX_SUCCESS) {
/* Call the tx_timer_activate to activates the specified application
timer. The expiration routines of timers that expire at the same
time are executed in the order they were activated. */
timer. The expiration routines of timers that expire at the same
time are executed in the order they were activated. */
if (tx_timer_activate((TX_TIMER *)timer->timer) == TX_SUCCESS) {
/* Return osOK for success */
} else {
@@ -296,7 +259,7 @@ size_t usb_osal_enter_critical_section(void)
void usb_osal_leave_critical_section(size_t flag)
{
int interrupt_save;
TX_INTERRUPT_SAVE_AREA
interrupt_save = flag;
TX_RESTORE
@@ -322,4 +285,40 @@ void *usb_osal_malloc(size_t size)
void usb_osal_free(void *ptr)
{
tx_byte_release(ptr);
}
}
static void usb_osal_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
int ret;
usb_osal_thread_t thread;
while (1) {
ret = usb_osal_mq_recv(usb_osal_mq, (uintptr_t *)&thread, TX_WAIT_FOREVER);
if (ret < 0) {
continue;
}
tx_thread_delete(thread);
tx_byte_release(thread);
}
}
void usb_osal_init(uint8_t *mem, uint32_t mem_size)
{
usb_osal_thread_t thread;
tx_byte_pool_create(&usb_byte_pool, "usb byte pool", mem, mem_size);
thread = usb_osal_thread_create("usb_osal", 2048, 10, usb_osal_thread, NULL);
if (thread == NULL) {
USB_LOG_ERR("Create usb_osal_thread failed\r\n");
while (1) {
}
}
usb_osal_mq = usb_osal_mq_create(32);
if (usb_osal_mq == NULL) {
USB_LOG_ERR("Create usb_osal_mq failed\r\n");
while (1) {
}
}
}

View File

@@ -1,135 +0,0 @@
/*
* Copyright (c) 2022, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usb_osal.h"
#include "usb_errno.h"
#include <aos/kernel.h>
#include <csi_core.h>
usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args)
{
aos_task_t task_handle = NULL;
aos_task_new_ext(&task_handle, name, entry, args, stack_size, prio + AOS_DEFAULT_APP_PRI - 4);
return task_handle;
}
void usb_osal_thread_delete(usb_osal_thread_t thread)
{
aos_task_exit(0);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
aos_sem_t sem = NULL;
aos_sem_new(&sem, initial_count);
return sem;
}
void usb_osal_sem_delete(usb_osal_sem_t sem)
{
aos_sem_free((aos_sem_t *)&sem);
}
int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
{
if (timeout == USB_OSAL_WAITING_FOREVER) {
return aos_sem_wait((aos_sem_t *)&sem, AOS_WAIT_FOREVER);
} else {
return aos_sem_wait((aos_sem_t *)&sem, timeout);
}
}
int usb_osal_sem_give(usb_osal_sem_t sem)
{
aos_sem_signal((aos_sem_t *)&sem);
return 0;
}
void usb_osal_sem_reset(usb_osal_sem_t sem)
{
}
usb_osal_mutex_t usb_osal_mutex_create(void)
{
aos_mutex_t mutex = NULL;
aos_mutex_new(&mutex);
return (usb_osal_mutex_t)mutex;
}
void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
{
aos_mutex_free(((aos_mutex_t *)&mutex));
}
int usb_osal_mutex_take(usb_osal_mutex_t mutex)
{
return aos_mutex_lock(((aos_mutex_t *)&mutex), AOS_WAIT_FOREVER);
}
int usb_osal_mutex_give(usb_osal_mutex_t mutex)
{
return aos_mutex_unlock(((aos_mutex_t *)&mutex));
}
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
{
aos_queue_t queue = NULL;
aos_queue_create(&queue, sizeof(uintptr_t), max_msgs, 0);
return (usb_osal_mq_t)queue;
}
void usb_osal_mq_delete(usb_osal_mq_t mq)
{
aos_queue_free((aos_queue_t)mq);
}
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
{
return aos_queue_send((aos_queue_t *)&mq, &addr, sizeof(uintptr_t));
}
int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
{
size_t recv_size;
if (timeout == USB_OSAL_WAITING_FOREVER) {
return aos_queue_recv((aos_queue_t *)&mq, AOS_WAIT_FOREVER, addr, &recv_size);
} else {
return aos_queue_recv((aos_queue_t *)&mq, timeout, addr, &recv_size);
}
}
size_t usb_osal_enter_critical_section(void)
{
return csi_irq_save();
}
void usb_osal_leave_critical_section(size_t flag)
{
csi_irq_restore(flag);
}
void usb_osal_msleep(uint32_t delay)
{
aos_msleep(delay);
}
void *usb_osal_malloc(size_t size)
{
return aos_malloc(size);
}
void usb_osal_free(void *ptr)
{
aos_free(ptr);
}

View File

@@ -5,175 +5,313 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "dap_main.h"
#include "DAP_config.h"
#include "DAP.h"
#define USB_CONFIG_SIZE (9 + CMSIS_DAP_INTERFACE_SIZE + CDC_ACM_DESCRIPTOR_LEN + CONFIG_MSC_DESCRIPTOR_LEN)
#define INTF_NUM (2 + 1 + CONFIG_MSC_INTF_NUM)
#define CMSIS_DAP_INTERFACE_SIZE (9 + 7 + 7)
#define CUSTOM_HID_LEN (9 + 9 + 7 + 7)
#define HIDRAW_INTERVAL 4
#define HID_CUSTOM_REPORT_DESC_SIZE 53
#define USBD_WINUSB_VENDOR_CODE 0x20
#define USBD_WEBUSB_VENDOR_CODE 0x21
#define USBD_WEBUSB_ENABLE 1
#define USBD_BULK_ENABLE 1
#define USBD_WINUSB_ENABLE 1
/* WinUSB Microsoft OS 2.0 descriptor sizes */
#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
#define FUNCTION_SUBSET_LEN 160
#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
#define USBD_WEBUSB_DESC_LEN 24
#define USBD_WINUSB_DESC_LEN 28
#define USBD_BOS_WTOTALLENGTH (0x05 + \
USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
#define USB_CONFIG_SIZE (9 + CMSIS_DAP_INTERFACE_SIZE + CDC_ACM_DESCRIPTOR_LEN + \
CONFIG_CHERRYDAP_USE_CUSTOM_HID * CUSTOM_HID_LEN + \
CONFIG_CHERRYDAP_USE_MSC * MSC_DESCRIPTOR_LEN + USBD_WEBUSB_ENABLE * 9)
#define INTF_NUM (1 + 2 + CONFIG_CHERRYDAP_USE_CUSTOM_HID + CONFIG_CHERRYDAP_USE_MSC + USBD_WEBUSB_ENABLE)
#define MSC_INTF_NUM (3 + CONFIG_CHERRYDAP_USE_CUSTOM_HID)
#define WEBUSB_INTF_NUM (3 + CONFIG_CHERRYDAP_USE_CUSTOM_HID + CONFIG_CHERRYDAP_USE_MSC)
#define WEBUSB_URL_STRINGS \
'c', 'h', 'e', 'r', 'r', 'y', 'd', 'a', 'p', '.', 'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '.', 'o', 'r', 'g',
__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
#if (USBD_WEBUSB_ENABLE)
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
0, // bFirstInterface USBD_WINUSB_IF_NUM
0, // bReserved
WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId
0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
WBVAL(42), // wPropertyNameLength
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), // wPropertyDataLength
'{', 0,
'9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
'9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
'4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
'9', 0, '3', 0, '3', 0, 'B', 0, '-',
0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
'}', 0, 0, 0, 0, 0
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
WEBUSB_INTF_NUM, // bFirstInterface USBD_WINUSB_IF_NUM
0, // bReserved
WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId
0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
WBVAL(42), // wPropertyNameLength
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), // wPropertyDataLength
'{', 0,
'9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
'9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
'4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
'9', 0, '3', 0, '3', 0, 'B', 0, '-',
0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
'}', 0, 0, 0, 0, 0,
#endif
#if USBD_BULK_ENABLE
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
0, /* bFirstInterface USBD_BULK_IF_NUM*/
0, /* bReserved */
WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/
0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
WBVAL(42), /* wPropertyNameLength */
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), /* wPropertyDataLength */
'{', 0,
'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
'4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
'A', 0, 'A', 0, '3', 0, '6', 0, '-',
0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
'}', 0, 0, 0, 0, 0
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
0, /* bFirstInterface USBD_BULK_IF_NUM*/
0, /* bReserved */
WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/
0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
WBVAL(42), /* wPropertyNameLength */
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
WBVAL(80), /* wPropertyDataLength */
'{', 0,
'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
'4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
'A', 0, 'A', 0, '3', 0, '6', 0, '-',
0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
'}', 0, 0, 0, 0, 0
#endif
};
__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
0x05, /* bLength */
0x0f, /* bDescriptorType */
WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */
0x05, /* bLength */
0x0f, /* bDescriptorType */
WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */
#if (USBD_WEBUSB_ENABLE)
USBD_WEBUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */
0xA9, 0x09, 0xA0, 0x47,
0x8B, 0xFD, 0xA0, 0x76,
0x88, 0x15, 0xB6, 0x65,
WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0, /* iLandingPage */
USBD_WEBUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */
0xA9, 0x09, 0xA0, 0x47,
0x8B, 0xFD, 0xA0, 0x76,
0x88, 0x15, 0xB6, 0x65,
WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
USBD_WEBUSB_VENDOR_CODE, /* bVendorCode */
1, /* iLandingPage */
#endif
#if (USBD_WINUSB_ENABLE)
USBD_WINUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
0x89, 0x45, 0xC7, 0x4C,
0x9C, 0xD2, 0x65, 0x9D,
0x9E, 0x64, 0x8A, 0x9F,
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0, /* bAltEnumCode */
USBD_WINUSB_DESC_LEN, /* bLength */
0x10, /* bDescriptorType */
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */
0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
0x89, 0x45, 0xC7, 0x4C,
0x9C, 0xD2, 0x65, 0x9D,
0x9E, 0x64, 0x8A, 0x9F,
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0, /* bAltEnumCode */
#endif
};
#define URL_DESCRIPTOR_LENGTH (3 + 29)
const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
URL_DESCRIPTOR_LENGTH,
WEBUSB_URL_TYPE,
WEBUSB_URL_SCHEME_HTTPS,
WEBUSB_URL_STRINGS
};
// clang-format off
#define HID_DESC() \
/************** Descriptor of Custom interface *****************/ \
0x09, /* bLength: Interface Descriptor size */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
0X03, /* 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: */ \
HID_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ \
0x03, /* bmAttributes: Interrupt endpoint */ \
WBVAL(HID_PACKET_SIZE), /* wMaxPacketSize: 4 Byte max */ \
HIDRAW_INTERVAL, /* bInterval: Polling Interval */ /******************** Descriptor of Custom out endpoint ********************/ \
0x07, /* bLength: Endpoint Descriptor size */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
HID_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ \
0x03, /* bmAttributes: Interrupt endpoint */ \
WBVAL(HID_PACKET_SIZE), /* wMaxPacketSize: 4 Byte max */ \
HIDRAW_INTERVAL /* bInterval: Polling Interval */
// clang-format on
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
};
static const uint8_t config_descriptor[] = {
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(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
/* Endpoint IN 1 */
USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
#ifdef CONFIG_CHERRYDAP_USE_MSC
MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
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(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
/* Endpoint IN 1 */
USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
#if CONFIG_CHERRYDAP_USE_CUSTOM_HID
HID_DESC(),
#endif
#if CONFIG_CHERRYDAP_USE_MSC
MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
#endif
#if USBD_WEBUSB_ENABLE
USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x04),
#endif
};
static const uint8_t other_speed_config_descriptor[] = {
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(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
/* Endpoint IN 1 */
USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
#ifdef CONFIG_CHERRYDAP_USE_MSC
MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
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(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
/* Endpoint IN 1 */
USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
#if CONFIG_CHERRYDAP_USE_CUSTOM_HID
HID_DESC(),
#endif
#if CONFIG_CHERRYDAP_USE_MSC
MSC_DESCRIPTOR_INIT(0x04, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
#endif
#if USBD_WEBUSB_ENABLE
USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x04),
#endif
};
/*!< custom hid report descriptor */
const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
/* USER CODE BEGIN 0 */
0x06, 0x00, 0xff, /* USAGE_PAGE (Vendor Defined Page 1) */
0x09, 0x01, /* USAGE (Vendor Usage 1) */
0xa1, 0x01, /* COLLECTION (Application) */
0x85, 0x02, /* REPORT ID (0x02) */
0x09, 0x02, /* USAGE (Vendor Usage 1) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0xff, /*LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
/* <___________________________________________________> */
0x85, 0x01, /* REPORT ID (0x01) */
0x09, 0x03, /* USAGE (Vendor Usage 1) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
/* <___________________________________________________> */
0x85, 0x03, /* REPORT ID (0x03) */
0x09, 0x04, /* USAGE (Vendor Usage 1) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */
0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */
};
char serial_number_dynamic[36] = "00000000000000000123456789ABCDEF"; // Dynamic serial number
char *string_descriptors[] = {
(char[]) {0x09, 0x04}, /* Langid */
"CherryUSB", /* Manufacturer */
"CherryUSB CMSIS-DAP", /* Product */
"00000000000000000123456789ABCDEF", /* Serial Number */
(char[]){ 0x09, 0x04 }, /* Langid */
"CherryUSB", /* Manufacturer */
"CherryUSB CMSIS-DAP", /* Product */
"00000000000000000123456789ABCDEF", /* Serial Number */
"CherryUSB WebUSB",
};
static const uint8_t device_quality_descriptor[] = {
USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01),
USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01),
};
__WEAK const uint8_t *device_descriptor_callback(uint8_t speed)
{
(void) speed;
(void)speed;
return device_descriptor;
}
__WEAK const uint8_t *config_descriptor_callback(uint8_t speed)
{
(void) speed;
(void)speed;
return config_descriptor;
}
__WEAK const uint8_t *device_quality_descriptor_callback(uint8_t speed)
{
(void) speed;
(void)speed;
return device_quality_descriptor;
}
__WEAK const uint8_t *other_speed_config_descriptor_callback(uint8_t speed)
{
(void) speed;
(void)speed;
return other_speed_config_descriptor;
}
__WEAK const char *string_descriptor_callback(uint8_t speed, uint8_t index)
{
(void) speed;
(void)speed;
if (index == 3) {
return serial_number_dynamic;
}
if (index >= (sizeof(string_descriptors) / sizeof(char *))) {
return NULL;
@@ -214,7 +352,7 @@ USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_usbrx;
void usbd_event_handler(uint8_t busid, uint8_t event)
{
(void) busid;
(void)busid;
switch (event) {
case USBD_EVENT_RESET:
usbrx_idle_flag = 0;
@@ -250,7 +388,7 @@ void usbd_event_handler(uint8_t busid, uint8_t event)
void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
(void) busid;
(void)busid;
if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
DAP_TransferAbort = 1U;
} else {
@@ -262,7 +400,7 @@ void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
}
// Start reception of next request packet
if ((uint16_t) (USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
} else {
USB_RequestIdle = 1U;
@@ -271,7 +409,7 @@ void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
void dap_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
(void) busid;
(void)busid;
if (USB_ResponseCountI != USB_ResponseCountO) {
// Load data from response buffer to be sent back
usbd_ep_start_write(0, DAP_IN_EP, USB_Response[USB_ResponseIndexO], USB_RespSize[USB_ResponseIndexO]);
@@ -287,7 +425,7 @@ void dap_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
(void) busid;
(void)busid;
chry_ringbuffer_write(&g_usbrx, usb_tmpbuffer, nbytes);
if (chry_ringbuffer_get_free(&g_usbrx) >= DAP_PACKET_SIZE) {
usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE);
@@ -298,7 +436,7 @@ void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
(void) busid;
(void)busid;
uint32_t size;
uint8_t *buffer;
@@ -317,52 +455,110 @@ void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
}
struct usbd_endpoint dap_out_ep = {
.ep_addr = DAP_OUT_EP,
.ep_cb = dap_out_callback
.ep_addr = DAP_OUT_EP,
.ep_cb = dap_out_callback
};
struct usbd_endpoint dap_in_ep = {
.ep_addr = DAP_IN_EP,
.ep_cb = dap_in_callback
.ep_addr = DAP_IN_EP,
.ep_cb = dap_in_callback
};
struct usbd_endpoint cdc_out_ep = {
.ep_addr = CDC_OUT_EP,
.ep_cb = usbd_cdc_acm_bulk_out
.ep_addr = CDC_OUT_EP,
.ep_cb = usbd_cdc_acm_bulk_out
};
struct usbd_endpoint cdc_in_ep = {
.ep_addr = CDC_IN_EP,
.ep_cb = usbd_cdc_acm_bulk_in
.ep_addr = CDC_IN_EP,
.ep_cb = usbd_cdc_acm_bulk_in
};
#if CONFIG_CHERRYDAP_USE_CUSTOM_HID
struct usbd_endpoint hid_custom_in_ep = {
.ep_addr = HID_IN_EP,
.ep_cb = usbd_hid_custom_in_callback,
};
struct usbd_endpoint hid_custom_out_ep = {
.ep_addr = HID_OUT_EP,
.ep_cb = usbd_hid_custom_out_callback,
};
#endif
struct usbd_interface dap_intf;
struct usbd_interface intf1;
struct usbd_interface intf2;
struct usbd_interface intf3;
#if CONFIG_CHERRYDAP_USE_CUSTOM_HID
struct usbd_interface hid_intf;
#endif
#if CONFIG_CHERRYDAP_USE_MSC
struct usbd_interface intf3;
#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,
.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
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = USBD_BOS_WTOTALLENGTH
};
struct usb_webusb_descriptor webusb_url_desc = {
.vendor_code = USBD_WEBUSB_VENDOR_CODE,
.string = USBD_WebUSBURLDescriptor,
.string_len = URL_DESCRIPTOR_LENGTH
};
const struct usb_descriptor cmsisdap_descriptor = {
.device_descriptor_callback = device_descriptor_callback,
.config_descriptor_callback = config_descriptor_callback,
.device_quality_descriptor_callback = device_quality_descriptor_callback,
.other_speed_descriptor_callback = other_speed_config_descriptor_callback,
.string_descriptor_callback = string_descriptor_callback,
.bos_descriptor = &bos_desc,
.msosv2_descriptor = &msosv2_desc,
.device_descriptor_callback = device_descriptor_callback,
.config_descriptor_callback = config_descriptor_callback,
.device_quality_descriptor_callback = device_quality_descriptor_callback,
.other_speed_descriptor_callback = other_speed_config_descriptor_callback,
.string_descriptor_callback = string_descriptor_callback,
.bos_descriptor = &bos_desc,
.msosv2_descriptor = &msosv2_desc,
.webusb_url_descriptor = &webusb_url_desc
};
void chry_dap_init(uint8_t busid, uint32_t reg_base)
{
chry_ringbuffer_init(&g_uartrx, uartrx_ringbuffer, CONFIG_UARTRX_RINGBUF_SIZE);
chry_ringbuffer_init(&g_usbrx, usbrx_ringbuffer, CONFIG_USBRX_RINGBUF_SIZE);
DAP_Setup();
usbd_desc_register(0, &cmsisdap_descriptor);
/*!< winusb */
usbd_add_interface(0, &dap_intf);
usbd_add_endpoint(0, &dap_out_ep);
usbd_add_endpoint(0, &dap_in_ep);
/*!< cdc acm */
usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf1));
usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf2));
usbd_add_endpoint(0, &cdc_out_ep);
usbd_add_endpoint(0, &cdc_in_ep);
#if CONFIG_CHERRYDAP_USE_CUSTOM_HID
/*!< hid */
usbd_add_interface(0, usbd_hid_init_intf(0, &hid_intf, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE));
hid_intf.notify_handler = hid_custom_notify_handler;
usbd_add_endpoint(0, &hid_custom_in_ep);
usbd_add_endpoint(0, &hid_custom_out_ep);
#endif
#if CONFIG_CHERRYDAP_USE_MSC
usbd_add_interface(0, usbd_msc_init_intf(0, &intf3, MSC_OUT_EP, MSC_IN_EP));
#endif
usbd_initialize(busid, reg_base, usbd_event_handler);
}
void chry_dap_handle(void)
{
uint32_t n;
@@ -387,7 +583,7 @@ void chry_dap_handle(void)
// Execute DAP Command (process request and prepare response)
USB_RespSize[USB_ResponseIndexI] =
(uint16_t) DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
(uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
// Update Request Index and Count
USB_RequestIndexO++;
@@ -397,7 +593,7 @@ void chry_dap_handle(void)
USB_RequestCountO++;
if (USB_RequestIdle) {
if ((uint16_t) (USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
USB_RequestIdle = 0U;
usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
}
@@ -427,9 +623,9 @@ void chry_dap_handle(void)
void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
{
(void) busid;
if (memcmp(line_coding, (uint8_t *) &g_cdc_lincoding, sizeof(struct cdc_line_coding)) != 0) {
memcpy((uint8_t *) &g_cdc_lincoding, line_coding, sizeof(struct cdc_line_coding));
(void)busid;
if (memcmp(line_coding, (uint8_t *)&g_cdc_lincoding, sizeof(struct cdc_line_coding)) != 0) {
memcpy((uint8_t *)&g_cdc_lincoding, line_coding, sizeof(struct cdc_line_coding));
config_uart = 1;
config_uart_transfer = 0;
}
@@ -437,8 +633,8 @@ void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_c
void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
{
(void) busid;
memcpy(line_coding, (uint8_t *) &g_cdc_lincoding, sizeof(struct cdc_line_coding));
(void)busid;
memcpy(line_coding, (uint8_t *)&g_cdc_lincoding, sizeof(struct cdc_line_coding));
}
void chry_dap_usb2uart_handle(void)
@@ -450,7 +646,7 @@ void chry_dap_usb2uart_handle(void)
/* disable irq here */
config_uart = 0;
/* config uart here */
chry_dap_usb2uart_uart_config_callback((struct cdc_line_coding *) &g_cdc_lincoding);
chry_dap_usb2uart_uart_config_callback((struct cdc_line_coding *)&g_cdc_lincoding);
usbtx_idle_flag = 1;
uarttx_idle_flag = 1;
config_uart_transfer = 1;
@@ -521,7 +717,7 @@ __WEAK void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len)
{
}
#ifdef CONFIG_CHERRYDAP_USE_MSC
#if CONFIG_CHERRYDAP_USE_MSC
#define BLOCK_SIZE 512
#define BLOCK_COUNT 10

View File

@@ -10,6 +10,7 @@
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_msc.h"
#include "usbd_hid.h"
#include "chry_ringbuffer.h"
#include "DAP_config.h"
#include "DAP.h"
@@ -24,23 +25,14 @@
#define MSC_IN_EP 0x86
#define MSC_OUT_EP 0x07
#define HID_IN_EP 0x88
#define HID_OUT_EP 0x09
#define USBD_VID 0x0D28
#define USBD_PID 0x0204
#define USBD_MAX_POWER 500
#define USBD_LANGID_STRING 1033
#define CMSIS_DAP_INTERFACE_SIZE (9 + 7 + 7)
#ifdef CONFIG_CHERRYDAP_USE_MSC
#define CONFIG_MSC_DESCRIPTOR_LEN CDC_ACM_DESCRIPTOR_LEN
#define CONFIG_MSC_INTF_NUM 1
#define MSC_INTF_NUM (0x02 + 1)
#else
#define CONFIG_MSC_DESCRIPTOR_LEN 0
#define CONFIG_MSC_INTF_NUM 0
#define MSC_INTF_NUM (0x02)
#endif
#ifdef CONFIG_USB_HS
#if DAP_PACKET_SIZE != 512
#error "DAP_PACKET_SIZE must be 512 in hs"
@@ -51,99 +43,57 @@
#endif
#endif
#define USBD_WINUSB_VENDOR_CODE 0x20
#define USBD_WEBUSB_ENABLE 0
#define USBD_BULK_ENABLE 1
#define USBD_WINUSB_ENABLE 1
/* WinUSB Microsoft OS 2.0 descriptor sizes */
#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
#define FUNCTION_SUBSET_LEN 160
#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
#define USBD_WEBUSB_DESC_LEN 24
#define USBD_WINUSB_DESC_LEN 28
#define USBD_BOS_WTOTALLENGTH (0x05 + \
USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
#ifdef CONFIG_USB_HS
#define HID_PACKET_SIZE 1024
#else
#define HID_PACKET_SIZE 64
#endif
#define CONFIG_UARTRX_RINGBUF_SIZE (8 * 1024)
#define CONFIG_USBRX_RINGBUF_SIZE (8 * 1024)
#ifdef __cplusplus
extern "C"
{
#ifndef CONFIG_CHERRYDAP_USE_MSC
#define CONFIG_CHERRYDAP_USE_MSC 0
#endif
extern USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t uartrx_ringbuffer[CONFIG_UARTRX_RINGBUF_SIZE];
extern USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usbrx_ringbuffer[CONFIG_USBRX_RINGBUF_SIZE];
extern USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_tmpbuffer[DAP_PACKET_SIZE];
#ifndef CONFIG_CHERRYDAP_USE_CUSTOM_HID
#define CONFIG_CHERRYDAP_USE_CUSTOM_HID 0
#endif
extern const struct usb_descriptor cmsisdap_descriptor;
extern __ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[];
extern __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[];
extern char *string_descriptors[];
#ifdef __cplusplus
extern "C" {
#endif
extern char serial_number_dynamic[36];
extern struct usbd_interface dap_intf;
extern struct usbd_interface intf1;
extern struct usbd_interface intf2;
extern struct usbd_interface intf3;
extern struct usbd_interface hid_intf;
extern struct usbd_endpoint dap_out_ep;
extern struct usbd_endpoint dap_in_ep;
extern struct usbd_endpoint cdc_out_ep;
extern struct usbd_endpoint cdc_in_ep;
extern chry_ringbuffer_t g_uartrx;
extern chry_ringbuffer_t g_usbrx;
__STATIC_INLINE void chry_dap_init(uint8_t busid, uint32_t reg_base)
{
chry_ringbuffer_init(&g_uartrx, uartrx_ringbuffer, CONFIG_UARTRX_RINGBUF_SIZE);
chry_ringbuffer_init(&g_usbrx, usbrx_ringbuffer, CONFIG_USBRX_RINGBUF_SIZE);
DAP_Setup();
usbd_desc_register(0, &cmsisdap_descriptor);
/*!< winusb */
usbd_add_interface(0, &dap_intf);
usbd_add_endpoint(0, &dap_out_ep);
usbd_add_endpoint(0, &dap_in_ep);
/*!< cdc acm */
usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf1));
usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf2));
usbd_add_endpoint(0, &cdc_out_ep);
usbd_add_endpoint(0, &cdc_in_ep);
#ifdef CONFIG_CHERRYDAP_USE_MSC
usbd_add_interface(0, usbd_msc_init_intf(0, &intf3, MSC_OUT_EP, MSC_IN_EP));
#endif
extern void usbd_event_handler(uint8_t busid, uint8_t event);
usbd_initialize(busid, reg_base, usbd_event_handler);
}
void chry_dap_init(uint8_t busid, uint32_t reg_base);
void chry_dap_handle(void);
void chry_dap_usb2uart_handle(void);
void chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding *line_coding);
/* implment by user */
extern void chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding *line_coding);
void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len);
/* implment by user */
extern void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len);
void chry_dap_usb2uart_uart_send_complete(uint32_t size);
/* implment by user */
extern void hid_custom_notify_handler(uint8_t busid, uint8_t event, void *arg);
/* implment by user */
extern void usbd_hid_custom_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes);
/* implment by user */
extern void usbd_hid_custom_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes);
#ifdef __cplusplus
}
#endif

View File

@@ -34,7 +34,7 @@ int USB_disk_read(BYTE *buff, LBA_t sector, UINT count)
uint8_t *align_buf;
align_buf = (uint8_t *)buff;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
if (!align_buf) {
@@ -42,19 +42,19 @@ int USB_disk_read(BYTE *buff, LBA_t sector, UINT count)
return -USB_ERR_NOMEM;
}
}
#endif
ret = usbh_msc_scsi_read10(active_msc_class, sector, align_buf, count);
if (ret < 0) {
ret = RES_ERROR;
} else {
ret = RES_OK;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
usb_memcpy(buff, align_buf, count * active_msc_class->blocksize);
free(align_buf);
}
#endif
return ret;
}
@@ -64,7 +64,7 @@ int USB_disk_write(const BYTE *buff, LBA_t sector, UINT count)
uint8_t *align_buf;
align_buf = (uint8_t *)buff;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
if (!align_buf) {
@@ -73,18 +73,18 @@ int USB_disk_write(const BYTE *buff, LBA_t sector, UINT count)
}
usb_memcpy(align_buf, buff, count * active_msc_class->blocksize);
}
#endif
ret = usbh_msc_scsi_write10(active_msc_class, sector, align_buf, count);
if (ret < 0) {
ret = RES_ERROR;
} else {
ret = RES_OK;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
free(align_buf);
}
#endif
return ret;
}

296
platform/idf/usbh_fatfs.c Normal file
View File

@@ -0,0 +1,296 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_check.h"
#include "diskio_impl.h"
#include "ffconf.h"
#include "ff.h"
#include "esp_vfs_fat.h"
#include "usbh_core.h"
#include "usbh_msc.h"
static char *TAG = "MSC";
#define DRIVE_STR_LEN 3
typedef struct msc_host_vfs {
uint8_t pdrv;
FATFS *fs;
char base_path[0];
} msc_host_vfs_t;
static struct usbh_msc *s_mscs[FF_VOLUMES] = { NULL };
static DSTATUS usb_disk_initialize(BYTE pdrv)
{
return RES_OK;
}
static DSTATUS usb_disk_status(BYTE pdrv)
{
return RES_OK;
}
static DRESULT usb_disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
{
struct usbh_msc *msc_class;
assert(pdrv < FF_VOLUMES);
msc_class = s_mscs[pdrv];
assert(msc_class);
if (sector >= msc_class->blocknum - count) {
ESP_LOGW(TAG, "%s: sector 0x%"PRIX32" out of range", __FUNCTION__, (uint32_t)sector);
return RES_PARERR;
}
uint8_t *dma_buff = buff;
size_t len = msc_class->blocksize * count;
if (((uint32_t)dma_buff & (CONFIG_USB_ALIGN_SIZE - 1)) || (len & (CONFIG_USB_ALIGN_SIZE - 1))) {
dma_buff = heap_caps_aligned_alloc(CONFIG_USB_ALIGN_SIZE, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (dma_buff == NULL) {
return RES_ERROR;
}
}
int ret = usbh_msc_scsi_read10(msc_class, sector, dma_buff, count);
if (dma_buff != buff) {
if (ret == 0) {
memcpy(buff, dma_buff, len);
}
heap_caps_free(dma_buff);
}
if (ret != 0) {
ESP_LOGE(TAG, "usbh_msc_scsi_read10 failed (%d)", ret);
return RES_ERROR;
}
return RES_OK;
}
static DRESULT usb_disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
{
struct usbh_msc *msc_class;
assert(pdrv < FF_VOLUMES);
msc_class = s_mscs[pdrv];
assert(msc_class);
if (sector >= msc_class->blocknum - count) {
ESP_LOGW(TAG, "%s: sector 0x%"PRIX32" out of range", __FUNCTION__, (uint32_t)sector);
return RES_PARERR;
}
const uint8_t *dma_buff = buff;
size_t len = msc_class->blocksize * count;
if (((uint32_t)dma_buff & (CONFIG_USB_ALIGN_SIZE - 1)) || (len & (CONFIG_USB_ALIGN_SIZE - 1))) {
dma_buff = heap_caps_aligned_alloc(CONFIG_USB_ALIGN_SIZE, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (dma_buff == NULL) {
return RES_ERROR;
}
memcpy((uint8_t *)dma_buff, buff, len);
}
int ret = usbh_msc_scsi_write10(msc_class, sector, dma_buff, count);
if (dma_buff != buff) {
heap_caps_free((uint8_t *)dma_buff);
}
if (ret != ESP_OK) {
ESP_LOGE(TAG, "usbh_msc_scsi_write10 failed (%d)", ret);
return RES_ERROR;
}
return RES_OK;
}
static DRESULT usb_disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
{
struct usbh_msc *msc_class;
assert(pdrv < FF_VOLUMES);
msc_class = s_mscs[pdrv];
assert(msc_class);
switch (cmd) {
case CTRL_SYNC:
return RES_OK;
case GET_SECTOR_COUNT:
*((DWORD *) buff) = msc_class->blocknum;
return RES_OK;
case GET_SECTOR_SIZE:
*((WORD *) buff) = msc_class->blocksize;
return RES_OK;
case GET_BLOCK_SIZE:
return RES_ERROR;
}
return RES_ERROR;
}
void ff_diskio_register_msc(BYTE pdrv, struct usbh_msc *msc_class)
{
assert(pdrv < FF_VOLUMES);
static const ff_diskio_impl_t usb_disk_impl = {
.init = &usb_disk_initialize,
.status = &usb_disk_status,
.read = &usb_disk_read,
.write = &usb_disk_write,
.ioctl = &usb_disk_ioctl
};
s_mscs[pdrv] = msc_class;
ff_diskio_register(pdrv, &usb_disk_impl);
}
BYTE ff_diskio_get_pdrv_disk(const struct usbh_msc *msc_class)
{
for (int i = 0; i < FF_VOLUMES; i++) {
if (msc_class == s_mscs[i]) {
return i;
}
}
return 0xff;
}
static esp_err_t msc_host_format(struct usbh_msc *msc_class, size_t allocation_size)
{
ESP_RETURN_ON_FALSE((msc_class != NULL && msc_class->user_data != NULL), ESP_ERR_INVALID_ARG, TAG, "");
void *workbuf = NULL;
const size_t workbuf_size = 4096;
msc_host_vfs_t *vfs = (msc_host_vfs_t *)msc_class->user_data;
char drive[DRIVE_STR_LEN] = {(char)('0' + vfs->pdrv), ':', 0};
ESP_RETURN_ON_FALSE((workbuf = ff_memalloc(workbuf_size)), ESP_ERR_NO_MEM, TAG, "");
// Valid value of cluster size is between sector_size and 128 * sector_size.
size_t cluster_size = MIN(MAX(allocation_size, msc_class->blocksize), 128 * msc_class->blocksize);
ESP_LOGW(TAG, "Formatting card, allocation unit size=%d", cluster_size);
f_mount(0, drive, 0);
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
FRESULT err = f_mkfs(drive, FM_ANY | FM_SFD, cluster_size, workbuf, workbuf_size);
#else
const MKFS_PARM opt = {(BYTE)(FM_ANY | FM_SFD), 0, 0, 0, cluster_size};
FRESULT err = f_mkfs(drive, &opt, workbuf, workbuf_size);
#endif
free(workbuf);
if (err != FR_OK || (err = f_mount(vfs->fs, drive, 0)) != FR_OK) {
ESP_LOGE(TAG, "Formatting failed with error: %d", err);
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t msc_host_vfs_register(struct usbh_msc *msc_class,
const char *base_path,
const esp_vfs_fat_mount_config_t *mount_config)
{
ESP_RETURN_ON_FALSE((msc_class != NULL && msc_class->user_data == NULL && base_path != NULL && mount_config != NULL), ESP_ERR_INVALID_ARG, TAG, "");
FATFS *fs = NULL;
BYTE pdrv;
if (ff_diskio_get_drive(&pdrv) != ESP_OK) {
ESP_LOGW(TAG, "the maximum count of volumes is already mounted");
return ESP_ERR_NO_MEM;
}
esp_err_t ret;
msc_host_vfs_t *vfs = malloc(sizeof(msc_host_vfs_t) + strlen(base_path) + 1);
ESP_RETURN_ON_FALSE(vfs != NULL, ESP_ERR_NO_MEM, TAG, "");
ff_diskio_register_msc(pdrv, msc_class);
char drive[DRIVE_STR_LEN] = {(char)('0' + pdrv), ':', 0};
strcpy(vfs->base_path, base_path);
vfs->pdrv = pdrv;
ret = esp_vfs_fat_register(base_path, drive, mount_config->max_files, &fs);
ESP_GOTO_ON_ERROR(ret, fail, TAG, "Failed to register filesystem, error=%s", esp_err_to_name(ret));
vfs->fs = fs;
msc_class->user_data = vfs;
if (f_mount(fs, drive, 1) != FR_OK) {
if ((!mount_config->format_if_mount_failed) || msc_host_format(msc_class, mount_config->allocation_unit_size) != ESP_OK) {
ret = ESP_FAIL;
goto fail;
}
}
return ESP_OK;
fail:
msc_class->user_data = NULL;
if (fs) {
f_mount(NULL, drive, 0);
}
esp_vfs_fat_unregister_path(base_path);
ff_diskio_unregister(pdrv);
s_mscs[pdrv] = NULL;
return ret;
}
esp_err_t msc_host_vfs_unregister(struct usbh_msc *msc_class)
{
ESP_RETURN_ON_FALSE((msc_class != NULL && ff_diskio_get_pdrv_disk(msc_class) != 0XFF), ESP_ERR_INVALID_ARG, TAG, "");
msc_host_vfs_t *vfs = (msc_host_vfs_t *)msc_class->user_data;
msc_class->user_data = NULL;
char drive[DRIVE_STR_LEN] = {(char)('0' + vfs->pdrv), ':', 0};
f_mount(NULL, drive, 0);
ff_diskio_unregister(vfs->pdrv);
s_mscs[vfs->pdrv] = NULL;
esp_vfs_fat_unregister_path(vfs->base_path);
heap_caps_free(vfs);
return ESP_OK;
}
static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
int ret;
ret = usbh_msc_scsi_init(msc_class);
if (ret < 0) {
ESP_LOGE(TAG, "scsi_init error,ret:%d", ret);
return;
}
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
.format_if_mount_failed = true,
#else
.format_if_mount_failed = false,
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
.max_files = 5,
.allocation_unit_size = 4 * 1024
};
ESP_LOGI(TAG, "Mounting msc host filesystem");
if (msc_host_vfs_register(msc_class, "/usb", &mount_config) != ESP_OK) {
ESP_LOGE(TAG, "msc_host_vfs_register fail");
return;
}
ESP_LOGI(TAG, "MSC host filesystem mounted");
usb_osal_thread_delete(NULL);
}
void usbh_msc_run(struct usbh_msc *msc_class)
{
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
}
void usbh_msc_stop(struct usbh_msc *msc_class)
{
msc_host_vfs_unregister(msc_class);
}

View File

@@ -21,7 +21,6 @@
// #define CONFIG_USBHOST_PLATFORM_CDC_NCM
// #define CONFIG_USBHOST_PLATFORM_ASIX
// #define CONFIG_USBHOST_PLATFORM_RTL8152
// #define CONFIG_USBHOST_PLATFORM_BL616
struct usbh_net_netif_glue {
esp_netif_driver_base_t base;

View File

@@ -35,7 +35,6 @@
// #define CONFIG_USBHOST_PLATFORM_CDC_NCM
// #define CONFIG_USBHOST_PLATFORM_ASIX
// #define CONFIG_USBHOST_PLATFORM_RTL8152
// #define CONFIG_USBHOST_PLATFORM_BL616
ip_addr_t g_ipaddr;
ip_addr_t g_netmask;
@@ -545,104 +544,3 @@ void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
netif_remove(netif);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_BL616
#include "usbh_bl616.h"
struct netif g_bl616_netif;
static err_t usbh_bl616_linkoutput(struct netif *netif, struct pbuf *p)
{
int ret;
(void)netif;
usbh_lwip_eth_output_common(p, usbh_bl616_get_eth_txbuf());
ret = usbh_bl616_eth_output(p->tot_len);
if (ret < 0) {
return ERR_BUF;
} else {
return ERR_OK;
}
}
void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(&g_bl616_netif, buf, buflen);
}
static err_t usbh_bl616_if_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
netif->state = NULL;
netif->name[0] = 'E';
netif->name[1] = 'X';
netif->output = etharp_output;
netif->linkoutput = usbh_bl616_linkoutput;
return ERR_OK;
}
void usbh_bl616_sta_connect_callback(void)
{
}
void usbh_bl616_sta_disconnect_callback(void)
{
struct netif *netif = &g_bl616_netif;
netif_set_down(netif);
}
void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4])
{
struct netif *netif = &g_bl616_netif;
IP4_ADDR(&netif->ip_addr, ip4_addr[0], ip4_addr[1], ip4_addr[2], ip4_addr[3]);
IP4_ADDR(&netif->netmask, ip4_mask[0], ip4_mask[1], ip4_mask[2], ip4_mask[3]);
IP4_ADDR(&netif->gw, ip4_gw[0], ip4_gw[1], ip4_gw[2], ip4_gw[3]);
netif_set_up(netif);
}
void usbh_bl616_run(struct usbh_bl616 *bl616_class)
{
struct netif *netif = &g_bl616_netif;
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, bl616_class->sta_mac, 6);
IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&g_netmask, 0, 0, 0, 0);
IP4_ADDR(&g_gateway, 0, 0, 0, 0);
netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_bl616_if_init, tcpip_input);
netif_set_down(netif);
netif_set_default(netif);
dhcp_handle = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_timer_start(dhcp_handle);
usb_osal_thread_create("usbh_bl616", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_bl616_rx_thread, NULL);
}
void usbh_bl616_stop(struct usbh_bl616 *bl616_class)
{
struct netif *netif = &g_bl616_netif;
(void)bl616_class;
netif_set_down(netif);
netif_remove(netif);
}
// #include "shell.h"
// CSH_CMD_EXPORT(wifi_sta_connect, );
// CSH_CMD_EXPORT(wifi_scan, );
#endif

View File

@@ -17,8 +17,11 @@
#endif
#endif
#if defined(ARCH_ARM_CORTEX_M7) || \
defined(SOC_HPM6000) || defined(SOC_HPM6E00) || defined(SOC_HPM6P00) || \
#if defined(ARCH_ARM_CORTEX_M7) || \
defined(ARCH_ARM_CORTEX_A) || \
defined(ARCH_RISCV64) || \
defined(SOC_HPM6200) || defined(SOC_HPM6300) || defined(SOC_HPM6700) || defined(SOC_HPM6800) || \
defined(SOC_HPM6E00) || defined(SOC_HPM6P00) || \
defined(BSP_USING_BL61X) || defined(BSP_USING_BL808)
#ifndef RT_USING_CACHE
#error RT_USING_CACHE must be enabled in this chip
@@ -27,6 +30,6 @@
#ifdef RT_USING_CACHE
#ifndef CONFIG_USB_DCACHE_ENABLE
#warning CONFIG_USB_DCACHE_ENABLE must be enabled if you do not config nocache ram
#error CONFIG_USB_DCACHE_ENABLE must be enabled if you do not config nocache ram
#endif
#endif

View File

@@ -76,9 +76,8 @@ static rt_err_t usbd_serial_open(struct rt_device *dev, rt_uint16_t oflag)
serial = (struct usbd_serial *)dev;
if (!usb_device_is_configured(serial->busid)) {
USB_LOG_ERR("USB device is not configured\n");
return -RT_EPERM;
while(!usb_device_is_configured(serial->busid)) {
rt_thread_mdelay(10);
}
usbd_ep_start_read(serial->busid, serial->out_ep,
@@ -123,9 +122,8 @@ static rt_ssize_t usbd_serial_write(struct rt_device *dev,
}
align_buf = (rt_uint8_t *)buffer;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
align_buf = rt_malloc_align(USB_ALIGN_UP(size, CONFIG_USB_ALIGN_SIZE), CONFIG_USB_ALIGN_SIZE);
if (!align_buf) {
USB_LOG_ERR("serial get align buf failed\n");
return 0;
@@ -133,7 +131,7 @@ static rt_ssize_t usbd_serial_write(struct rt_device *dev,
usb_memcpy(align_buf, buffer, size);
}
#endif
usb_osal_sem_reset(serial->tx_done);
usbd_ep_start_write(serial->busid, serial->in_ep, align_buf, size);
ret = usb_osal_sem_take(serial->tx_done, 3000);
@@ -144,11 +142,9 @@ static rt_ssize_t usbd_serial_write(struct rt_device *dev,
ret = size;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
rt_free_align(align_buf);
}
#endif
return ret;
}

View File

@@ -38,7 +38,7 @@ static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
rt_uint8_t *align_buf;
align_buf = (rt_uint8_t *)buffer;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE);
if (!align_buf) {
@@ -47,18 +47,18 @@ static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
}
} else {
}
#endif
ret = usbh_msc_scsi_read10(msc_class, pos, (uint8_t *)align_buf, size);
if (ret < 0) {
rt_kprintf("usb mass_storage read failed\n");
return 0;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
usb_memcpy(buffer, align_buf, size * msc_class->blocksize);
rt_free_align(align_buf);
}
#endif
return size;
}
@@ -70,7 +70,7 @@ static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buff
rt_uint8_t *align_buf;
align_buf = (rt_uint8_t *)buffer;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE);
if (!align_buf) {
@@ -80,17 +80,16 @@ static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buff
usb_memcpy(align_buf, buffer, size * msc_class->blocksize);
}
#endif
ret = usbh_msc_scsi_write10(msc_class, pos, (uint8_t *)align_buf, size);
if (ret < 0) {
rt_kprintf("usb mass_storage write failed\n");
return 0;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
rt_free_align(align_buf);
}
#endif
return size;
}

View File

@@ -25,7 +25,7 @@
#endif
#ifndef LWIP_NO_RX_THREAD
#error must enable LWIP_NO_RX_THREAD, we do not use rtthread eth rx thread
#warning suggest you to enable LWIP_NO_RX_THREAD, we do not use rtthread eth rx thread
#endif
#ifndef LWIP_NO_TX_THREAD
@@ -33,7 +33,7 @@
#endif
#if LWIP_TCPIP_CORE_LOCKING_INPUT != 1
#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread
#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1 for better performance, usb handles eth input with own thread
#endif
#if LWIP_TCPIP_CORE_LOCKING != 1

View File

@@ -193,9 +193,9 @@ static rt_ssize_t usbh_serial_write(struct rt_device *dev,
serial = (struct usbh_serial *)dev;
align_buf = (rt_uint8_t *)buffer;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
align_buf = rt_malloc_align(USB_ALIGN_UP(size, CONFIG_USB_ALIGN_SIZE), CONFIG_USB_ALIGN_SIZE);
if (!align_buf) {
USB_LOG_ERR("serial get align buf failed\n");
return 0;
@@ -203,7 +203,6 @@ static rt_ssize_t usbh_serial_write(struct rt_device *dev,
usb_memcpy(align_buf, buffer, size);
}
#endif
switch (serial->type) {
#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
@@ -211,10 +210,7 @@ static rt_ssize_t usbh_serial_write(struct rt_device *dev,
ret = usbh_cdc_acm_bulk_out_transfer((struct usbh_cdc_acm *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
if (ret < 0) {
USB_LOG_ERR("usbh_cdc_acm_bulk_out_transfer failed: %d\n", ret);
#ifdef CONFIG_USB_DCACHE_ENABLE
rt_free_align(align_buf);
#endif
return 0;
ret = 0;
}
break;
#endif
@@ -223,10 +219,7 @@ static rt_ssize_t usbh_serial_write(struct rt_device *dev,
ret = usbh_ftdi_bulk_out_transfer((struct usbh_ftdi *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
if (ret < 0) {
USB_LOG_ERR("usbh_ftdi_bulk_out_transfer failed: %d\n", ret);
#ifdef CONFIG_USB_DCACHE_ENABLE
rt_free_align(align_buf);
#endif
return 0;
ret = 0;
}
break;
#endif
@@ -235,10 +228,7 @@ static rt_ssize_t usbh_serial_write(struct rt_device *dev,
ret = usbh_ch34x_bulk_out_transfer((struct usbh_ch34x *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
if (ret < 0) {
USB_LOG_ERR("usbh_ch34x_bulk_out_transfer failed: %d\n", ret);
#ifdef CONFIG_USB_DCACHE_ENABLE
rt_free_align(align_buf);
#endif
return 0;
ret = 0;
}
break;
#endif
@@ -247,10 +237,7 @@ static rt_ssize_t usbh_serial_write(struct rt_device *dev,
ret = usbh_pl2303_bulk_out_transfer((struct usbh_pl2303 *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
if (ret < 0) {
USB_LOG_ERR("usbh_pl2303_bulk_out_transfer failed: %d\n", ret);
#ifdef CONFIG_USB_DCACHE_ENABLE
rt_free_align(align_buf);
#endif
return 0;
ret = 0;
}
break;
#endif
@@ -258,11 +245,9 @@ static rt_ssize_t usbh_serial_write(struct rt_device *dev,
break;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
rt_free_align(align_buf);
}
#endif
return ret;
}

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