Compare commits
111 Commits
v1.5.1
...
v1.5.3-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c746f57ddc | ||
|
|
3882560646 | ||
|
|
9cf680148e | ||
|
|
e25c12f6a8 | ||
|
|
f09198704b | ||
|
|
af519ac42c | ||
|
|
c34cbc5bfb | ||
|
|
38dff565cf | ||
|
|
6067343775 | ||
|
|
6c34938883 | ||
|
|
7cd4ff71d7 | ||
|
|
999ddb1a9d | ||
|
|
01b22bb138 | ||
|
|
e0dc9c9890 | ||
|
|
6105d7a1d6 | ||
|
|
757187e967 | ||
|
|
a33396fa93 | ||
|
|
ab8efcb07d | ||
|
|
5c9550d00e | ||
|
|
c8a713a49a | ||
|
|
87c49f9359 | ||
|
|
6e8a63fd77 | ||
|
|
71a966bbd5 | ||
|
|
32cf0e0b3c | ||
|
|
88b1158b4f | ||
|
|
38a4c5e375 | ||
|
|
b758fa814a | ||
|
|
9730f63b2c | ||
|
|
0365aa0d63 | ||
|
|
649ad6686b | ||
|
|
868dbee668 | ||
|
|
84b1d3feeb | ||
|
|
1045f877c8 | ||
|
|
12694eed49 | ||
|
|
ed344579ff | ||
|
|
c3b01eed25 | ||
|
|
f087e0777a | ||
|
|
82487c80aa | ||
|
|
86e9422e06 | ||
|
|
6c239e175f | ||
|
|
1b973b5cc5 | ||
|
|
102af3be37 | ||
|
|
347df77372 | ||
|
|
778465654b | ||
|
|
e2791c7d04 | ||
|
|
7902c1c352 | ||
|
|
1768079a89 | ||
|
|
c77557510e | ||
|
|
4d6b12c704 | ||
|
|
5d2a7ca6bc | ||
|
|
3ab47e0295 | ||
|
|
2081360f2c | ||
|
|
8cf12c1958 | ||
|
|
c0f544dafe | ||
|
|
599b11ef1a | ||
|
|
7037fd0e8d | ||
|
|
3905eff2f4 | ||
|
|
20ceaced92 | ||
|
|
9ddcbf58ca | ||
|
|
6e9e769e10 | ||
|
|
65288c9d5b | ||
|
|
4ab097d9dc | ||
|
|
f994422c41 | ||
|
|
5ae04f1273 | ||
|
|
e574ea8ae3 | ||
|
|
f949e16564 | ||
|
|
1bec84471e | ||
|
|
1f065cec44 | ||
|
|
3b1853ceb5 | ||
|
|
72d19ec8cc | ||
|
|
90de3354b5 | ||
|
|
3784ddc389 | ||
|
|
81d8f22e05 | ||
|
|
3b04facd09 | ||
|
|
8dd3106e62 | ||
|
|
9e4122f2a0 | ||
|
|
083ec57384 | ||
|
|
ccd4354960 | ||
|
|
60ac6fe3ad | ||
|
|
0986e8b5ec | ||
|
|
ae2a24642b | ||
|
|
1a68d94c32 | ||
|
|
c102f4adfa | ||
|
|
d589b9417d | ||
|
|
7b39de9630 | ||
|
|
6702ab9225 | ||
|
|
ecb98f399d | ||
|
|
a9ec951c93 | ||
|
|
9de28f9342 | ||
|
|
dc7e53d79f | ||
|
|
d3a5aae7af | ||
|
|
7153fb9756 | ||
|
|
0e31b40407 | ||
|
|
fa5a9fbcaa | ||
|
|
68b28a43f3 | ||
|
|
ddda03c4cb | ||
|
|
96ab19e398 | ||
|
|
2783793b17 | ||
|
|
e499871a59 | ||
|
|
7c38af1b04 | ||
|
|
cc3e91e8d7 | ||
|
|
a95e06a951 | ||
|
|
502c88084c | ||
|
|
a9f0374fa7 | ||
|
|
56c864b008 | ||
|
|
80f0f97efa | ||
|
|
4fdbe4ed26 | ||
|
|
1e8e440721 | ||
|
|
605a967282 | ||
|
|
7a357a10da | ||
|
|
d58037e3d4 |
83
.github/workflows/build_tests.yml
vendored
Normal 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
@@ -1,4 +1,5 @@
|
||||
.vscode
|
||||
build
|
||||
**/Drivers/**
|
||||
**/MDK-ARM/DebugConfig/**
|
||||
**/MDK-ARM/RTE/**
|
||||
|
||||
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "third_party/zephyr_bluetooth-2.7.5/zephyr_bluetooth"]
|
||||
path = third_party/zephyr_bluetooth-2.7.5/zephyr_bluetooth
|
||||
url = https://github.com/sakumisu/zephyr_bluetooth.git
|
||||
@@ -64,6 +64,14 @@ elseif(ESP_PLATFORM)
|
||||
|
||||
idf_component_get_property(freertos_include freertos ORIG_INCLUDE_PATH)
|
||||
|
||||
if(CONFIG_CHERRYUSB_HOST_MSC)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_fatfs.c)
|
||||
endif()
|
||||
|
||||
set(priv_req esp_mm esp_netif esp_timer fatfs)
|
||||
if(${IDF_VERSION_MAJOR} LESS 6)
|
||||
list(APPEND priv_req usb)
|
||||
endif()
|
||||
idf_component_register(
|
||||
SRCS
|
||||
${cherryusb_srcs}
|
||||
@@ -71,7 +79,7 @@ elseif(ESP_PLATFORM)
|
||||
${cherryusb_incs}
|
||||
${freertos_include}
|
||||
PRIV_REQUIRES
|
||||
usb esp_mm esp_netif
|
||||
${priv_req}
|
||||
LDFRAGMENTS
|
||||
${ldfragments}
|
||||
)
|
||||
|
||||
2
Kconfig
@@ -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
|
||||
@@ -338,6 +339,7 @@ if CHERRYUSB
|
||||
config CHERRYUSB_HOST_BLUETOOTH
|
||||
bool
|
||||
prompt "Enable usb bluetooth driver"
|
||||
depends on !IDF_CMAKE
|
||||
default n
|
||||
|
||||
config CHERRYUSB_HOST_ASIX
|
||||
|
||||
@@ -465,12 +465,16 @@ if PKG_USING_CHERRYUSB
|
||||
|
||||
choice
|
||||
prompt "Version"
|
||||
default PKG_USING_CHERRYUSB_V010500
|
||||
default PKG_USING_CHERRYUSB_V010503
|
||||
help
|
||||
Select the package version
|
||||
|
||||
config PKG_USING_CHERRYUSB_LATEST_VERSION
|
||||
bool "latest"
|
||||
config PKG_USING_CHERRYUSB_V010502
|
||||
bool "v1.5.3"
|
||||
config PKG_USING_CHERRYUSB_V010502
|
||||
bool "v1.5.2"
|
||||
config PKG_USING_CHERRYUSB_V010501
|
||||
bool "v1.5.1"
|
||||
config PKG_USING_CHERRYUSB_V010500
|
||||
@@ -488,6 +492,8 @@ if PKG_USING_CHERRYUSB
|
||||
config PKG_CHERRYUSB_VER
|
||||
string
|
||||
default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION
|
||||
default "v1.5.3" if PKG_USING_CHERRYUSB_V010503
|
||||
default "v1.5.2" if PKG_USING_CHERRYUSB_V010502
|
||||
default "v1.5.1" if PKG_USING_CHERRYUSB_V010501
|
||||
default "v1.5.0" if PKG_USING_CHERRYUSB_V010500
|
||||
default "v1.4.3" if PKG_USING_CHERRYUSB_V010403
|
||||
|
||||
44
README.md
@@ -40,6 +40,8 @@ Taking into account USB performance issues and trying to achieve the theoretical
|
||||
- Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
|
||||
- Packetization is handled in interrupt
|
||||
|
||||
Performance show:https://cherryusb.cherry-embedded.org/show/
|
||||
|
||||
## Directory Structure
|
||||
|
||||
| Directory | Description |
|
||||
@@ -103,7 +105,7 @@ CherryUSB Host Stack has the following functions:
|
||||
- Support blocking transfers and asynchronous transfers
|
||||
- Support Composite Device
|
||||
- Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2/ehci/xhci/rp2040)
|
||||
- Support Communication Device Class (CDC_ACM, CDC_ECM)
|
||||
- Support Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM)
|
||||
- Support Human Interface Device (HID)
|
||||
- Support Mass Storage Class (MSC)
|
||||
- Support USB Video CLASS (UVC1.0, UVC1.5)
|
||||
@@ -141,7 +143,7 @@ Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affe
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
```
|
||||
|
||||
@@ -187,24 +189,25 @@ TODO
|
||||
|
||||
## Demo Repo
|
||||
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note |
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|
||||
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update |
|
||||
|
||||
## Package Support
|
||||
|
||||
@@ -226,5 +229,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
|
||||
|
||||
Thanks to the following companies for their support (in no particular order):
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" /> <img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/sifli.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
|
||||
44
README_zh.md
@@ -40,6 +40,8 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(
|
||||
- 长度无限制,方便对接硬件 DMA 并且发挥 DMA 的优势
|
||||
- 分包过程在中断中执行
|
||||
|
||||
性能展示:https://cherryusb.cherry-embedded.org/show/
|
||||
|
||||
## 目录结构
|
||||
|
||||
| 目录名 | 描述 |
|
||||
@@ -103,7 +105,7 @@ CherryUSB Host 协议栈当前实现以下功能:
|
||||
- 支持阻塞式传输和异步传输
|
||||
- 支持复合设备
|
||||
- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,仅支持 dwc2/ehci/xhci/rp2040)
|
||||
- 支持 Communication Device Class (CDC_ACM, CDC_ECM)
|
||||
- 支持 Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM)
|
||||
- 支持 Human Interface Device (HID)
|
||||
- 支持 Mass Storage Class (MSC)
|
||||
- Support USB Video CLASS (UVC1.0、UVC1.5)
|
||||
@@ -141,7 +143,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2,关闭 log)
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
```
|
||||
|
||||
@@ -187,24 +189,25 @@ TODO
|
||||
|
||||
## 示例仓库
|
||||
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note |
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official |
|
||||
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community |
|
||||
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|
||||
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|
||||
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update |
|
||||
|
||||
## 软件包支持
|
||||
|
||||
@@ -228,5 +231,4 @@ CherryUSB 微信群:与我联系后邀请加入
|
||||
|
||||
感谢以下企业支持(顺序不分先后):
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" /> <img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/sifli.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
|
||||
@@ -90,6 +90,7 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_BL']):
|
||||
src += Glob('port/bouffalolab/usb_dc_bl.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_HPM']):
|
||||
path += [cwd + '/port/hpmicro']
|
||||
src += Glob('port/hpmicro/usb_dc_hpm.c')
|
||||
src += Glob('port/hpmicro/usb_glue_hpm.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_AIC']):
|
||||
@@ -184,6 +185,7 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/ehci/usb_glue_bouffalo.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_EHCI_HPM']):
|
||||
path += [cwd + '/port/hpmicro']
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/hpmicro/usb_hc_hpm.c')
|
||||
src += Glob('port/hpmicro/usb_glue_hpm.c')
|
||||
|
||||
2
VERSION
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 5
|
||||
PATCHLEVEL = 1
|
||||
PATCHLEVEL = 3
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
||||
@@ -340,6 +340,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)
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
@@ -250,22 +250,11 @@
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
#ifndef CONFIG_USBDEV_MAX_BUS
|
||||
#define CONFIG_USBDEV_MAX_BUS 1 // for now, bus num must be 1 except hpm ip
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 8
|
||||
#define CONFIG_USBDEV_MAX_BUS 1
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBDEV_SOF_ENABLE
|
||||
|
||||
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
|
||||
* the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
|
||||
*
|
||||
* in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them).
|
||||
*/
|
||||
// #define CONFIG_USB_HS
|
||||
|
||||
/* ---------------- FSDEV Configuration ---------------- */
|
||||
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
|
||||
|
||||
@@ -276,6 +265,7 @@
|
||||
// #define CONFIG_USB_DWC2_DMA_ENABLE
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
#define CONFIG_USB_MUSB_EP_NUM 8
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
@@ -283,15 +273,11 @@
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
#endif
|
||||
|
||||
/* ---------------- EHCI Configuration ---------------- */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_EHCI_QH_NUM 10
|
||||
#define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USB_EHCI_QH_NUM * 3)
|
||||
#define CONFIG_USB_EHCI_ITD_NUM 4
|
||||
// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
|
||||
@@ -302,15 +288,27 @@
|
||||
|
||||
/* ---------------- OHCI Configuration ---------------- */
|
||||
#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0)
|
||||
#define CONFIG_USB_OHCI_ED_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_OHCI_ED_NUM 10
|
||||
#define CONFIG_USB_OHCI_TD_NUM 3
|
||||
// #define CONFIG_USB_OHCI_DESC_DCACHE_ENABLE
|
||||
|
||||
/* ---------------- XHCI Configuration ---------------- */
|
||||
#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
// nothing to define
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
#define CONFIG_USB_MUSB_PIPE_NUM 8
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
// #define CONFIG_USB_MUSB_WITHOUT_MULTIPOINT
|
||||
|
||||
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
|
||||
* the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
|
||||
*
|
||||
* in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them).
|
||||
*/
|
||||
// #define CONFIG_USB_HS
|
||||
|
||||
#ifndef usb_phyaddr2ramaddr
|
||||
#define usb_phyaddr2ramaddr(addr) (addr)
|
||||
@@ -320,4 +318,7 @@
|
||||
#define usb_ramaddr2phyaddr(addr) (addr)
|
||||
#endif
|
||||
|
||||
/* Enable OTG support, only support hpmicro now */
|
||||
// #define CONFIG_USB_OTG_ENABLE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -121,7 +121,7 @@ get_mac:
|
||||
}
|
||||
|
||||
memset(mac_buffer, 0, 12);
|
||||
ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer);
|
||||
ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer, 12);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ get_mac:
|
||||
}
|
||||
|
||||
memset(mac_buffer, 0, 12);
|
||||
ret = usbh_get_string_desc(cdc_ncm_class->hport, mac_str_idx, (uint8_t *)mac_buffer);
|
||||
ret = usbh_get_string_desc(cdc_ncm_class->hport, mac_str_idx, (uint8_t *)mac_buffer, 12);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,15 +179,15 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length
|
||||
USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
|
||||
return -2;
|
||||
} else {
|
||||
USB_LOG_RAW("Hub Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_RAW("PortPwrCtrlMask: 0x%02x \r\n", desc->PortPwrCtrlMask);
|
||||
USB_LOG_DBG("Hub Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_DBG("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_DBG("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_DBG("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_DBG("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_DBG("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_DBG("PortPwrCtrlMask: 0x%02x \r\n", desc->PortPwrCtrlMask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -203,14 +203,14 @@ static int parse_hub_ss_descriptor(struct usb_hub_ss_descriptor *desc, uint16_t
|
||||
USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
|
||||
return -2;
|
||||
} else {
|
||||
USB_LOG_RAW("SuperSpeed Hub Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_DBG("SuperSpeed Hub Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_DBG("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_DBG("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_DBG("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_DBG("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_DBG("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -373,6 +373,11 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5);
|
||||
}
|
||||
|
||||
if (hub->nports > CONFIG_USBHOST_MAX_EHPORTS) {
|
||||
USB_LOG_ERR("Hub nports %u overflow\r\n", hub->nports);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hub->child[port].port = port + 1;
|
||||
hub->child[port].parent = hub;
|
||||
@@ -403,7 +408,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
|
||||
USB_LOG_INFO("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange);
|
||||
USB_LOG_DBG("port %u, status:0x%03x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -497,7 +502,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
USB_LOG_DBG("port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
/* First, clear all change bits */
|
||||
mask = 1;
|
||||
@@ -532,7 +537,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("Port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
USB_LOG_DBG("Port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
if (!(portchange & HUB_PORT_STATUS_C_CONNECTION) &&
|
||||
((portstatus & HUB_PORT_STATUS_CONNECTION) == connection)) {
|
||||
@@ -562,7 +567,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
if (portstatus & HUB_PORT_STATUS_CONNECTION) {
|
||||
ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_RESET);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to reset port %u,errorcode:%d\r\n", port, ret);
|
||||
USB_LOG_ERR("Failed to reset port %u, errorcode: %d\r\n", port + 1, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -576,11 +581,15 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("Port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
if (!(portstatus & HUB_PORT_STATUS_RESET) && (portstatus & HUB_PORT_STATUS_ENABLE)) {
|
||||
if (portchange & HUB_PORT_STATUS_C_RESET) {
|
||||
ret = usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_RESET);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to clear port %u reset change, errorcode: %d\r\n", port, ret);
|
||||
USB_LOG_ERR("Failed to clear port %u reset change, errorcode: %d\r\n", port + 1, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -704,7 +713,6 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
struct usbh_hub *hub;
|
||||
size_t flags;
|
||||
|
||||
hub = &bus->hcd.roothub;
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
@@ -713,14 +721,10 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
|
||||
usbh_hubport_release(hport);
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
usb_hc_deinit(bus);
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
usb_osal_mq_delete(bus->hub_mq);
|
||||
usb_osal_thread_delete(bus->hub_thread);
|
||||
usb_osal_mq_delete(bus->hub_mq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usb_scsi.h"
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
#include "usb_osal.h"
|
||||
#endif
|
||||
|
||||
#undef USB_DBG_TAG
|
||||
#define USB_DBG_TAG "usbd_msc"
|
||||
#include "usb_log.h"
|
||||
|
||||
#define MSD_OUT_EP_IDX 0
|
||||
#define MSD_IN_EP_IDX 1
|
||||
@@ -516,19 +517,14 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
|
||||
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
|
||||
return false;
|
||||
}
|
||||
g_usbd_msc[busid].stage = MSC_DATA_IN;
|
||||
@@ -554,19 +550,14 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
|
||||
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
|
||||
return false;
|
||||
}
|
||||
g_usbd_msc[busid].stage = MSC_DATA_IN;
|
||||
@@ -594,14 +585,10 @@ static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -627,14 +614,10 @@ static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
|
||||
|
||||
data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -646,52 +629,6 @@ static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, g_usbd_msc[busid].block_buffer, data_len);
|
||||
return true;
|
||||
}
|
||||
/* do not use verify to reduce code size */
|
||||
#if 0
|
||||
static bool SCSI_verify10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/* Logical Block Address of First Block */
|
||||
uint32_t lba = 0;
|
||||
uint32_t blk_num = 0;
|
||||
|
||||
if ((g_usbd_msc[busid].cbw.CB[1] & 0x02U) == 0x00U) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((g_usbd_msc[busid].cbw.CB[1] & 0x02U) == 0x02U) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDFIELDINCBA);
|
||||
return false; /* Error, Verify Mode Not supported*/
|
||||
}
|
||||
|
||||
lba = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]);
|
||||
USB_LOG_DBG("lba: 0x%x\r\n", lba);
|
||||
|
||||
g_usbd_msc[busid].scsi_blk_addr = lba * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
|
||||
/* Number of Blocks to transfer */
|
||||
blk_num = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]);
|
||||
|
||||
USB_LOG_DBG("num (block) : 0x%x\r\n", blk_num);
|
||||
g_usbd_msc[busid].scsi_blk_len = blk_num * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
|
||||
|
||||
if ((lba + blk_num) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usbd_msc[busid].cbw.dDataLength != g_usbd_msc[busid].scsi_blk_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_usbd_msc[busid].stage = MSC_DATA_OUT;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool SCSI_processRead(uint8_t busid)
|
||||
{
|
||||
@@ -722,6 +659,7 @@ static bool SCSI_processRead(uint8_t busid)
|
||||
static bool SCSI_processWrite(uint8_t busid, uint32_t nbytes)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
|
||||
USB_LOG_DBG("write lba:%d\r\n", g_usbd_msc[busid].start_sector);
|
||||
|
||||
if (usbd_msc_sector_write(busid, g_usbd_msc[busid].cbw.bLUN, g_usbd_msc[busid].start_sector, g_usbd_msc[busid].block_buffer, nbytes) != 0) {
|
||||
@@ -804,7 +742,6 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
|
||||
ret = SCSI_write12(busid, NULL, 0);
|
||||
break;
|
||||
case SCSI_CMD_VERIFY10:
|
||||
//ret = SCSI_verify10(NULL, 0);
|
||||
ret = false;
|
||||
break;
|
||||
case SCSI_CMD_SYNCHCACHE10:
|
||||
@@ -812,7 +749,6 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
|
||||
break;
|
||||
default:
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
USB_LOG_WRN("unsupported cmd:0x%02x\r\n", g_usbd_msc[busid].cbw.CB[0]);
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
@@ -820,7 +756,7 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
|
||||
if (ret) {
|
||||
if (g_usbd_msc[busid].stage == MSC_READ_CBW) {
|
||||
if (len2send) {
|
||||
USB_LOG_DBG("Send info len:%d\r\n", len2send);
|
||||
USB_LOG_DBG("Send info len: %d\r\n", len2send);
|
||||
usbd_msc_send_info(busid, buf2send, len2send);
|
||||
} else {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_PASSED);
|
||||
@@ -837,7 +773,7 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
switch (g_usbd_msc[busid].stage) {
|
||||
case MSC_READ_CBW:
|
||||
if (SCSI_CBWDecode(busid, nbytes) == false) {
|
||||
USB_LOG_ERR("Command:0x%02x decode err\r\n", g_usbd_msc[busid].cbw.CB[0]);
|
||||
USB_LOG_ERR("Command: 0x%02x decode err\r\n", g_usbd_msc[busid].cbw.CB[0]);
|
||||
usbd_msc_bot_abort(busid);
|
||||
return;
|
||||
}
|
||||
@@ -921,7 +857,6 @@ static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
USB_LOG_DBG("event:%d\r\n", event);
|
||||
if (event == MSC_DATA_OUT) {
|
||||
if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
@@ -943,7 +878,6 @@ void usbd_msc_polling(uint8_t busid)
|
||||
|
||||
if (event != 0) {
|
||||
g_usbd_msc[busid].event = 0;
|
||||
USB_LOG_DBG("event:%d\r\n", event);
|
||||
if (event == MSC_DATA_OUT) {
|
||||
if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
|
||||
@@ -284,6 +284,7 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret == -USB_ERR_STALL) {
|
||||
USB_LOG_WRN("Device does not support multiple LUNs\r\n");
|
||||
g_msc_buf[msc_class->sdchar - 'a'][0] = 0;
|
||||
ret = 0;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ struct mtp_object {
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
/*Length of template descriptor: 23 bytes*/
|
||||
/*Length of template descriptor: 30 bytes*/
|
||||
#define MTP_DESCRIPTOR_LEN (9 + 7 + 7 + 7)
|
||||
|
||||
// clang-format off
|
||||
|
||||
10
class/vendor/net/usbh_rtl8152.c
vendored
@@ -1034,17 +1034,17 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si
|
||||
static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t byteen,
|
||||
uint16_t size, void *data, uint16_t type)
|
||||
{
|
||||
int ret;
|
||||
int ret = -USB_ERR_INVAL;
|
||||
uint16_t byteen_start, byteen_end, byen;
|
||||
uint16_t limit = 512;
|
||||
uint8_t *buf = data;
|
||||
|
||||
/* both size and indix must be 4 bytes align */
|
||||
if ((size & 3) || !size || (index & 3) || !buf)
|
||||
return -USB_ERR_INVAL;
|
||||
return ret;
|
||||
|
||||
if ((uint32_t)index + (uint32_t)size > 0xffff)
|
||||
return -USB_ERR_INVAL;
|
||||
return ret;
|
||||
|
||||
byteen_start = byteen & BYTE_EN_START_MASK;
|
||||
byteen_end = byteen & BYTE_EN_END_MASK;
|
||||
@@ -1121,7 +1121,7 @@ static inline int usb_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_
|
||||
|
||||
static uint32_t ocp_read_dword(struct usbh_rtl8152 *tp, uint16_t type, uint16_t index)
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t data = 0;
|
||||
|
||||
generic_ocp_read(tp, index, sizeof(data), &data, type);
|
||||
|
||||
@@ -2050,7 +2050,7 @@ static int usbh_rtl8152_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
|
||||
memset(mac_buffer, 0, 12);
|
||||
ret = usbh_get_string_desc(rtl8152_class->hport, 3, (uint8_t *)mac_buffer);
|
||||
ret = usbh_get_string_desc(rtl8152_class->hport, 3, (uint8_t *)mac_buffer, 12);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -68,7 +68,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
||||
|
||||
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)cmd);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("rndis_initialize_msg_t send error, ret: %d\r\n", ret);
|
||||
USB_LOG_ERR("init send error, ret: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -84,14 +84,14 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
||||
|
||||
ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("rndis_initialize_cmplt_t recv error, ret: %d\r\n", ret);
|
||||
USB_LOG_ERR("init recv error, ret: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rndis_class->max_transfer_pkts = resp->MaxPacketsPerTransfer;
|
||||
rndis_class->max_transfer_size = resp->MaxTransferSize;
|
||||
USB_LOG_INFO("MaxPacketsPerTransfer:%u\r\n", (unsigned int)resp->MaxPacketsPerTransfer);
|
||||
USB_LOG_INFO("MaxTransferSize:%u\r\n", (unsigned int)resp->MaxTransferSize);
|
||||
USB_LOG_INFO("MaxPacketsPerTransfer: %u\r\n", (unsigned int)resp->MaxPacketsPerTransfer);
|
||||
USB_LOG_INFO("MaxTransferSize: %u\r\n", (unsigned int)resp->MaxTransferSize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -312,14 +312,13 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
USB_LOG_INFO("rndis init success\r\n");
|
||||
|
||||
ret = usbh_rndis_query_msg_transfer(rndis_class, OID_GEN_SUPPORTED_LIST, 0, tmp_buffer, &data_len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
oid_num = (data_len / 4);
|
||||
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%u\r\n", (unsigned int)oid_num);
|
||||
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num: %u\r\n", (unsigned int)oid_num);
|
||||
|
||||
oid_support_list = (uint32_t *)tmp_buffer;
|
||||
|
||||
@@ -380,10 +379,8 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Ignore rndis query iod:%08x\r\n", (unsigned int)oid);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
USB_LOG_INFO("rndis query iod:%08x success\r\n", (unsigned int)oid);
|
||||
}
|
||||
|
||||
uint32_t packet_filter = 0x0f;
|
||||
@@ -391,14 +388,12 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
USB_LOG_INFO("rndis set OID_GEN_CURRENT_PACKET_FILTER success\r\n");
|
||||
|
||||
uint8_t multicast_list[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x01 };
|
||||
ret = usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
USB_LOG_INFO("rndis set OID_802_3_MULTICAST_LIST success\r\n");
|
||||
|
||||
USB_LOG_INFO("rndis MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
|
||||
rndis_class->mac[0],
|
||||
@@ -487,7 +482,7 @@ find_class:
|
||||
usbh_bulk_urb_fill(&g_rndis_class.bulkin_urb, g_rndis_class.hport, g_rndis_class.bulkin, &g_rndis_rx_buffer[g_rndis_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL);
|
||||
ret = usbh_submit_urb(&g_rndis_class.bulkin_urb);
|
||||
if (ret < 0) {
|
||||
goto find_class;
|
||||
break;
|
||||
}
|
||||
|
||||
g_rndis_rx_length += g_rndis_class.bulkin_urb.actual_length;
|
||||
@@ -607,3 +602,12 @@ CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = {
|
||||
.id_table = NULL,
|
||||
.class_driver = &rndis_class_driver
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info rndis_cdcacm_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
|
||||
.bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = 0xff,
|
||||
.id_table = NULL,
|
||||
.class_driver = &rndis_class_driver
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define USB_ERR_RANGE 7
|
||||
#define USB_ERR_STALL 8
|
||||
#define USB_ERR_BABBLE 9
|
||||
#define USB_ERR_NAK 10
|
||||
#define USB_ERR_NAK 10 /* only for dwc2 buffer dma mode */
|
||||
#define USB_ERR_DT 11
|
||||
#define USB_ERR_IO 12
|
||||
#define USB_ERR_SHUTDOWN 13
|
||||
|
||||
@@ -39,7 +39,7 @@ struct usbh_urb {
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
uint8_t data_toggle;
|
||||
uint8_t interval;
|
||||
uint32_t interval;
|
||||
struct usb_setup_packet *setup;
|
||||
uint8_t *transfer_buffer;
|
||||
uint32_t transfer_buffer_length;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__) || defined(__ICCRISCV__)
|
||||
#if (__VER__ >= 8000000)
|
||||
#define __ICCARM_V8 1
|
||||
#else
|
||||
#define __ICCARM_V8 0
|
||||
#endif
|
||||
|
||||
#ifndef __USED
|
||||
#if defined(__ICCARM_V8) || defined(__ICCRISCV__)
|
||||
#define __USED __attribute__((used))
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#undef CHERRYUSB_VERSION_STR
|
||||
#endif
|
||||
|
||||
#define CHERRYUSB_VERSION 0x010501
|
||||
#define CHERRYUSB_VERSION_STR "v1.5.1"
|
||||
#define CHERRYUSB_VERSION 0x010503
|
||||
#define CHERRYUSB_VERSION_STR "v1.5.3"
|
||||
|
||||
#endif
|
||||
@@ -950,7 +950,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -964,7 +963,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = g_usbd_core[busid].descriptors->msosv2_descriptor->compat_id_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -980,7 +978,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1008,7 +1005,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1021,7 +1017,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = g_usbd_core[busid].msosv2_desc->compat_id_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1037,7 +1032,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1151,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;
|
||||
@@ -1542,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;
|
||||
@@ -1575,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;
|
||||
|
||||
662
core/usbh_core.c
@@ -33,29 +33,27 @@ struct usbh_bus g_usbhost_bus[CONFIG_USBHOST_MAX_BUS];
|
||||
|
||||
static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
|
||||
{
|
||||
uint8_t startaddr = devgen->next;
|
||||
uint8_t devaddr;
|
||||
uint8_t lastaddr = devgen->last;
|
||||
uint8_t devaddr = lastaddr;
|
||||
int index;
|
||||
int bitno;
|
||||
|
||||
for (;;) {
|
||||
devaddr = devgen->next;
|
||||
if (devgen->next >= 0x7f) {
|
||||
devgen->next = 2;
|
||||
} else {
|
||||
devgen->next++;
|
||||
devaddr++;
|
||||
if (devaddr > 0x7f) {
|
||||
devaddr = 2;
|
||||
}
|
||||
if (devaddr == lastaddr) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
index = devaddr >> 5;
|
||||
bitno = devaddr & 0x1f;
|
||||
if ((devgen->alloctab[index] & (1 << bitno)) == 0) {
|
||||
devgen->alloctab[index] |= (1 << bitno);
|
||||
if ((devgen->alloctab[index] & (1ul << bitno)) == 0) {
|
||||
devgen->alloctab[index] |= (1ul << bitno);
|
||||
devgen->last = devaddr;
|
||||
return (int)devaddr;
|
||||
}
|
||||
|
||||
if (startaddr == devaddr) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,15 +67,11 @@ static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
|
||||
bitno = devaddr & USB_DEV_ADDR_MARK_MASK;
|
||||
|
||||
/* Free the address */
|
||||
if ((devgen->alloctab[index] |= (1 << bitno)) != 0) {
|
||||
devgen->alloctab[index] &= ~(1 << bitno);
|
||||
if ((devgen->alloctab[index] & (1ul << bitno)) != 0) {
|
||||
devgen->alloctab[index] &= ~(1ul << bitno);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (devaddr < devgen->next) {
|
||||
devgen->next = devaddr;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -91,7 +85,7 @@ static int usbh_free_devaddr(struct usbh_hubport *hport)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol,
|
||||
static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, uint8_t intf,
|
||||
uint16_t vid, uint16_t pid)
|
||||
{
|
||||
struct usbh_class_info *index = NULL;
|
||||
@@ -106,6 +100,9 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) {
|
||||
continue;
|
||||
}
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_NUM) && !(index->bInterfaceNumber == intf)) {
|
||||
continue;
|
||||
}
|
||||
if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) {
|
||||
/* scan id table */
|
||||
uint32_t i;
|
||||
@@ -228,12 +225,21 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
|
||||
cur_ep_num = intf_desc->bNumEndpoints;
|
||||
cur_ep = 0;
|
||||
|
||||
USB_ASSERT_MSG(cur_iface < CONFIG_USBHOST_MAX_INTERFACES,
|
||||
"Interface num %d overflow", cur_iface);
|
||||
USB_ASSERT_MSG(cur_alt_setting < CONFIG_USBHOST_MAX_INTF_ALTSETTINGS,
|
||||
"Interface altsetting num %d overflow", cur_alt_setting);
|
||||
USB_ASSERT_MSG(cur_ep_num <= CONFIG_USBHOST_MAX_ENDPOINTS,
|
||||
"Endpoint num %d overflow", cur_ep_num);
|
||||
if (cur_iface >= CONFIG_USBHOST_MAX_INTERFACES) {
|
||||
USB_LOG_ERR("Interface num %d overflow\r\n", cur_iface);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
if (cur_ep_num >= CONFIG_USBHOST_MAX_ENDPOINTS) {
|
||||
USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep_num);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
if (cur_alt_setting >= CONFIG_USBHOST_MAX_INTF_ALTSETTINGS) {
|
||||
USB_LOG_ERR("Interface altsetting num %d overflow\r\n", cur_alt_setting);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
#if 0
|
||||
USB_LOG_DBG("Interface Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", intf_desc->bLength);
|
||||
@@ -266,60 +272,6 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usbh_print_hubport_info(struct usbh_hubport *hport)
|
||||
{
|
||||
USB_LOG_RAW("Device Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType);
|
||||
USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB);
|
||||
USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass);
|
||||
USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass);
|
||||
USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol);
|
||||
USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0);
|
||||
USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor);
|
||||
USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct);
|
||||
USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice);
|
||||
USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer);
|
||||
USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct);
|
||||
USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber);
|
||||
USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
|
||||
|
||||
USB_LOG_RAW("Config Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType);
|
||||
USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength);
|
||||
USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces);
|
||||
USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
|
||||
USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration);
|
||||
USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes);
|
||||
USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower);
|
||||
|
||||
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
|
||||
for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
|
||||
USB_LOG_RAW("\tInterface Descriptor:\r\n");
|
||||
USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
|
||||
USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
|
||||
USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
|
||||
USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
|
||||
USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
|
||||
USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
|
||||
USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
|
||||
USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
|
||||
USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
|
||||
|
||||
for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
|
||||
USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n");
|
||||
USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
|
||||
USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
|
||||
USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
|
||||
USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
|
||||
USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
|
||||
USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_print_setup(struct usb_setup_packet *setup)
|
||||
{
|
||||
(void)setup;
|
||||
@@ -389,7 +341,11 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
|
||||
ret = parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse device descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Extract the correct max packetsize from the device descriptor */
|
||||
dev_desc = (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid];
|
||||
@@ -427,7 +383,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
}
|
||||
|
||||
/* Wait device set address completely */
|
||||
usb_osal_msleep(2);
|
||||
usb_osal_msleep(10);
|
||||
|
||||
/*Reconfigure EP0 with the correct address */
|
||||
hport->dev_addr = dev_addr;
|
||||
@@ -469,7 +425,11 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_CONFIG_DESC);
|
||||
ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_CONFIG_DESC);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse config descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Read the full size of the configuration data */
|
||||
uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->wTotalLength;
|
||||
@@ -494,9 +454,10 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
|
||||
ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], wTotalLength);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse config fail\r\n");
|
||||
USB_LOG_ERR("Parse config descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumInterfaces);
|
||||
hport->raw_config_desc = usb_osal_malloc(wTotalLength + 1);
|
||||
if (hport->raw_config_desc == NULL) {
|
||||
@@ -512,35 +473,47 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
#ifdef CONFIG_USBHOST_GET_STRING_DESC
|
||||
uint8_t string_buffer[128];
|
||||
|
||||
/* Get Manufacturer string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
if (hport->device_desc.iManufacturer > 0) {
|
||||
/* Get Manufacturer string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support Manufacturer string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
|
||||
if (hport->device_desc.iProduct > 0) {
|
||||
/* Get Product string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Product string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get Product string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
USB_LOG_INFO("Product: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support Product string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Product: %s\r\n", string_buffer);
|
||||
if (hport->device_desc.iSerialNumber > 0) {
|
||||
/* Get SerialNumber string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get SerialNumber string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get SerialNumber string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support SerialNumber string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
|
||||
#endif
|
||||
/* Select device configuration 1 */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
@@ -573,18 +546,25 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
|
||||
intf_desc = &hport->config.intf[i].altsetting[0].intf_desc;
|
||||
|
||||
struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol, hport->device_desc.idVendor, hport->device_desc.idProduct);
|
||||
USB_ASSERT_MSG(intf_desc->bInterfaceNumber == i, "Interface number mismatch, do not support non-standard device\r\n");
|
||||
|
||||
struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass,
|
||||
intf_desc->bInterfaceSubClass,
|
||||
intf_desc->bInterfaceProtocol,
|
||||
intf_desc->bInterfaceNumber,
|
||||
hport->device_desc.idVendor,
|
||||
hport->device_desc.idProduct);
|
||||
|
||||
if (class_driver == NULL) {
|
||||
USB_LOG_ERR("do not support Class:0x%02x,Subclass:0x%02x,Protocl:0x%02x\r\n",
|
||||
USB_LOG_ERR("Do not support Class:0x%02x, Subclass:0x%02x, Protocl:0x%02x on interface %u\r\n",
|
||||
intf_desc->bInterfaceClass,
|
||||
intf_desc->bInterfaceSubClass,
|
||||
intf_desc->bInterfaceProtocol);
|
||||
|
||||
intf_desc->bInterfaceProtocol,
|
||||
i);
|
||||
continue;
|
||||
}
|
||||
hport->config.intf[i].class_driver = class_driver;
|
||||
USB_LOG_INFO("Loading %s class driver\r\n", class_driver->driver_name);
|
||||
USB_LOG_INFO("Loading %s class driver on interface %u\r\n", class_driver->driver_name, i);
|
||||
ret = CLASS_CONNECT(hport, i);
|
||||
}
|
||||
|
||||
@@ -600,6 +580,7 @@ void usbh_hubport_release(struct usbh_hubport *hport)
|
||||
{
|
||||
if (hport->connected) {
|
||||
hport->connected = false;
|
||||
usbh_kill_urb(&hport->ep0_urb);
|
||||
usbh_free_devaddr(hport);
|
||||
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
|
||||
if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->disconnect) {
|
||||
@@ -607,7 +588,6 @@ void usbh_hubport_release(struct usbh_hubport *hport)
|
||||
}
|
||||
}
|
||||
hport->config.config_desc.bNumInterfaces = 0;
|
||||
usbh_kill_urb(&hport->ep0_urb);
|
||||
if (hport->mutex) {
|
||||
usb_osal_mutex_delete(hport->mutex);
|
||||
}
|
||||
@@ -622,7 +602,7 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_bas
|
||||
bus->hcd.reg_base = reg_base;
|
||||
|
||||
/* devaddr 1 is for roothub */
|
||||
bus->devgen.next = 2;
|
||||
bus->devgen.last = 0x7f;
|
||||
|
||||
usb_slist_add_tail(&g_bus_head, &bus->list);
|
||||
}
|
||||
@@ -631,11 +611,7 @@ int usbh_initialize(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
struct usbh_bus *bus;
|
||||
|
||||
if (busid >= CONFIG_USBHOST_MAX_BUS) {
|
||||
USB_LOG_ERR("bus overflow\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
|
||||
|
||||
bus = &g_usbhost_bus[busid];
|
||||
|
||||
@@ -663,11 +639,7 @@ int usbh_deinitialize(uint8_t busid)
|
||||
{
|
||||
struct usbh_bus *bus;
|
||||
|
||||
if (busid >= CONFIG_USBHOST_MAX_BUS) {
|
||||
USB_LOG_ERR("bus overflow\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
|
||||
|
||||
bus = &g_usbhost_bus[busid];
|
||||
|
||||
@@ -681,6 +653,7 @@ int usbh_deinitialize(uint8_t busid)
|
||||
int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
|
||||
{
|
||||
struct usbh_urb *urb;
|
||||
volatile uint8_t retry = 3;
|
||||
int ret;
|
||||
|
||||
if (!hport || !setup) {
|
||||
@@ -693,17 +666,26 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
|
||||
|
||||
usbh_print_setup(setup);
|
||||
|
||||
resubmit:
|
||||
usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret == 0) {
|
||||
ret = urb->actual_length;
|
||||
}
|
||||
|
||||
if (ret < 0 && (ret != -USB_ERR_TIMEOUT)) {
|
||||
retry--;
|
||||
if (retry > 0) {
|
||||
USB_LOG_WRN("Control transfer failed, errorcode %d, retrying...\r\n", ret);
|
||||
goto resubmit;
|
||||
}
|
||||
}
|
||||
|
||||
usb_osal_mutex_give(hport->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output, uint16_t output_len)
|
||||
{
|
||||
struct usb_setup_packet *setup = hport->setup;
|
||||
int ret;
|
||||
@@ -729,6 +711,10 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
|
||||
dst = output;
|
||||
len = src[0];
|
||||
|
||||
if (((len - 2) / 2) > output_len) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
while (i < len) {
|
||||
dst[j] = src[i];
|
||||
i += 2;
|
||||
@@ -782,73 +768,6 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_list_all_interface_driver(struct usbh_hub *hub)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
struct usbh_hub *hub_next;
|
||||
const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
|
||||
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hport = &hub->child[port];
|
||||
if (hport->connected) {
|
||||
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
|
||||
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
|
||||
for (uint8_t j = 0; j < hub->index; j++) {
|
||||
USB_LOG_RAW("\t");
|
||||
}
|
||||
|
||||
USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n",
|
||||
hport->port,
|
||||
hport->dev_addr,
|
||||
itf,
|
||||
hport->config.intf[itf].class_driver->driver_name,
|
||||
speed_table[hport->speed]);
|
||||
|
||||
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
|
||||
hub_next = hport->config.intf[itf].priv;
|
||||
|
||||
if (hub_next && hub_next->connected) {
|
||||
usbh_list_all_interface_driver(hub_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *hub)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
struct usbh_hub *hub_next;
|
||||
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hport = &hub->child[port];
|
||||
if (hport->connected) {
|
||||
USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
|
||||
bus->busid,
|
||||
hub->index,
|
||||
hport->port,
|
||||
hport->dev_addr,
|
||||
hport->device_desc.idVendor,
|
||||
hport->device_desc.idProduct);
|
||||
usbh_print_hubport_info(hport);
|
||||
|
||||
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
|
||||
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
|
||||
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
|
||||
hub_next = hport->config.intf[itf].priv;
|
||||
|
||||
if (hub_next && hub_next->connected) {
|
||||
usbh_list_all_interface_desc(bus, hub_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
@@ -926,64 +845,341 @@ struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t
|
||||
return hport;
|
||||
}
|
||||
|
||||
static void usbh_print_hubport_info(struct usbh_hubport *hport)
|
||||
{
|
||||
USB_LOG_RAW("Device Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType);
|
||||
USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB);
|
||||
USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass);
|
||||
USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass);
|
||||
USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol);
|
||||
USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0);
|
||||
USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor);
|
||||
USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct);
|
||||
USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice);
|
||||
USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer);
|
||||
USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct);
|
||||
USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber);
|
||||
USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
|
||||
|
||||
USB_LOG_RAW("Config Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType);
|
||||
USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength);
|
||||
USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces);
|
||||
USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
|
||||
USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration);
|
||||
USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes);
|
||||
USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower);
|
||||
|
||||
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
|
||||
for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
|
||||
USB_LOG_RAW("\tInterface Descriptor:\r\n");
|
||||
USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
|
||||
USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
|
||||
USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
|
||||
USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
|
||||
USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
|
||||
USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
|
||||
USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
|
||||
USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
|
||||
USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
|
||||
|
||||
for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
|
||||
USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n");
|
||||
USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
|
||||
USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
|
||||
USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
|
||||
USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
|
||||
USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
|
||||
USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_list_device(struct usbh_hub *hub, bool astree, bool verbose, int dev_addr, int vid, int pid)
|
||||
{
|
||||
static const char *speed_table[] = {
|
||||
"UNKNOWN",
|
||||
"low-speed",
|
||||
"full-speed",
|
||||
"high-speed",
|
||||
"wireless",
|
||||
"super-speed",
|
||||
"super-speed-plus",
|
||||
};
|
||||
|
||||
static const char *root_speed_table[] = {
|
||||
"UNKNOWN",
|
||||
"1.1",
|
||||
"1.1",
|
||||
"2.0",
|
||||
"2.5",
|
||||
"3.0",
|
||||
"3.0",
|
||||
};
|
||||
|
||||
static const uint16_t speed_baud[] = {
|
||||
0,
|
||||
12,
|
||||
12,
|
||||
480,
|
||||
480,
|
||||
5000,
|
||||
10000,
|
||||
};
|
||||
|
||||
struct usbh_bus *bus;
|
||||
struct usbh_hubport *hport;
|
||||
struct usbh_hub *hub_next;
|
||||
|
||||
uint8_t imbuf[64];
|
||||
uint8_t ipbuf[64];
|
||||
|
||||
const char *pimstr;
|
||||
const char *pipstr;
|
||||
|
||||
bool imvalid = false;
|
||||
bool ipvalid = false;
|
||||
|
||||
int ret;
|
||||
|
||||
bus = hub->bus;
|
||||
|
||||
(void)speed_table;
|
||||
|
||||
if (hub->is_roothub) {
|
||||
if (astree) {
|
||||
USB_LOG_RAW("/: Bus %02u.Port 1: Dev %u, Class=root_hub, Driver=hcd, %uM\r\n",
|
||||
bus->busid, hub->hub_addr, speed_baud[hub->speed]);
|
||||
|
||||
} else {
|
||||
if ((dev_addr < 0) || (hub->hub_addr == dev_addr)) {
|
||||
if (((vid < 0) || (vid == 0xffff)) && ((pid < 0) || (pid == 0xffff))) {
|
||||
USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s root hub\r\n",
|
||||
bus->busid, hub->hub_addr, 0xffff, 0xffff,
|
||||
"Cherry-Embedded", root_speed_table[hub->speed]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hport = &hub->child[port];
|
||||
if (hport->connected) {
|
||||
ret = 0;
|
||||
if (hport->device_desc.iManufacturer) {
|
||||
memset(imbuf, 0, sizeof(imbuf));
|
||||
ret = usbh_get_string_desc(hport, hport->device_desc.iManufacturer, imbuf, sizeof(imbuf));
|
||||
if (ret == 0) {
|
||||
imvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hport->device_desc.iProduct) {
|
||||
memset(ipbuf, 0, sizeof(ipbuf));
|
||||
ret = usbh_get_string_desc(hport, hport->device_desc.iProduct, ipbuf, sizeof(ipbuf));
|
||||
if (ret == 0) {
|
||||
ipvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (imvalid) {
|
||||
pimstr = (const char *)imbuf;
|
||||
} else {
|
||||
pimstr = "Not specified Manufacturer";
|
||||
}
|
||||
|
||||
if (ipvalid) {
|
||||
pipstr = (const char *)ipbuf;
|
||||
} else {
|
||||
pipstr = "Not specified Product";
|
||||
}
|
||||
|
||||
if (!astree) {
|
||||
if ((dev_addr < 0) || (hport->dev_addr == dev_addr)) {
|
||||
if (((vid < 0) || (vid == hport->device_desc.idVendor)) && ((pid < 0) || (pid == hport->device_desc.idProduct))) {
|
||||
USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s\r\n",
|
||||
bus->busid, hport->dev_addr, hport->device_desc.idVendor, hport->device_desc.idProduct,
|
||||
pimstr, pipstr);
|
||||
|
||||
if (verbose) {
|
||||
usbh_print_hubport_info(hport);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t intf = 0; intf < hport->config.config_desc.bNumInterfaces; intf++) {
|
||||
if (hport->config.intf[intf].class_driver && hport->config.intf[intf].class_driver->driver_name) {
|
||||
if (astree) {
|
||||
for (uint8_t j = 0; j < hub->index; j++) {
|
||||
USB_LOG_RAW(" ");
|
||||
}
|
||||
|
||||
USB_LOG_RAW("|__ Port %u: Dev %u, If %u, ClassDriver=%s, %uM\r\n",
|
||||
hport->port, hport->dev_addr, intf, hport->config.intf[intf].class_driver->driver_name, speed_baud[hport->speed]);
|
||||
}
|
||||
|
||||
if (!strcmp(hport->config.intf[intf].class_driver->driver_name, "hub")) {
|
||||
hub_next = hport->config.intf[intf].priv;
|
||||
|
||||
if (hub_next && hub_next->connected) {
|
||||
usbh_list_device(hub_next, astree, verbose, dev_addr, vid, pid);
|
||||
}
|
||||
}
|
||||
} else if (astree) {
|
||||
for (uint8_t j = 0; j < hub->index; j++) {
|
||||
USB_LOG_RAW(" ");
|
||||
}
|
||||
|
||||
USB_LOG_RAW("|__ Port %u: Dev %u, If 0 ClassDriver=none, %uM\r\n",
|
||||
hport->port, hport->dev_addr, speed_baud[hport->speed]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lsusb_help(void)
|
||||
{
|
||||
USB_LOG_RAW("List USB Devices\r\n"
|
||||
"Usage: lsusb [options]...\r\n"
|
||||
"\r\n"
|
||||
"-v, --verbose\r\n"
|
||||
" - increase verbosity (show descriptors)\r\n"
|
||||
"-s [[bus]:][dev_addr]\r\n"
|
||||
" - show only devices with specified device and/or\r\n"
|
||||
" bus numbers (in decimal)\r\n"
|
||||
"-d vendor:[product]\r\n"
|
||||
" - show only devices with the specified vendor and\r\n"
|
||||
" product ID numbers (in hexadecimal)\r\n"
|
||||
"-t, --tree\r\n"
|
||||
" - dump the physical USB device hierarchy as a tree\r\n"
|
||||
"-V, --version\r\n"
|
||||
" - show version of the cherryusb\r\n"
|
||||
"-h, --help\r\n"
|
||||
" - show usage and help information\r\n");
|
||||
}
|
||||
|
||||
int lsusb(int argc, char **argv)
|
||||
{
|
||||
usb_slist_t *bus_list;
|
||||
struct usbh_hub *hub;
|
||||
struct usbh_bus *bus;
|
||||
size_t flags;
|
||||
|
||||
int busid = -1;
|
||||
int dev_addr = -1;
|
||||
int vid = -1;
|
||||
int pid = -1;
|
||||
bool astree = false;
|
||||
bool verbose = false;
|
||||
|
||||
if (argc < 2) {
|
||||
USB_LOG_RAW("Usage: lsusb [options]...\r\n");
|
||||
USB_LOG_RAW("List USB devices\r\n");
|
||||
USB_LOG_RAW(" -v, --verbose\r\n");
|
||||
USB_LOG_RAW(" Increase verbosity (show descriptors)\r\n");
|
||||
// USB_LOG_RAW(" -s [[bus]:[devnum]]\r\n");
|
||||
// USB_LOG_RAW(" Show only devices with specified device and/or bus numbers (in decimal)\r\n");
|
||||
// USB_LOG_RAW(" -d vendor:[product]\r\n");
|
||||
// USB_LOG_RAW(" Show only devices with the specified vendor and product ID numbers (in hexadecimal)\r\n");
|
||||
USB_LOG_RAW(" -t, --tree\r\n");
|
||||
USB_LOG_RAW(" Dump the physical USB device hierachy as a tree\r\n");
|
||||
USB_LOG_RAW(" -V, --version\r\n");
|
||||
USB_LOG_RAW(" Show version of program\r\n");
|
||||
USB_LOG_RAW(" -h, --help\r\n");
|
||||
USB_LOG_RAW(" Show usage and help\r\n");
|
||||
return 0;
|
||||
}
|
||||
if (argc > 3) {
|
||||
lsusb_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
while (argc > 1) {
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (strcmp(argv[1], "-V") == 0) {
|
||||
USB_LOG_RAW("CherryUSB Version %s\r\n", CHERRYUSB_VERSION_STR);
|
||||
}
|
||||
if (!strcmp(*argv, "-V") || !strcmp(*argv, "--version")) {
|
||||
USB_LOG_RAW("CherryUSB version %s\r\n", CHERRYUSB_VERSION_STR);
|
||||
return 0;
|
||||
} else if (!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) {
|
||||
lsusb_help();
|
||||
return 0;
|
||||
} else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) {
|
||||
verbose = true;
|
||||
} else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--tree")) {
|
||||
astree = true;
|
||||
} else if (!strcmp(*argv, "-s")) {
|
||||
if (argc > 1) {
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (strcmp(argv[1], "-t") == 0) {
|
||||
usb_slist_for_each(bus_list, &g_bus_head)
|
||||
{
|
||||
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
|
||||
hub = &bus->hcd.roothub;
|
||||
if (*argv[0] == '-') {
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
|
||||
bus->busid,
|
||||
hub->index,
|
||||
hub->nports);
|
||||
usbh_list_all_interface_driver(hub);
|
||||
char *endptr;
|
||||
const char *colon = strchr(*argv, ':');
|
||||
(void)endptr;
|
||||
|
||||
if (colon != NULL) {
|
||||
const char *str;
|
||||
if (colon > *argv) {
|
||||
busid = strtol(*argv, &endptr, 10);
|
||||
}
|
||||
str = colon + 1;
|
||||
if (*str != '\0') {
|
||||
dev_addr = strtol(str, &endptr, 10);
|
||||
if (dev_addr <= 0 || dev_addr >= 128) {
|
||||
dev_addr = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dev_addr = strtol(*argv, &endptr, 10);
|
||||
if (dev_addr <= 0 || dev_addr >= 128) {
|
||||
dev_addr = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(*argv, "-d")) {
|
||||
if (argc > 1) {
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (*argv[0] == '-') {
|
||||
continue;
|
||||
}
|
||||
|
||||
char *endptr;
|
||||
const char *colon = strchr(*argv, ':');
|
||||
(void)endptr;
|
||||
|
||||
if (colon == NULL) {
|
||||
continue;
|
||||
}
|
||||
const char *str;
|
||||
|
||||
vid = strtol(*argv, &endptr, 16);
|
||||
if (vid < 0 || vid > 0xffff) {
|
||||
vid = -1;
|
||||
continue;
|
||||
}
|
||||
str = colon + 1;
|
||||
if (*str != '\0') {
|
||||
pid = strtol(str, &endptr, 16);
|
||||
if (pid < 0 || pid > 0xffff) {
|
||||
pid = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "-v") == 0) {
|
||||
usb_slist_for_each(bus_list, &g_bus_head)
|
||||
{
|
||||
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
|
||||
hub = &bus->hcd.roothub;
|
||||
|
||||
usbh_list_all_interface_desc(bus, hub);
|
||||
}
|
||||
if (astree) {
|
||||
busid = -1;
|
||||
dev_addr = -1;
|
||||
vid = -1;
|
||||
pid = -1;
|
||||
verbose = false;
|
||||
}
|
||||
|
||||
usb_slist_for_each(bus_list, &g_bus_head)
|
||||
{
|
||||
bus = usb_slist_entry(bus_list, struct usbh_bus, list);
|
||||
if (busid >= 0) {
|
||||
if (bus->busid != busid) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
usbh_list_device(&bus->hcd.roothub, astree, verbose, dev_addr, vid, pid);
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
@@ -65,6 +66,7 @@ struct usbh_class_info {
|
||||
uint8_t bInterfaceClass; /* Base device class code */
|
||||
uint8_t bInterfaceSubClass; /* Sub-class, depends on base class. Eg. */
|
||||
uint8_t bInterfaceProtocol; /* Protocol, depends on base class. Eg. */
|
||||
uint8_t bInterfaceNumber; /* Interface number */
|
||||
const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */
|
||||
const struct usbh_class_driver *class_driver;
|
||||
};
|
||||
@@ -150,7 +152,7 @@ struct usbh_devaddr_map {
|
||||
* alloctab[3]:addr from 96~127
|
||||
*
|
||||
*/
|
||||
uint8_t next; /* Next device address */
|
||||
uint8_t last; /* Last device address */
|
||||
uint32_t alloctab[4]; /* Bit allocation table */
|
||||
};
|
||||
|
||||
@@ -255,9 +257,10 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
|
||||
* @param hport Pointer to the USB hub port structure.
|
||||
* @param index Index of the string descriptor to retrieve.
|
||||
* @param output Pointer to the buffer where the retrieved descriptor will be stored.
|
||||
* @param output_len Length of the output buffer.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output);
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output, uint16_t output_len);
|
||||
|
||||
/**
|
||||
* @brief Sets the alternate setting for a USB interface on a specific hub port.
|
||||
|
||||
@@ -5,39 +5,57 @@
|
||||
*/
|
||||
#include "usbotg_core.h"
|
||||
|
||||
#ifdef CONFIG_USB_OTG_ENABLE
|
||||
#undef USB_DBG_TAG
|
||||
#define USB_DBG_TAG "usbotg_core"
|
||||
#include "usb_log.h"
|
||||
|
||||
#define CONFIG_USB_OTG_MAX_BUS CONFIG_USBHOST_MAX_BUS
|
||||
|
||||
struct usbotg_core_priv {
|
||||
uint8_t busid;
|
||||
uint32_t reg_base;
|
||||
usb_osal_sem_t change_sem;
|
||||
usb_osal_thread_t change_thread;
|
||||
bool usbh_initialized;
|
||||
bool usbd_initialized;
|
||||
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base);
|
||||
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base);
|
||||
} g_usbotg_core[CONFIG_USBHOST_MAX_BUS];
|
||||
void *device_event_callback;
|
||||
void *host_event_callback;
|
||||
uint8_t current_mode;
|
||||
usb_osal_sem_t change_sem;
|
||||
usb_osal_thread_t change_thread;
|
||||
} g_usbotg_core[CONFIG_USB_OTG_MAX_BUS];
|
||||
|
||||
static void usbotg_host_initialize(uint8_t busid)
|
||||
{
|
||||
if (g_usbotg_core[busid].usbh_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_usbotg_core[busid].usbd_initialized) {
|
||||
g_usbotg_core[busid].usbd_initialized = false;
|
||||
usbd_deinitialize(busid);
|
||||
}
|
||||
if (g_usbotg_core[busid].usbh_initialize && !g_usbotg_core[busid].usbh_initialized) {
|
||||
g_usbotg_core[busid].usbh_initialized = true;
|
||||
g_usbotg_core[busid].usbh_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base);
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Switch to HOST mode\r\n");
|
||||
|
||||
usbh_initialize(busid, g_usbotg_core[busid].reg_base);
|
||||
g_usbotg_core[busid].usbh_initialized = true;
|
||||
}
|
||||
|
||||
static void usbotg_device_initialize(uint8_t busid)
|
||||
{
|
||||
if (g_usbotg_core[busid].usbd_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_usbotg_core[busid].usbh_initialized) {
|
||||
g_usbotg_core[busid].usbh_initialized = false;
|
||||
usbh_deinitialize(busid);
|
||||
}
|
||||
if (g_usbotg_core[busid].usbd_initialize && !g_usbotg_core[busid].usbd_initialize) {
|
||||
g_usbotg_core[busid].usbd_initialized = true;
|
||||
g_usbotg_core[busid].usbd_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base);
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Switch to DEVICE mode\r\n");
|
||||
|
||||
usbd_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base, g_usbotg_core[busid].device_event_callback);
|
||||
g_usbotg_core[busid].usbd_initialized = true;
|
||||
}
|
||||
|
||||
static void usbotg_rolechange_thread(void *argument)
|
||||
@@ -48,58 +66,49 @@ static void usbotg_rolechange_thread(void *argument)
|
||||
|
||||
while (1) {
|
||||
if (usb_osal_sem_take(g_usbotg_core[busid].change_sem, USB_OSAL_WAITING_FOREVER) == 0) {
|
||||
if (usbotg_get_current_mode(busid) == USBOTG_MODE_HOST) {
|
||||
if (g_usbotg_core[busid].current_mode == USBOTG_MODE_HOST) {
|
||||
usbotg_host_initialize(busid);
|
||||
} else if (usbotg_get_current_mode(busid) == USBOTG_MODE_DEVICE) {
|
||||
} else if (g_usbotg_core[busid].current_mode == USBOTG_MODE_DEVICE) {
|
||||
usbotg_device_initialize(busid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int usbotg_initialize(uint8_t otg_mode, uint8_t busid, uint32_t reg_base,
|
||||
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base),
|
||||
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base))
|
||||
int usbotg_initialize(uint8_t busid, uint32_t reg_base, void *device_event_callback, void *host_event_callback, uint8_t default_role)
|
||||
{
|
||||
char thread_name[32] = { 0 };
|
||||
|
||||
if (busid >= CONFIG_USBHOST_MAX_BUS) {
|
||||
USB_LOG_ERR("bus overflow\r\n");
|
||||
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
|
||||
|
||||
g_usbotg_core[busid].busid = busid;
|
||||
g_usbotg_core[busid].reg_base = reg_base;
|
||||
g_usbotg_core[busid].device_event_callback = device_event_callback;
|
||||
g_usbotg_core[busid].host_event_callback = host_event_callback;
|
||||
|
||||
g_usbotg_core[busid].change_sem = usb_osal_sem_create(0);
|
||||
if (g_usbotg_core[busid].change_sem == NULL) {
|
||||
USB_LOG_ERR("Failed to create change_sem\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
g_usbotg_core[busid].busid = busid;
|
||||
g_usbotg_core[busid].reg_base = reg_base;
|
||||
g_usbotg_core[busid].usbh_initialize = usbh_initialize;
|
||||
g_usbotg_core[busid].usbd_initialize = usbd_initialize;
|
||||
|
||||
if (otg_mode == USBOTG_MODE_OTG) {
|
||||
g_usbotg_core[busid].change_sem = usb_osal_sem_create(0);
|
||||
if (g_usbotg_core[busid].change_sem == NULL) {
|
||||
USB_LOG_ERR("Failed to create change_sem\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(thread_name, 32, "usbotg%u", busid);
|
||||
g_usbotg_core[busid].change_thread = usb_osal_thread_create(thread_name, CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbotg_rolechange_thread, (void *)(uintptr_t)busid);
|
||||
if (g_usbotg_core[busid].change_thread == NULL) {
|
||||
USB_LOG_ERR("Failed to create usbotg thread\r\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (otg_mode == USBOTG_MODE_HOST) {
|
||||
usbotg_host_initialize(busid);
|
||||
} else if (otg_mode == USBOTG_MODE_DEVICE) {
|
||||
usbotg_device_initialize(busid);
|
||||
snprintf(thread_name, 32, "usbotg%u", busid);
|
||||
g_usbotg_core[busid].change_thread = usb_osal_thread_create(thread_name, 2048, 10, usbotg_rolechange_thread, (void *)(uintptr_t)busid);
|
||||
if (g_usbotg_core[busid].change_thread == NULL) {
|
||||
USB_LOG_ERR("Failed to create usbotg thread\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
usbotg_trigger_role_change(busid, default_role);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbotg_deinitialize(uint8_t busid, uint32_t reg_base)
|
||||
int usbotg_deinitialize(uint8_t busid)
|
||||
{
|
||||
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
|
||||
|
||||
if (g_usbotg_core[busid].usbd_initialized) {
|
||||
g_usbotg_core[busid].usbd_initialized = false;
|
||||
usbd_deinitialize(busid);
|
||||
@@ -110,28 +119,37 @@ int usbotg_deinitialize(uint8_t busid, uint32_t reg_base)
|
||||
usbh_deinitialize(busid);
|
||||
}
|
||||
|
||||
if (g_usbotg_core[busid].change_thread) {
|
||||
usb_osal_thread_delete(g_usbotg_core[busid].change_thread);
|
||||
}
|
||||
|
||||
if (g_usbotg_core[busid].change_sem) {
|
||||
usb_otg_deinit(busid);
|
||||
usb_osal_sem_delete(g_usbotg_core[busid].change_sem);
|
||||
}
|
||||
|
||||
if (g_usbotg_core[busid].change_thread) {
|
||||
usb_osal_thread_delete(g_usbotg_core[busid].change_thread);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usbotg_trigger_role_change(uint8_t busid)
|
||||
void usbotg_trigger_role_change(uint8_t busid, uint8_t mode)
|
||||
{
|
||||
usb_osal_sem_give(g_usbotg_core[busid].change_sem);
|
||||
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
|
||||
|
||||
g_usbotg_core[busid].current_mode = mode;
|
||||
|
||||
if (g_usbotg_core[busid].change_sem) {
|
||||
usb_osal_sem_give(g_usbotg_core[busid].change_sem);
|
||||
}
|
||||
}
|
||||
|
||||
void USBOTG_IRQHandler(uint8_t busid)
|
||||
{
|
||||
if (usbotg_get_current_mode(busid) == USBOTG_MODE_HOST) {
|
||||
USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n");
|
||||
|
||||
if (g_usbotg_core[busid].current_mode == USBOTG_MODE_HOST && g_usbotg_core[busid].usbh_initialized) {
|
||||
USBH_IRQHandler(busid);
|
||||
} else if (usbotg_get_current_mode(busid) == USBOTG_MODE_DEVICE) {
|
||||
} else if (g_usbotg_core[busid].current_mode == USBOTG_MODE_DEVICE && g_usbotg_core[busid].usbd_initialized) {
|
||||
USBD_IRQHandler(busid);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_USB_OTG_ENABLE */
|
||||
@@ -10,22 +10,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define USBOTG_MODE_UNKNOWN 0
|
||||
#define USBOTG_MODE_OTG 1
|
||||
#define USBOTG_MODE_HOST 2
|
||||
#define USBOTG_MODE_DEVICE 3
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usb_otg.h"
|
||||
|
||||
int usbotg_initialize(uint8_t otg_mode, uint8_t busid, uint32_t reg_base,
|
||||
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base),
|
||||
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base));
|
||||
int usbotg_deinitialize(uint8_t busid, uint32_t reg_base);
|
||||
int usbotg_initialize(uint8_t busid, uint32_t reg_base, void *device_event_callback, void *host_event_callback, uint8_t default_role);
|
||||
int usbotg_deinitialize(uint8_t busid);
|
||||
|
||||
/* called by user */
|
||||
void usbotg_trigger_role_change(uint8_t busid);
|
||||
void usbotg_trigger_role_change(uint8_t busid, uint8_t mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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 (;;) {
|
||||
;
|
||||
}
|
||||
|
||||
@@ -297,11 +297,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
|
||||
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value); /* uac1 can only use 10.14 */
|
||||
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
|
||||
#endif
|
||||
printf("OPEN1\r\n");
|
||||
USB_LOG_INFO("OPEN1\r\n");
|
||||
} else {
|
||||
tx_flag = 1;
|
||||
ep_tx_busy_flag = false;
|
||||
printf("OPEN2\r\n");
|
||||
USB_LOG_INFO("OPEN2\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,11 +309,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
|
||||
{
|
||||
if (intf == 1) {
|
||||
rx_flag = 0;
|
||||
printf("CLOSE1\r\n");
|
||||
USB_LOG_INFO("CLOSE1\r\n");
|
||||
} else {
|
||||
tx_flag = 0;
|
||||
ep_tx_busy_flag = false;
|
||||
printf("CLOSE2\r\n");
|
||||
USB_LOG_INFO("CLOSE2\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -68,6 +68,7 @@ static const char *string_descriptors[] = {
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC ECM DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
"aabbccddeeff", /* ecm mac address */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
|
||||
@@ -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)
|
||||
|
||||
233
demo/mongoose/cdc_rndis_mongoose.c
Normal 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
|
After Width: | Height: | Size: 270 KiB |
22
demo/mongoose/mongoose_config.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -448,6 +448,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
video_iso_tx_busy = false;
|
||||
@@ -465,11 +469,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
|
||||
audio_rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, AUDIO_OUT_EP, audio_read_buffer, AUDIO_OUT_PACKET);
|
||||
printf("OPEN1\r\n");
|
||||
USB_LOG_RAW("OPEN1\r\n");
|
||||
} else if (intf == 4) {
|
||||
audio_tx_flag = 1;
|
||||
audio_iso_tx_busy = false;
|
||||
printf("OPEN2\r\n");
|
||||
USB_LOG_RAW("OPEN2\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,11 +481,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
|
||||
{
|
||||
if (intf == 3) {
|
||||
audio_rx_flag = 0;
|
||||
printf("CLOSE1\r\n");
|
||||
USB_LOG_RAW("CLOSE1\r\n");
|
||||
} else if (intf == 4) {
|
||||
audio_tx_flag = 0;
|
||||
audio_iso_tx_busy = false;
|
||||
printf("CLOSE2\r\n");
|
||||
USB_LOG_RAW("CLOSE2\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -252,6 +252,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
|
||||
@@ -252,6 +252,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
|
||||
@@ -256,6 +256,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (nbytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
|
||||
BIN
docs/assets/sifli.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
@@ -6,8 +6,8 @@ project = 'CherryUSB'
|
||||
copyright = '2022 ~ 2025, sakumisu'
|
||||
author = 'sakumisu'
|
||||
|
||||
release = '1.5.1'
|
||||
version = '1.5.1'
|
||||
release = '1.5.3'
|
||||
version = '1.5.3'
|
||||
|
||||
# -- General configuration
|
||||
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
usbd_audiov1
|
||||
===============
|
||||
|
||||
.. note:: 在使用windows 时,当修改描述符任意参数时,必须同步修改字符串描述符,并且卸载驱动,否则windows会认为设备未更改,继续使用旧的驱动,导致无法识别设备。Linux 不受此限制。
|
||||
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
usbd_audiov2
|
||||
===============
|
||||
|
||||
.. note:: 在使用windows 时,当修改描述符任意参数时,必须同步修改字符串描述符,并且卸载驱动,否则windows会认为设备未更改,继续使用旧的驱动,导致无法识别设备。Linux 不受此限制。
|
||||
|
||||
.. note:: windows 10 uac2.0 功能不完善,请使用 windows 11 测试uac2.0 功能。Linux 不受此限制。
|
||||
@@ -56,3 +56,7 @@ Klipper is a 3d-printer firmware.
|
||||
适配链接:待开放
|
||||
|
||||
|
||||
MAKCU/KMBOX
|
||||
--------------
|
||||
|
||||
懂的都懂,不开放
|
||||
@@ -10,12 +10,13 @@ Q & A
|
||||
|
||||
提问中请包含以下信息:
|
||||
|
||||
- 使用的版本
|
||||
- 使用的板子,引脚,USB IP
|
||||
- USB 中断,时钟,引脚,寄存器地址是否正确,截图
|
||||
- 是否配置 USB 中断,USB 时钟,USB 引脚,USB phy 配置,以及 USB 寄存器地址是否正确,截图
|
||||
- 是否能进 USB 中断
|
||||
- 芯片是否带有 cache功能,是否做了 no cache 处理,截图
|
||||
- 硬件是否正常,是否使用杜邦线连接,如果正常,请说明正常原因
|
||||
- 配置 **#define CONFIG_USB_DBG_LEVEL USB_DBG_LOG** 并提供 log,仅限商业 IP, 其余 IP 禁止开启 log,否则无法枚举
|
||||
- USB 电路是否画正确,是否使用杜邦线连接,是否直连,如果正常,请说明正常原因
|
||||
- 如果能进中断,配置 **#define CONFIG_USB_DBG_LEVEL USB_DBG_LOG** 并提供 log,仅限商业 IP, 其余 IP 禁止开启 log,否则无法枚举
|
||||
- 是否流片并销售
|
||||
|
||||
其余问题提问模板
|
||||
@@ -36,12 +37,7 @@ ST 命名为 USB_OTG_FS, USB_OTG_HS,并不是说明本身是高速或者全速
|
||||
GD IP 问题
|
||||
------------------
|
||||
|
||||
GD IP 采用 DWC2,但是读取的硬件参数都是 0(我也不懂为什么不给人知道),因此需要用户自行知道硬件信息,以下列举 GD32F4 的信息:
|
||||
|
||||
CONFIG_USBDEV_EP_NUM pa11/pa12 引脚必须为 4,PB14/PB15 引脚必须为 6,并删除 usb_dc_dwc2.c 中 while(1){}
|
||||
|
||||
- 当 CONFIG_USBDEV_EP_NUM 为4 时,fifo_num 不得大于 320 字
|
||||
- 当 CONFIG_USBDEV_EP_NUM 为6 时,fifo_num 不得大于 1280 字
|
||||
GD IP 采用 DWC2,但是读取的硬件参数都是 0(我也不懂为什么不给人知道),因此需要用户自行知道硬件信息,从 1.5.0 开始由于需要读取硬件信息,因此无法直接使用。
|
||||
|
||||
其次 GD 复位以后无法使用 EPDIS 功能关闭端点,需要用户删除 reset 中断中的以下代码:
|
||||
|
||||
@@ -50,11 +46,6 @@ CONFIG_USBDEV_EP_NUM pa11/pa12 引脚必须为 4,PB14/PB15 引脚必须为 6
|
||||
USB_OTG_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
|
||||
USB_OTG_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
|
||||
|
||||
dwc2 has less endpoints than config, please check
|
||||
---------------------------------------------------------------
|
||||
|
||||
该 IP 硬件上没有这么多端点,请修改 `CONFIG_USBDEV_EP_NUM`
|
||||
|
||||
Ep addr XXX overflow
|
||||
------------------------------
|
||||
|
||||
@@ -75,7 +66,6 @@ CONFIG_USB_HS 何时使用
|
||||
|
||||
当你的芯片硬件支持高速,并想初始化成高速模式时开启,相关 IP 会根据该宏配置内部或者外部 高速 PHY。
|
||||
|
||||
|
||||
Failed to enable port
|
||||
----------------------------------------------------------------
|
||||
|
||||
@@ -84,6 +74,25 @@ Failed to enable port
|
||||
移植 usb host 出现 urb 返回 -12/-14
|
||||
----------------------------------------------------------------
|
||||
|
||||
-12 就检查 phy 配置,通信不良
|
||||
检查 phy 配置,cache 配置(如果有),电源供电(建议自供电)
|
||||
|
||||
-14 就检查 phy 配置,cache 配置(如果有),fifo配置,寄存器地址, IP 是否真的标准等等
|
||||
USB_ERR_NAK 说明
|
||||
----------------------------------------------------------------
|
||||
USB_ERR_NAK 只存在于 DWC2 buffer dma 模式,DWC2 在 buffer dma模式下对于中断传输不支持硬件处理 NAK 中断,因此需要软件处理,导致 NAK 中断非常多,建议搭配定时器使用。
|
||||
DWC2 scatter/gather dma 模式下全部由硬件处理,但是不支持 split 传输。总结, **半斤 IP**。
|
||||
|
||||
USB host 连接 USB 网卡问题
|
||||
----------------------------------------------------------------
|
||||
|
||||
表现为能识别网卡并且分配到 IP 地址,但是无法 ping 通,这是因为网卡自身需要开启自动拨号,通常需要使用 AT 口设置。具体为 EC20/ML307 等模块。
|
||||
|
||||
PC 识别的 COM 口如何更改名称
|
||||
----------------------------------------------------------------
|
||||
|
||||
这是微软对 CDC ACM 的驱动问题,无法修改,如需修改,请联系微软并缴纳费用即可更改。
|
||||
|
||||
connect 和 disconnect event 不触发
|
||||
----------------------------------------------------------------
|
||||
|
||||
当前仅 hpm 芯片支持 connect 和 disconnect 事件,其他芯片请使用 USB 检测 vbus 电路。DWC2 IP 支持,但是由于需要占用引脚,并且大多是log 口,
|
||||
然后不同使能的配置也不一样,因此不做支持。
|
||||
@@ -4,60 +4,71 @@
|
||||
在学习 USB 或者是学习 CherryUSB 代码之前,我们需要先基于现有的 demo 进行快速验证,为什么?是为了提升对 USB 的兴趣,能有信心进行下一步的动作,如果 demo 都跑不起来,或者自己摸索写代码,或者先看 USB 基本概念,结果看到最后,
|
||||
发现一点都看不懂,概念好多,根本记不住,从而丧失对 USB 的兴趣。因此,先跑 demo 非常重要。下面我将给大家罗列目前支持的 demo 仓库。
|
||||
|
||||
基于 bouffalolab 系列芯片
|
||||
---------------------------
|
||||
基于 bouffalolab 系列芯片(官方 SDK 支持)
|
||||
------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_bouffalolab
|
||||
|
||||
- BL616/BL808 是一个 USB2.0 并且内置高速 PHY 芯片,共 5个端点(包含端点0)。支持主从机。
|
||||
- BL616/BL808:USB2.0 内置 HS phy 芯片,支持主从机。device 支持 5 个端点(包括端点0),不支持双向同时使用。
|
||||
- USB 的相关应用位于 `examples/usbdev` 和 `examples/usbhost` 目录下,根据官方环境搭建完成后,即可编译使用。
|
||||
|
||||
基于 HPMicro 系列芯片
|
||||
---------------------------
|
||||
基于 HPMicro 系列芯片(官方 SDK 支持)
|
||||
-----------------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_hpmicro
|
||||
|
||||
- HPM 系列芯片均 USB 2.0 并且内置高速 PHY,支持主从机,端点共 8/16 个,并且可以同时使用双向,不同芯片个数有差异
|
||||
- HPM 系列: USB2.0 内置 HS phy 芯片,支持主从机。device 支持 8/16 端点(包括端点0),并且可以同时使用双向,不同芯片个数有差异。
|
||||
- USB 的相关应用位于 `samples/cherryusb` ,根据官方环境搭建完成后,即可编译使用。
|
||||
|
||||
基于 esp32s2/s3/p4 系列芯片
|
||||
---------------------------
|
||||
基于 esp32s2/s3/p4 系列芯片(官方 SDK 即将支持)
|
||||
-------------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_esp32
|
||||
|
||||
- esp32s2/s3 支持全速主从机,esp32p4 支持高速主从机
|
||||
- 默认提供主机 demo,并且使用 esp 组件库进行开发, 在 https://components.espressif.com/ 中搜索 cherryusb 即可
|
||||
- esp32s2/s3:USB2.0 内置全速 PHY 芯片,支持主从机,device 支持 7 个端点(包括端点0),并且可以同时使用双向。
|
||||
- esp32p4:一个 USB2.0 内置全速 PHY 芯片,一个 USB2.0 内置高速 PHY 芯片,支持主从机。
|
||||
- 默认 demo 采用组件库安装的形式,在 https://components.espressif.com/ 中搜索 cherryusb 即可
|
||||
|
||||
基于飞腾派系列芯片
|
||||
---------------------------
|
||||
基于飞腾派系列芯片(官方 SDK 支持)
|
||||
-----------------------------------
|
||||
|
||||
仓库参考:https://gitee.com/phytium_embedded/phytium-free-rtos-sdk
|
||||
|
||||
- 飞腾派支持两个 USB3.0 主机(采用 XHCI), 两个 USB2.0 主从机
|
||||
- USB 的相关应用位于 `example/peripheral/usb` ,根据官方环境搭建完成后,即可编译使用。
|
||||
|
||||
基于 Essemi 系列芯片
|
||||
---------------------------
|
||||
基于 Essemi 系列芯片(官方 SDK 支持)
|
||||
-----------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_es32
|
||||
|
||||
- 支持全速和高速主从机
|
||||
- 支持全速和高速主从机。device 支持 6 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
基于 Artinchip 系列芯片(官方 SDK 支持)
|
||||
-----------------------------------------------
|
||||
|
||||
仓库参考:https://gitee.com/artinchip/luban-lite
|
||||
|
||||
- 支持全速和高速主从机,主机采用 EHCI + OHCI。device 支持 8 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
基于 canmv-k230 芯片(官方 SDK 支持)
|
||||
---------------------------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/k230_sdk
|
||||
|
||||
- K230: 两个 USB2.0 内置 HS PHY 芯片,支持主从机。device 支持 16 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
基于 NXP MCX系列芯片
|
||||
---------------------------
|
||||
|
||||
仓库参考:https://github.com/CherryUSB/cherryusb_mcx 或者 https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx
|
||||
|
||||
- 支持全速 IP 和高速 IP, 高速 IP 支持主机和从机
|
||||
- 支持全速 IP 和高速 IP, 高速 IP 支持主机和从机。device 支持 8 个端点(包括端点0),并且可以同时使用双向。
|
||||
|
||||
- 支持全速和高速主从机
|
||||
基于 RP2040/RP2035 芯片(官方 SDK 即将支持)
|
||||
--------------------------------------------
|
||||
|
||||
基于 Artinchip 系列芯片
|
||||
---------------------------
|
||||
|
||||
仓库参考:https://gitee.com/artinchip/luban-lite
|
||||
|
||||
- 支持全速和高速主从机,主机采用 EHCI + OHCI。
|
||||
仓库参考: https://github.com/CherryUSB/pico-examples 和 https://github.com/CherryUSB/pico-sdk
|
||||
|
||||
基于 ST 系列芯片
|
||||
---------------------------
|
||||
@@ -67,8 +78,8 @@
|
||||
默认提供以下 demo 工程:
|
||||
|
||||
- F103 使用 fsdev ip
|
||||
- F429 主从使用 USB1, 引脚 pb14/pb15, 并且都使用 dma 模式
|
||||
- H7 设备使用 USB0, 引脚 pa11/pa12,没有开DMA 模式。主机使用 USB1 ,引脚 pb14/pb15,并且需要做 nocache 处理
|
||||
- F429 主从使用 USB1, 引脚 pb14/pb15, 默认从机没有开启 DMA 模式
|
||||
- H7 设备使用 USB0, 引脚 pa11/pa12,没有开 DMA 模式。主机使用 USB1 ,引脚 pb14/pb15,并且需要做 nocache 处理
|
||||
|
||||
demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate Code** 即可。
|
||||
|
||||
@@ -78,7 +89,7 @@ demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate
|
||||
|
||||
- usb ip 区别:F1使用 fsdev,F4/H7使用 dwc2
|
||||
- dwc2 ip 区别: USB0 (引脚是 PA11/PA12) 和 USB1 (引脚是 PB14/PB15), 其中 USB1 默认全速,可以接外部PHY 形成高速主机,并且带 dma 功能
|
||||
- F4 无cache,H7 有 cache
|
||||
- F4 无 cache,H7 有 cache
|
||||
|
||||
如果是 STM32F7/STM32H7 这种带 cache 功能,需要将 usb 使用到的 ram 定位到 no cache ram 区域。举例如下
|
||||
|
||||
@@ -116,12 +127,12 @@ USB Device 移植要点
|
||||
- 如果使用 fsdev ip,勾选 **USB** 。如果使用 dwc2 ip,勾选 **USB_OTG_FS** 或者勾选 **USB_OTG_HS**。开启 USB 中断,其他配置对我们没用,代码中不会使用任何 st 的 usb 库。
|
||||
|
||||
.. figure:: img/stm32_3_1.png
|
||||
.. figure:: img/stm32_3.png
|
||||
.. figure:: img/stm32_3_2.png
|
||||
|
||||
- 配置 usb clock 为 48M
|
||||
|
||||
.. figure:: img/stm32_4_1.png
|
||||
.. figure:: img/stm32_4.png
|
||||
.. figure:: img/stm32_4_2.png
|
||||
|
||||
- 选择好工程,这里我们选择 keil,设置好 stack 和 heap,如果使用 msc 可以推荐设置大点,然后点击 **Generate Code**。
|
||||
|
||||
@@ -139,26 +150,10 @@ USB Device 移植要点
|
||||
|
||||
.. figure:: img/stm32_8.png
|
||||
|
||||
- 如果使用 dwc2 ip,需要增加 **dwc2/usb_glue_st.c** 文件,并在 `usb_config.h` 中实现以下宏:
|
||||
- 如果使用 fsdev ip,(V1.5.0 开始需要增加 **fsdev/usb_glue_st.c**) 在 `usb_config.h` 中实现以下宏,具体数值不同芯片不一样:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// 以下细节如有出入,请对照 stm32xxx.h 文件修改
|
||||
// 需要根据硬件实际的 fifo 深度进行修改,默认是最基础的配置
|
||||
#define CONFIG_USBDEV_EP_NUM 6
|
||||
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1012 - 16 * 6)
|
||||
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
|
||||
|
||||
- 如果使用 fsdev ip,(V1.5.0 开始需要增加 **fsdev/usb_glue_st.c**) 在 `usb_config.h` 中实现以下宏:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
#define CONFIG_USBDEV_EP_NUM 8
|
||||
#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2
|
||||
|
||||
- 编译器推荐使用 **AC6**。勾选 **Microlib**,并实现 **printf** ,方便后续查看 log。
|
||||
@@ -188,7 +183,7 @@ USB Host 移植要点
|
||||
|
||||
前面 6 步与 Device 一样。需要注意,host 驱动只支持带 dma 的 hs port (引脚是 PB14/PB15),所以 fs port (引脚是 PA11/PA12)不做支持(没有 dma 你玩什么主机)。
|
||||
|
||||
- 添加 CherryUSB 必须要的源码( **usbh_core.c** 、 **usbh_hub.c** 、 **usb_hc_dwc2.c** 、以及 **osal** 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 **usb host.c** 添加方便测试。
|
||||
- 添加 CherryUSB 必须要的源码( **usbh_core.c** 、 **usbh_hub.c** 、 **usb_hc_dwc2.c** 、 **usb_glue_st.c** 以及 **osal** 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 **usb host.c** 添加方便测试。
|
||||
|
||||
.. figure:: img/stm32_16.png
|
||||
|
||||
@@ -199,25 +194,16 @@ USB Host 移植要点
|
||||
|
||||
- 复制一份 **cherryusb_config_template.h**,放到 `Core/Inc` 目录下,并命名为 `usb_config.h`
|
||||
|
||||
- 增加 **usb_glue_st.c** 文件,并在 `usb_config.h` 中实现以下宏:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// 以下细节如有出入,请对照 stm32xxx.h 文件修改
|
||||
// 需要根据硬件实际的 fifo 深度进行修改,默认是最基础的配置
|
||||
#define CONFIG_USBHOST_PIPE_NUM 12
|
||||
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
|
||||
#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4)
|
||||
|
||||
.. note :: 以下两个步骤从 V1.5.0 开始不再需要,**fsdev/usb_glue_st.c**, **dwc2/usb_glue_st.c** 文件中已经实现
|
||||
|
||||
- 拷贝 **xxx_msp.c** 中的 `HAL_HCD_MspInit` 函数中的内容到 `usb_hc_low_level_init` 函数中,屏蔽 st 生成的 usb 初始化
|
||||
- 在中断函数中调用 `USBH_IRQHandler`,并传入 `busid`
|
||||
|
||||
.. figure:: img/stm32_19.png
|
||||
|
||||
- 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
|
||||
- 启动线程
|
||||
|
||||
.. figure:: img/stm32_18.png
|
||||
.. figure:: img/stm32_19.png
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 16 KiB |
@@ -6,26 +6,24 @@
|
||||
USB Device 移植要点
|
||||
-----------------------
|
||||
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,其中 `usbd_core.c` 和 `usb_dc_xxx.c` 为必须添加项。而 `usb_dc_xxx.c` 是芯片所对应的 USB IP dcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,头文件路径建议全部添加。其中 `usbd_core.c` 和 `usb_dc_xxx.c` 为必须添加项。而 `usb_dc_xxx.c` 是芯片所对应的 USB IP dcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径
|
||||
- 实现 `usb_dc_low_level_init` 函数(该函数主要负责 USB 时钟、引脚、中断的初始化)。该函数可以放在你想要放的任何参与编译的 c 文件中。如何进行 USB 的时钟、引脚、中断等初始化,请自行根据你使用的芯片原厂提供的源码中进行添加。
|
||||
- 描述符的注册、class的注册、接口的注册、端点中断的注册。不会的参考 demo 下的 template
|
||||
- 调用 `usbd_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
|
||||
- 在中断函数中调用 `USBD_IRQHandler`,并传入 `busid`, 如果你的 SDK 中中断入口已经存在 `USBD_IRQHandler` ,请更改 USB 协议栈中的名称
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 编译使用。各个 class 如何使用,参考 demo 下的 template
|
||||
- 注册描述符并调用 `usbd_initialize`,填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`,可以直接使用 demo 下的 template
|
||||
|
||||
USB Host 移植要点
|
||||
-----------------------
|
||||
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,其中 `usbh_core.c` 、 `usb_hc_xxx.c` 以及 **osal** 目录下源文件(根据不同的 os 选择对应的源文件)为必须添加项。而 `usb_hc_xxx.c` 是芯片所对应的 USB IP hcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,头文件路径建议全部添加。其中 `usbh_core.c` 、 `usb_hc_xxx.c` 以及 **osal** 目录下源文件(根据不同的 os 选择对应的源文件)为必须添加项。而 `usb_hc_xxx.c` 是芯片所对应的 USB IP hcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
|
||||
- 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径
|
||||
- 实现 `usb_hc_low_level_init` 函数(该函数主要负责 USB 时钟、引脚、中断的初始化)。该函数可以放在你想要放的任何参与编译的 c 文件中。如何进行 USB 的时钟、引脚、中断等初始化,请自行根据你使用的芯片原厂提供的源码中进行添加。
|
||||
- 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
|
||||
- 在中断函数中调用 `USBH_IRQHandler`,并传入 `busid`, 如果你的 SDK 中中断入口已经存在 `USBH_IRQHandler` ,请更改 USB 协议栈中的名称
|
||||
- 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 编译使用。基础的 cdc + hid + msc 参考 `usb_host.c` 文件,其余参考 **platform** 目录下适配
|
||||
- 调用 `usbh_initialize` ,填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS` 。基础的 cdc + hid + msc 参考 `usb_host.c` 文件,其余参考 **platform** 目录下适配
|
||||
|
||||
.. _usbh_link_script:
|
||||
|
||||
|
||||
BIN
docs/source/show/img/usbhost_ax88772_1.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
docs/source/show/img/usbhost_ax88772_2.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 540 KiB |
|
Before Width: | Height: | Size: 125 KiB |
@@ -80,6 +80,21 @@ USB Host UVC
|
||||
|
||||
.. figure:: img/usbhost_uvc.gif
|
||||
|
||||
USB Host ASIX 网卡
|
||||
-----------------------
|
||||
|
||||
演示 USB Host 驱动 AX88772 USB 以太网模块。
|
||||
|
||||
.. figure:: img/usbhost_ax88772_1.png
|
||||
.. figure:: img/usbhost_ax88772_2.png
|
||||
|
||||
USB Host RNDIS 网卡
|
||||
-----------------------
|
||||
|
||||
演示 USB Host 驱动手机,手机开启 USB 共享网络即可使用 RNDIS 。
|
||||
|
||||
.. figure:: img/usbhost_rndis.png
|
||||
|
||||
USB Host WIFI
|
||||
-----------------------
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 314 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 327 KiB |
BIN
docs/source/support/img/dwc2_hostuvc3.png
Normal file
|
After Width: | Height: | Size: 319 KiB |
BIN
docs/source/support/img/usbhost_uvc.gif
Normal file
|
After Width: | Height: | Size: 8.2 MiB |
@@ -7,18 +7,23 @@
|
||||
|
||||
.. figure:: img/ohci.png
|
||||
|
||||
- 主机 UVC & UAC 类 EHCI IP 中 ISO 驱动和 UAC/UVC 框架
|
||||
- EHCI IP 中 ISO 驱动和 UAC/UVC 框架,搭配主机 UVC & UAC 类(这部分是开源的)使用。iso 支持一个微帧 1/2/3 包,支持 MJPEG 和 YUV 摄像头
|
||||
|
||||
.. figure:: img/ehci_hostuvc1.png
|
||||
.. figure:: img/ehci_hostuvc2.png
|
||||
|
||||
- 主机 UVC & UAC 类 DWC2 IP 中 ISO 驱动和 UAC/UVC 框架
|
||||
演示 USB Host UVC 驱动 648 * 480 YUV 摄像头。FPS 30。
|
||||
|
||||
.. figure:: img/usbhost_uvc.gif
|
||||
|
||||
- DWC2 IP 中 ISO 驱动和 UAC/UVC 框架,搭配主机 UVC & UAC 类(这部分是开源的)使用。iso 支持一个微帧 1/2/3 包,支持 MJPEG 和 YUV 摄像头
|
||||
|
||||
.. figure:: img/dwc2_hostuvc1.png
|
||||
.. figure:: img/dwc2_hostuvc2.png
|
||||
.. figure:: img/dwc2_hostuvc3.png
|
||||
.. figure:: img/dwc2_hostuac.png
|
||||
|
||||
- 主机 UVC & UAC 类 MUSB IP 中 ISO 驱动和 UAC/UVC 框架, MUSB 需要为 mentor 公司制定的标准 IP
|
||||
- MUSB IP 中 ISO 驱动和 UAC/UVC 框架,搭配主机 UVC & UAC 类(这部分是开源的)使用。MUSB 需要为 mentor 公司制定的标准 IP
|
||||
|
||||
- 从机 MTP 类驱动, 支持多文件和多文件夹,支持 MCU 端增删文件并与 PC 同步
|
||||
|
||||
@@ -34,5 +39,5 @@
|
||||
.. figure:: img/rndistx.png
|
||||
.. figure:: img/rndisrx.png
|
||||
|
||||
- 定制化 class 驱动或者 IP 驱动
|
||||
- 定制化 class 驱动或者 IP 驱动适配
|
||||
- 技术支持相关
|
||||
|
Before Width: | Height: | Size: 503 KiB After Width: | Height: | Size: 684 KiB |
@@ -134,4 +134,32 @@ v1.5.1
|
||||
- **dwc2 增加多个 usbport 不同参数的配置功能,比如一个全速一个高速,fifo配置和phy配置不同**
|
||||
- **ehci 在控制传输中如果没有 nodata 阶段会导致 data qtd 未释放,导致内存泄漏**
|
||||
- **dwc2 读取 setup 使用 usbd_get_next_ep0_state 去判断,避免 setup 和 ep0 out 使用在 USB_OTG_DOEPINT_XFRC 状态下冲突**
|
||||
- sifli usb device 初步支持
|
||||
- sifli usb device 初步支持
|
||||
|
||||
v1.5.2
|
||||
----------------------
|
||||
|
||||
- 对 1.5.1 下 rt-thread 组件的一些 bugfix
|
||||
- idf timer osal 替换为 esp timer,freertos timer会有启动失败的可能性;xTaskCreate 使用 xTaskCreatePinnedToCore 替换,方便多核使用
|
||||
- 主机枚举中,删除描述符溢出相关的 ASSERT 操作,改成返回错误。获取字符串描述符改成支持才获取。2 ms 延时改成 10ms,因为一些 os 使用的是 100hz,会造成延时失效
|
||||
- **dwc2 ep mult 支持,split 传输代码优化,对 split 相关的 cache 处理修改**
|
||||
- **dwc2 halt 中不能清除 USB_OTG_HCCHAR_EPDIR,reset port 中使用超时机制,防止在枚举时由于拔出而造成死等**
|
||||
- 更新 DWC2 中 at32,stm32,kendryte,espressif glue 代码
|
||||
- musb 对于标准的 IP 结构采用独立 EP 控制寄存器组,不使用 EPIDX 寄存器去控制
|
||||
- 删除所有 CONFIG_USBDEV_EP_NUM & CONFIG_USBHOST_PIPE_NUM,不再使用,因为 IP 本身会携带这些信息,或者厂家 SDK 提供了对应的宏
|
||||
- CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 默认使用 2 减少内存,只有 UVC 和UAC 使用(商业收费),所以不需要开很大
|
||||
- urb interval 从 u8 改 u32,最大支持 2^15 * 125us
|
||||
|
||||
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
|
||||
@@ -1,4 +1,4 @@
|
||||
version: "1.5.1"
|
||||
version: "1.5.3"
|
||||
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
|
||||
tags:
|
||||
- usb
|
||||
|
||||
@@ -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,16 +149,13 @@
|
||||
#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
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
@@ -247,9 +249,16 @@
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define ESP_USB_FS0_BASE 0x60080000
|
||||
#define ESP_USBD_BASE ESP_USB_FS0_BASE
|
||||
#define ESP_USBH_BASE ESP_USB_FS0_BASE
|
||||
#define CONFIG_USBDEV_MAX_BUS 1
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ESP_USB_HS0_BASE 0x50000000
|
||||
#define ESP_USB_FS0_BASE 0x50040000
|
||||
#define ESP_USBD_BASE ESP_USB_HS0_BASE
|
||||
#define ESP_USBH_BASE ESP_USB_HS0_BASE
|
||||
#define CONFIG_USBDEV_MAX_BUS 2
|
||||
#define CONFIG_USBHOST_MAX_BUS 2
|
||||
#define CONFIG_USB_HS
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
@@ -16,7 +17,7 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size,
|
||||
{
|
||||
TaskHandle_t htask = NULL;
|
||||
stack_size /= sizeof(StackType_t);
|
||||
xTaskCreate(entry, name, stack_size, args, configMAX_PRIORITIES - 1 - prio, &htask);
|
||||
xTaskCreatePinnedToCore(entry, name, stack_size, args, configMAX_PRIORITIES - 1 - prio, &htask, CONFIG_ESP_TIMER_TASK_AFFINITY);
|
||||
return (usb_osal_thread_t)htask;
|
||||
}
|
||||
|
||||
@@ -145,9 +146,9 @@ int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
|
||||
}
|
||||
}
|
||||
|
||||
static void __usb_timeout(TimerHandle_t *handle)
|
||||
static void usb_timeout(void *arg)
|
||||
{
|
||||
struct usb_osal_timer *timer = (struct usb_osal_timer *)pvTimerGetTimerID((TimerHandle_t)handle);
|
||||
struct usb_osal_timer *timer = (struct usb_osal_timer *)arg;
|
||||
|
||||
timer->handler(timer->argument);
|
||||
}
|
||||
@@ -155,50 +156,56 @@ static void __usb_timeout(TimerHandle_t *handle)
|
||||
struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ms, usb_timer_handler_t handler, void *argument, bool is_period)
|
||||
{
|
||||
struct usb_osal_timer *timer;
|
||||
(void)name;
|
||||
|
||||
timer = pvPortMalloc(sizeof(struct usb_osal_timer));
|
||||
|
||||
if (timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(timer, 0, sizeof(struct usb_osal_timer));
|
||||
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = usb_timeout,
|
||||
// argument specified here will be passed to timer callback function
|
||||
.arg = (void *)timer,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = name,
|
||||
.skip_unhandled_events = true
|
||||
};
|
||||
|
||||
timer->handler = handler;
|
||||
timer->argument = argument;
|
||||
timer->is_period = is_period;
|
||||
timer->timeout_ms = timeout_ms;
|
||||
|
||||
timer->timer = (void *)xTimerCreate("usb_tim", pdMS_TO_TICKS(timeout_ms), is_period, timer, (TimerCallbackFunction_t)__usb_timeout);
|
||||
if (timer->timer == NULL) {
|
||||
if (esp_timer_create(&timer_args, (esp_timer_handle_t *)&timer->timer) != ESP_OK) {
|
||||
vPortFree(timer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
void usb_osal_timer_delete(struct usb_osal_timer *timer)
|
||||
{
|
||||
xTimerStop(timer->timer, 0);
|
||||
xTimerDelete(timer->timer, 0);
|
||||
esp_timer_stop((esp_timer_handle_t)timer->timer);
|
||||
esp_timer_delete((esp_timer_handle_t)timer->timer);
|
||||
vPortFree(timer);
|
||||
}
|
||||
|
||||
void usb_osal_timer_start(struct usb_osal_timer *timer)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
int ret;
|
||||
esp_timer_stop((esp_timer_handle_t)timer->timer);
|
||||
|
||||
if (xPortInIsrContext()) {
|
||||
ret = xTimerStartFromISR(timer->timer, &xHigherPriorityTaskWoken);
|
||||
if (ret == pdPASS) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
if (timer->is_period) {
|
||||
esp_timer_start_periodic((esp_timer_handle_t)timer->timer, ((uint64_t)timer->timeout_ms) * 1000);
|
||||
} else {
|
||||
xTimerStart(timer->timer, 0);
|
||||
esp_timer_start_once((esp_timer_handle_t)timer->timer, ((uint64_t)timer->timeout_ms) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_osal_timer_stop(struct usb_osal_timer *timer)
|
||||
{
|
||||
xTimerStop(timer->timer, 0);
|
||||
esp_timer_stop((esp_timer_handle_t)timer->timer);
|
||||
}
|
||||
|
||||
size_t usb_osal_enter_critical_section(void)
|
||||
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -12,14 +12,16 @@
|
||||
#error must enable RT_USING_TIMER_SOFT to support timer callback in thread
|
||||
#endif
|
||||
|
||||
#if RT_TIMER_THREAD_STACK_SIZE < 2048
|
||||
#error "RT_TIMER_THREAD_STACK_SIZE must be >= 2048"
|
||||
#if RT_TIMER_THREAD_STACK_SIZE < 1024
|
||||
#error "RT_TIMER_THREAD_STACK_SIZE must be >= 1024"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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
|
||||
@@ -28,9 +30,6 @@
|
||||
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifndef CONFIG_USB_DCACHE_ENABLE
|
||||
#error CONFIG_USB_DCACHE_ENABLE must be enabled
|
||||
#endif
|
||||
#if RT_ALIGN_SIZE != 32 && RT_ALIGN_SIZE != 64
|
||||
#error RT_ALIGN_SIZE must be cacheline to 32 or 64
|
||||
#error CONFIG_USB_DCACHE_ENABLE must be enabled if you do not config nocache ram
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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 RT_USING_CACHE
|
||||
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;
|
||||
}
|
||||
@@ -190,7 +186,7 @@ rt_err_t usbd_serial_register(struct usbd_serial *serial,
|
||||
device->user_data = data;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
@@ -209,6 +205,13 @@ void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
serial = &g_usbd_serial_cdc_acm[devno];
|
||||
if (serial->out_ep == ep) {
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbd_serial_cdc_acm_rx_buf[serial->minor], nbytes);
|
||||
usbd_ep_start_read(serial->busid, serial->out_ep,
|
||||
g_usbd_serial_cdc_acm_rx_buf[serial->minor],
|
||||
usbd_get_ep_mps(serial->busid, serial->out_ep));
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -269,4 +272,4 @@ void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep)
|
||||
}
|
||||
|
||||
USB_LOG_INFO("USB CDC ACM Serial Device %s initialized\n", serial->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -587,7 +572,7 @@ rt_err_t usbh_serial_register(struct usbh_serial *serial,
|
||||
device->user_data = data;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
@@ -911,4 +896,4 @@ void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
|
||||
serial = (struct usbh_serial *)pl2303_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -202,7 +202,6 @@ VOID _fx_usbh_msc_driver(FX_MEDIA *media_ptr)
|
||||
media_ptr->fx_media_driver_status = FX_IO_ERROR;
|
||||
return;
|
||||
}
|
||||
printf("read success\r\n");
|
||||
/* Successful driver request. */
|
||||
media_ptr->fx_media_driver_status = FX_SUCCESS;
|
||||
break;
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#define CHIPIDEA_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
|
||||
#define QTD_COUNT_EACH_ENDPOINT (8U)
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 8
|
||||
#endif
|
||||
|
||||
/* ENDPTCTRL */
|
||||
enum {
|
||||
ENDPTCTRL_STALL = CHIPIDEA_BITSMASK(1, 0),
|
||||
@@ -590,10 +594,15 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
USB_ASSERT_MSG(!((uintptr_t)data % CONFIG_USB_ALIGN_SIZE), "data is not aligned %d", CONFIG_USB_ALIGN_SIZE);
|
||||
#endif
|
||||
|
||||
g_chipidea_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
g_chipidea_udc[busid].in_ep[ep_idx].xfer_len = data_len;
|
||||
g_chipidea_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
|
||||
chipidea_start_xfer(busid, ep, (uint8_t *)data, data_len);
|
||||
|
||||
return 0;
|
||||
@@ -610,10 +619,15 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
USB_ASSERT_MSG(!((uintptr_t)data % CONFIG_USB_ALIGN_SIZE), "data is not aligned %d", CONFIG_USB_ALIGN_SIZE);
|
||||
#endif
|
||||
|
||||
g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
g_chipidea_udc[busid].out_ep[ep_idx].xfer_len = data_len;
|
||||
g_chipidea_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
usb_dcache_invalidate((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
|
||||
chipidea_start_xfer(busid, ep, data, data_len);
|
||||
|
||||
return 0;
|
||||
@@ -645,7 +659,7 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
|
||||
memset(g_chipidea_udc[busid].out_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
|
||||
usbd_event_reset_handler(busid);
|
||||
chipidea_bus_reset(busid, 64);
|
||||
chipidea_bus_reset(busid, g_chipidea_udc[busid].in_ep[0].ep_mps);
|
||||
}
|
||||
|
||||
if (int_status & intr_suspend) {
|
||||
@@ -708,6 +722,7 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
if (ep_addr & 0x80) {
|
||||
usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len);
|
||||
} else {
|
||||
usb_dcache_invalidate((uintptr_t)g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(transfer_len, CONFIG_USB_ALIGN_SIZE));
|
||||
usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Note
|
||||
|
||||
If you are using more than one port, all ip parameters must be the same(like fifo num, endpoint num, dma support and so on), otherwise give up using multi ports.
|
||||
Please note that host must support dma mode.
|
||||
|
||||
## Support Chip List
|
||||
|
||||
## STM32
|
||||
### STM32
|
||||
|
||||
**有且仅有 PB14/PB15 引脚支持 host 模式, 部分 F7/H7 可能 PA11/PA12 也支持**。
|
||||
|
||||
@@ -16,13 +16,13 @@ If you are using more than one port, all ip parameters must be the same(like fif
|
||||
- STM32L4xx
|
||||
- STM32U5xx
|
||||
|
||||
## AT32
|
||||
### AT32
|
||||
|
||||
**有且仅有 AT32F405xx PB14/PB15引脚支持 host 模式**。
|
||||
|
||||
- AT32F402xx、AT32F405xx、AT32F415xx、AT32F423xx、AT32F425xx、AT32F435xx、AT32F437xx
|
||||
|
||||
## GD32
|
||||
### GD32
|
||||
|
||||
**由于无法读取 DWC2 配置信息,并且有部分寄存器是非标准的,因此暂时无法支持 GD 系列**。
|
||||
|
||||
@@ -30,22 +30,22 @@ If you are using more than one port, all ip parameters must be the same(like fif
|
||||
- GD32F405、GD32F407
|
||||
- GD32F350、GD32F450
|
||||
|
||||
## HC32
|
||||
### HC32
|
||||
|
||||
- HC32F4A0
|
||||
|
||||
## Espressif
|
||||
### Espressif
|
||||
|
||||
- ESP32S2、ESP32S3、ESP32P4
|
||||
|
||||
## Sophgo
|
||||
### Sophgo
|
||||
|
||||
- CV18xx
|
||||
|
||||
## Kendryte
|
||||
### Kendryte
|
||||
|
||||
- K230
|
||||
|
||||
## Nationstech
|
||||
### Nationstech
|
||||
|
||||
- N32H4X
|
||||
@@ -15,6 +15,13 @@
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||
#endif
|
||||
#elif defined (__ICCARM__)
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||
#endif
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma clang diagnostic push
|
||||
@@ -172,7 +179,12 @@ static inline void dwc2_set_mode(uint8_t busid, uint8_t mode)
|
||||
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
|
||||
}
|
||||
|
||||
usbd_dwc2_delay_ms(50);
|
||||
while (1) {
|
||||
if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_DEVICE) {
|
||||
break;
|
||||
}
|
||||
usbd_dwc2_delay_ms(10);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int dwc2_flush_rxfifo(uint8_t busid)
|
||||
@@ -329,6 +341,8 @@ static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup)
|
||||
USB_OTG_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
|
||||
|
||||
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
||||
usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE));
|
||||
|
||||
USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
|
||||
/* EP enable */
|
||||
USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
|
||||
@@ -670,6 +684,7 @@ uint8_t usbd_get_port_speed(uint8_t busid)
|
||||
int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
|
||||
uint16_t ep_mps;
|
||||
|
||||
USB_ASSERT_MSG(ep_idx < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1), "Ep addr %02x overflow", ep->bEndpointAddress);
|
||||
|
||||
@@ -677,14 +692,34 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
g_dwc2_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
|
||||
ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
if (ep_idx == 0) {
|
||||
switch (ep_mps) {
|
||||
case 64:
|
||||
ep_mps = EP_MPS_64;
|
||||
break;
|
||||
case 32:
|
||||
ep_mps = EP_MPS_32;
|
||||
break;
|
||||
case 16:
|
||||
ep_mps = EP_MPS_16;
|
||||
break;
|
||||
case 8:
|
||||
ep_mps = EP_MPS_8;
|
||||
break;
|
||||
|
||||
default:
|
||||
ep_mps = EP_MPS_64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx));
|
||||
|
||||
if ((USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_USBAEP) == 0) {
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & USB_OTG_DOEPCTL_MPSIZ) |
|
||||
((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) |
|
||||
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
|
||||
USB_OTG_DOEPCTL_USBAEP;
|
||||
}
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (ep_mps & USB_OTG_DOEPCTL_MPSIZ) |
|
||||
((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) |
|
||||
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
|
||||
USB_OTG_DOEPCTL_USBAEP;
|
||||
} else {
|
||||
uint16_t fifo_size;
|
||||
if (ep_idx == 0) {
|
||||
@@ -698,14 +733,34 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
g_dwc2_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
g_dwc2_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
|
||||
ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
if (ep_idx == 0) {
|
||||
switch (ep_mps) {
|
||||
case 64:
|
||||
ep_mps = EP_MPS_64;
|
||||
break;
|
||||
case 32:
|
||||
ep_mps = EP_MPS_32;
|
||||
break;
|
||||
case 16:
|
||||
ep_mps = EP_MPS_16;
|
||||
break;
|
||||
case 8:
|
||||
ep_mps = EP_MPS_8;
|
||||
break;
|
||||
|
||||
default:
|
||||
ep_mps = EP_MPS_64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx);
|
||||
|
||||
if ((USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0) {
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & USB_OTG_DIEPCTL_MPSIZ) |
|
||||
((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | (ep_idx << 22) |
|
||||
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
|
||||
USB_OTG_DIEPCTL_USBAEP;
|
||||
}
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= (ep_mps & USB_OTG_DIEPCTL_MPSIZ) |
|
||||
((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | (ep_idx << 22) |
|
||||
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
|
||||
USB_OTG_DIEPCTL_USBAEP;
|
||||
dwc2_flush_txfifo(busid, ep_idx);
|
||||
}
|
||||
return 0;
|
||||
@@ -877,8 +932,12 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SODDFRM;
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS ||
|
||||
g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
|
||||
USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
|
||||
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
|
||||
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & ((usbd_get_ep_mult(busid, ep) + 1) << 29));
|
||||
}
|
||||
|
||||
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
||||
@@ -943,6 +1002,7 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
|
||||
}
|
||||
|
||||
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
||||
usb_dcache_invalidate((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
|
||||
}
|
||||
if (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
@@ -1017,7 +1077,9 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
}
|
||||
|
||||
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
|
||||
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
|
||||
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
||||
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
|
||||
|
||||
if (usbd_get_ep0_next_state(busid) == USBD_EP0_STATE_SETUP) {
|
||||
@@ -1027,15 +1089,19 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
} else {
|
||||
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
|
||||
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
|
||||
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
|
||||
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
||||
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
|
||||
}
|
||||
}
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
process_setup:
|
||||
// clang-format on
|
||||
if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) {
|
||||
usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE));
|
||||
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
||||
usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,102 +14,102 @@
|
||||
#define dwc2_readl(addr) \
|
||||
(*(volatile uint32_t *)(addr))
|
||||
|
||||
#define GUID_OFFSET HSOTG_REG(0x003c)
|
||||
#define GUID_OFFSET HSOTG_REG(0x003C)
|
||||
|
||||
#define GSNPSID_OFFSET HSOTG_REG(0x0040)
|
||||
#define GSNPSID_ID_MASK 0xffff0000
|
||||
#define GSNPSID_ID_MASK (0xFFFF0000UL)
|
||||
|
||||
#define GHWCFG1_OFFSET HSOTG_REG(0x0044)
|
||||
|
||||
#define GHWCFG2_OFFSET HSOTG_REG(0x0048)
|
||||
#define GHWCFG2_OTG_ENABLE_IC_USB (1U << 31)
|
||||
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1f << 26)
|
||||
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT 26
|
||||
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24)
|
||||
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT 24
|
||||
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22)
|
||||
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT 22
|
||||
#define GHWCFG2_MULTI_PROC_INT (1 << 20)
|
||||
#define GHWCFG2_DYNAMIC_FIFO (1 << 19)
|
||||
#define GHWCFG2_PERIO_EP_SUPPORTED (1 << 18)
|
||||
#define GHWCFG2_NUM_HOST_CHAN_MASK (0xf << 14)
|
||||
#define GHWCFG2_NUM_HOST_CHAN_SHIFT 14
|
||||
#define GHWCFG2_NUM_DEV_EP_MASK (0xf << 10)
|
||||
#define GHWCFG2_NUM_DEV_EP_SHIFT 10
|
||||
#define GHWCFG2_FS_PHY_TYPE_MASK (0x3 << 8)
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHIFT 8
|
||||
#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0
|
||||
#define GHWCFG2_FS_PHY_TYPE_DEDICATED 1
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI 2
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI 3
|
||||
#define GHWCFG2_HS_PHY_TYPE_MASK (0x3 << 6)
|
||||
#define GHWCFG2_HS_PHY_TYPE_SHIFT 6
|
||||
#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
|
||||
#define GHWCFG2_HS_PHY_TYPE_UTMI 1
|
||||
#define GHWCFG2_HS_PHY_TYPE_ULPI 2
|
||||
#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
|
||||
#define GHWCFG2_POINT2POINT (1 << 5)
|
||||
#define GHWCFG2_ARCHITECTURE_MASK (0x3 << 3)
|
||||
#define GHWCFG2_ARCHITECTURE_SHIFT 3
|
||||
#define GHWCFG2_SLAVE_ONLY_ARCH 0
|
||||
#define GHWCFG2_EXT_DMA_ARCH 1
|
||||
#define GHWCFG2_INT_DMA_ARCH 2
|
||||
#define GHWCFG2_OP_MODE_MASK (0x7 << 0)
|
||||
#define GHWCFG2_OP_MODE_SHIFT 0
|
||||
#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE 0
|
||||
#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE 1
|
||||
#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE 2
|
||||
#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
|
||||
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
|
||||
#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
|
||||
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
|
||||
#define GHWCFG2_OP_MODE_UNDEFINED 7
|
||||
#define GHWCFG2_OTG_ENABLE_IC_USB (0x01UL << 31U)
|
||||
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1FUL << 26U)
|
||||
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT (26U)
|
||||
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x03UL << 24U)
|
||||
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT (24U)
|
||||
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x03UL << 22U)
|
||||
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT (22U)
|
||||
#define GHWCFG2_MULTI_PROC_INT (0x01UL << 20U)
|
||||
#define GHWCFG2_DYNAMIC_FIFO (0x01UL << 19U)
|
||||
#define GHWCFG2_PERIO_EP_SUPPORTED (0x01UL << 18U)
|
||||
#define GHWCFG2_NUM_HOST_CHAN_MASK (0x0FUL << 14U)
|
||||
#define GHWCFG2_NUM_HOST_CHAN_SHIFT (14U)
|
||||
#define GHWCFG2_NUM_DEV_EP_MASK (0x0FUL << 10U)
|
||||
#define GHWCFG2_NUM_DEV_EP_SHIFT (10U)
|
||||
#define GHWCFG2_FS_PHY_TYPE_MASK (0x03UL << 8U)
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHIFT (8U)
|
||||
#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED (0x00UL)
|
||||
#define GHWCFG2_FS_PHY_TYPE_DEDICATED (0x01UL)
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI (0x02UL)
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI (0x03UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_MASK (0x03UL << 6U)
|
||||
#define GHWCFG2_HS_PHY_TYPE_SHIFT (6U)
|
||||
#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED (0x00UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_UTMI (0x01UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_ULPI (0x02UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI (0x03UL)
|
||||
#define GHWCFG2_POINT2POINT (0x01UL << 5U)
|
||||
#define GHWCFG2_ARCHITECTURE_MASK (0x03UL << 3U)
|
||||
#define GHWCFG2_ARCHITECTURE_SHIFT (3U)
|
||||
#define GHWCFG2_SLAVE_ONLY_ARCH (0x00UL)
|
||||
#define GHWCFG2_EXT_DMA_ARCH (0x01UL)
|
||||
#define GHWCFG2_INT_DMA_ARCH (0x02UL)
|
||||
#define GHWCFG2_OP_MODE_MASK (0x07UL << 0U)
|
||||
#define GHWCFG2_OP_MODE_SHIFT (0U)
|
||||
#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE (0x00UL)
|
||||
#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE (0x01UL)
|
||||
#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE (0x02UL)
|
||||
#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE (0x03UL)
|
||||
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE (0x04UL)
|
||||
#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST (0x05UL)
|
||||
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST (0x06UL)
|
||||
#define GHWCFG2_OP_MODE_UNDEFINED (0x07UL)
|
||||
|
||||
#define GHWCFG3_OFFSET HSOTG_REG(0x004c)
|
||||
#define GHWCFG3_DFIFO_DEPTH_MASK (0xffff << 16)
|
||||
#define GHWCFG3_DFIFO_DEPTH_SHIFT 16
|
||||
#define GHWCFG3_OTG_LPM_EN (1 << 15)
|
||||
#define GHWCFG3_BC_SUPPORT (1 << 14)
|
||||
#define GHWCFG3_OTG_ENABLE_HSIC (1 << 13)
|
||||
#define GHWCFG3_ADP_SUPP (1 << 12)
|
||||
#define GHWCFG3_SYNCH_RESET_TYPE (1 << 11)
|
||||
#define GHWCFG3_OPTIONAL_FEATURES (1 << 10)
|
||||
#define GHWCFG3_VENDOR_CTRL_IF (1 << 9)
|
||||
#define GHWCFG3_I2C (1 << 8)
|
||||
#define GHWCFG3_OTG_FUNC (1 << 7)
|
||||
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4)
|
||||
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT 4
|
||||
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xf << 0)
|
||||
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT 0
|
||||
#define GHWCFG3_OFFSET HSOTG_REG(0x004C)
|
||||
#define GHWCFG3_DFIFO_DEPTH_MASK (0xFFFFUL << 16U)
|
||||
#define GHWCFG3_DFIFO_DEPTH_SHIFT (16U)
|
||||
#define GHWCFG3_OTG_LPM_EN (0x0001UL << 15U)
|
||||
#define GHWCFG3_BC_SUPPORT (0x0001UL << 14U)
|
||||
#define GHWCFG3_OTG_ENABLE_HSIC (0x0001UL << 13U)
|
||||
#define GHWCFG3_ADP_SUPP (0x0001UL << 12U)
|
||||
#define GHWCFG3_SYNCH_RESET_TYPE (0x0001UL << 11U)
|
||||
#define GHWCFG3_OPTIONAL_FEATURES (0x0001UL << 10U)
|
||||
#define GHWCFG3_VENDOR_CTRL_IF (0x0001UL << 9U)
|
||||
#define GHWCFG3_I2C (0x0001UL << 8U)
|
||||
#define GHWCFG3_OTG_FUNC (0x0001UL << 7U)
|
||||
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x0007UL << 4U)
|
||||
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT (4U)
|
||||
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0x000FUL << 0U)
|
||||
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT (0U)
|
||||
|
||||
#define GHWCFG4_OFFSET HSOTG_REG(0x0050)
|
||||
#define GHWCFG4_DESC_DMA_DYN (1U << 31)
|
||||
#define GHWCFG4_DESC_DMA (1 << 30)
|
||||
#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26)
|
||||
#define GHWCFG4_NUM_IN_EPS_SHIFT 26
|
||||
#define GHWCFG4_DED_FIFO_EN (1 << 25)
|
||||
#define GHWCFG4_DED_FIFO_SHIFT 25
|
||||
#define GHWCFG4_SESSION_END_FILT_EN (1 << 24)
|
||||
#define GHWCFG4_B_VALID_FILT_EN (1 << 23)
|
||||
#define GHWCFG4_A_VALID_FILT_EN (1 << 22)
|
||||
#define GHWCFG4_VBUS_VALID_FILT_EN (1 << 21)
|
||||
#define GHWCFG4_IDDIG_FILT_EN (1 << 20)
|
||||
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xf << 16)
|
||||
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT 16
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2
|
||||
#define GHWCFG4_ACG_SUPPORTED (1 << 12)
|
||||
#define GHWCFG4_IPG_ISOC_SUPPORTED (1 << 11)
|
||||
#define GHWCFG4_SERVICE_INTERVAL_SUPPORTED (1 << 10)
|
||||
#define GHWCFG4_XHIBER (1 << 7)
|
||||
#define GHWCFG4_HIBER (1 << 6)
|
||||
#define GHWCFG4_MIN_AHB_FREQ (1 << 5)
|
||||
#define GHWCFG4_POWER_OPTIMIZ (1 << 4)
|
||||
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xf << 0)
|
||||
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT 0
|
||||
#define GHWCFG4_DESC_DMA_DYN (0x1UL << 31U)
|
||||
#define GHWCFG4_DESC_DMA (0x1UL << 30U)
|
||||
#define GHWCFG4_NUM_IN_EPS_MASK (0xFUL << 26U)
|
||||
#define GHWCFG4_NUM_IN_EPS_SHIFT (26U)
|
||||
#define GHWCFG4_DED_FIFO_EN (0x1UL << 25U)
|
||||
#define GHWCFG4_DED_FIFO_SHIFT (25U)
|
||||
#define GHWCFG4_SESSION_END_FILT_EN (0x1UL << 24U)
|
||||
#define GHWCFG4_B_VALID_FILT_EN (0x1UL << 23U)
|
||||
#define GHWCFG4_A_VALID_FILT_EN (0x1UL << 22U)
|
||||
#define GHWCFG4_VBUS_VALID_FILT_EN (0x1UL << 21U)
|
||||
#define GHWCFG4_IDDIG_FILT_EN (0x1UL << 20U)
|
||||
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xFUL << 16U)
|
||||
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT (16U)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3UL << 14U)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT (14U)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 (0x0UL)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 (0x1UL)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 (0x2UL)
|
||||
#define GHWCFG4_ACG_SUPPORTED (0x1UL << 12U)
|
||||
#define GHWCFG4_IPG_ISOC_SUPPORTED (0x1UL << 11U)
|
||||
#define GHWCFG4_SERVICE_INTERVAL_SUPPORTED (0x1UL << 10U)
|
||||
#define GHWCFG4_XHIBER (0x1UL << 7U)
|
||||
#define GHWCFG4_HIBER (0x1UL << 6U)
|
||||
#define GHWCFG4_MIN_AHB_FREQ (0x1UL << 5U)
|
||||
#define GHWCFG4_POWER_OPTIMIZ (0x1UL << 4U)
|
||||
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xFUL << 0U)
|
||||
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT (0U)
|
||||
|
||||
/**
|
||||
* struct dwc2_hw_params - Autodetected parameters.
|
||||
|
||||
@@ -215,9 +215,7 @@ typedef struct
|
||||
#define USB_OTG_HCFG_FSLSS_Pos (2U)
|
||||
#define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */
|
||||
#define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */
|
||||
#define USB_OTG_HFIR_RELOAD_CTRL_Pos (16U)
|
||||
#define USB_OTG_HFIR_RELOAD_CTRL_Msk (0x1UL << USB_OTG_HFIR_RELOAD_CTRL_Pos)
|
||||
#define USB_OTG_HFIR_RELOAD_CTRL USB_OTG_HFIR_RELOAD_CTRL_Msk
|
||||
|
||||
/******************** Bit definition for USB_OTG_DCFG register ********************/
|
||||
|
||||
#define USB_OTG_DCFG_DSPD_Pos (0U)
|
||||
@@ -335,6 +333,9 @@ typedef struct
|
||||
#define USB_OTG_HFIR_FRIVL_Pos (0U)
|
||||
#define USB_OTG_HFIR_FRIVL_Msk (0xFFFFUL << USB_OTG_HFIR_FRIVL_Pos) /*!< 0x0000FFFF */
|
||||
#define USB_OTG_HFIR_FRIVL USB_OTG_HFIR_FRIVL_Msk /*!< Frame interval */
|
||||
#define USB_OTG_HFIR_RELOAD_CTRL_Pos (16U)
|
||||
#define USB_OTG_HFIR_RELOAD_CTRL_Msk (0x1UL << USB_OTG_HFIR_RELOAD_CTRL_Pos)
|
||||
#define USB_OTG_HFIR_RELOAD_CTRL USB_OTG_HFIR_RELOAD_CTRL_Msk
|
||||
|
||||
/******************** Bit definition for USB_OTG_HFNUM register ********************/
|
||||
#define USB_OTG_HFNUM_FRNUM_Pos (0U)
|
||||
|
||||