Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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
|
||||
@@ -71,7 +71,7 @@ elseif(ESP_PLATFORM)
|
||||
${cherryusb_incs}
|
||||
${freertos_include}
|
||||
PRIV_REQUIRES
|
||||
usb esp_mm esp_netif
|
||||
usb esp_mm esp_netif esp_timer
|
||||
LDFRAGMENTS
|
||||
${ldfragments}
|
||||
)
|
||||
|
||||
@@ -465,12 +465,14 @@ if PKG_USING_CHERRYUSB
|
||||
|
||||
choice
|
||||
prompt "Version"
|
||||
default PKG_USING_CHERRYUSB_V010500
|
||||
default PKG_USING_CHERRYUSB_V010502
|
||||
help
|
||||
Select the package version
|
||||
|
||||
config PKG_USING_CHERRYUSB_LATEST_VERSION
|
||||
bool "latest"
|
||||
config PKG_USING_CHERRYUSB_V010502
|
||||
bool "v1.5.2"
|
||||
config PKG_USING_CHERRYUSB_V010501
|
||||
bool "v1.5.1"
|
||||
config PKG_USING_CHERRYUSB_V010500
|
||||
@@ -488,6 +490,7 @@ if PKG_USING_CHERRYUSB
|
||||
config PKG_CHERRYUSB_VER
|
||||
string
|
||||
default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION
|
||||
default "v1.5.2" if PKG_USING_CHERRYUSB_V010502
|
||||
default "v1.5.1" if PKG_USING_CHERRYUSB_V010501
|
||||
default "v1.5.0" if PKG_USING_CHERRYUSB_V010500
|
||||
default "v1.4.3" if PKG_USING_CHERRYUSB_V010403
|
||||
|
||||
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)|<= latest | Official ongoing |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|
||||
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update |
|
||||
|
||||
## Package Support
|
||||
|
||||
@@ -226,5 +229,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
|
||||
|
||||
Thanks to the following companies for their support (in no particular order):
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" /> <img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/sifli.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
|
||||
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)|<= latest | Official ongoing |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official |
|
||||
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official |
|
||||
|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community |
|
||||
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update |
|
||||
|
||||
## 软件包支持
|
||||
|
||||
@@ -228,5 +231,4 @@ CherryUSB 微信群:与我联系后邀请加入
|
||||
|
||||
感谢以下企业支持(顺序不分先后):
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" /> <img src="docs/assets/actions.jpg" width="100" height="80" /> <img src="docs/assets/sifli.jpg" width="100" height="80" /> <img src="docs/assets/nationstech.jpg" width="100" height="80" />
|
||||
|
||||
@@ -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 = 2
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
||||
@@ -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,16 +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
|
||||
|
||||
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
|
||||
* the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
|
||||
*
|
||||
* in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them).
|
||||
*/
|
||||
// #define CONFIG_USB_HS
|
||||
|
||||
#ifndef usb_phyaddr2ramaddr
|
||||
#define usb_phyaddr2ramaddr(addr) (addr)
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -179,15 +179,15 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length
|
||||
USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
|
||||
return -2;
|
||||
} else {
|
||||
USB_LOG_RAW("Hub Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_RAW("PortPwrCtrlMask: 0x%02x \r\n", desc->PortPwrCtrlMask);
|
||||
USB_LOG_DBG("Hub Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_DBG("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_DBG("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_DBG("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_DBG("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_DBG("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_DBG("PortPwrCtrlMask: 0x%02x \r\n", desc->PortPwrCtrlMask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -203,14 +203,14 @@ static int parse_hub_ss_descriptor(struct usb_hub_ss_descriptor *desc, uint16_t
|
||||
USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType);
|
||||
return -2;
|
||||
} else {
|
||||
USB_LOG_RAW("SuperSpeed Hub Descriptor:\r\n");
|
||||
USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
USB_LOG_DBG("SuperSpeed Hub Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
|
||||
USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
|
||||
USB_LOG_DBG("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts);
|
||||
USB_LOG_DBG("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics);
|
||||
USB_LOG_DBG("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood);
|
||||
USB_LOG_DBG("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent);
|
||||
USB_LOG_DBG("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -403,7 +403,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
|
||||
USB_LOG_INFO("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange);
|
||||
USB_LOG_DBG("port %u, status:0x%03x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -497,7 +497,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
USB_LOG_DBG("port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
/* First, clear all change bits */
|
||||
mask = 1;
|
||||
@@ -532,7 +532,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("Port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
USB_LOG_DBG("Port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
if (!(portchange & HUB_PORT_STATUS_C_CONNECTION) &&
|
||||
((portstatus & HUB_PORT_STATUS_CONNECTION) == connection)) {
|
||||
@@ -562,7 +562,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
if (portstatus & HUB_PORT_STATUS_CONNECTION) {
|
||||
ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_RESET);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to reset port %u,errorcode:%d\r\n", port, ret);
|
||||
USB_LOG_ERR("Failed to reset port %u, errorcode: %d\r\n", port + 1, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -576,11 +576,15 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
|
||||
portstatus = port_status.wPortStatus;
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("Port %u, status:0x%03x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
|
||||
if (!(portstatus & HUB_PORT_STATUS_RESET) && (portstatus & HUB_PORT_STATUS_ENABLE)) {
|
||||
if (portchange & HUB_PORT_STATUS_C_RESET) {
|
||||
ret = usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_RESET);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to clear port %u reset change, errorcode: %d\r\n", port, ret);
|
||||
USB_LOG_ERR("Failed to clear port %u reset change, errorcode: %d\r\n", port + 1, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
4
class/vendor/net/usbh_rtl8152.c
vendored
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 0x010502
|
||||
#define CHERRYUSB_VERSION_STR "v1.5.2"
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
100
core/usbh_core.c
@@ -228,12 +228,21 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
|
||||
cur_ep_num = intf_desc->bNumEndpoints;
|
||||
cur_ep = 0;
|
||||
|
||||
USB_ASSERT_MSG(cur_iface < CONFIG_USBHOST_MAX_INTERFACES,
|
||||
"Interface num %d overflow", cur_iface);
|
||||
USB_ASSERT_MSG(cur_alt_setting < CONFIG_USBHOST_MAX_INTF_ALTSETTINGS,
|
||||
"Interface altsetting num %d overflow", cur_alt_setting);
|
||||
USB_ASSERT_MSG(cur_ep_num <= CONFIG_USBHOST_MAX_ENDPOINTS,
|
||||
"Endpoint num %d overflow", cur_ep_num);
|
||||
if (cur_iface >= CONFIG_USBHOST_MAX_INTERFACES) {
|
||||
USB_LOG_ERR("Interface num %d overflow\r\n", cur_iface);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
if (cur_ep_num >= CONFIG_USBHOST_MAX_ENDPOINTS) {
|
||||
USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep_num);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
if (cur_alt_setting >= CONFIG_USBHOST_MAX_INTF_ALTSETTINGS) {
|
||||
USB_LOG_ERR("Interface altsetting num %d overflow\r\n", cur_alt_setting);
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
#if 0
|
||||
USB_LOG_DBG("Interface Descriptor:\r\n");
|
||||
USB_LOG_DBG("bLength: 0x%02x \r\n", intf_desc->bLength);
|
||||
@@ -389,7 +398,11 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
|
||||
ret = parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse device descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Extract the correct max packetsize from the device descriptor */
|
||||
dev_desc = (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid];
|
||||
@@ -427,7 +440,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
}
|
||||
|
||||
/* Wait device set address completely */
|
||||
usb_osal_msleep(2);
|
||||
usb_osal_msleep(10);
|
||||
|
||||
/*Reconfigure EP0 with the correct address */
|
||||
hport->dev_addr = dev_addr;
|
||||
@@ -469,7 +482,11 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_CONFIG_DESC);
|
||||
ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_CONFIG_DESC);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse config descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Read the full size of the configuration data */
|
||||
uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->wTotalLength;
|
||||
@@ -494,9 +511,10 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
|
||||
ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], wTotalLength);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Parse config fail\r\n");
|
||||
USB_LOG_ERR("Parse config descriptor fail\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumInterfaces);
|
||||
hport->raw_config_desc = usb_osal_malloc(wTotalLength + 1);
|
||||
if (hport->raw_config_desc == NULL) {
|
||||
@@ -512,35 +530,47 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
#ifdef CONFIG_USBHOST_GET_STRING_DESC
|
||||
uint8_t string_buffer[128];
|
||||
|
||||
/* Get Manufacturer string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
if (hport->device_desc.iManufacturer > 0) {
|
||||
/* Get Manufacturer string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support Manufacturer string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
|
||||
if (hport->device_desc.iProduct > 0) {
|
||||
/* Get Product string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Product string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get Product string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
USB_LOG_INFO("Product: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support Product string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Product: %s\r\n", string_buffer);
|
||||
if (hport->device_desc.iSerialNumber > 0) {
|
||||
/* Get SerialNumber string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer, 128);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get SerialNumber string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get SerialNumber string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
|
||||
} else {
|
||||
USB_LOG_WRN("Do not support SerialNumber string\r\n");
|
||||
}
|
||||
|
||||
USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
|
||||
#endif
|
||||
/* Select device configuration 1 */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
@@ -703,7 +733,7 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output, uint16_t output_len)
|
||||
{
|
||||
struct usb_setup_packet *setup = hport->setup;
|
||||
int ret;
|
||||
@@ -729,6 +759,10 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
|
||||
dst = output;
|
||||
len = src[0];
|
||||
|
||||
if (((len - 2) / 2) > output_len) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
while (i < len) {
|
||||
dst[j] = src[i];
|
||||
i += 2;
|
||||
|
||||
@@ -255,9 +255,10 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
|
||||
* @param hport Pointer to the USB hub port structure.
|
||||
* @param index Index of the string descriptor to retrieve.
|
||||
* @param output Pointer to the buffer where the retrieved descriptor will be stored.
|
||||
* @param output_len Length of the output buffer.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output);
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output, uint16_t output_len);
|
||||
|
||||
/**
|
||||
* @brief Sets the alternate setting for a USB interface on a specific hub port.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.2'
|
||||
version = '1.5.2'
|
||||
|
||||
# -- General configuration
|
||||
|
||||
|
||||
@@ -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**。
|
||||
|
||||
@@ -154,11 +165,10 @@ USB Device 移植要点
|
||||
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
|
||||
|
||||
- 如果使用 fsdev ip,(V1.5.0 开始需要增加 **fsdev/usb_glue_st.c**) 在 `usb_config.h` 中实现以下宏:
|
||||
- 如果使用 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 +198,7 @@ USB Host 移植要点
|
||||
|
||||
前面 6 步与 Device 一样。需要注意,host 驱动只支持带 dma 的 hs port (引脚是 PB14/PB15),所以 fs port (引脚是 PA11/PA12)不做支持(没有 dma 你玩什么主机)。
|
||||
|
||||
- 添加 CherryUSB 必须要的源码( **usbh_core.c** 、 **usbh_hub.c** 、 **usb_hc_dwc2.c** 、以及 **osal** 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 **usb host.c** 添加方便测试。
|
||||
- 添加 CherryUSB 必须要的源码( **usbh_core.c** 、 **usbh_hub.c** 、 **usb_hc_dwc2.c** 、 **usb_glue_st.c** 以及 **osal** 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 **usb host.c** 添加方便测试。
|
||||
|
||||
.. figure:: img/stm32_16.png
|
||||
|
||||
@@ -199,25 +209,16 @@ USB Host 移植要点
|
||||
|
||||
- 复制一份 **cherryusb_config_template.h**,放到 `Core/Inc` 目录下,并命名为 `usb_config.h`
|
||||
|
||||
- 增加 **usb_glue_st.c** 文件,并在 `usb_config.h` 中实现以下宏:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// 以下细节如有出入,请对照 stm32xxx.h 文件修改
|
||||
// 需要根据硬件实际的 fifo 深度进行修改,默认是最基础的配置
|
||||
#define CONFIG_USBHOST_PIPE_NUM 12
|
||||
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
|
||||
#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4)
|
||||
|
||||
.. note :: 以下两个步骤从 V1.5.0 开始不再需要,**fsdev/usb_glue_st.c**, **dwc2/usb_glue_st.c** 文件中已经实现
|
||||
|
||||
- 拷贝 **xxx_msp.c** 中的 `HAL_HCD_MspInit` 函数中的内容到 `usb_hc_low_level_init` 函数中,屏蔽 st 生成的 usb 初始化
|
||||
- 在中断函数中调用 `USBH_IRQHandler`,并传入 `busid`
|
||||
|
||||
.. figure:: img/stm32_19.png
|
||||
|
||||
- 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
- 如果芯片带 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 |
@@ -80,6 +80,14 @@ USB Host UVC
|
||||
|
||||
.. figure:: img/usbhost_uvc.gif
|
||||
|
||||
USB Host ASIX 网卡
|
||||
-----------------------
|
||||
|
||||
演示 USB Host 驱动 AX88772 USB 以太网模块。
|
||||
|
||||
.. figure:: img/usbhost_ax88772_1.png
|
||||
.. figure:: img/usbhost_ax88772_2.png
|
||||
|
||||
USB Host WIFI
|
||||
-----------------------
|
||||
|
||||
|
||||
|
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,18 @@ 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
|
||||
@@ -1,4 +1,4 @@
|
||||
version: "1.5.1"
|
||||
version: "1.5.2"
|
||||
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
|
||||
tags:
|
||||
- usb
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
@@ -247,9 +247,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)
|
||||
|
||||
@@ -12,10 +12,9 @@
|
||||
#error must enable RT_USING_TIMER_SOFT to support timer callback in thread
|
||||
#endif
|
||||
|
||||
#if RT_TIMER_THREAD_STACK_SIZE < 2048
|
||||
#error "RT_TIMER_THREAD_STACK_SIZE must be >= 2048"
|
||||
#if RT_TIMER_THREAD_STACK_SIZE < 1024
|
||||
#error "RT_TIMER_THREAD_STACK_SIZE must be >= 1024"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_ARM_CORTEX_M7) || \
|
||||
@@ -28,9 +27,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
|
||||
#warning CONFIG_USB_DCACHE_ENABLE must be enabled if you do not config nocache ram
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -123,7 +123,7 @@ static rt_ssize_t usbd_serial_write(struct rt_device *dev,
|
||||
}
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
@@ -190,7 +190,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 +209,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 +276,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,7 +587,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 +911,4 @@ void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
|
||||
serial = (struct usbh_serial *)pl2303_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
@@ -172,7 +172,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)
|
||||
@@ -777,6 +782,7 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
|
||||
}
|
||||
|
||||
if ((ep_idx == 0) && 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));
|
||||
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
||||
}
|
||||
|
||||
@@ -877,8 +883,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 +953,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 +1028,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,7 +1040,9 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -1035,7 +1050,9 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
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)
|
||||
|
||||
@@ -68,7 +68,7 @@ const struct dwc2_user_params param_pb14_pb15 = {
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 628,
|
||||
.host_rx_fifo_size = 624,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include "usbh_core.h"
|
||||
#include "usb_dwc2_param.h"
|
||||
|
||||
#define GET_USB_INDEX(reg_base) 0
|
||||
#define GET_USB_INTR_SOURCE(reg_base) ETS_USB_INTR_SOURCE
|
||||
#define GET_USB_PHY_TARGET(reg_base) USB_PHY_TARGET_INT
|
||||
#define GET_USB_PHY_SPEED(reg_base) USB_PHY_SPEED_UNDEFINED
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
|
||||
@@ -21,15 +25,24 @@
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#undef GET_USB_INDEX
|
||||
#define GET_USB_INDEX(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? 0 : 1)
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_USB_INTR_SOURCE ETS_USB_OTG_INTR_SOURCE
|
||||
#define USB_FS_INTR_SOURCE ETS_USB_OTG11_CH0_INTR_SOURCE
|
||||
#undef GET_USB_INTR_SOURCE
|
||||
#define GET_USB_INTR_SOURCE(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? DEFAULT_USB_INTR_SOURCE : USB_FS_INTR_SOURCE)
|
||||
#undef GET_USB_PHY_TARGET
|
||||
#define GET_USB_PHY_TARGET(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? USB_PHY_TARGET_UTMI : USB_PHY_TARGET_INT)
|
||||
#undef GET_USB_PHY_SPEED
|
||||
#define GET_USB_PHY_SPEED(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? USB_PHY_SPEED_HIGH : USB_PHY_SPEED_FULL)
|
||||
#else
|
||||
#define DEFAULT_CPU_FREQ_MHZ 160
|
||||
#endif
|
||||
|
||||
uint32_t SystemCoreClock = (DEFAULT_CPU_FREQ_MHZ * 1000 * 1000);
|
||||
static usb_phy_handle_t s_phy_handle = NULL;
|
||||
static intr_handle_t s_interrupt_handle = NULL;
|
||||
static usb_phy_handle_t s_phy_handle[SOC_USB_OTG_PERIPH_NUM] = {NULL};
|
||||
static intr_handle_t s_interrupt_handle[SOC_USB_OTG_PERIPH_NUM] = {NULL};
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
const struct dwc2_user_params param_fs = {
|
||||
@@ -123,29 +136,31 @@ const struct dwc2_user_params param_hs = {
|
||||
static void usb_dc_interrupt_cb(void *arg_pv)
|
||||
{
|
||||
extern void USBD_IRQHandler(uint8_t busid);
|
||||
USBD_IRQHandler(0);
|
||||
uint8_t busid = (uintptr_t)arg_pv;
|
||||
USBD_IRQHandler(busid);
|
||||
}
|
||||
|
||||
void usb_dc_low_level_init(uint8_t busid)
|
||||
{
|
||||
esp_err_t ret;
|
||||
void *reg_base = (void*)g_usbdev_bus[busid].reg_base;
|
||||
(void)reg_base;
|
||||
usb_phy_config_t phy_config = {
|
||||
.controller = USB_PHY_CTRL_OTG,
|
||||
.otg_mode = USB_OTG_MODE_DEVICE,
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 // ESP32-P4 has 2 USB-DWC peripherals, each with its dedicated PHY. We support HS+UTMI only ATM.
|
||||
.target = USB_PHY_TARGET_UTMI,
|
||||
#else
|
||||
.target = USB_PHY_TARGET_INT,
|
||||
#endif
|
||||
};
|
||||
|
||||
esp_err_t ret = usb_new_phy(&phy_config, &s_phy_handle);
|
||||
phy_config.target = GET_USB_PHY_TARGET(reg_base);
|
||||
phy_config.otg_speed = GET_USB_PHY_SPEED(reg_base);
|
||||
|
||||
ret = usb_new_phy(&phy_config, &s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Phy Init Failed!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uintptr_t arg = busid;
|
||||
// TODO: Check when to enable interrupt
|
||||
ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_dc_interrupt_cb, 0, &s_interrupt_handle);
|
||||
ret = esp_intr_alloc(GET_USB_INTR_SOURCE(reg_base), ESP_INTR_FLAG_LOWMED, usb_dc_interrupt_cb, (void *)arg, &s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
|
||||
return;
|
||||
@@ -155,46 +170,48 @@ void usb_dc_low_level_init(uint8_t busid)
|
||||
|
||||
void usb_dc_low_level_deinit(uint8_t busid)
|
||||
{
|
||||
if (s_interrupt_handle) {
|
||||
esp_intr_free(s_interrupt_handle);
|
||||
s_interrupt_handle = NULL;
|
||||
void *reg_base = (void*)g_usbdev_bus[busid].reg_base;
|
||||
(void)reg_base;
|
||||
if (s_interrupt_handle[GET_USB_INDEX(reg_base)]) {
|
||||
esp_intr_free(s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_interrupt_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
if (s_phy_handle) {
|
||||
usb_del_phy(s_phy_handle);
|
||||
s_phy_handle = NULL;
|
||||
if (s_phy_handle[GET_USB_INDEX(reg_base)]) {
|
||||
usb_del_phy(s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_phy_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_hc_interrupt_cb(void *arg_pv)
|
||||
{
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
USBH_IRQHandler(0);
|
||||
uint8_t busid = (uintptr_t)arg_pv;
|
||||
USBH_IRQHandler(busid);
|
||||
}
|
||||
|
||||
void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
void *reg_base = (void*)bus->hcd.reg_base;
|
||||
(void)reg_base;
|
||||
// Host Library defaults to internal PHY
|
||||
usb_phy_config_t phy_config = {
|
||||
.controller = USB_PHY_CTRL_OTG,
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 // ESP32-P4 has 2 USB-DWC peripherals, each with its dedicated PHY. We support HS+UTMI only ATM.
|
||||
.target = USB_PHY_TARGET_UTMI,
|
||||
#else
|
||||
.target = USB_PHY_TARGET_INT,
|
||||
#endif
|
||||
.otg_mode = USB_OTG_MODE_HOST,
|
||||
.otg_speed = USB_PHY_SPEED_UNDEFINED, // In Host mode, the speed is determined by the connected device
|
||||
.ext_io_conf = NULL,
|
||||
.otg_io_conf = NULL,
|
||||
};
|
||||
phy_config.target = GET_USB_PHY_TARGET(reg_base);
|
||||
|
||||
esp_err_t ret = usb_new_phy(&phy_config, &s_phy_handle);
|
||||
esp_err_t ret = usb_new_phy(&phy_config, &s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Phy Init Failed!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uintptr_t arg = bus->busid;
|
||||
// TODO: Check when to enable interrupt
|
||||
ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_hc_interrupt_cb, 0, &s_interrupt_handle);
|
||||
ret = esp_intr_alloc(GET_USB_INTR_SOURCE(reg_base), ESP_INTR_FLAG_LOWMED, usb_hc_interrupt_cb, (void*)(arg), &s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
|
||||
return;
|
||||
@@ -204,13 +221,15 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
|
||||
void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
if (s_interrupt_handle) {
|
||||
esp_intr_free(s_interrupt_handle);
|
||||
s_interrupt_handle = NULL;
|
||||
void *reg_base = (void*)bus->hcd.reg_base;
|
||||
(void)reg_base;
|
||||
if (s_interrupt_handle[GET_USB_INDEX(reg_base)]) {
|
||||
esp_intr_free(s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_interrupt_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
if (s_phy_handle) {
|
||||
usb_del_phy(s_phy_handle);
|
||||
s_phy_handle = NULL;
|
||||
if (s_phy_handle[GET_USB_INDEX(reg_base)]) {
|
||||
usb_del_phy(s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_phy_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +238,7 @@ void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
memcpy(params, ¶m_fs, sizeof(struct dwc2_user_params));
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
if (reg_base == 0x50000000UL) {
|
||||
if (reg_base == ESP_USB_HS0_BASE) {
|
||||
memcpy(params, ¶m_hs, sizeof(struct dwc2_user_params));
|
||||
} else {
|
||||
memcpy(params, ¶m_fs, sizeof(struct dwc2_user_params));
|
||||
|
||||
@@ -27,33 +27,84 @@
|
||||
#include <rthw.h>
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usb_dwc2_param.h"
|
||||
|
||||
#include <riscv_io.h>
|
||||
#include "sysctl_rst.h"
|
||||
#include "ioremap.h"
|
||||
#include "mmu.h"
|
||||
#include "cache.h"
|
||||
|
||||
extern rt_mmu_info mmu_info;
|
||||
|
||||
#if defined(ENABLE_CHERRY_USB) || defined(PKG_USING_CHERRYUSB) || defined(RT_USING_CHERRYUSB)
|
||||
#define DEFAULT_USB_HCLK_FREQ_MHZ 200
|
||||
|
||||
uint32_t SystemCoreClock = (DEFAULT_USB_HCLK_FREQ_MHZ * 1000 * 1000);
|
||||
uintptr_t g_usb_otg0_base = (uintptr_t)0x91500000UL;
|
||||
uintptr_t g_usb_otg1_base = (uintptr_t)0x91540000UL;
|
||||
|
||||
static void sysctl_reset_hw_done(volatile uint32_t *reset_reg, uint8_t reset_bit, uint8_t done_bit)
|
||||
{
|
||||
*reset_reg |= (1 << done_bit); /* clear done bit */
|
||||
rt_thread_mdelay(1);
|
||||
|
||||
*reset_reg |= (1 << reset_bit); /* set reset bit */
|
||||
rt_thread_mdelay(1);
|
||||
/* check done bit */
|
||||
while (*reset_reg & (1 << done_bit) == 0)
|
||||
;
|
||||
}
|
||||
const uintptr_t usb_dev_addr[2] = { 0x91500000UL, 0x91540000UL };
|
||||
|
||||
#define USB_IDPULLUP0 (1 << 4)
|
||||
#define USB_DMPULLDOWN0 (1 << 8)
|
||||
#define USB_DPPULLDOWN0 (1 << 9)
|
||||
|
||||
#ifdef PKG_CHERRYUSB_HOST
|
||||
const struct dwc2_user_params param_common = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (3016 - 16 - 256 * 8),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 512, // 1024 byte, double buffer
|
||||
[2] = 256, // 1024 byte
|
||||
[3] = 512, // 1024 byte, double buffer
|
||||
[4] = 256, // 1024 byte
|
||||
[5] = 256, // 1024 byte
|
||||
[6] = 256, // 1024 byte
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 3016 - 128 * 2 - 256 * 2,
|
||||
.host_nperio_tx_fifo_size = 128 * 2, // 512 byte, double buffer
|
||||
.host_perio_tx_fifo_size = 256 * 2, // 1024 byte, double buffer
|
||||
|
||||
.device_gccfg = 0,
|
||||
.host_gccfg = 0
|
||||
};
|
||||
|
||||
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
|
||||
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
|
||||
{
|
||||
memcpy(params, ¶m_common, sizeof(struct dwc2_user_params));
|
||||
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
|
||||
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
|
||||
|
||||
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
|
||||
|
||||
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
|
||||
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) {
|
||||
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// USB Host
|
||||
#if defined(ENABLE_CHERRY_USB_HOST) || defined(PKG_CHERRYUSB_HOST) || defined(RT_CHERRYUSB_HOST)
|
||||
static void usb_hc_interrupt_cb(int irq, void *arg_pv)
|
||||
{
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
USBH_IRQHandler((uint8_t)(uintptr_t)arg_pv);
|
||||
}
|
||||
|
||||
@@ -62,8 +113,10 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
uint32_t *hs_reg;
|
||||
uint32_t usb_ctl3;
|
||||
|
||||
if (bus->hcd.hcd_id == 0) {
|
||||
sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28);
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)bus->hcd.reg_base) == usb_dev_addr[0]) {
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB0)) {
|
||||
USB_LOG_ERR("reset usb0 fail\n");
|
||||
}
|
||||
|
||||
hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
|
||||
usb_ctl3 = *hs_reg | USB_IDPULLUP0;
|
||||
@@ -72,11 +125,13 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(173, usb_hc_interrupt_cb, NULL, "usbh0");
|
||||
rt_hw_interrupt_install(173, usb_hc_interrupt_cb, (void *)(uintptr_t)bus->hcd.hcd_id, "usbh0");
|
||||
rt_hw_interrupt_umask(173);
|
||||
|
||||
} else {
|
||||
sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29);
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB1)) {
|
||||
USB_LOG_ERR("reset usb1 fail\n");
|
||||
}
|
||||
|
||||
hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
|
||||
usb_ctl3 = *hs_reg | USB_IDPULLUP0;
|
||||
@@ -85,73 +140,85 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(174, usb_hc_interrupt_cb, 1, "usbh1");
|
||||
rt_hw_interrupt_install(174, usb_hc_interrupt_cb, (void *)(uintptr_t)bus->hcd.hcd_id, "usbh1");
|
||||
rt_hw_interrupt_umask(174);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
if (bus->hcd.hcd_id == 0) {
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)bus->hcd.reg_base) == usb_dev_addr[0]) {
|
||||
rt_hw_interrupt_mask(173);
|
||||
} else {
|
||||
rt_hw_interrupt_mask(174);
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_CHERRY_USB_HOST
|
||||
|
||||
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PKG_CHERRYUSB_DEVICE
|
||||
// USB Device
|
||||
#if defined(ENABLE_CHERRY_USB_DEVICE) || defined(PKG_CHERRYUSB_DEVICE) || defined(RT_CHERRYUSB_DEVICE)
|
||||
static void usb_dc_interrupt_cb(int irq, void *arg_pv)
|
||||
{
|
||||
extern void USBD_IRQHandler(uint8_t busid);
|
||||
USBD_IRQHandler(0);
|
||||
USBD_IRQHandler((uint8_t)(uintptr_t)arg_pv);
|
||||
}
|
||||
|
||||
#ifdef CHERRYUSB_DEVICE_USING_USB0
|
||||
void usb_dc_low_level_init(uint8_t busid)
|
||||
{
|
||||
sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28);
|
||||
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
|
||||
*hs_reg = 0x37;
|
||||
rt_iounmap(hs_reg);
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)g_usbdev_bus[busid].reg_base) == usb_dev_addr[0]) {
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB0)) {
|
||||
USB_LOG_ERR("reset usb0 fail\n");
|
||||
}
|
||||
|
||||
rt_hw_interrupt_install(173, usb_dc_interrupt_cb, NULL, "usbd");
|
||||
rt_hw_interrupt_umask(173);
|
||||
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
|
||||
*hs_reg = 0x37;
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(173, usb_dc_interrupt_cb, (void *)(uintptr_t)busid, "usbd0");
|
||||
rt_hw_interrupt_umask(173);
|
||||
} else {
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB1)) {
|
||||
USB_LOG_ERR("reset usb1 fail\n");
|
||||
}
|
||||
|
||||
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
|
||||
*hs_reg = 0x37;
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(174, usb_dc_interrupt_cb, (void *)(uintptr_t)busid, "usbd1");
|
||||
rt_hw_interrupt_umask(174);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_dc_low_level_deinit(uint8_t busid)
|
||||
{
|
||||
rt_hw_interrupt_mask(173);
|
||||
}
|
||||
#else
|
||||
void usb_dc_low_level_init(uint8_t busid)
|
||||
{
|
||||
sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29);
|
||||
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
|
||||
*hs_reg = 0x37;
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(174, usb_dc_interrupt_cb, NULL, "usbd");
|
||||
rt_hw_interrupt_umask(174);
|
||||
}
|
||||
|
||||
void usb_dc_low_level_deinit(uint8_t busid)
|
||||
{
|
||||
rt_hw_interrupt_mask(174);
|
||||
}
|
||||
#endif
|
||||
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
return 0;
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)g_usbdev_bus[busid].reg_base) == usb_dev_addr[0]) {
|
||||
rt_hw_interrupt_mask(173);
|
||||
} else {
|
||||
rt_hw_interrupt_mask(174);
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_CHERRY_USB_DEVICE
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
/* implement later */
|
||||
rt_thread_mdelay(ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
void usb_dcache_clean(uintptr_t addr, size_t size)
|
||||
{
|
||||
rt_hw_cpu_dcache_clean((void *)addr, size);
|
||||
}
|
||||
|
||||
void usb_dcache_invalidate(uintptr_t addr, size_t size)
|
||||
{
|
||||
rt_hw_cpu_dcache_invalidate((void *)addr, size);
|
||||
}
|
||||
|
||||
void usb_dcache_flush(uintptr_t addr, size_t size)
|
||||
{
|
||||
rt_hw_cpu_dcache_clean_flush((void *)addr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_CHERRY_USB
|
||||
|
||||
@@ -166,7 +166,7 @@ const struct dwc2_user_params param_pb14_pb15 = {
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (1012 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_rx_fifo_size = (1006 - 16 - 256 - 128 - 128 - 128 - 128), // 1006/1012
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
@@ -186,7 +186,7 @@ const struct dwc2_user_params param_pb14_pb15 = {
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 628,
|
||||
.host_rx_fifo_size = 622,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
#ifdef CONFIG_USB_HS
|
||||
|
||||
@@ -20,7 +20,6 @@ struct dwc2_chan {
|
||||
uint32_t xferlen;
|
||||
uint8_t chidx;
|
||||
bool inuse;
|
||||
bool dir_in;
|
||||
bool do_ssplit;
|
||||
bool do_csplit;
|
||||
uint8_t hub_addr;
|
||||
@@ -136,7 +135,12 @@ static inline void dwc2_set_mode(struct usbh_bus *bus, uint8_t mode)
|
||||
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
|
||||
}
|
||||
|
||||
usb_osal_msleep(50);
|
||||
while (1) {
|
||||
if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_HOST) {
|
||||
break;
|
||||
}
|
||||
usb_osal_msleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int dwc2_flush_rxfifo(struct usbh_bus *bus)
|
||||
@@ -222,7 +226,14 @@ static inline uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t po
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dwc2_chan_char_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
|
||||
static inline void dwc2_chan_char_init(struct usbh_bus *bus,
|
||||
uint8_t ch_num,
|
||||
uint8_t dev_addr,
|
||||
uint8_t ep_addr,
|
||||
uint8_t ep_type,
|
||||
uint16_t ep_mps,
|
||||
uint8_t ep_mult,
|
||||
uint8_t speed)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
@@ -230,7 +241,8 @@ static inline void dwc2_chan_char_init(struct usbh_bus *bus, uint8_t ch_num, uin
|
||||
regval = (((uint32_t)ep_mps << USB_OTG_HCCHAR_MPSIZ_Pos) & USB_OTG_HCCHAR_MPSIZ) |
|
||||
((((uint32_t)ep_addr & 0x7FU) << USB_OTG_HCCHAR_EPNUM_Pos) & USB_OTG_HCCHAR_EPNUM) |
|
||||
(((uint32_t)ep_type << USB_OTG_HCCHAR_EPTYP_Pos) & USB_OTG_HCCHAR_EPTYP) |
|
||||
(((uint32_t)devaddr << USB_OTG_HCCHAR_DAD_Pos) & USB_OTG_HCCHAR_DAD);
|
||||
(((uint32_t)ep_mult << USB_OTG_HCCHAR_MC_Pos) & USB_OTG_HCCHAR_MC) |
|
||||
(((uint32_t)dev_addr << USB_OTG_HCCHAR_DAD_Pos) & USB_OTG_HCCHAR_DAD);
|
||||
|
||||
if ((ep_addr & 0x80U) == 0x80U) {
|
||||
regval |= USB_OTG_HCCHAR_EPDIR;
|
||||
@@ -272,7 +284,14 @@ static inline void dwc2_chan_splt_init(struct usbh_bus *bus, uint8_t ch_num)
|
||||
}
|
||||
}
|
||||
|
||||
static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
|
||||
static void dwc2_chan_init(struct usbh_bus *bus,
|
||||
uint8_t ch_num,
|
||||
uint8_t dev_addr,
|
||||
uint8_t ep_addr,
|
||||
uint8_t ep_type,
|
||||
uint16_t ep_mps,
|
||||
uint8_t ep_mult,
|
||||
uint8_t speed)
|
||||
{
|
||||
/* Clear old interrupt conditions for this host channel. */
|
||||
USB_OTG_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
|
||||
@@ -283,31 +302,20 @@ static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr
|
||||
/* Enable the top level host channel interrupt. */
|
||||
USB_OTG_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
|
||||
|
||||
dwc2_chan_char_init(bus, ch_num, devaddr, ep_addr, ep_type, ep_mps, speed);
|
||||
dwc2_chan_char_init(bus, ch_num, dev_addr, ep_addr, ep_type, ep_mps, ep_mult, speed);
|
||||
dwc2_chan_splt_init(bus, ch_num);
|
||||
}
|
||||
|
||||
/* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of ep_mps size.*/
|
||||
static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint8_t ep_addr, uint8_t *buf, uint32_t size, uint16_t num_packets, uint8_t pid)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
uint8_t is_oddframe;
|
||||
struct dwc2_chan *chan;
|
||||
|
||||
chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[ch_num];
|
||||
|
||||
/* Initialize the HCTSIZn register */
|
||||
USB_OTG_HC(ch_num)->HCTSIZ = (size & USB_OTG_HCTSIZ_XFRSIZ) |
|
||||
(((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
|
||||
(((uint32_t)pid << 29) & USB_OTG_HCTSIZ_DPID);
|
||||
|
||||
if (!(ep_addr & 0x80)) {
|
||||
chan->dir_in = false;
|
||||
usb_dcache_clean((uintptr_t)buf, USB_ALIGN_UP(size, CONFIG_USB_ALIGN_SIZE));
|
||||
} else {
|
||||
chan->dir_in = true;
|
||||
}
|
||||
|
||||
/* xfer_buff MUST be 32-bits aligned */
|
||||
USB_OTG_HC(ch_num)->HCDMA = (uint32_t)buf;
|
||||
|
||||
@@ -322,6 +330,31 @@ static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint
|
||||
USB_OTG_HC(ch_num)->HCCHAR = tmpreg;
|
||||
}
|
||||
|
||||
static inline void dwc2_chan_enable_csplit(struct usbh_bus *bus, uint8_t ch_num, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
USB_OTG_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
|
||||
} else {
|
||||
USB_OTG_HC((uint32_t)ch_num)->HCSPLT &= ~USB_OTG_HCSPLT_COMPLSPLT;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dwc2_chan_reenable(struct usbh_bus *bus, uint8_t ch_num)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
uint8_t is_oddframe;
|
||||
|
||||
is_oddframe = (((uint32_t)USB_OTG_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
|
||||
USB_OTG_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
|
||||
USB_OTG_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
|
||||
|
||||
/* Set host channel enable */
|
||||
tmpreg = USB_OTG_HC(ch_num)->HCCHAR;
|
||||
tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
|
||||
tmpreg |= USB_OTG_HCCHAR_CHENA;
|
||||
USB_OTG_HC(ch_num)->HCCHAR = tmpreg;
|
||||
}
|
||||
|
||||
static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num)
|
||||
{
|
||||
volatile uint32_t ChannelEna = (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
|
||||
@@ -338,7 +371,6 @@ static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num)
|
||||
value = USB_OTG_HC(ch_num)->HCCHAR;
|
||||
value |= USB_OTG_HCCHAR_CHDIS;
|
||||
value |= USB_OTG_HCCHAR_CHENA;
|
||||
value &= ~USB_OTG_HCCHAR_EPDIR;
|
||||
USB_OTG_HC(ch_num)->HCCHAR = value;
|
||||
do {
|
||||
if (++count > 200000U) {
|
||||
@@ -352,6 +384,7 @@ static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num)
|
||||
static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
|
||||
{
|
||||
__IO uint32_t hprt0 = 0U;
|
||||
volatile uint32_t timeout = 0;
|
||||
|
||||
hprt0 = USB_OTG_HPRT;
|
||||
|
||||
@@ -364,6 +397,14 @@ static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
|
||||
usb_osal_msleep(10U);
|
||||
|
||||
while (!(USB_OTG_HPRT & USB_OTG_HPRT_PENA)) {
|
||||
if (!(USB_OTG_HPRT & USB_OTG_HPRT_PCSTS)) {
|
||||
return -USB_ERR_NOTCONN; /* Port not connected */
|
||||
}
|
||||
timeout++;
|
||||
if (timeout > 10) {
|
||||
USB_LOG_ERR("Reset port timeout\r\n");
|
||||
return -USB_ERR_TIMEOUT;
|
||||
}
|
||||
usb_osal_msleep(10U);
|
||||
}
|
||||
return 0;
|
||||
@@ -463,6 +504,10 @@ static void dwc2_chan_free(struct dwc2_chan *chan)
|
||||
size_t flags;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
if (chan->urb) {
|
||||
chan->urb->hcpriv = NULL;
|
||||
chan->urb = NULL;
|
||||
}
|
||||
chan->inuse = false;
|
||||
usb_osal_leave_critical_section(flags);
|
||||
}
|
||||
@@ -519,27 +564,62 @@ static void dwc2_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct us
|
||||
if (chan->ep0_state == DWC2_EP0_STATE_SETUP) /* fill setup */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(8, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_init(bus,
|
||||
chidx,
|
||||
urb->hport->dev_addr,
|
||||
0x00,
|
||||
USB_ENDPOINT_TYPE_CONTROL,
|
||||
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
|
||||
1,
|
||||
urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x00, (uint8_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_INDATA) /* fill in data */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(datalen, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_init(bus,
|
||||
chidx,
|
||||
urb->hport->dev_addr,
|
||||
0x80,
|
||||
USB_ENDPOINT_TYPE_CONTROL,
|
||||
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
|
||||
1,
|
||||
urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x80, buffer, chan->xferlen, chan->num_packets, data_pid);
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) /* fill out data */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(datalen, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_init(bus,
|
||||
chidx,
|
||||
urb->hport->dev_addr,
|
||||
0x00,
|
||||
USB_ENDPOINT_TYPE_CONTROL,
|
||||
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
|
||||
1,
|
||||
urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x00, buffer, chan->xferlen, chan->num_packets, data_pid);
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) /* fill in status */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(0, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_init(bus,
|
||||
chidx,
|
||||
urb->hport->dev_addr,
|
||||
0x80,
|
||||
USB_ENDPOINT_TYPE_CONTROL,
|
||||
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
|
||||
1,
|
||||
urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) /* fill out status */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(0, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_init(bus,
|
||||
chidx,
|
||||
urb->hport->dev_addr,
|
||||
0x00,
|
||||
USB_ENDPOINT_TYPE_CONTROL,
|
||||
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
|
||||
1,
|
||||
urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
|
||||
}
|
||||
}
|
||||
@@ -562,7 +642,14 @@ static void dwc2_bulk_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct
|
||||
}
|
||||
|
||||
chan->num_packets = dwc2_calculate_packet_num(datalen, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_init(bus,
|
||||
chidx,
|
||||
urb->hport->dev_addr,
|
||||
urb->ep->bEndpointAddress,
|
||||
USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes),
|
||||
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
|
||||
USB_GET_MULT(urb->ep->wMaxPacketSize) + 1,
|
||||
urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, buffer, chan->xferlen, chan->num_packets, urb->data_toggle == 0 ? HC_PID_DATA0 : HC_PID_DATA1);
|
||||
}
|
||||
|
||||
@@ -845,8 +932,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u
|
||||
dwc2_drivebus(bus, 1);
|
||||
break;
|
||||
case HUB_PORT_FEATURE_RESET:
|
||||
usbh_reset_port(bus, port);
|
||||
break;
|
||||
return usbh_reset_port(bus, port);
|
||||
|
||||
default:
|
||||
return -USB_ERR_NOTSUPP;
|
||||
@@ -930,11 +1016,6 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
||||
return -USB_ERR_BUSY;
|
||||
}
|
||||
|
||||
chidx = dwc2_chan_alloc(bus);
|
||||
if (chidx == -1) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
if (urb->ep->bEndpointAddress & 0x80) {
|
||||
/* Check if pipe rx fifo is overflow */
|
||||
if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size * 4)) {
|
||||
@@ -954,6 +1035,11 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
||||
}
|
||||
}
|
||||
|
||||
chidx = dwc2_chan_alloc(bus);
|
||||
if (chidx == -1) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
|
||||
@@ -975,6 +1061,25 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
if (urb->setup) {
|
||||
usb_dcache_clean((uintptr_t)urb->setup, USB_ALIGN_UP(sizeof(struct usb_setup_packet), CONFIG_USB_ALIGN_SIZE));
|
||||
|
||||
if (urb->transfer_buffer) {
|
||||
if (urb->setup->bmRequestType & 0x80) {
|
||||
usb_dcache_invalidate((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(urb->transfer_buffer_length, CONFIG_USB_ALIGN_SIZE));
|
||||
} else {
|
||||
usb_dcache_clean((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(urb->transfer_buffer_length, CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
}
|
||||
} else if (urb->transfer_buffer && (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS)) {
|
||||
if (urb->ep->bEndpointAddress & 0x80) {
|
||||
usb_dcache_invalidate((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(urb->transfer_buffer_length, CONFIG_USB_ALIGN_SIZE));
|
||||
} else {
|
||||
usb_dcache_clean((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(urb->transfer_buffer_length, CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
chan->ep0_state = DWC2_EP0_STATE_SETUP;
|
||||
@@ -1026,8 +1131,6 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
|
||||
dwc2_halt(bus, chan->chidx);
|
||||
|
||||
chan->urb = NULL;
|
||||
urb->hcpriv = NULL;
|
||||
urb->errorcode = -USB_ERR_SHUTDOWN;
|
||||
|
||||
if (urb->timeout) {
|
||||
@@ -1036,6 +1139,10 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
dwc2_chan_free(chan);
|
||||
}
|
||||
|
||||
if (urb->complete) {
|
||||
urb->complete(urb->arg, urb->errorcode);
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
return 0;
|
||||
@@ -1046,8 +1153,6 @@ static inline void dwc2_urb_waitup(struct usbh_urb *urb)
|
||||
struct dwc2_chan *chan;
|
||||
|
||||
chan = (struct dwc2_chan *)urb->hcpriv;
|
||||
chan->urb = NULL;
|
||||
urb->hcpriv = NULL;
|
||||
|
||||
if (urb->timeout) {
|
||||
usb_osal_sem_give(chan->waitsem);
|
||||
@@ -1079,31 +1184,26 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
if (chan_intstatus & USB_OTG_HCINT_CHH) {
|
||||
USB_OTG_HC(ch_num)->HCINT = chan_intstatus;
|
||||
if (chan_intstatus & USB_OTG_HCINT_XFRC) {
|
||||
urb->errorcode = 0;
|
||||
|
||||
uint32_t count = chan->xferlen - (USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* how many size has received */
|
||||
//uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
|
||||
uint8_t data_toggle = ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_DPID) >> USB_OTG_HCTSIZ_DPID_Pos);
|
||||
|
||||
urb->actual_length += count;
|
||||
urb->transfer_buffer_length -= count;
|
||||
|
||||
uint8_t data_toggle = ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_DPID) >> USB_OTG_HCTSIZ_DPID_Pos);
|
||||
|
||||
if (data_toggle == HC_PID_DATA0) {
|
||||
urb->data_toggle = 0;
|
||||
} else {
|
||||
urb->data_toggle = 1;
|
||||
}
|
||||
|
||||
if (chan->dir_in) {
|
||||
usb_dcache_invalidate((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(count, CONFIG_USB_ALIGN_SIZE));
|
||||
if (chan->do_csplit) {
|
||||
chan->do_csplit = 0;
|
||||
dwc2_chan_enable_csplit(bus, ch_num, false);
|
||||
}
|
||||
|
||||
chan->do_csplit = 0;
|
||||
|
||||
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
|
||||
if (chan->ep0_state == DWC2_EP0_STATE_INDATA) {
|
||||
if (chan->do_ssplit && urb->transfer_buffer_length > 0) {
|
||||
if (chan->do_ssplit && urb->transfer_buffer_length > 0 && (count == USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize))) {
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length);
|
||||
} else {
|
||||
chan->ep0_state = DWC2_EP0_STATE_OUTSTATUS;
|
||||
@@ -1111,6 +1211,7 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
}
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) {
|
||||
chan->ep0_state = DWC2_EP0_STATE_SETUP;
|
||||
urb->errorcode = 0;
|
||||
dwc2_urb_waitup(urb);
|
||||
}
|
||||
} else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
@@ -1118,6 +1219,8 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
if (chan->do_ssplit && urb->transfer_buffer_length > 0 && (count == USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize))) {
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
} else {
|
||||
usb_dcache_invalidate((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(urb->actual_length, CONFIG_USB_ALIGN_SIZE));
|
||||
urb->errorcode = 0;
|
||||
dwc2_urb_waitup(urb);
|
||||
}
|
||||
}
|
||||
@@ -1129,20 +1232,20 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
dwc2_urb_waitup(urb);
|
||||
} else if (chan_intstatus & USB_OTG_HCINT_NAK) {
|
||||
if (chan->do_ssplit) {
|
||||
/*
|
||||
* Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
|
||||
* interrupt. Re-start the SSPLIT transfer.
|
||||
*/
|
||||
/* restart ssplit transfer */
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
chan->do_csplit = 0;
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
chan->do_csplit = 0;
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
dwc2_chan_enable_csplit(bus, ch_num, false);
|
||||
dwc2_chan_reenable(bus, ch_num);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
dwc2_chan_enable_csplit(bus, ch_num, false);
|
||||
urb->errorcode = -USB_ERR_NAK;
|
||||
dwc2_urb_waitup(urb);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1152,46 +1255,17 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
}
|
||||
} else if (chan_intstatus & USB_OTG_HCINT_ACK) {
|
||||
if (chan->do_ssplit) {
|
||||
/* Handle ACK on SSPLIT. ACK should not occur in CSPLIT. */
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
chan->do_csplit = 1;
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
//printf("intr ack, len:%d\r\n", urb->actual_length);
|
||||
chan->do_csplit = 1;
|
||||
chan->ssplit_frame = dwc2_get_full_frame_num(bus);
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* start ssplit transfer */
|
||||
chan->do_csplit = 1;
|
||||
chan->ssplit_frame = dwc2_get_full_frame_num(bus);
|
||||
dwc2_chan_enable_csplit(bus, ch_num, true);
|
||||
dwc2_chan_reenable(bus, ch_num);
|
||||
}
|
||||
} else if (chan_intstatus & USB_OTG_HCINT_NYET) {
|
||||
if (chan->do_ssplit) {
|
||||
/*
|
||||
* NYET on CSPLIT
|
||||
* re-do the CSPLIT immediately on non-periodic
|
||||
*/
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
chan->do_csplit = 1;
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
if ((dwc2_get_full_frame_num(bus) - chan->ssplit_frame) > 4) {
|
||||
chan->do_csplit = 0;
|
||||
} else {
|
||||
chan->do_csplit = 1;
|
||||
}
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* restart csplit transfer */
|
||||
dwc2_chan_enable_csplit(bus, ch_num, true);
|
||||
dwc2_chan_reenable(bus, ch_num);
|
||||
} else {
|
||||
urb->errorcode = -USB_ERR_NAK;
|
||||
dwc2_urb_waitup(urb);
|
||||
@@ -1227,12 +1301,11 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
if (chan_intstatus & USB_OTG_HCINT_CHH) {
|
||||
USB_OTG_HC(ch_num)->HCINT = chan_intstatus;
|
||||
if (chan_intstatus & USB_OTG_HCINT_XFRC) {
|
||||
urb->errorcode = 0;
|
||||
|
||||
uint32_t count = USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ; /* last packet size */
|
||||
uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
|
||||
uint32_t olen = (has_used_packets - 1) * USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) + count; /* the same with urb->actual_length += chan->xferlen; */
|
||||
uint8_t data_toggle = ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_DPID) >> USB_OTG_HCTSIZ_DPID_Pos);
|
||||
|
||||
uint32_t olen = (has_used_packets - 1) * USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) + count; //the same with urb->actual_length += chan->xferlen;
|
||||
urb->actual_length += olen;
|
||||
|
||||
if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA || urb->setup == NULL) {
|
||||
@@ -1243,15 +1316,16 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t data_toggle = ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_DPID) >> USB_OTG_HCTSIZ_DPID_Pos);
|
||||
|
||||
if (data_toggle == HC_PID_DATA0) {
|
||||
urb->data_toggle = 0;
|
||||
} else {
|
||||
urb->data_toggle = 1;
|
||||
}
|
||||
|
||||
chan->do_csplit = 0;
|
||||
if (chan->do_csplit) {
|
||||
chan->do_csplit = 0;
|
||||
dwc2_chan_enable_csplit(bus, ch_num, false);
|
||||
}
|
||||
|
||||
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
|
||||
if (chan->ep0_state == DWC2_EP0_STATE_SETUP) {
|
||||
@@ -1273,7 +1347,9 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
}
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) {
|
||||
usb_dcache_invalidate((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(urb->actual_length - 8, CONFIG_USB_ALIGN_SIZE));
|
||||
chan->ep0_state = DWC2_EP0_STATE_SETUP;
|
||||
urb->errorcode = 0;
|
||||
dwc2_urb_waitup(urb);
|
||||
}
|
||||
} else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
@@ -1281,6 +1357,7 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
if (chan->do_ssplit && urb->transfer_buffer_length > 0) {
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
} else {
|
||||
urb->errorcode = 0;
|
||||
dwc2_urb_waitup(urb);
|
||||
}
|
||||
}
|
||||
@@ -1292,20 +1369,20 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
dwc2_urb_waitup(urb);
|
||||
} else if (chan_intstatus & USB_OTG_HCINT_NAK) {
|
||||
if (chan->do_ssplit) {
|
||||
/*
|
||||
* Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
|
||||
* interrupt. Re-start the SSPLIT transfer.
|
||||
*/
|
||||
/* restart ssplit transfer */
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
chan->do_csplit = 0;
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
chan->do_csplit = 0;
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
dwc2_chan_enable_csplit(bus, ch_num, false);
|
||||
dwc2_chan_reenable(bus, ch_num);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
dwc2_chan_enable_csplit(bus, ch_num, false);
|
||||
urb->errorcode = -USB_ERR_NAK;
|
||||
dwc2_urb_waitup(urb);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1315,45 +1392,17 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
||||
}
|
||||
} else if (chan_intstatus & USB_OTG_HCINT_ACK) {
|
||||
if (chan->do_ssplit) {
|
||||
/* Handle ACK on SSPLIT. ACK should not occur in CSPLIT. */
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
chan->do_csplit = 1;
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
chan->do_csplit = 1;
|
||||
chan->ssplit_frame = dwc2_get_full_frame_num(bus);
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* start ssplit transfer */
|
||||
chan->do_csplit = 1;
|
||||
chan->ssplit_frame = dwc2_get_full_frame_num(bus);
|
||||
dwc2_chan_enable_csplit(bus, ch_num, true);
|
||||
dwc2_chan_reenable(bus, ch_num);
|
||||
}
|
||||
} else if (chan_intstatus & USB_OTG_HCINT_NYET) {
|
||||
if (chan->do_ssplit) {
|
||||
/*
|
||||
* NYET on CSPLIT
|
||||
* re-do the CSPLIT immediately on non-periodic
|
||||
*/
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
chan->do_csplit = 1;
|
||||
dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
if ((dwc2_get_full_frame_num(bus) - chan->ssplit_frame) > 4) {
|
||||
chan->do_csplit = 0;
|
||||
} else {
|
||||
chan->do_csplit = 1;
|
||||
}
|
||||
dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* restart csplit transfer */
|
||||
dwc2_chan_enable_csplit(bus, ch_num, true);
|
||||
dwc2_chan_reenable(bus, ch_num);
|
||||
} else {
|
||||
urb->errorcode = -USB_ERR_NAK;
|
||||
dwc2_urb_waitup(urb);
|
||||
|
||||
@@ -99,6 +99,10 @@ static void ehci_qh_free(struct usbh_bus *bus, struct ehci_qh_hw *qh)
|
||||
size_t flags;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
if (qh->urb) {
|
||||
qh->urb->hcpriv = NULL;
|
||||
qh->urb = NULL;
|
||||
}
|
||||
qtd = EHCI_ADDR2QTD(qh->first_qtd);
|
||||
|
||||
while (qtd) {
|
||||
@@ -616,8 +620,6 @@ static void ehci_urb_waitup(struct usbh_bus *bus, struct usbh_urb *urb)
|
||||
struct ehci_qh_hw *qh;
|
||||
|
||||
qh = (struct ehci_qh_hw *)urb->hcpriv;
|
||||
qh->urb = NULL;
|
||||
urb->hcpriv = NULL;
|
||||
|
||||
qh->remove_in_iaad = 0;
|
||||
|
||||
@@ -1335,9 +1337,7 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
EHCI_HCOR->usbcmd |= (EHCI_USBCMD_PSEN | EHCI_USBCMD_ASEN);
|
||||
|
||||
qh = (struct ehci_qh_hw *)urb->hcpriv;
|
||||
urb->hcpriv = NULL;
|
||||
urb->errorcode = -USB_ERR_SHUTDOWN;
|
||||
qh->urb = NULL;
|
||||
|
||||
if (urb->timeout) {
|
||||
usb_osal_sem_give(qh->waitsem);
|
||||
@@ -1349,9 +1349,9 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
volatile uint32_t timeout = 0;
|
||||
EHCI_HCOR->usbcmd |= EHCI_USBCMD_IAAD;
|
||||
while (!(EHCI_HCOR->usbsts & EHCI_USBSTS_IAA)) {
|
||||
usb_osal_msleep(1);
|
||||
timeout++;
|
||||
if (timeout > 100) {
|
||||
if (timeout > 200000) {
|
||||
USB_LOG_ERR("iaad timeout\r\n");
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return -USB_ERR_TIMEOUT;
|
||||
}
|
||||
@@ -1359,6 +1359,10 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
EHCI_HCOR->usbsts = EHCI_USBSTS_IAA;
|
||||
}
|
||||
|
||||
if (urb->complete) {
|
||||
urb->complete(urb->arg, urb->errorcode);
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
|
||||
|
||||
#ifndef CONFIG_USB_EHCI_QH_NUM
|
||||
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_EHCI_QH_NUM 10
|
||||
#endif
|
||||
#ifndef CONFIG_USB_EHCI_QTD_NUM
|
||||
#define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USB_EHCI_QH_NUM * 3)
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
#define CONFIG_USB_FSDEV_RAM_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#undef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 8
|
||||
#endif
|
||||
|
||||
#define USB ((USB_TypeDef *)g_usbdev_bus[0].reg_base)
|
||||
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#include "hpm_usb_device.h"
|
||||
#include "usb_glue_hpm.h"
|
||||
|
||||
#ifndef USB_NUM_BIDIR_ENDPOINTS
|
||||
#define USB_NUM_BIDIR_ENDPOINTS CONFIG_USBDEV_EP_NUM
|
||||
#endif
|
||||
#define USB_NUM_BIDIR_ENDPOINTS USB_SOC_DCD_MAX_ENDPOINT_COUNT
|
||||
|
||||
/* USBSTS, USBINTR */
|
||||
enum {
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usb_kinetis_reg.h"
|
||||
|
||||
#undef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 16
|
||||
|
||||
#define USB_OTG_DEV ((KINETIS_TypeDef *)g_usbdev_bus[busid].reg_base)
|
||||
|
||||
/* Endpoint state */
|
||||
|
||||
@@ -17,3 +17,7 @@
|
||||
### AllwinnerTech
|
||||
|
||||
- F1Cxxx, F2Cxxx
|
||||
|
||||
### SIFLI
|
||||
|
||||
- SF325X
|
||||
|
||||
@@ -26,13 +26,17 @@
|
||||
#define MUSB_IE_OFFSET 0x50
|
||||
#define MUSB_EPIDX_OFFSET 0x42
|
||||
|
||||
#define MUSB_IND_TXMAP_OFFSET 0x80
|
||||
#define MUSB_IND_TXCSRL_OFFSET 0x82
|
||||
#define MUSB_IND_TXCSRH_OFFSET 0x83
|
||||
#define MUSB_IND_RXMAP_OFFSET 0x84
|
||||
#define MUSB_IND_RXCSRL_OFFSET 0x86
|
||||
#define MUSB_IND_RXCSRH_OFFSET 0x87
|
||||
#define MUSB_IND_RXCOUNT_OFFSET 0x88
|
||||
#define MUSB_IND_TXMAP_OFFSET 0x80
|
||||
#define MUSB_IND_TXCSRL_OFFSET 0x82
|
||||
#define MUSB_IND_TXCSRH_OFFSET 0x83
|
||||
#define MUSB_IND_RXMAP_OFFSET 0x84
|
||||
#define MUSB_IND_RXCSRL_OFFSET 0x86
|
||||
#define MUSB_IND_RXCSRH_OFFSET 0x87
|
||||
#define MUSB_IND_RXCOUNT_OFFSET 0x88
|
||||
#define MUSB_IND_TXTYPE_OFFSET 0x8C
|
||||
#define MUSB_IND_TXINTERVAL_OFFSET 0x8D
|
||||
#define MUSB_IND_RXTYPE_OFFSET 0x8E
|
||||
#define MUSB_IND_RXINTERVAL_OFFSET 0x8F
|
||||
|
||||
#define MUSB_FIFO_OFFSET 0x00
|
||||
|
||||
@@ -43,6 +47,35 @@
|
||||
#define MUSB_TXFIFOADD_OFFSET 0x92
|
||||
#define MUSB_RXFIFOADD_OFFSET 0x96
|
||||
|
||||
#define MUSB_TXFUNCADDR0_OFFSET 0x98
|
||||
#define MUSB_TXHUBADDR0_OFFSET 0x9A
|
||||
#define MUSB_TXHUBPORT0_OFFSET 0x9B
|
||||
#define MUSB_TXFUNCADDRx_OFFSET 0x98
|
||||
#define MUSB_TXHUBADDRx_OFFSET 0x9A
|
||||
#define MUSB_TXHUBPORTx_OFFSET 0x9B
|
||||
#define MUSB_RXFUNCADDRx_OFFSET 0x9C
|
||||
#define MUSB_RXHUBADDRx_OFFSET 0x9E
|
||||
#define MUSB_RXHUBPORTx_OFFSET 0x9F
|
||||
|
||||
#define USB_TXMAP_BASE(ep_idx) (USB_BASE + MUSB_IND_TXMAP_OFFSET)
|
||||
#define USB_TXCSRL_BASE(ep_idx) (USB_BASE + MUSB_IND_TXCSRL_OFFSET)
|
||||
#define USB_TXCSRH_BASE(ep_idx) (USB_BASE + MUSB_IND_TXCSRH_OFFSET)
|
||||
#define USB_RXMAP_BASE(ep_idx) (USB_BASE + MUSB_IND_RXMAP_OFFSET)
|
||||
#define USB_RXCSRL_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCSRL_OFFSET)
|
||||
#define USB_RXCSRH_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCSRH_OFFSET)
|
||||
#define USB_RXCOUNT_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCOUNT_OFFSET)
|
||||
#define USB_TXTYPE_BASE(ep_idx) (USB_BASE + MUSB_IND_TXTYPE_OFFSET)
|
||||
#define USB_TXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_IND_TXINTERVAL_OFFSET)
|
||||
#define USB_RXTYPE_BASE(ep_idx) (USB_BASE + MUSB_IND_RXTYPE_OFFSET)
|
||||
#define USB_RXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_IND_RXINTERVAL_OFFSET)
|
||||
|
||||
#define USB_TXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDRx_OFFSET)
|
||||
#define USB_TXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXHUBADDRx_OFFSET)
|
||||
#define USB_TXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXHUBPORTx_OFFSET)
|
||||
#define USB_RXADDR_BASE(ep_idx) (USB_BASE + MUSB_RXFUNCADDRx_OFFSET)
|
||||
#define USB_RXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_RXHUBADDRx_OFFSET)
|
||||
#define USB_RXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_RXHUBPORTx_OFFSET)
|
||||
|
||||
#elif defined(CONFIG_USB_MUSB_CUSTOM)
|
||||
#include "musb_custom.h"
|
||||
#else
|
||||
@@ -57,13 +90,17 @@
|
||||
|
||||
#define MUSB_EPIDX_OFFSET 0x0E
|
||||
|
||||
#define MUSB_IND_TXMAP_OFFSET 0x10
|
||||
#define MUSB_IND_TXCSRL_OFFSET 0x12
|
||||
#define MUSB_IND_TXCSRH_OFFSET 0x13
|
||||
#define MUSB_IND_RXMAP_OFFSET 0x14
|
||||
#define MUSB_IND_RXCSRL_OFFSET 0x16
|
||||
#define MUSB_IND_RXCSRH_OFFSET 0x17
|
||||
#define MUSB_IND_RXCOUNT_OFFSET 0x18
|
||||
#define MUSB_IND_TXMAP_OFFSET 0x10
|
||||
#define MUSB_IND_TXCSRL_OFFSET 0x12
|
||||
#define MUSB_IND_TXCSRH_OFFSET 0x13
|
||||
#define MUSB_IND_RXMAP_OFFSET 0x14
|
||||
#define MUSB_IND_RXCSRL_OFFSET 0x16
|
||||
#define MUSB_IND_RXCSRH_OFFSET 0x17
|
||||
#define MUSB_IND_RXCOUNT_OFFSET 0x18
|
||||
#define MUSB_IND_TXTYPE_OFFSET 0x1A
|
||||
#define MUSB_IND_TXINTERVAL_OFFSET 0x1B
|
||||
#define MUSB_IND_RXTYPE_OFFSET 0x1C
|
||||
#define MUSB_IND_RXINTERVAL_OFFSET 0x1D
|
||||
|
||||
#define MUSB_FIFO_OFFSET 0x20
|
||||
|
||||
@@ -74,7 +111,38 @@
|
||||
#define MUSB_TXFIFOADD_OFFSET 0x64
|
||||
#define MUSB_RXFIFOADD_OFFSET 0x66
|
||||
|
||||
#endif // CONFIG_USB_MUSB_SUNXI
|
||||
#define MUSB_TXFUNCADDR0_OFFSET 0x80
|
||||
#define MUSB_TXHUBADDR0_OFFSET 0x82
|
||||
#define MUSB_TXHUBPORT0_OFFSET 0x83
|
||||
#define MUSB_TXFUNCADDRx_OFFSET 0x88
|
||||
#define MUSB_TXHUBADDRx_OFFSET 0x8A
|
||||
#define MUSB_TXHUBPORTx_OFFSET 0x8B
|
||||
#define MUSB_RXFUNCADDRx_OFFSET 0x8C
|
||||
#define MUSB_RXHUBADDRx_OFFSET 0x8E
|
||||
#define MUSB_RXHUBPORTx_OFFSET 0x8F
|
||||
|
||||
#define MUSB_TXMAP0_OFFSET 0x100
|
||||
|
||||
// do not use EPIDX
|
||||
#define USB_TXMAP_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx)
|
||||
#define USB_TXCSRL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 2)
|
||||
#define USB_TXCSRH_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 3)
|
||||
#define USB_RXMAP_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 4)
|
||||
#define USB_RXCSRL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 6)
|
||||
#define USB_RXCSRH_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 7)
|
||||
#define USB_RXCOUNT_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 8)
|
||||
#define USB_TXTYPE_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0A)
|
||||
#define USB_TXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0B)
|
||||
#define USB_RXTYPE_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0C)
|
||||
#define USB_RXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0D)
|
||||
|
||||
#define USB_TXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx)
|
||||
#define USB_TXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 2)
|
||||
#define USB_TXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 3)
|
||||
#define USB_RXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 4)
|
||||
#define USB_RXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 6)
|
||||
#define USB_RXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 7)
|
||||
#endif
|
||||
|
||||
#define USB_FIFO_BASE(ep_idx) (USB_BASE + MUSB_FIFO_OFFSET + 0x4 * ep_idx)
|
||||
|
||||
@@ -103,8 +171,8 @@ struct musb_ep_state {
|
||||
struct musb_udc {
|
||||
volatile uint8_t dev_addr;
|
||||
__attribute__((aligned(32))) struct usb_setup_packet setup;
|
||||
struct musb_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
|
||||
struct musb_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
|
||||
struct musb_ep_state in_ep[CONFIG_USB_MUSB_EP_NUM]; /*!< IN endpoint parameters*/
|
||||
struct musb_ep_state out_ep[CONFIG_USB_MUSB_EP_NUM]; /*!< OUT endpoint parameters */
|
||||
} g_musb_udc;
|
||||
|
||||
static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
|
||||
@@ -342,7 +410,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
return 0;
|
||||
}
|
||||
|
||||
USB_ASSERT_MSG(ep_idx < CONFIG_USBDEV_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress);
|
||||
USB_ASSERT_MSG(ep_idx < CONFIG_USB_MUSB_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress);
|
||||
|
||||
old_ep_idx = musb_get_active_ep();
|
||||
musb_set_active_ep(ep_idx);
|
||||
@@ -357,7 +425,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
"Ep %02x fifo is overflow", ep->bEndpointAddress);
|
||||
#endif
|
||||
|
||||
HWREGH(USB_BASE + MUSB_IND_RXMAP_OFFSET) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
HWREGH(USB_RXMAP_BASE(ep_idx)) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
|
||||
//
|
||||
// Allow auto clearing of RxPktRdy when packet of size max packet
|
||||
@@ -389,15 +457,15 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
ui32Register |= USB_RXCSRH1_ISO;
|
||||
}
|
||||
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET) = ui32Register;
|
||||
HWREGB(USB_RXCSRH_BASE(ep_idx)) = ui32Register;
|
||||
|
||||
// Reset the Data toggle to zero.
|
||||
if (HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_RXRDY)
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = (USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH);
|
||||
if (HWREGB(USB_RXCSRL_BASE(ep_idx)) & USB_RXCSRL1_RXRDY)
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) = (USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH);
|
||||
else
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_CLRDT;
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) = USB_RXCSRL1_CLRDT;
|
||||
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_TXCSRH_BASE(ep_idx)) &= ~USB_TXCSRH1_MODE;
|
||||
} else {
|
||||
g_musb_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
g_musb_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
@@ -408,7 +476,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
"Ep %02x fifo is overflow", ep->bEndpointAddress);
|
||||
#endif
|
||||
|
||||
HWREGH(USB_BASE + MUSB_IND_TXMAP_OFFSET) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
HWREGH(USB_TXMAP_BASE(ep_idx)) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
|
||||
//
|
||||
// Allow auto setting of TxPktRdy when max packet size has been loaded
|
||||
@@ -434,13 +502,13 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
ui32Register |= USB_TXCSRH1_ISO;
|
||||
}
|
||||
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) = ui32Register | USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_TXCSRH_BASE(ep_idx)) = ui32Register | USB_TXCSRH1_MODE;
|
||||
|
||||
// Reset the Data toggle to zero.
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_TXRDY)
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH);
|
||||
if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_TXRDY)
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH);
|
||||
else
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_CLRDT;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_CLRDT;
|
||||
}
|
||||
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
@@ -464,16 +532,16 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
if (ep_idx == 0x00) {
|
||||
usb_ep0_state = USB_EP0_STATE_STALL;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) |= USB_RXCSRL1_STALL;
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) |= USB_RXCSRL1_STALL;
|
||||
}
|
||||
} else {
|
||||
if (ep_idx == 0x00) {
|
||||
usb_ep0_state = USB_EP0_STATE_STALL;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= USB_TXCSRL1_STALL;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) |= USB_TXCSRL1_STALL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,21 +559,21 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
if (ep_idx == 0x00) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALLED;
|
||||
} else {
|
||||
// Clear the stall on an OUT endpoint.
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~(USB_RXCSRL1_STALL | USB_RXCSRL1_STALLED);
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~(USB_RXCSRL1_STALL | USB_RXCSRL1_STALLED);
|
||||
// Reset the data toggle.
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) |= USB_RXCSRL1_CLRDT;
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) |= USB_RXCSRL1_CLRDT;
|
||||
}
|
||||
} else {
|
||||
if (ep_idx == 0x00) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALLED;
|
||||
} else {
|
||||
// Clear the stall on an IN endpoint.
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~(USB_TXCSRL1_STALL | USB_TXCSRL1_STALLED);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~(USB_TXCSRL1_STALL | USB_TXCSRL1_STALLED);
|
||||
// Reset the data toggle.
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= USB_TXCSRL1_CLRDT;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) |= USB_TXCSRL1_CLRDT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,13 +590,13 @@ int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
|
||||
musb_set_active_ep(ep_idx);
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
if (HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_STALL) {
|
||||
if (HWREGB(USB_RXCSRL_BASE(ep_idx)) & USB_RXCSRL1_STALL) {
|
||||
*stalled = 1;
|
||||
} else {
|
||||
*stalled = 0;
|
||||
}
|
||||
} else {
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_STALL) {
|
||||
if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_STALL) {
|
||||
*stalled = 1;
|
||||
} else {
|
||||
*stalled = 0;
|
||||
@@ -553,7 +621,7 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
|
||||
old_ep_idx = musb_get_active_ep();
|
||||
musb_set_active_ep(ep_idx);
|
||||
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_TXRDY) {
|
||||
if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_TXRDY) {
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return -3;
|
||||
}
|
||||
@@ -569,9 +637,9 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
|
||||
} else {
|
||||
usb_ep0_state = USB_EP0_STATE_IN_ZLP;
|
||||
}
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_TXRDY;
|
||||
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
|
||||
}
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
@@ -585,12 +653,12 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
|
||||
if (ep_idx == 0x00) {
|
||||
usb_ep0_state = USB_EP0_STATE_IN_DATA;
|
||||
if (data_len < g_musb_udc.in_ep[ep_idx].ep_mps) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_TXRDY;
|
||||
}
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_TXRDY;
|
||||
}
|
||||
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
@@ -634,17 +702,18 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
|
||||
|
||||
static void handle_ep0(void)
|
||||
{
|
||||
uint8_t ep0_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
|
||||
uint8_t ep_idx = 0; // EP0 index is always 0
|
||||
uint8_t ep0_status = HWREGB(USB_TXCSRL_BASE(ep_idx));
|
||||
uint16_t read_count;
|
||||
|
||||
if (ep0_status & USB_CSRL0_STALLED) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALLED;
|
||||
usb_ep0_state = USB_EP0_STATE_SETUP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ep0_status & USB_CSRL0_SETEND) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_SETENDC;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_SETENDC;
|
||||
}
|
||||
|
||||
if (g_musb_udc.dev_addr > 0) {
|
||||
@@ -655,7 +724,7 @@ static void handle_ep0(void)
|
||||
switch (usb_ep0_state) {
|
||||
case USB_EP0_STATE_SETUP:
|
||||
if (ep0_status & USB_CSRL0_RXRDY) {
|
||||
read_count = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
read_count = HWREGH(USB_RXCOUNT_BASE(ep_idx));
|
||||
|
||||
if (read_count != 8) {
|
||||
return;
|
||||
@@ -663,9 +732,9 @@ static void handle_ep0(void)
|
||||
|
||||
musb_read_packet(0, (uint8_t *)&g_musb_udc.setup, 8);
|
||||
if (g_musb_udc.setup.wLength) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_RXRDYC;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_RXRDYC;
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
|
||||
}
|
||||
|
||||
usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_musb_udc.setup);
|
||||
@@ -686,7 +755,7 @@ static void handle_ep0(void)
|
||||
break;
|
||||
case USB_EP0_STATE_OUT_DATA:
|
||||
if (ep0_status & USB_CSRL0_RXRDY) {
|
||||
read_count = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
read_count = HWREGH(USB_RXCOUNT_BASE(ep_idx));
|
||||
|
||||
musb_read_packet(0, g_musb_udc.out_ep[0].xfer_buf, read_count);
|
||||
g_musb_udc.out_ep[0].xfer_buf += read_count;
|
||||
@@ -694,10 +763,10 @@ static void handle_ep0(void)
|
||||
|
||||
if (read_count < g_musb_udc.out_ep[0].ep_mps) {
|
||||
usbd_event_ep_out_complete_handler(0, 0x00, g_musb_udc.out_ep[0].actual_xfer_len);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
|
||||
usb_ep0_state = USB_EP0_STATE_IN_STATUS;
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_RXRDYC;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_RXRDYC;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -718,6 +787,10 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
uint8_t ep_idx;
|
||||
uint16_t write_count, read_count;
|
||||
|
||||
if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_HOST) {
|
||||
return;
|
||||
}
|
||||
|
||||
is = HWREGB(USB_BASE + MUSB_IS_OFFSET);
|
||||
txis = HWREGH(USB_BASE + MUSB_TXIS_OFFSET);
|
||||
rxis = HWREGH(USB_BASE + MUSB_RXIS_OFFSET);
|
||||
@@ -764,8 +837,8 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
if (txis & (1 << ep_idx)) {
|
||||
musb_set_active_ep(ep_idx);
|
||||
HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_UNDRN) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_UNDRN;
|
||||
if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_UNDRN) {
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_UNDRN;
|
||||
}
|
||||
|
||||
if (g_musb_udc.in_ep[ep_idx].xfer_len > g_musb_udc.in_ep[ep_idx].ep_mps) {
|
||||
@@ -785,7 +858,7 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
write_count = MIN(g_musb_udc.in_ep[ep_idx].xfer_len, g_musb_udc.in_ep[ep_idx].ep_mps);
|
||||
|
||||
musb_write_packet(ep_idx, g_musb_udc.in_ep[ep_idx].xfer_buf, write_count);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_TXRDY;
|
||||
}
|
||||
|
||||
txis &= ~(1 << ep_idx);
|
||||
@@ -799,11 +872,11 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
if (rxis & (1 << ep_idx)) {
|
||||
musb_set_active_ep(ep_idx);
|
||||
HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx);
|
||||
if (HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_RXRDY) {
|
||||
read_count = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
if (HWREGB(USB_RXCSRL_BASE(ep_idx)) & USB_RXCSRL1_RXRDY) {
|
||||
read_count = HWREGH(USB_RXCOUNT_BASE(ep_idx));
|
||||
|
||||
musb_read_packet(ep_idx, g_musb_udc.out_ep[ep_idx].xfer_buf, read_count);
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~(USB_RXCSRL1_RXRDY);
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~(USB_RXCSRL1_RXRDY);
|
||||
|
||||
g_musb_udc.out_ep[ep_idx].xfer_buf += read_count;
|
||||
g_musb_udc.out_ep[ep_idx].actual_xfer_len += read_count;
|
||||
|
||||
@@ -94,11 +94,11 @@
|
||||
#define NANENG_PHY_FC_REG1E (0x1E * 4)
|
||||
#define NANENG_PHY_FC_REG1F (0x1F * 4)
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM != 8
|
||||
#if CONFIG_USB_MUSB_EP_NUM != 8
|
||||
#error beken chips only support 8 endpoints
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBHOST_PIPE_NUM != 8
|
||||
#if CONFIG_USB_MUSB_PIPE_NUM != 8
|
||||
#error beken chips only support 8 pipes
|
||||
#endif
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
#include "stdint.h"
|
||||
#include "usb_musb_reg.h"
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM != 6
|
||||
#if CONFIG_USB_MUSB_EP_NUM != 6
|
||||
#error es32 chips only support 6 endpoints
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBHOST_PIPE_NUM != 6
|
||||
#if CONFIG_USB_MUSB_PIPE_NUM != 6
|
||||
#error es32 chips only support 6 pipes
|
||||
#endif
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
#error must define CONFIG_USB_MUSB_SUNXI when use sunxi chips
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM != 4
|
||||
#if CONFIG_USB_MUSB_EP_NUM != 4
|
||||
#error sunxi chips only support 4 endpoints
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBHOST_PIPE_NUM != 4
|
||||
#if CONFIG_USB_MUSB_PIPE_NUM != 4
|
||||
#error sunxi chips only support 4 pipes
|
||||
#endif
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#define USB_BASE (bus->hcd.reg_base)
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_SUNXI
|
||||
#if defined(CONFIG_USB_MUSB_SUNXI)
|
||||
#define MUSB_FADDR_OFFSET 0x98
|
||||
#define MUSB_POWER_OFFSET 0x40
|
||||
#define MUSB_TXIS_OFFSET 0x44
|
||||
@@ -58,6 +58,18 @@
|
||||
#define MUSB_RXHUBADDRx_OFFSET 0x9E
|
||||
#define MUSB_RXHUBPORTx_OFFSET 0x9F
|
||||
|
||||
#define USB_TXMAP_BASE(ep_idx) (USB_BASE + MUSB_IND_TXMAP_OFFSET)
|
||||
#define USB_TXCSRL_BASE(ep_idx) (USB_BASE + MUSB_IND_TXCSRL_OFFSET)
|
||||
#define USB_TXCSRH_BASE(ep_idx) (USB_BASE + MUSB_IND_TXCSRH_OFFSET)
|
||||
#define USB_RXMAP_BASE(ep_idx) (USB_BASE + MUSB_IND_RXMAP_OFFSET)
|
||||
#define USB_RXCSRL_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCSRL_OFFSET)
|
||||
#define USB_RXCSRH_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCSRH_OFFSET)
|
||||
#define USB_RXCOUNT_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCOUNT_OFFSET)
|
||||
#define USB_TXTYPE_BASE(ep_idx) (USB_BASE + MUSB_IND_TXTYPE_OFFSET)
|
||||
#define USB_TXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_IND_TXINTERVAL_OFFSET)
|
||||
#define USB_RXTYPE_BASE(ep_idx) (USB_BASE + MUSB_IND_RXTYPE_OFFSET)
|
||||
#define USB_RXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_IND_RXINTERVAL_OFFSET)
|
||||
|
||||
#define USB_TXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDRx_OFFSET)
|
||||
#define USB_TXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXHUBADDRx_OFFSET)
|
||||
#define USB_TXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXHUBPORTx_OFFSET)
|
||||
@@ -110,6 +122,21 @@
|
||||
#define MUSB_RXHUBADDRx_OFFSET 0x8E
|
||||
#define MUSB_RXHUBPORTx_OFFSET 0x8F
|
||||
|
||||
#define MUSB_TXMAP0_OFFSET 0x100
|
||||
|
||||
// do not use EPIDX
|
||||
#define USB_TXMAP_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx)
|
||||
#define USB_TXCSRL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 2)
|
||||
#define USB_TXCSRH_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 3)
|
||||
#define USB_RXMAP_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 4)
|
||||
#define USB_RXCSRL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 6)
|
||||
#define USB_RXCSRH_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 7)
|
||||
#define USB_RXCOUNT_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 8)
|
||||
#define USB_TXTYPE_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0A)
|
||||
#define USB_TXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0B)
|
||||
#define USB_RXTYPE_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0C)
|
||||
#define USB_RXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0D)
|
||||
|
||||
#define USB_TXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx)
|
||||
#define USB_TXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 2)
|
||||
#define USB_TXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 3)
|
||||
@@ -141,7 +168,7 @@ struct musb_hcd {
|
||||
volatile bool port_csc;
|
||||
volatile bool port_pec;
|
||||
volatile bool port_pe;
|
||||
struct musb_pipe pipe_pool[CONFIG_USBHOST_PIPE_NUM];
|
||||
struct musb_pipe pipe_pool[CONFIG_USB_MUSB_PIPE_NUM];
|
||||
} g_musb_hcd[CONFIG_USBHOST_MAX_BUS];
|
||||
|
||||
/* get current active ep */
|
||||
@@ -160,15 +187,15 @@ static void musb_fifo_flush(struct usbh_bus *bus, uint8_t ep)
|
||||
{
|
||||
uint8_t ep_idx = ep & 0x7f;
|
||||
if (ep_idx == 0) {
|
||||
if ((HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & (USB_CSRL0_RXRDY | USB_CSRL0_TXRDY)) != 0)
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) |= USB_CSRH0_FLUSH;
|
||||
if ((HWREGB(USB_TXCSRL_BASE(ep_idx)) & (USB_CSRL0_RXRDY | USB_CSRL0_TXRDY)) != 0)
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) |= USB_CSRH0_FLUSH;
|
||||
} else {
|
||||
if (ep & 0x80) {
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_TXRDY)
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= USB_TXCSRL1_FLUSH;
|
||||
if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_TXRDY)
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) |= USB_TXCSRL1_FLUSH;
|
||||
} else {
|
||||
if (HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_RXRDY)
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) |= USB_RXCSRL1_FLUSH;
|
||||
if (HWREGB(USB_RXCSRL_BASE(ep_idx)) & USB_RXCSRL1_RXRDY)
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) |= USB_RXCSRL1_FLUSH;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,12 +329,12 @@ void musb_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb
|
||||
}
|
||||
|
||||
HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = speed;
|
||||
HWREGB(USB_TXTYPE_BASE(chidx)) = speed;
|
||||
HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0;
|
||||
HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0;
|
||||
|
||||
musb_write_packet(bus, chidx, (uint8_t *)setup, 8);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY | USB_CSRL0_SETUP;
|
||||
HWREGB(USB_TXCSRL_BASE(chidx)) = USB_CSRL0_TXRDY | USB_CSRL0_SETUP;
|
||||
musb_set_active_ep(bus, old_ep_index);
|
||||
}
|
||||
|
||||
@@ -334,12 +361,13 @@ int musb_bulk_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb
|
||||
}
|
||||
|
||||
HWREGB(USB_RXADDR_BASE(chidx)) = urb->hport->dev_addr;
|
||||
HWREGB(USB_BASE + MUSB_IND_RXTYPE_OFFSET) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK;
|
||||
HWREGB(USB_BASE + MUSB_IND_RXINTERVAL_OFFSET) = 0;
|
||||
HWREGB(USB_RXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK;
|
||||
HWREGH(USB_RXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
HWREGB(USB_RXINTERVAL_BASE(chidx)) = 0;
|
||||
HWREGB(USB_RXHUBADDR_BASE(chidx)) = 0;
|
||||
HWREGB(USB_RXHUBPORT_BASE(chidx)) = 0;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_REQPKT;
|
||||
HWREGB(USB_TXCSRH_BASE(chidx)) &= ~USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_RXCSRL_BASE(chidx)) = USB_RXCSRL1_REQPKT;
|
||||
|
||||
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << chidx);
|
||||
} else {
|
||||
@@ -349,8 +377,9 @@ int musb_bulk_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb
|
||||
}
|
||||
|
||||
HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXINTERVAL_OFFSET) = 0;
|
||||
HWREGB(USB_TXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK;
|
||||
HWREGH(USB_TXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
HWREGB(USB_TXINTERVAL_BASE(chidx)) = 0;
|
||||
HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0;
|
||||
HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0;
|
||||
|
||||
@@ -359,8 +388,8 @@ int musb_bulk_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb
|
||||
}
|
||||
|
||||
musb_write_packet(bus, chidx, buffer, buflen);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
|
||||
HWREGB(USB_TXCSRH_BASE(chidx)) |= USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_TXCSRL_BASE(chidx)) = USB_TXCSRL1_TXRDY;
|
||||
|
||||
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << chidx);
|
||||
}
|
||||
@@ -391,12 +420,13 @@ int musb_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb
|
||||
}
|
||||
|
||||
HWREGB(USB_RXADDR_BASE(chidx)) = urb->hport->dev_addr;
|
||||
HWREGB(USB_BASE + MUSB_IND_RXTYPE_OFFSET) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT;
|
||||
HWREGB(USB_BASE + MUSB_IND_RXINTERVAL_OFFSET) = urb->ep->bInterval;
|
||||
HWREGB(USB_RXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT;
|
||||
HWREGH(USB_RXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
HWREGB(USB_RXINTERVAL_BASE(chidx)) = urb->ep->bInterval;
|
||||
HWREGB(USB_RXHUBADDR_BASE(chidx)) = 0;
|
||||
HWREGB(USB_RXHUBPORT_BASE(chidx)) = 0;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_REQPKT;
|
||||
HWREGB(USB_TXCSRH_BASE(chidx)) &= ~USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_RXCSRL_BASE(chidx)) = USB_RXCSRL1_REQPKT;
|
||||
|
||||
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << chidx);
|
||||
} else {
|
||||
@@ -406,8 +436,9 @@ int musb_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb
|
||||
}
|
||||
|
||||
HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXINTERVAL_OFFSET) = urb->ep->bInterval;
|
||||
HWREGB(USB_TXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT;
|
||||
HWREGH(USB_TXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
HWREGB(USB_TXINTERVAL_BASE(chidx)) = urb->ep->bInterval;
|
||||
HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0;
|
||||
HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0;
|
||||
|
||||
@@ -416,8 +447,8 @@ int musb_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb
|
||||
}
|
||||
|
||||
musb_write_packet(bus, chidx, buffer, buflen);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
|
||||
HWREGB(USB_TXCSRH_BASE(chidx)) |= USB_TXCSRH1_MODE;
|
||||
HWREGB(USB_TXCSRL_BASE(chidx)) = USB_TXCSRL1_TXRDY;
|
||||
|
||||
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << chidx);
|
||||
}
|
||||
@@ -464,7 +495,7 @@ static int musb_pipe_alloc(void)
|
||||
{
|
||||
int chidx;
|
||||
|
||||
for (chidx = 1; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
|
||||
for (chidx = 1; chidx < CONFIG_USB_MUSB_PIPE_NUM; chidx++) {
|
||||
if (!g_musb_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse) {
|
||||
g_musb_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse = true;
|
||||
return chidx;
|
||||
@@ -477,6 +508,10 @@ static int musb_pipe_alloc(void)
|
||||
|
||||
static void musb_pipe_free(struct musb_pipe *pipe)
|
||||
{
|
||||
if (pipe->urb) {
|
||||
pipe->urb->hcpriv = NULL;
|
||||
pipe->urb = NULL;
|
||||
}
|
||||
#if 0
|
||||
pipe->inuse = false;
|
||||
#endif
|
||||
@@ -499,14 +534,14 @@ int usb_hc_init(struct usbh_bus *bus)
|
||||
uint8_t cfg_num;
|
||||
struct musb_fifo_cfg *cfg;
|
||||
|
||||
usb_hc_low_level_init(bus);
|
||||
|
||||
memset(&g_musb_hcd[bus->hcd.hcd_id], 0, sizeof(struct musb_hcd));
|
||||
|
||||
for (uint8_t i = 0; i < CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
for (uint8_t i = 0; i < CONFIG_USB_MUSB_PIPE_NUM; i++) {
|
||||
g_musb_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem = usb_osal_sem_create(0);
|
||||
}
|
||||
|
||||
usb_hc_low_level_init(bus);
|
||||
|
||||
cfg_num = usbh_get_musb_fifo_cfg(&cfg);
|
||||
|
||||
for (uint8_t i = 0; i < cfg_num; i++) {
|
||||
@@ -530,7 +565,7 @@ int usb_hc_init(struct usbh_bus *bus)
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_SUNXI
|
||||
musb_set_active_ep(bus, 0);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(0)) = USB_CSRL0_TXRDY;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -544,7 +579,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
|
||||
HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_HSENAB;
|
||||
HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) &= ~USB_DEVCTL_SESSION;
|
||||
|
||||
for (uint8_t i = 0; i < CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
for (uint8_t i = 0; i < CONFIG_USB_MUSB_PIPE_NUM; i++) {
|
||||
usb_osal_sem_delete(g_musb_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem);
|
||||
}
|
||||
|
||||
@@ -697,7 +732,7 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
||||
} else {
|
||||
chidx = (urb->ep->bEndpointAddress & 0x0f);
|
||||
|
||||
if (chidx > (CONFIG_USBHOST_PIPE_NUM - 1)) {
|
||||
if (chidx > (CONFIG_USB_MUSB_PIPE_NUM - 1)) {
|
||||
return -USB_ERR_RANGE;
|
||||
}
|
||||
}
|
||||
@@ -720,12 +755,14 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
ret = musb_bulk_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
if (ret < 0) {
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
ret = musb_intr_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
if (ret < 0) {
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
@@ -771,9 +808,7 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
pipe = (struct musb_pipe *)urb->hcpriv;
|
||||
urb->hcpriv = NULL;
|
||||
urb->errorcode = -USB_ERR_SHUTDOWN;
|
||||
pipe->urb = NULL;
|
||||
|
||||
if (urb->ep->bEndpointAddress & 0x80) {
|
||||
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) &= ~(1 << (urb->ep->bEndpointAddress & 0x0f));
|
||||
@@ -791,6 +826,10 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
musb_pipe_free(pipe);
|
||||
}
|
||||
|
||||
if (urb->complete) {
|
||||
urb->complete(urb->arg, urb->errorcode);
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return 0;
|
||||
}
|
||||
@@ -820,6 +859,7 @@ static void musb_urb_waitup(struct usbh_urb *urb)
|
||||
|
||||
void handle_ep0(struct usbh_bus *bus)
|
||||
{
|
||||
uint8_t ep_idx = 0;
|
||||
uint8_t ep0_status;
|
||||
struct musb_pipe *pipe;
|
||||
struct usbh_urb *urb;
|
||||
@@ -832,16 +872,16 @@ void handle_ep0(struct usbh_bus *bus)
|
||||
}
|
||||
|
||||
musb_set_active_ep(bus, 0);
|
||||
ep0_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
|
||||
ep0_status = HWREGB(USB_TXCSRL_BASE(ep_idx));
|
||||
if (ep0_status & USB_CSRL0_STALLED) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALLED;
|
||||
pipe->ep0_state = USB_EP0_STATE_SETUP;
|
||||
urb->errorcode = -USB_ERR_STALL;
|
||||
musb_urb_waitup(urb);
|
||||
return;
|
||||
}
|
||||
if (ep0_status & USB_CSRL0_ERROR) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_ERROR;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_ERROR;
|
||||
musb_fifo_flush(bus, 0);
|
||||
pipe->ep0_state = USB_EP0_STATE_SETUP;
|
||||
urb->errorcode = -USB_ERR_IO;
|
||||
@@ -849,7 +889,7 @@ void handle_ep0(struct usbh_bus *bus)
|
||||
return;
|
||||
}
|
||||
if (ep0_status & USB_CSRL0_STALL) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALL;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALL;
|
||||
pipe->ep0_state = USB_EP0_STATE_SETUP;
|
||||
urb->errorcode = -USB_ERR_STALL;
|
||||
musb_urb_waitup(urb);
|
||||
@@ -862,7 +902,7 @@ void handle_ep0(struct usbh_bus *bus)
|
||||
if (urb->transfer_buffer_length) {
|
||||
if (urb->setup->bmRequestType & 0x80) {
|
||||
pipe->ep0_state = USB_EP0_STATE_IN_DATA;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_REQPKT;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_REQPKT;
|
||||
} else {
|
||||
pipe->ep0_state = USB_EP0_STATE_OUT_DATA;
|
||||
size = urb->transfer_buffer_length;
|
||||
@@ -871,7 +911,7 @@ void handle_ep0(struct usbh_bus *bus)
|
||||
}
|
||||
|
||||
musb_write_packet(bus, 0, urb->transfer_buffer, size);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_TXRDY;
|
||||
|
||||
urb->transfer_buffer += size;
|
||||
urb->transfer_buffer_length -= size;
|
||||
@@ -879,23 +919,23 @@ void handle_ep0(struct usbh_bus *bus)
|
||||
}
|
||||
} else {
|
||||
pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_REQPKT | USB_CSRL0_STATUS);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_REQPKT | USB_CSRL0_STATUS);
|
||||
}
|
||||
break;
|
||||
case USB_EP0_STATE_IN_DATA:
|
||||
if (ep0_status & USB_CSRL0_RXRDY) {
|
||||
size = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
size = HWREGH(USB_RXCOUNT_BASE(ep_idx));
|
||||
musb_read_packet(bus, 0, urb->transfer_buffer, size);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_RXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_RXRDY;
|
||||
urb->transfer_buffer += size;
|
||||
urb->transfer_buffer_length -= size;
|
||||
urb->actual_length += size;
|
||||
|
||||
if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
|
||||
pipe->ep0_state = USB_EP0_STATE_OUT_STATUS;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_TXRDY | USB_CSRL0_STATUS);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_TXRDY | USB_CSRL0_STATUS);
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_REQPKT;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_REQPKT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -907,14 +947,14 @@ void handle_ep0(struct usbh_bus *bus)
|
||||
}
|
||||
|
||||
musb_write_packet(bus, 0, urb->transfer_buffer, size);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_TXRDY;
|
||||
|
||||
urb->transfer_buffer += size;
|
||||
urb->transfer_buffer_length -= size;
|
||||
urb->actual_length += size;
|
||||
} else {
|
||||
pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_REQPKT | USB_CSRL0_STATUS);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_REQPKT | USB_CSRL0_STATUS);
|
||||
}
|
||||
break;
|
||||
case USB_EP0_STATE_OUT_STATUS:
|
||||
@@ -923,7 +963,7 @@ void handle_ep0(struct usbh_bus *bus)
|
||||
break;
|
||||
case USB_EP0_STATE_IN_STATUS:
|
||||
if (ep0_status & (USB_CSRL0_RXRDY | USB_CSRL0_STATUS)) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~(USB_CSRL0_RXRDY | USB_CSRL0_STATUS);
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~(USB_CSRL0_RXRDY | USB_CSRL0_STATUS);
|
||||
urb->errorcode = 0;
|
||||
musb_urb_waitup(urb);
|
||||
}
|
||||
@@ -947,6 +987,10 @@ void USBH_IRQHandler(uint8_t busid)
|
||||
|
||||
bus = &g_usbhost_bus[busid];
|
||||
|
||||
if (!(HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_HOST)) {
|
||||
return;
|
||||
}
|
||||
|
||||
is = HWREGB(USB_BASE + MUSB_IS_OFFSET);
|
||||
txis = HWREGH(USB_BASE + MUSB_TXIS_OFFSET);
|
||||
rxis = HWREGH(USB_BASE + MUSB_RXIS_OFFSET);
|
||||
@@ -997,7 +1041,7 @@ void USBH_IRQHandler(uint8_t busid)
|
||||
handle_ep0(bus);
|
||||
}
|
||||
|
||||
for (ep_idx = 1; ep_idx < CONFIG_USBHOST_PIPE_NUM; ep_idx++) {
|
||||
for (ep_idx = 1; ep_idx < CONFIG_USB_MUSB_PIPE_NUM; ep_idx++) {
|
||||
if (txis & (1 << ep_idx)) {
|
||||
HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
|
||||
|
||||
@@ -1005,45 +1049,47 @@ void USBH_IRQHandler(uint8_t busid)
|
||||
urb = pipe->urb;
|
||||
musb_set_active_ep(bus, ep_idx);
|
||||
|
||||
ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
|
||||
ep_csrl_status = HWREGB(USB_TXCSRL_BASE(ep_idx));
|
||||
|
||||
if (ep_csrl_status & USB_TXCSRL1_ERROR) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_ERROR;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_ERROR;
|
||||
urb->errorcode = -USB_ERR_IO;
|
||||
musb_urb_waitup(urb);
|
||||
} else if (ep_csrl_status & USB_TXCSRL1_NAKTO) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_NAKTO;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_NAKTO;
|
||||
urb->errorcode = -USB_ERR_NAK;
|
||||
musb_urb_waitup(urb);
|
||||
} else if (ep_csrl_status & USB_TXCSRL1_STALL) {
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_STALL;
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_STALL;
|
||||
urb->errorcode = -USB_ERR_STALL;
|
||||
musb_urb_waitup(urb);
|
||||
} else {
|
||||
uint32_t size = urb->transfer_buffer_length;
|
||||
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
uint32_t size = urb->transfer_buffer_length;
|
||||
|
||||
if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
|
||||
size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
}
|
||||
if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
|
||||
size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
}
|
||||
|
||||
urb->transfer_buffer += size;
|
||||
urb->transfer_buffer_length -= size;
|
||||
urb->actual_length += size;
|
||||
urb->transfer_buffer += size;
|
||||
urb->transfer_buffer_length -= size;
|
||||
urb->actual_length += size;
|
||||
|
||||
if (urb->transfer_buffer_length == 0) {
|
||||
//HWREGH(USB_BASE + MUSB_TXIE_OFFSET) &= ~(1 << ep_idx);
|
||||
urb->errorcode = 0;
|
||||
musb_urb_waitup(urb);
|
||||
} else {
|
||||
musb_write_packet(bus, ep_idx, urb->transfer_buffer, MIN(urb->transfer_buffer_length, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)));
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
|
||||
if (urb->transfer_buffer_length == 0) {
|
||||
//HWREGH(USB_BASE + MUSB_TXIE_OFFSET) &= ~(1 << ep_idx);
|
||||
urb->errorcode = 0;
|
||||
musb_urb_waitup(urb);
|
||||
} else {
|
||||
musb_write_packet(bus, ep_idx, urb->transfer_buffer, MIN(urb->transfer_buffer_length, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)));
|
||||
HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_TXRDY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rxis &= HWREGH(USB_BASE + MUSB_RXIE_OFFSET);
|
||||
for (ep_idx = 1; ep_idx < CONFIG_USBHOST_PIPE_NUM; ep_idx++) {
|
||||
for (ep_idx = 1; ep_idx < CONFIG_USB_MUSB_PIPE_NUM; ep_idx++) {
|
||||
if (rxis & (1 << ep_idx)) {
|
||||
HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx); // clear isr flag
|
||||
|
||||
@@ -1051,38 +1097,40 @@ void USBH_IRQHandler(uint8_t busid)
|
||||
urb = pipe->urb;
|
||||
musb_set_active_ep(bus, ep_idx);
|
||||
|
||||
ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET);
|
||||
//ep_csrh_status = HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET); // todo:for iso transfer
|
||||
ep_csrl_status = HWREGB(USB_RXCSRL_BASE(ep_idx));
|
||||
//ep_csrh_status = HWREGB(USB_BASE + USB_RXCSRH_BASE(ep_idx)); // todo:for iso transfer
|
||||
|
||||
if (ep_csrl_status & USB_RXCSRL1_ERROR) {
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_ERROR;
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~USB_RXCSRL1_ERROR;
|
||||
urb->errorcode = -USB_ERR_IO;
|
||||
musb_urb_waitup(urb);
|
||||
} else if (ep_csrl_status & USB_RXCSRL1_NAKTO) {
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_NAKTO;
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~USB_RXCSRL1_NAKTO;
|
||||
urb->errorcode = -USB_ERR_NAK;
|
||||
musb_urb_waitup(urb);
|
||||
} else if (ep_csrl_status & USB_RXCSRL1_STALL) {
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_STALL;
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~USB_RXCSRL1_STALL;
|
||||
urb->errorcode = -USB_ERR_STALL;
|
||||
musb_urb_waitup(urb);
|
||||
} else if (ep_csrl_status & USB_RXCSRL1_RXRDY) {
|
||||
size = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
size = HWREGH(USB_RXCOUNT_BASE(ep_idx));
|
||||
|
||||
musb_read_packet(bus, ep_idx, urb->transfer_buffer, size);
|
||||
musb_read_packet(bus, ep_idx, urb->transfer_buffer, size);
|
||||
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_RXRDY;
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~USB_RXCSRL1_RXRDY;
|
||||
|
||||
urb->transfer_buffer += size;
|
||||
urb->transfer_buffer_length -= size;
|
||||
urb->actual_length += size;
|
||||
urb->transfer_buffer += size;
|
||||
urb->transfer_buffer_length -= size;
|
||||
urb->actual_length += size;
|
||||
|
||||
if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
|
||||
//HWREGH(USB_BASE + MUSB_RXIE_OFFSET) &= ~(1 << ep_idx);
|
||||
urb->errorcode = 0;
|
||||
musb_urb_waitup(urb);
|
||||
} else {
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_REQPKT;
|
||||
if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
|
||||
//HWREGH(USB_BASE + MUSB_RXIE_OFFSET) &= ~(1 << ep_idx);
|
||||
urb->errorcode = 0;
|
||||
musb_urb_waitup(urb);
|
||||
} else {
|
||||
HWREGB(USB_RXCSRL_BASE(ep_idx)) = USB_RXCSRL1_REQPKT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@ Modify USB_NOCACHE_RAM_SECTION
|
||||
|
||||
- MCXN9XX/MCXN236 (chipidea + EHCI)
|
||||
|
||||
## IMRT
|
||||
### IMRT
|
||||
|
||||
- IMRT10XX/IMRT11XX (chipidea + EHCI)
|
||||
@@ -17,7 +17,7 @@
|
||||
#define OHCI_ADDR2TD(x) ((struct ohci_td_hw *)(uintptr_t)((uint32_t)(x) & ~0x0F))
|
||||
|
||||
#ifndef CONFIG_USB_OHCI_ED_NUM
|
||||
#define CONFIG_USB_OHCI_ED_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_OHCI_ED_NUM 10
|
||||
#endif
|
||||
#ifndef CONFIG_USB_OHCI_TD_NUM
|
||||
#define CONFIG_USB_OHCI_TD_NUM 3
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
#define usb_hw_set hw_set_alias(usb_hw)
|
||||
#define usb_hw_clear hw_clear_alias(usb_hw)
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 16
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_VBUS_DETECT
|
||||
#define FORCE_VBUS_DETECT 1
|
||||
#endif
|
||||
@@ -43,8 +39,8 @@ struct rp2040_ep_state {
|
||||
/* Driver state */
|
||||
struct rp2040_udc {
|
||||
volatile uint8_t dev_addr;
|
||||
struct rp2040_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
|
||||
struct rp2040_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
|
||||
struct rp2040_ep_state in_ep[USB_NUM_ENDPOINTS]; /*!< IN endpoint parameters*/
|
||||
struct rp2040_ep_state out_ep[USB_NUM_ENDPOINTS]; /*!< OUT endpoint parameters */
|
||||
struct usb_setup_packet setup; /*!< Setup package that may be used in interrupt processing (outside the protocol stack) */
|
||||
} g_rp2040_udc;
|
||||
|
||||
@@ -125,7 +121,7 @@ int usb_dc_init(uint8_t busid)
|
||||
g_rp2040_udc.out_ep[0].endpoint_control = NULL;
|
||||
g_rp2040_udc.out_ep[0].data_buffer = &usb_dpram->ep0_buf_a[0];
|
||||
|
||||
for (uint32_t i = 0; i < CONFIG_USBDEV_EP_NUM; i++) {
|
||||
for (uint32_t i = 0; i < USB_NUM_ENDPOINTS; i++) {
|
||||
g_rp2040_udc.in_ep[i].buffer_control = &usb_dpram->ep_buf_ctrl[i].in;
|
||||
g_rp2040_udc.out_ep[i].buffer_control = &usb_dpram->ep_buf_ctrl[i].out;
|
||||
|
||||
@@ -137,7 +133,7 @@ int usb_dc_init(uint8_t busid)
|
||||
|
||||
next_buffer_ptr = &usb_dpram->epx_data[0];
|
||||
|
||||
for (uint32_t i = 1; i < CONFIG_USBDEV_EP_NUM; i++) {
|
||||
for (uint32_t i = 1; i < USB_NUM_ENDPOINTS; i++) {
|
||||
g_rp2040_udc.in_ep[i].data_buffer = next_buffer_ptr;
|
||||
if (i == 1) {
|
||||
next_buffer_ptr += 1024; /* for iso video */
|
||||
@@ -541,7 +537,7 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
|
||||
usb_hw->dev_addr_ctrl = 0;
|
||||
|
||||
for (uint8_t i = 0; i < CONFIG_USBDEV_EP_NUM - 1; i++) {
|
||||
for (uint8_t i = 0; i < USB_NUM_ENDPOINTS - 1; i++) {
|
||||
/*!< Start at ep1 */
|
||||
usb_dpram->ep_ctrl[i].in = 0;
|
||||
usb_dpram->ep_ctrl[i].out = 0;
|
||||
|
||||
@@ -42,7 +42,7 @@ struct rp2040_hcd {
|
||||
volatile bool port_pec;
|
||||
volatile bool port_pe;
|
||||
usb_osal_mutex_t ep0_mutex;
|
||||
struct rp2040_pipe pipe_pool[1 + CONFIG_USBHOST_PIPE_NUM];
|
||||
struct rp2040_pipe pipe_pool[1 + USB_HOST_INTERRUPT_ENDPOINTS];
|
||||
} g_rp2040_hcd[CONFIG_USBHOST_MAX_BUS];
|
||||
|
||||
void rp2040_usbh_irq(void);
|
||||
@@ -53,7 +53,7 @@ static int rp2040_pipe_alloc(struct usbh_bus *bus)
|
||||
int chidx;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
for (chidx = 1; chidx <= CONFIG_USBHOST_PIPE_NUM; chidx++) {
|
||||
for (chidx = 1; chidx <= USB_HOST_INTERRUPT_ENDPOINTS; chidx++) {
|
||||
if (!g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse) {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse = true;
|
||||
usb_osal_leave_critical_section(flags);
|
||||
@@ -69,6 +69,10 @@ static void rp2040_pipe_free(struct rp2040_pipe *pipe)
|
||||
size_t flags;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
if (pipe->urb) {
|
||||
pipe->urb->hcpriv = NULL;
|
||||
pipe->urb = NULL;
|
||||
}
|
||||
pipe->inuse = false;
|
||||
usb_osal_leave_critical_section(flags);
|
||||
}
|
||||
@@ -286,7 +290,7 @@ int usb_hc_init(struct usbh_bus *bus)
|
||||
|
||||
memset(&g_rp2040_hcd[bus->hcd.hcd_id], 0, sizeof(struct rp2040_hcd));
|
||||
|
||||
for (uint8_t i = 0; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
for (uint8_t i = 0; i <= USB_HOST_INTERRUPT_ENDPOINTS; i++) {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem = usb_osal_sem_create(0);
|
||||
if (g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem == NULL) {
|
||||
USB_LOG_ERR("Failed to create waitsem\r\n");
|
||||
@@ -307,7 +311,7 @@ int usb_hc_init(struct usbh_bus *bus)
|
||||
|
||||
next_buffer_ptr = &usb_dpram->epx_data[64 * 2];
|
||||
|
||||
for (uint8_t i = 1; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
for (uint8_t i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS; i++) {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].chidx = i;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].endpoint_control = &usbh_dpram->int_ep_ctrl[i - 1].ctrl;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].buffer_control = &usbh_dpram->int_ep_buffer_ctrl[i - 1].ctrl;
|
||||
@@ -359,7 +363,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
|
||||
// Remove shared irq if it was previously added so as not to fill up shared irq slots
|
||||
irq_remove_handler(USBCTRL_IRQ, rp2040_usbh_irq);
|
||||
|
||||
for (uint8_t i = 0; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
for (uint8_t i = 0; i <= USB_HOST_INTERRUPT_ENDPOINTS; i++) {
|
||||
usb_osal_sem_delete(g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem);
|
||||
}
|
||||
|
||||
@@ -587,9 +591,8 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
pipe = (struct rp2040_pipe *)urb->hcpriv;
|
||||
urb->hcpriv = NULL;
|
||||
urb->errorcode = -USB_ERR_SHUTDOWN;
|
||||
pipe->urb = NULL;
|
||||
|
||||
usb_hw_clear->int_ep_ctrl = 1 << pipe->chidx;
|
||||
usb_hw_clear->buf_status = 1 << (pipe->chidx * 2 + 0);
|
||||
usb_hw_clear->buf_status = 1 << (pipe->chidx * 2 + 1);
|
||||
@@ -602,6 +605,10 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
rp2040_pipe_free(pipe);
|
||||
}
|
||||
|
||||
if (urb->complete) {
|
||||
urb->complete(urb->arg, urb->errorcode);
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
return 0;
|
||||
@@ -612,8 +619,6 @@ static void rp2040_urb_waitup(struct usbh_urb *urb)
|
||||
struct rp2040_pipe *pipe;
|
||||
|
||||
pipe = (struct rp2040_pipe *)urb->hcpriv;
|
||||
pipe->urb = NULL;
|
||||
urb->hcpriv = NULL;
|
||||
|
||||
if (urb->timeout) {
|
||||
usb_osal_sem_give(pipe->waitsem);
|
||||
@@ -697,7 +702,7 @@ static void rp2040_handle_buffer_status(struct usbh_bus *bus)
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 1; remaining_buffers && i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
for (uint8_t i = 1; remaining_buffers && i <= USB_HOST_INTERRUPT_ENDPOINTS; i++) {
|
||||
for (uint8_t j = 0; j < 2; j++) {
|
||||
bit = 1 << (i * 2 + j);
|
||||
if (remaining_buffers & bit) {
|
||||
|
||||
2
third_party/cherrymp/README.md
vendored
@@ -1,3 +1,3 @@
|
||||
# CherryMempool
|
||||
|
||||
CherryMempool is a tiny block memory pool based on CherryRB, support nonos or os(but we suggest you use in os), and only transfer data address not data content.
|
||||
CherryMempool is a tiny block memory pool based on CherryRB, support nonos or os(but we suggest you use in os).
|
||||
|
||||
152
third_party/cherrymp/chry_mempool.c
vendored
@@ -5,6 +5,138 @@
|
||||
*/
|
||||
#include "chry_mempool.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* @brief init ringbuffer
|
||||
*
|
||||
* @param[in] rb ringbuffer instance
|
||||
* @param[in] pool memory pool address
|
||||
* @param[in] size memory size in byte,
|
||||
* must be power of 2 !!!
|
||||
*
|
||||
* @retval int 0:Success -1:Error
|
||||
*****************************************************************************/
|
||||
static int __chry_ringbuffer_init(chry_mempool_ringbuffer_t *rb, void *pool, uint32_t size)
|
||||
{
|
||||
if (NULL == rb) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == pool) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((size < 2) || (size & (size - 1))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rb->in = 0;
|
||||
rb->out = 0;
|
||||
rb->mask = size - 1;
|
||||
rb->pool = pool;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* @brief reset ringbuffer, clean all data,
|
||||
* should be add lock in multithread
|
||||
*
|
||||
* @param[in] rb ringbuffer instance
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void __chry_ringbuffer_reset(chry_mempool_ringbuffer_t *rb)
|
||||
{
|
||||
rb->in = 0;
|
||||
rb->out = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* @brief write data to ringbuffer,
|
||||
* should be add lock in multithread,
|
||||
* in single write thread not need lock
|
||||
*
|
||||
* @param[in] rb ringbuffer instance
|
||||
* @param[in] data data pointer
|
||||
* @param[in] size size in byte
|
||||
*
|
||||
* @retval uint32_t actual write size in byte
|
||||
*****************************************************************************/
|
||||
static uint32_t __chry_ringbuffer_write(chry_mempool_ringbuffer_t *rb, void *data, uint32_t size)
|
||||
{
|
||||
uint32_t unused;
|
||||
uint32_t offset;
|
||||
uint32_t remain;
|
||||
|
||||
unused = (rb->mask + 1) - (rb->in - rb->out);
|
||||
|
||||
if (size > unused) {
|
||||
size = unused;
|
||||
}
|
||||
|
||||
offset = rb->in & rb->mask;
|
||||
|
||||
remain = rb->mask + 1 - offset;
|
||||
remain = remain > size ? size : remain;
|
||||
|
||||
memcpy(((uint8_t *)(rb->pool)) + offset, data, remain);
|
||||
memcpy(rb->pool, (uint8_t *)data + remain, size - remain);
|
||||
|
||||
rb->in += size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* @brief peek data from ringbuffer
|
||||
* should be add lock in multithread,
|
||||
* in single read thread not need lock
|
||||
*
|
||||
* @param[in] rb ringbuffer instance
|
||||
* @param[in] data data pointer
|
||||
* @param[in] size size in byte
|
||||
*
|
||||
* @retval uint32_t actual peek size in byte
|
||||
*****************************************************************************/
|
||||
static uint32_t __chry_ringbuffer_peek(chry_mempool_ringbuffer_t *rb, void *data, uint32_t size)
|
||||
{
|
||||
uint32_t used;
|
||||
uint32_t offset;
|
||||
uint32_t remain;
|
||||
|
||||
used = rb->in - rb->out;
|
||||
if (size > used) {
|
||||
size = used;
|
||||
}
|
||||
|
||||
offset = rb->out & rb->mask;
|
||||
|
||||
remain = rb->mask + 1 - offset;
|
||||
remain = remain > size ? size : remain;
|
||||
|
||||
memcpy(data, ((uint8_t *)(rb->pool)) + offset, remain);
|
||||
memcpy((uint8_t *)data + remain, rb->pool, size - remain);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* @brief read data from ringbuffer
|
||||
* should be add lock in multithread,
|
||||
* in single read thread not need lock
|
||||
*
|
||||
* @param[in] rb ringbuffer instance
|
||||
* @param[in] data data pointer
|
||||
* @param[in] size size in byte
|
||||
*
|
||||
* @retval uint32_t actual read size in byte
|
||||
*****************************************************************************/
|
||||
static uint32_t __chry_ringbuffer_read(chry_mempool_ringbuffer_t *rb, void *data, uint32_t size)
|
||||
{
|
||||
size = __chry_ringbuffer_peek(rb, data, size);
|
||||
rb->out += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
int chry_mempool_create(struct chry_mempool *pool, void *block, uint32_t block_size, uint32_t block_count)
|
||||
{
|
||||
uintptr_t *item;
|
||||
@@ -17,11 +149,11 @@ int chry_mempool_create(struct chry_mempool *pool, void *block, uint32_t block_s
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chry_ringbuffer_init(&pool->in, pool->in_buf, sizeof(uintptr_t) * block_count) == -1) {
|
||||
if (__chry_ringbuffer_init(&pool->in, pool->in_buf, sizeof(uintptr_t) * block_count) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chry_ringbuffer_init(&pool->out, pool->out_buf, sizeof(uintptr_t) * block_count) == -1) {
|
||||
if (__chry_ringbuffer_init(&pool->out, pool->out_buf, sizeof(uintptr_t) * block_count) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -45,8 +177,8 @@ int chry_mempool_create(struct chry_mempool *pool, void *block, uint32_t block_s
|
||||
void chry_mempool_delete(struct chry_mempool *pool)
|
||||
{
|
||||
chry_mempool_osal_sem_delete(pool->out_sem);
|
||||
chry_ringbuffer_reset(&pool->in);
|
||||
chry_ringbuffer_reset(&pool->out);
|
||||
__chry_ringbuffer_reset(&pool->in);
|
||||
__chry_ringbuffer_reset(&pool->out);
|
||||
}
|
||||
|
||||
uintptr_t *chry_mempool_alloc(struct chry_mempool *pool)
|
||||
@@ -54,7 +186,7 @@ uintptr_t *chry_mempool_alloc(struct chry_mempool *pool)
|
||||
uintptr_t *addr;
|
||||
uint32_t len;
|
||||
|
||||
len = chry_ringbuffer_read(&pool->in, (uintptr_t *)&addr, sizeof(uintptr_t));
|
||||
len = __chry_ringbuffer_read(&pool->in, (uintptr_t *)&addr, sizeof(uintptr_t));
|
||||
if (len == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
@@ -67,7 +199,7 @@ int chry_mempool_free(struct chry_mempool *pool, uintptr_t *item)
|
||||
uintptr_t addr;
|
||||
|
||||
addr = (uintptr_t)item;
|
||||
return chry_ringbuffer_write(&pool->in, &addr, sizeof(uintptr_t));
|
||||
return __chry_ringbuffer_write(&pool->in, &addr, sizeof(uintptr_t));
|
||||
}
|
||||
|
||||
int chry_mempool_send(struct chry_mempool *pool, uintptr_t *item)
|
||||
@@ -75,7 +207,7 @@ int chry_mempool_send(struct chry_mempool *pool, uintptr_t *item)
|
||||
uintptr_t addr;
|
||||
|
||||
addr = (uintptr_t)item;
|
||||
chry_ringbuffer_write(&pool->out, &addr, sizeof(uintptr_t));
|
||||
__chry_ringbuffer_write(&pool->out, &addr, sizeof(uintptr_t));
|
||||
return chry_mempool_osal_sem_give(pool->out_sem);
|
||||
}
|
||||
|
||||
@@ -89,7 +221,7 @@ int chry_mempool_recv(struct chry_mempool *pool, uintptr_t **item, uint32_t time
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = chry_ringbuffer_read(&pool->out, (uintptr_t *)item, sizeof(uintptr_t));
|
||||
len = __chry_ringbuffer_read(&pool->out, (uintptr_t *)item, sizeof(uintptr_t));
|
||||
if (len == 0) {
|
||||
return -1;
|
||||
} else {
|
||||
@@ -101,8 +233,8 @@ void chry_mempool_reset(struct chry_mempool *pool)
|
||||
{
|
||||
uintptr_t *item;
|
||||
|
||||
chry_ringbuffer_reset(&pool->in);
|
||||
chry_ringbuffer_reset(&pool->out);
|
||||
__chry_ringbuffer_reset(&pool->in);
|
||||
__chry_ringbuffer_reset(&pool->out);
|
||||
|
||||
for (uint32_t i = 0; i < pool->block_count; i++) {
|
||||
item = (uintptr_t *)((uint8_t *)pool->block + i * pool->block_size);
|
||||
|
||||
13
third_party/cherrymp/chry_mempool.h
vendored
@@ -10,17 +10,22 @@
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "chry_ringbuffer.h"
|
||||
|
||||
typedef void *chry_mempool_osal_sem_t;
|
||||
|
||||
#ifndef CONFIG_CHRY_MEMPOOL_MAX_BLOCK_COUNT
|
||||
#define CONFIG_CHRY_MEMPOOL_MAX_BLOCK_COUNT 128
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t in; /*!< Define the write pointer. */
|
||||
uint32_t out; /*!< Define the read pointer. */
|
||||
uint32_t mask; /*!< Define the write and read pointer mask. */
|
||||
void *pool; /*!< Define the memory pointer. */
|
||||
} chry_mempool_ringbuffer_t;
|
||||
|
||||
struct chry_mempool {
|
||||
chry_ringbuffer_t in;
|
||||
chry_ringbuffer_t out;
|
||||
chry_mempool_ringbuffer_t in;
|
||||
chry_mempool_ringbuffer_t out;
|
||||
chry_mempool_osal_sem_t out_sem;
|
||||
|
||||
void *block;
|
||||
|
||||
10
third_party/cherrymp/chry_mempool_osal_nonos.c
vendored
@@ -23,14 +23,4 @@ int chry_mempool_osal_sem_take(chry_mempool_osal_sem_t sem, uint32_t timeout)
|
||||
int chry_mempool_osal_sem_give(chry_mempool_osal_sem_t sem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *chry_mempool_osal_malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void chry_mempool_osal_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
@@ -41,14 +41,4 @@ int chry_mempool_osal_sem_take(chry_mempool_osal_sem_t sem, uint32_t timeout)
|
||||
int chry_mempool_osal_sem_give(chry_mempool_osal_sem_t sem)
|
||||
{
|
||||
return (int)rt_sem_release((rt_sem_t)sem);
|
||||
}
|
||||
|
||||
void *chry_mempool_osal_malloc(size_t size)
|
||||
{
|
||||
return rt_malloc(size);
|
||||
}
|
||||
|
||||
void chry_mempool_osal_free(void *ptr)
|
||||
{
|
||||
rt_free(ptr);
|
||||
}
|
||||
1
third_party/zephyr_bluetooth-2.7.5/zephyr_bluetooth/.gitkeep
vendored
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/sakumisu/zephyr_bluetooth
|
||||