63 Commits

Author SHA1 Message Date
sakumisu
4d6b12c704 docs: release v1.5.2
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-07 21:49:51 +08:00
sakumisu
5d2a7ca6bc fix(port/musb/usb_hc_musb): add rxmap & txmap config
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-07 21:11:05 +08:00
sakumisu
3ab47e0295 feat(port): add urb->complete in usbh_kill_urb
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-06 21:24:59 +08:00
sakumisu
2081360f2c update(port/dwc2): add mode check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-05 21:46:01 +08:00
sakumisu
8cf12c1958 update(port/musb): add mode check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-05 21:27:45 +08:00
sakumisu
c0f544dafe fix(class/mtp): fix typo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-04 21:56:57 +08:00
sakumisu
599b11ef1a update(osal/idf): change xtaskcreate to xTaskCreatePinnedToCore
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-04 21:47:55 +08:00
sakumisu
7037fd0e8d update(port/dwc2/usb_hc_dwc2): only clean & invalid buffer in usbh_submit_urb, do not clean&invalid many times
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-02 21:09:50 +08:00
sakumisu
3905eff2f4 docs: update readme
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-02 17:55:46 +08:00
sakumisu
20ceaced92 update(core/usbh_core): check string support and then get string desc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-01 21:38:47 +08:00
sakumisu
9ddcbf58ca update(port/dwc2/usb_hc_dwc2): only set errorcode before urb waitup because split transfer will do many times
Signed-off-by: sakumisu <1203593632@qq.com>
2025-08-01 21:13:46 +08:00
sakumisu
6e9e769e10 docs: update image
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 21:23:02 +08:00
sakumisu
65288c9d5b update(port/dwc2/usb_hc_dwc2): stop split transfer when intr nak, follow with nosplit intr transfer
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 21:22:48 +08:00
sakumisu
4ab097d9dc fix(common/usb_util): fix missing __ICCARM_V8 define
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 18:15:42 +08:00
sakumisu
f994422c41 chore(scons): export hpmicro dir
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-31 18:14:49 +08:00
egahp
5ae04f1273 fix(port/dwc2/usb_dwc2_param): fix macro literal types
Signed-off-by: egahp <2687434412@qq.com>
2025-07-31 14:11:28 +08:00
sakumisu
e574ea8ae3 Revert "fix(port): reset sem when pipe free"
This reverts commit ccd4354960.
2025-07-30 22:50:21 +08:00
sakumisu
f949e16564 update(port/dwc2/usb_hc_dwc2): add new api for split transfer, make code simple
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-30 22:21:54 +08:00
sakumisu
1bec84471e docs: update img
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-29 18:22:38 +08:00
sakumisu
1f065cec44 update(port/musb/usb_hc_musb): check urb for iso to support iso later
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 22:08:20 +08:00
sakumisu
3b1853ceb5 fix(platform/rtthread): change RT_USING_CACHE to CONFIG_USB_DCACHE_ENABLE
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 21:23:23 +08:00
sakumisu
72d19ec8cc update(usb_config): change CONFIG_USBHOST_MAX_INTF_ALTSETTINGS to 2 as default to avoid -Warray-bounds warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 21:03:55 +08:00
sakumisu
90de3354b5 update(port/musb): If ep control register group exists, do not use epidx register
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 20:20:16 +08:00
sakumisu
3784ddc389 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 19:15:33 +08:00
sakumisu
81d8f22e05 update(port): remove all ips CONFIG_USBDEV_EP_NUM & CONFIG_USBHOST_PIPE_NUM
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 19:06:37 +08:00
sakumisu
3b04facd09 revert: revert 1a68d94c some changes
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-28 14:18:18 +08:00
sakumisu
8dd3106e62 update(common/usb_hc): change interval u16 to u32 for us
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 21:25:27 +08:00
sakumisu
9e4122f2a0 fix(osal/idf): fix esp timer handle
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 21:22:18 +08:00
sakumisu
083ec57384 update(core/usbh_core): do not assert when parse desc fail, just return error
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 21:06:19 +08:00
sakumisu
ccd4354960 fix(port): reset sem when pipe free
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 20:58:47 +08:00
sakumisu
60ac6fe3ad fix(port/ehci): remove usb_osal_msleep in critical section
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 20:46:12 +08:00
udoudou
0986e8b5ec Fix the bug that dwc2_halt may cause hardware abnormality 2025-07-27 20:30:08 +08:00
udoudou
ae2a24642b Fix a bug where the channel might not be released 2025-07-27 20:30:08 +08:00
udoudou
1a68d94c32 add reset port timeout check for dwc2 2025-07-27 20:30:08 +08:00
sakumisu
c102f4adfa update(usb_config): change CONFIG_USBHOST_MAX_INTF_ALTSETTINGS to 1 as default for less memory usage
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 10:26:31 +08:00
sakumisu
d589b9417d update(osal/idf): change freertos timer to esp_timer
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-27 10:21:00 +08:00
sakumisu
7b39de9630 update(port/dwc2/usb_glue_kendryte): update dwc2 param
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-26 16:48:12 +08:00
sakumisu
6702ab9225 update(port/dwc2): invalid data before start read
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-26 16:11:47 +08:00
sakumisu
ecb98f399d update: add output_len param for usbh_get_string_desc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-25 22:37:25 +08:00
sakumisu
a9ec951c93 update(common/usb_hc): change interval u8 to u16 for us
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-25 22:24:35 +08:00
sakumisu
9de28f9342 style: format log
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-25 18:45:38 +08:00
sakumisu
dc7e53d79f fix(port/dwc2/usb_hc_dwc2): exit porten loop check when device disconnets
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-24 21:03:22 +08:00
sakumisu
d3a5aae7af fix(class/hub/usbh_hub): fix port to port+1
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-24 21:00:21 +08:00
Matthew
7153fb9756 fix(platform/rtthread): add RT_DEVICE_FLAG_INT_RX falg to device 2025-07-24 18:29:34 +08:00
Matthew
0e31b40407 fix(platform/rtthread): restart read at usbd_cdc_acm_bulk_out 2025-07-24 18:29:34 +08:00
sakumisu
fa5a9fbcaa update(platform/rtthread): remove align size check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-22 20:24:41 +08:00
sakumisu
68b28a43f3 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-22 18:20:37 +08:00
sakumisu
ddda03c4cb update(port): remove CONFIG_USBDEV_EP_NUM & CONFIG_USBHOST_PIPE_NUM for some ips because they are constant
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-21 21:22:54 +08:00
sakumisu
96ab19e398 fix(core/usbh_core): change 2ms to 10ms because some platform's tick is 100hz then 2ms = 0ms, refs: #342
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-20 21:29:48 +08:00
sakumisu
2783793b17 fix(port/dwc2/usb_hc_dwc2): check buf is valid then using dcache clean
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-20 21:25:20 +08:00
sakumisu
e499871a59 fix(port/dwc2/usb_glue_st): reduce f4 total size for some specific f4 chips
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-19 10:08:52 +08:00
Derek Konigsberg
7c38af1b04 Clear error code after intentionally ignoring it
In the case of handling a stall on a max lun request, we need to clear the error code in `ret` after ignoring it. This is necessary so the connect function won't fail.

Fix #339
2025-07-19 09:20:49 +08:00
sakumisu
cc3e91e8d7 fix(port/dwc2/usb_hc_dwc2): invalid indata before urb done
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 23:16:41 +08:00
sakumisu
a95e06a951 update(cherrymp): update local ringbuf
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 22:50:48 +08:00
sakumisu
502c88084c update: remove zephyr bluetooth submodule
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 22:46:55 +08:00
sakumisu
a9f0374fa7 style: format code
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 22:36:23 +08:00
sakumisu
56c864b008 fix(port/dwc2/usb_hc_dwc2): fix control split transfer with short packet
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-18 21:36:19 +08:00
sakumisu
80f0f97efa fix(port/dwc2/usb_glue_at): fix host rx size
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-17 23:01:32 +08:00
sakumisu
4fdbe4ed26 docs: update image
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-17 22:23:45 +08:00
sakumisu
1e8e440721 fix(demo): ignore zero bytes for bl ip
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-16 22:54:21 +08:00
sakumisu
605a967282 style: remove some logs
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-16 22:17:19 +08:00
sakumisu
7a357a10da feat(port/dwc2): support ep mult
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-16 21:49:54 +08:00
LiPeng
d58037e3d4 Add FS support for ESP32-P4 2025-07-14 20:50:16 +08:00
91 changed files with 1342 additions and 894 deletions

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "third_party/zephyr_bluetooth-2.7.5/zephyr_bluetooth"]
path = third_party/zephyr_bluetooth-2.7.5/zephyr_bluetooth
url = https://github.com/sakumisu/zephyr_bluetooth.git

View File

@@ -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}
)

View File

@@ -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

View File

@@ -40,6 +40,8 @@ Taking into account USB performance issues and trying to achieve the theoretical
- Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
- Packetization is handled in interrupt
Performance showhttps://cherryusb.cherry-embedded.org/show/
## Directory Structure
| Directory | Description |
@@ -103,7 +105,7 @@ CherryUSB Host Stack has the following functions:
- Support blocking transfers and asynchronous transfers
- Support Composite Device
- Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2/ehci/xhci/rp2040)
- Support Communication Device Class (CDC_ACM, CDC_ECM)
- Support Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM)
- Support Human Interface Device (HID)
- Support Mass Storage Class (MSC)
- Support USB Video CLASS (UVC1.0, UVC1.5)
@@ -141,7 +143,7 @@ Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affe
#define CONFIG_USBHOST_MAX_EXTHUBS 1
#define CONFIG_USBHOST_MAX_EHPORTS 4
#define CONFIG_USBHOST_MAX_INTERFACES 8
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
```
@@ -187,24 +189,25 @@ TODO
## Demo Repo
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note |
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term |
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term |
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD |
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official |
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community |
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official |
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= 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" />

View File

@@ -40,6 +40,8 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(
- 长度无限制,方便对接硬件 DMA 并且发挥 DMA 的优势
- 分包过程在中断中执行
性能展示https://cherryusb.cherry-embedded.org/show/
## 目录结构
| 目录名 | 描述 |
@@ -103,7 +105,7 @@ CherryUSB Host 协议栈当前实现以下功能:
- 支持阻塞式传输和异步传输
- 支持复合设备
- 支持多级 HUB最高可拓展到 7 级(目前测试 1拖 10 没有问题,仅支持 dwc2/ehci/xhci/rp2040)
- 支持 Communication Device Class (CDC_ACM, CDC_ECM)
- 支持 Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM)
- 支持 Human Interface Device (HID)
- 支持 Mass Storage Class (MSC)
- Support USB Video CLASS (UVC1.0、UVC1.5)
@@ -141,7 +143,7 @@ CherryUSB Host 协议栈资源占用说明GCC 10.2 with -O2关闭 log
#define CONFIG_USBHOST_MAX_EXTHUBS 1
#define CONFIG_USBHOST_MAX_EHPORTS 4
#define CONFIG_USBHOST_MAX_INTERFACES 8
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
```
@@ -187,24 +189,25 @@ TODO
## 示例仓库
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status |
| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note |
|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:|
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term |
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term |
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term |
|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term |
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD |
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official |
|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community |
|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official |
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official |
|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official |
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official |
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= 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" />

View File

@@ -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')

View File

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

View File

@@ -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

View File

@@ -121,7 +121,7 @@ get_mac:
}
memset(mac_buffer, 0, 12);
ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer);
ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer, 12);
if (ret < 0) {
return ret;
}

View File

@@ -148,7 +148,7 @@ get_mac:
}
memset(mac_buffer, 0, 12);
ret = usbh_get_string_desc(cdc_ncm_class->hport, mac_str_idx, (uint8_t *)mac_buffer);
ret = usbh_get_string_desc(cdc_ncm_class->hport, mac_str_idx, (uint8_t *)mac_buffer, 12);
if (ret < 0) {
return ret;
}

View File

@@ -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;
}
}

View File

@@ -7,9 +7,10 @@
#include "usbd_core.h"
#include "usbd_msc.h"
#include "usb_scsi.h"
#if defined(CONFIG_USBDEV_MSC_THREAD)
#include "usb_osal.h"
#endif
#undef USB_DBG_TAG
#define USB_DBG_TAG "usbd_msc"
#include "usb_log.h"
#define MSD_OUT_EP_IDX 0
#define MSD_IN_EP_IDX 1
@@ -516,19 +517,14 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
}
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
USB_LOG_ERR("LBA out of range\r\n");
return false;
}
if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
return false;
}
g_usbd_msc[busid].stage = MSC_DATA_IN;
@@ -554,19 +550,14 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
}
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
USB_LOG_ERR("LBA out of range\r\n");
return false;
}
if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
return false;
}
g_usbd_msc[busid].stage = MSC_DATA_IN;
@@ -594,14 +585,10 @@ static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
}
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
USB_LOG_ERR("LBA out of range\r\n");
return false;
}
@@ -627,14 +614,10 @@ static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
}
g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc[busid].start_sector);
g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc[busid].nsectors);
data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
USB_LOG_ERR("LBA out of range\r\n");
return false;
}
@@ -646,52 +629,6 @@ static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, g_usbd_msc[busid].block_buffer, data_len);
return true;
}
/* do not use verify to reduce code size */
#if 0
static bool SCSI_verify10(uint8_t busid, uint8_t **data, uint32_t *len)
{
/* Logical Block Address of First Block */
uint32_t lba = 0;
uint32_t blk_num = 0;
if ((g_usbd_msc[busid].cbw.CB[1] & 0x02U) == 0x00U) {
return true;
}
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
return false;
}
if ((g_usbd_msc[busid].cbw.CB[1] & 0x02U) == 0x02U) {
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDFIELDINCBA);
return false; /* Error, Verify Mode Not supported*/
}
lba = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]);
USB_LOG_DBG("lba: 0x%x\r\n", lba);
g_usbd_msc[busid].scsi_blk_addr = lba * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
/* Number of Blocks to transfer */
blk_num = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]);
USB_LOG_DBG("num (block) : 0x%x\r\n", blk_num);
g_usbd_msc[busid].scsi_blk_len = blk_num * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
if ((lba + blk_num) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
USB_LOG_ERR("LBA out of range\r\n");
return false;
}
if (g_usbd_msc[busid].cbw.dDataLength != g_usbd_msc[busid].scsi_blk_len) {
return false;
}
g_usbd_msc[busid].stage = MSC_DATA_OUT;
return true;
}
#endif
static bool SCSI_processRead(uint8_t busid)
{
@@ -722,6 +659,7 @@ static bool SCSI_processRead(uint8_t busid)
static bool SCSI_processWrite(uint8_t busid, uint32_t nbytes)
{
uint32_t data_len = 0;
USB_LOG_DBG("write lba:%d\r\n", g_usbd_msc[busid].start_sector);
if (usbd_msc_sector_write(busid, g_usbd_msc[busid].cbw.bLUN, g_usbd_msc[busid].start_sector, g_usbd_msc[busid].block_buffer, nbytes) != 0) {
@@ -804,7 +742,6 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
ret = SCSI_write12(busid, NULL, 0);
break;
case SCSI_CMD_VERIFY10:
//ret = SCSI_verify10(NULL, 0);
ret = false;
break;
case SCSI_CMD_SYNCHCACHE10:
@@ -812,7 +749,6 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
break;
default:
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
USB_LOG_WRN("unsupported cmd:0x%02x\r\n", g_usbd_msc[busid].cbw.CB[0]);
ret = false;
break;
}
@@ -820,7 +756,7 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
if (ret) {
if (g_usbd_msc[busid].stage == MSC_READ_CBW) {
if (len2send) {
USB_LOG_DBG("Send info len:%d\r\n", len2send);
USB_LOG_DBG("Send info len: %d\r\n", len2send);
usbd_msc_send_info(busid, buf2send, len2send);
} else {
usbd_msc_send_csw(busid, CSW_STATUS_CMD_PASSED);
@@ -837,7 +773,7 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
switch (g_usbd_msc[busid].stage) {
case MSC_READ_CBW:
if (SCSI_CBWDecode(busid, nbytes) == false) {
USB_LOG_ERR("Command:0x%02x decode err\r\n", g_usbd_msc[busid].cbw.CB[0]);
USB_LOG_ERR("Command: 0x%02x decode err\r\n", g_usbd_msc[busid].cbw.CB[0]);
usbd_msc_bot_abort(busid);
return;
}
@@ -921,7 +857,6 @@ static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
if (ret < 0) {
continue;
}
USB_LOG_DBG("event:%d\r\n", event);
if (event == MSC_DATA_OUT) {
if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
@@ -943,7 +878,6 @@ void usbd_msc_polling(uint8_t busid)
if (event != 0) {
g_usbd_msc[busid].event = 0;
USB_LOG_DBG("event:%d\r\n", event);
if (event == MSC_DATA_OUT) {
if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/

View File

@@ -284,6 +284,7 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
if (ret == -USB_ERR_STALL) {
USB_LOG_WRN("Device does not support multiple LUNs\r\n");
g_msc_buf[msc_class->sdchar - 'a'][0] = 0;
ret = 0;
} else {
return ret;
}

View File

@@ -644,7 +644,7 @@ struct mtp_object {
bool in_use;
};
/*Length of template descriptor: 23 bytes*/
/*Length of template descriptor: 30 bytes*/
#define MTP_DESCRIPTOR_LEN (9 + 7 + 7 + 7)
// clang-format off

View File

@@ -1121,7 +1121,7 @@ static inline int usb_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_
static uint32_t ocp_read_dword(struct usbh_rtl8152 *tp, uint16_t type, uint16_t index)
{
uint32_t data;
uint32_t data = 0;
generic_ocp_read(tp, index, sizeof(data), &data, type);
@@ -2050,7 +2050,7 @@ static int usbh_rtl8152_connect(struct usbh_hubport *hport, uint8_t intf)
}
memset(mac_buffer, 0, 12);
ret = usbh_get_string_desc(rtl8152_class->hport, 3, (uint8_t *)mac_buffer);
ret = usbh_get_string_desc(rtl8152_class->hport, 3, (uint8_t *)mac_buffer, 12);
if (ret < 0) {
return ret;
}

View File

@@ -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;

View File

@@ -15,7 +15,7 @@
#define USB_ERR_RANGE 7
#define USB_ERR_STALL 8
#define USB_ERR_BABBLE 9
#define USB_ERR_NAK 10
#define USB_ERR_NAK 10 /* only for dwc2 buffer dma mode */
#define USB_ERR_DT 11
#define USB_ERR_IO 12
#define USB_ERR_SHUTDOWN 13

View File

@@ -39,7 +39,7 @@ struct usbh_urb {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *ep;
uint8_t data_toggle;
uint8_t interval;
uint32_t interval;
struct usb_setup_packet *setup;
uint8_t *transfer_buffer;
uint32_t transfer_buffer_length;

View File

@@ -45,6 +45,12 @@
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#elif defined(__ICCARM__) || defined(__ICCRX__) || defined(__ICCRISCV__)
#if (__VER__ >= 8000000)
#define __ICCARM_V8 1
#else
#define __ICCARM_V8 0
#endif
#ifndef __USED
#if defined(__ICCARM_V8) || defined(__ICCRISCV__)
#define __USED __attribute__((used))

View File

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

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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.

View File

@@ -448,6 +448,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
if (nbytes == 0) {
return;
}
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
video_iso_tx_busy = false;

View File

@@ -252,6 +252,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
if (nbytes == 0) {
return;
}
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;

View File

@@ -252,6 +252,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
if (nbytes == 0) {
return;
}
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;

View File

@@ -256,6 +256,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
if (nbytes == 0) {
return;
}
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;

BIN
docs/assets/sifli.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -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

View File

@@ -56,3 +56,7 @@ Klipper is a 3d-printer firmware.
适配链接:待开放
MAKCU/KMBOX
--------------
懂的都懂,不开放

View File

@@ -10,12 +10,13 @@ Q & A
提问中请包含以下信息:
- 使用的版本
- 使用的板子引脚USB IP
- USB 中断,时钟,引脚,寄存器地址是否正确,截图
- 是否配置 USB 中断,USB 时钟USB 引脚USB phy 配置,以及 USB 寄存器地址是否正确,截图
- 是否能进 USB 中断
- 芯片是否带有 cache功能是否做了 no cache 处理,截图
- 硬件是否正常,是否使用杜邦线连接,如果正常,请说明正常原因
- 配置 **#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 引脚必须为 4PB14/PB15 引脚必须为 6并删除 usb_dc_dwc2.c 中 while(1){}
- 当 CONFIG_USBDEV_EP_NUM 为4 时fifo_num 不得大于 320 字
- 当 CONFIG_USBDEV_EP_NUM 为6 时fifo_num 不得大于 1280 字
GD IP 采用 DWC2但是读取的硬件参数都是 0我也不懂为什么不给人知道因此需要用户自行知道硬件信息从 1.5.0 开始由于需要读取硬件信息,因此无法直接使用。
其次 GD 复位以后无法使用 EPDIS 功能关闭端点,需要用户删除 reset 中断中的以下代码:
@@ -50,11 +46,6 @@ CONFIG_USBDEV_EP_NUM pa11/pa12 引脚必须为 4PB14/PB15 引脚必须为 6
USB_OTG_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
USB_OTG_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
dwc2 has less endpoints than config, please check
---------------------------------------------------------------
该 IP 硬件上没有这么多端点,请修改 `CONFIG_USBDEV_EP_NUM`
Ep addr XXX overflow
------------------------------
@@ -75,7 +66,6 @@ CONFIG_USB_HS 何时使用
当你的芯片硬件支持高速,并想初始化成高速模式时开启,相关 IP 会根据该宏配置内部或者外部 高速 PHY。
Failed to enable port
----------------------------------------------------------------
@@ -84,6 +74,25 @@ Failed to enable port
移植 usb host 出现 urb 返回 -12/-14
----------------------------------------------------------------
-12 就检查 phy 配置,通信不良
检查 phy 配置,cache 配置(如果有),电源供电(建议自供电)
-14 就检查 phy 配置cache 配置如果有fifo配置寄存器地址 IP 是否真的标准等等
USB_ERR_NAK 说明
----------------------------------------------------------------
USB_ERR_NAK 只存在于 DWC2 buffer dma 模式DWC2 在 buffer dma模式下对于中断传输不支持硬件处理 NAK 中断,因此需要软件处理,导致 NAK 中断非常多,建议搭配定时器使用。
DWC2 scatter/gather dma 模式下全部由硬件处理,但是不支持 split 传输。总结, **半斤 IP**
USB host 连接 USB 网卡问题
----------------------------------------------------------------
表现为能识别网卡并且分配到 IP 地址,但是无法 ping 通,这是因为网卡自身需要开启自动拨号,通常需要使用 AT 口设置。具体为 EC20/ML307 等模块。
PC 识别的 COM 口如何更改名称
----------------------------------------------------------------
这是微软对 CDC ACM 的驱动问题,无法修改,如需修改,请联系微软并缴纳费用即可更改。
connect 和 disconnect event 不触发
----------------------------------------------------------------
当前仅 hpm 芯片支持 connect 和 disconnect 事件,其他芯片请使用 USB 检测 vbus 电路。DWC2 IP 支持但是由于需要占用引脚并且大多是log 口,
然后不同使能的配置也不一样,因此不做支持。

View File

@@ -4,60 +4,71 @@
在学习 USB 或者是学习 CherryUSB 代码之前,我们需要先基于现有的 demo 进行快速验证,为什么?是为了提升对 USB 的兴趣,能有信心进行下一步的动作,如果 demo 都跑不起来,或者自己摸索写代码,或者先看 USB 基本概念,结果看到最后,
发现一点都看不懂,概念好多,根本记不住,从而丧失对 USB 的兴趣。因此,先跑 demo 非常重要。下面我将给大家罗列目前支持的 demo 仓库。
基于 bouffalolab 系列芯片
---------------------------
基于 bouffalolab 系列芯片(官方 SDK 支持)
------------------------------------------
仓库参考https://github.com/CherryUSB/cherryusb_bouffalolab
- BL616/BL808 是一个 USB2.0 并且内置高速 PHY 芯片,共 5个端点端点0。支持主从机
- BL616/BL808USB2.0 内置 HS phy 芯片支持主从机。device 支持 5 个端点(包端点0,不支持双向同时使用
- USB 的相关应用位于 `examples/usbdev``examples/usbhost` 目录下,根据官方环境搭建完成后,即可编译使用。
基于 HPMicro 系列芯片
---------------------------
基于 HPMicro 系列芯片(官方 SDK 支持)
-----------------------------------------------------
仓库参考https://github.com/CherryUSB/cherryusb_hpmicro
- HPM 系列芯片均 USB 2.0 并且内置高速 PHY支持主从机端点共 8/16 个,并且可以同时使用双向,不同芯片个数有差异
- HPM 系列: USB2.0 内置 HS phy 芯片支持主从机。device 支持 8/16 端点包括端点0,并且可以同时使用双向,不同芯片个数有差异
- USB 的相关应用位于 `samples/cherryusb` ,根据官方环境搭建完成后,即可编译使用。
基于 esp32s2/s3/p4 系列芯片
---------------------------
基于 esp32s2/s3/p4 系列芯片(官方 SDK 即将支持)
-------------------------------------------------
仓库参考https://github.com/CherryUSB/cherryusb_esp32
- esp32s2/s3 支持全速主从机esp32p4 支持高速主从机
- 默认提供主机 demo并且使用 esp 组件库进行开发, 在 https://components.espressif.com/ 中搜索 cherryusb 即可
- esp32s2/s3USB2.0 内置全速 PHY 芯片支持主从机device 支持 7 个端点包括端点0并且可以同时使用双向。
- esp32p4一个 USB2.0 内置全速 PHY 芯片,一个 USB2.0 内置高速 PHY 芯片,支持主从机。
- 默认 demo 采用组件库安装的形式,在 https://components.espressif.com/ 中搜索 cherryusb 即可
基于飞腾派系列芯片
---------------------------
基于飞腾派系列芯片(官方 SDK 支持)
-----------------------------------
仓库参考https://gitee.com/phytium_embedded/phytium-free-rtos-sdk
- 飞腾派支持两个 USB3.0 主机(采用 XHCI 两个 USB2.0 主从机
- USB 的相关应用位于 `example/peripheral/usb` ,根据官方环境搭建完成后,即可编译使用。
基于 Essemi 系列芯片
---------------------------
基于 Essemi 系列芯片(官方 SDK 支持)
-----------------------------------------
仓库参考https://github.com/CherryUSB/cherryusb_es32
- 支持全速和高速主从机
- 支持全速和高速主从机。device 支持 6 个端点包括端点0并且可以同时使用双向。
基于 Artinchip 系列芯片(官方 SDK 支持)
-----------------------------------------------
仓库参考https://gitee.com/artinchip/luban-lite
- 支持全速和高速主从机,主机采用 EHCI + OHCI。device 支持 8 个端点包括端点0并且可以同时使用双向。
基于 canmv-k230 芯片(官方 SDK 支持)
---------------------------------------------
仓库参考https://github.com/CherryUSB/k230_sdk
- K230: 两个 USB2.0 内置 HS PHY 芯片支持主从机。device 支持 16 个端点包括端点0并且可以同时使用双向。
基于 NXP MCX系列芯片
---------------------------
仓库参考https://github.com/CherryUSB/cherryusb_mcx 或者 https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx
- 支持全速 IP 和高速 IP 高速 IP 支持主机和从机
- 支持全速 IP 和高速 IP 高速 IP 支持主机和从机。device 支持 8 个端点包括端点0并且可以同时使用双向。
- 支持全速和高速主从机
基于 RP2040/RP2035 芯片(官方 SDK 即将支持)
--------------------------------------------
基于 Artinchip 系列芯片
---------------------------
仓库参考https://gitee.com/artinchip/luban-lite
- 支持全速和高速主从机,主机采用 EHCI + OHCI。
仓库参考: https://github.com/CherryUSB/pico-examples 和 https://github.com/CherryUSB/pico-sdk
基于 ST 系列芯片
---------------------------
@@ -67,8 +78,8 @@
默认提供以下 demo 工程:
- F103 使用 fsdev ip
- F429 主从使用 USB1, 引脚 pb14/pb15, 并且都使用 dma 模式
- H7 设备使用 USB0, 引脚 pa11/pa12没有开DMA 模式。主机使用 USB1 ,引脚 pb14/pb15并且需要做 nocache 处理
- F429 主从使用 USB1, 引脚 pb14/pb15, 默认从机没有开启 DMA 模式
- H7 设备使用 USB0, 引脚 pa11/pa12没有开 DMA 模式。主机使用 USB1 ,引脚 pb14/pb15并且需要做 nocache 处理
demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate Code** 即可。
@@ -78,7 +89,7 @@ demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate
- usb ip 区别F1使用 fsdevF4/H7使用 dwc2
- dwc2 ip 区别: USB0 (引脚是 PA11/PA12) 和 USB1 (引脚是 PB14/PB15), 其中 USB1 默认全速可以接外部PHY 形成高速主机,并且带 dma 功能
- F4 无cacheH7 有 cache
- F4 无 cacheH7 有 cache
如果是 STM32F7/STM32H7 这种带 cache 功能,需要将 usb 使用到的 ram 定位到 no cache ram 区域。举例如下
@@ -116,12 +127,12 @@ USB Device 移植要点
- 如果使用 fsdev ip勾选 **USB** 。如果使用 dwc2 ip勾选 **USB_OTG_FS** 或者勾选 **USB_OTG_HS**。开启 USB 中断,其他配置对我们没用,代码中不会使用任何 st 的 usb 库。
.. figure:: img/stm32_3_1.png
.. figure:: img/stm32_3.png
.. figure:: img/stm32_3_2.png
- 配置 usb clock 为 48M
.. figure:: img/stm32_4_1.png
.. figure:: img/stm32_4.png
.. figure:: img/stm32_4_2.png
- 选择好工程,这里我们选择 keil设置好 stack 和 heap如果使用 msc 可以推荐设置大点,然后点击 **Generate Code**
@@ -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 ipV1.5.0 开始需要增加 **fsdev/usb_glue_st.c**`usb_config.h` 中实现以下宏:
- 如果使用 fsdev ipV1.5.0 开始需要增加 **fsdev/usb_glue_st.c**`usb_config.h` 中实现以下宏,具体数值不同芯片不一样
.. code-block:: C
#define CONFIG_USBDEV_EP_NUM 8
#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2
- 编译器推荐使用 **AC6**。勾选 **Microlib**,并实现 **printf** ,方便后续查看 log。
@@ -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` 章节
- 如果芯片带 cachecache 修改参考 :ref:`usb_cache` 章节
- 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base` `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
- 启动线程
.. figure:: img/stm32_18.png
.. figure:: img/stm32_19.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -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 协议栈中的名称
- 如果芯片带 cachecache 修改参考 :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` 章节
- 如果芯片带 cachecache 修改参考 :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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -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
-----------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 MiB

View File

@@ -7,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 驱动适配
- 技术支持相关

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 503 KiB

After

Width:  |  Height:  |  Size: 684 KiB

View File

@@ -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 timerfreertos timer会有启动失败的可能性xTaskCreate 使用 xTaskCreatePinnedToCore 替换,方便多核使用
- 主机枚举中,删除描述符溢出相关的 ASSERT 操作改成返回错误。获取字符串描述符改成支持才获取。2 ms 延时改成 10ms因为一些 os 使用的是 100hz会造成延时失效
- **dwc2 ep mult 支持split 传输代码优化,对 split 相关的 cache 处理修改**
- **dwc2 halt 中不能清除 USB_OTG_HCCHAR_EPDIRreset port 中使用超时机制,防止在枚举时由于拔出而造成死等**
- 更新 DWC2 中 at32stm32kendryteespressif 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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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),

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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.

View File

@@ -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)

View File

@@ -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

View File

@@ -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, &param_fs, sizeof(struct dwc2_user_params));
#elif CONFIG_IDF_TARGET_ESP32P4
if (reg_base == 0x50000000UL) {
if (reg_base == ESP_USB_HS0_BASE) {
memcpy(params, &param_hs, sizeof(struct dwc2_user_params));
} else {
memcpy(params, &param_fs, sizeof(struct dwc2_user_params));

View File

@@ -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, &param_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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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 */

View File

@@ -17,3 +17,7 @@
### AllwinnerTech
- F1Cxxx, F2Cxxx
### SIFLI
- SF325X

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}
}
}

View File

@@ -12,6 +12,6 @@ Modify USB_NOCACHE_RAM_SECTION
- MCXN9XX/MCXN236 (chipidea + EHCI)
## IMRT
### IMRT
- IMRT10XX/IMRT11XX (chipidea + EHCI)

View File

@@ -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

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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).

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1 @@
https://github.com/sakumisu/zephyr_bluetooth