mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-05-28 09:56:32 +08:00
update(cherryusb): update to v1.4.0
This commit is contained in:
@@ -48,6 +48,10 @@ if RT_USING_CHERRYUSB
|
||||
bool "musb_bk"
|
||||
config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
|
||||
bool "musb_custom"
|
||||
config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
|
||||
bool "chipidea_mcx"
|
||||
config RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM
|
||||
bool "chipidea_custom"
|
||||
config RT_CHERRYUSB_DEVICE_BL
|
||||
bool "bouffalo"
|
||||
config RT_CHERRYUSB_DEVICE_CH32
|
||||
@@ -162,10 +166,12 @@ if RT_USING_CHERRYUSB
|
||||
bool "ehci_hpm"
|
||||
config RT_CHERRYUSB_HOST_EHCI_AIC
|
||||
bool "ehci_aic"
|
||||
config RT_CHERRYUSB_HOST_EHCI_NUVOTON_NUC980
|
||||
bool "ehci_nuvoton_nuc980"
|
||||
config RT_CHERRYUSB_HOST_EHCI_NUVOTON_MA35D0
|
||||
bool "ehci_nuvoton_ma35d0"
|
||||
config RT_CHERRYUSB_HOST_EHCI_MCX
|
||||
bool "ehci_mcx"
|
||||
config RT_CHERRYUSB_HOST_EHCI_NUC980
|
||||
bool "ehci_nuc980"
|
||||
config RT_CHERRYUSB_HOST_EHCI_MA35D0
|
||||
bool "ehci_ma35d0"
|
||||
config RT_CHERRYUSB_HOST_EHCI_CUSTOM
|
||||
bool "ehci_custom"
|
||||
config RT_CHERRYUSB_HOST_DWC2_ST
|
||||
@@ -294,7 +300,7 @@ if RT_USING_CHERRYUSB
|
||||
config CONFIG_USBHOST_PLATFORM_RTL8152
|
||||
bool
|
||||
|
||||
config CHERRYUSB_HOST_TEMPLATE
|
||||
config RT_CHERRYUSB_HOST_TEMPLATE
|
||||
bool
|
||||
prompt "Use usb host template"
|
||||
default n
|
||||
|
||||
@@ -34,7 +34,7 @@ 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
|
||||
- Subcontracting function is handled in interrupt
|
||||
|
||||
## Directoy Structure
|
||||
## Directory Structure
|
||||
|
||||
| Directory | Description |
|
||||
|:-------------:|:---------------------------:|
|
||||
@@ -65,15 +65,17 @@ CherryUSB Device Stack has the following functions:
|
||||
- Support Device Firmware Upgrade CLASS (DFU)
|
||||
- Support USB MIDI CLASS (MIDI)
|
||||
- Support Remote NDIS (RNDIS)
|
||||
- Support WINUSB1.0、WINUSB2.0(with BOS)
|
||||
- Support WINUSB1.0、WINUSB2.0、WEBUSB、BOS
|
||||
- Support Vendor class
|
||||
- Support UF2
|
||||
- Support Android Debug Bridge (Only support shell)
|
||||
- Support multi device with the same USB IP
|
||||
|
||||
CherryUSB Device Stack resource usage (GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|
||||
|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 |
|
||||
|usbd_core.c | 3516 | 512(default) + 320 | 0 | 0 |
|
||||
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|
||||
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|
||||
|usbd_hid.c | 364 | 0 | 0 | 0 |
|
||||
@@ -87,6 +89,7 @@ The CherryUSB Host Stack has a standard enumeration implementation for devices m
|
||||
|
||||
CherryUSB Host Stack has the following functions:
|
||||
|
||||
- Support low speed, full speed, high speed and super speed devices
|
||||
- Automatic loading of supported Class drivers
|
||||
- Support blocking transfers and asynchronous transfers
|
||||
- Support Composite Device
|
||||
@@ -98,7 +101,7 @@ CherryUSB Host Stack has the following functions:
|
||||
- Support USB Audio CLASS (UAC1.0)
|
||||
- Support Remote NDIS (RNDIS)
|
||||
- Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm)
|
||||
- Support Vendor class
|
||||
- Support Vendor class (serial, net, wifi)
|
||||
- Support USB modeswitch
|
||||
- Support multi host with the same USB IP
|
||||
|
||||
@@ -108,7 +111,7 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
|
||||
|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | 0 |
|
||||
|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|
||||
|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|
||||
|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|
||||
|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
|
||||
@@ -152,6 +155,7 @@ Only standard and commercial USB IP are listed.
|
||||
| DWC2(synopsys) | DWC2 | DWC2 | √ |
|
||||
| MUSB(mentor) | MUSB | MUSB | √ |
|
||||
| FOTG210(faraday)| FOTG210 | EHCI | √ |
|
||||
| CHIPIDEA(synopsys)| CHIPIDEA | EHCI | √ |
|
||||
| CDNS2(cadence) | CDNS2 | CDNS2 | √ |
|
||||
| CDNS3(cadence) | CDNS3 | XHCI | × |
|
||||
| DWC3(synopsys) | DWC3 | XHCI | × |
|
||||
@@ -175,17 +179,26 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|
||||
|ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= 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)|v0.10.2 | 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 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | the same with ST |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with Essemi |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with Essemi |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | the same with ST |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|
||||
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
|
||||
|
||||
## Package Support
|
||||
|
||||
CherryUSB package is available as follows:
|
||||
|
||||
- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB)
|
||||
- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook)
|
||||
- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb)
|
||||
|
||||
## Commercial Support
|
||||
|
||||
Refer to https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html.
|
||||
|
||||
@@ -65,15 +65,17 @@ CherryUSB Device 协议栈当前实现以下功能:
|
||||
- 支持 Device Firmware Upgrade CLASS (DFU)
|
||||
- 支持 USB MIDI CLASS (MIDI)
|
||||
- 支持 Remote NDIS (RNDIS)
|
||||
- 支持 WINUSB1.0、WINUSB2.0(带 BOS )
|
||||
- 支持 WINUSB1.0、WINUSB2.0、WEBUSB、BOS
|
||||
- 支持 Vendor 类 class
|
||||
- 支持 UF2
|
||||
- 支持 Android Debug Bridge (Only support shell)
|
||||
- 支持相同 USB IP 的多从机
|
||||
|
||||
CherryUSB Device 协议栈资源占用说明(GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|
||||
|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 |
|
||||
|usbd_core.c | 3516 | 512(default) + 320 | 0 | 0 |
|
||||
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|
||||
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|
||||
|usbd_hid.c | 364 | 0 | 0 | 0 |
|
||||
@@ -87,6 +89,7 @@ CherryUSB Host 协议栈对挂载在 roothub、外部 hub 上的设备规范了
|
||||
|
||||
CherryUSB Host 协议栈当前实现以下功能:
|
||||
|
||||
- 支持 low speed, full speed, high speed 和 super speed 设备
|
||||
- 自动加载支持的Class 驱动
|
||||
- 支持阻塞式传输和异步传输
|
||||
- 支持复合设备
|
||||
@@ -98,7 +101,7 @@ CherryUSB Host 协议栈当前实现以下功能:
|
||||
- Support USB Audio CLASS (UAC1.0)
|
||||
- 支持 Remote NDIS (RNDIS)
|
||||
- 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能)
|
||||
- 支持 Vendor 类 class
|
||||
- 支持 Vendor 类 class (serial, net, wifi)
|
||||
- 支持 USB modeswitch
|
||||
- 支持相同 USB IP 的多主机
|
||||
|
||||
@@ -108,7 +111,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
|
||||
|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | 0 |
|
||||
|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | raw_config_desc |
|
||||
|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|
||||
|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|
||||
|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
|
||||
@@ -152,6 +155,7 @@ x 受以下宏影响:
|
||||
| DWC2(synopsys) | DWC2 | DWC2 | √ |
|
||||
| MUSB(mentor) | MUSB | MUSB | √ |
|
||||
| FOTG210(faraday)| FOTG210 | EHCI | √ |
|
||||
| CHIPIDEA(synopsys)| CHIPIDEA | EHCI | √ |
|
||||
| CDNS2(cadence) | CDNS2 | CDNS2 | √ |
|
||||
| CDNS3(cadence) | CDNS3 | XHCI | × |
|
||||
| DWC3(synopsys) | DWC3 | XHCI | × |
|
||||
@@ -176,20 +180,29 @@ CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term |
|
||||
|ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= 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)|v0.10.2 | 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 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | the same with ST |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with Essemi |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with Essemi |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | the same with ST |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|
||||
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
|
||||
|
||||
## 软件包支持
|
||||
|
||||
CherryUSB 软件包可以通过以下方式获取:
|
||||
|
||||
- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB)
|
||||
- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook)
|
||||
- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb)
|
||||
|
||||
## 商业支持
|
||||
|
||||
参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html。
|
||||
参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html 。
|
||||
|
||||
## 联系
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ path += [cwd + '/class/vendor/net']
|
||||
path += [cwd + '/class/vendor/serial']
|
||||
src = []
|
||||
|
||||
LIBS = []
|
||||
LIBPATH = []
|
||||
CPPDEFINES = []
|
||||
|
||||
# USB DEVICE
|
||||
@@ -56,6 +58,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
|
||||
src += Glob('port/musb/usb_glue_bk.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_CUSTOM']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX']):
|
||||
src += Glob('port/chipidea/usb_dc_chipidea.c')
|
||||
src += Glob('port/chipidea/usb_glue_mcx.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_BL']):
|
||||
src += Glob('port/bouffalolab/usb_dc_bl.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_HPM']):
|
||||
@@ -68,6 +73,15 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
|
||||
src += Glob('port/ch32/usb_dc_usbhs.c')
|
||||
else:
|
||||
src += Glob('port/ch32/usb_dc_usbfs.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_PUSB2']):
|
||||
path += [cwd + '/port/xhci/rt-thread']
|
||||
src += Glob('port/pusb2/rt-thread/usb_dc_glue_phytium.c')
|
||||
if GetDepend(['ARCH_ARMV8']):
|
||||
LIBPATH = [cwd + '/port/pusb2']
|
||||
LIBS = ['libpusb2_dc_a64.a']
|
||||
if GetDepend(['ARCH_ARM_CORTEX_A']):
|
||||
LIBPATH = [cwd + '/port/pusb2']
|
||||
LIBS = ['libpusb2_dc_a32_softfp_neon.a']
|
||||
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_ACM']):
|
||||
src += Glob('class/cdc/usbd_cdc.c')
|
||||
@@ -140,10 +154,14 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/ehci/usb_glue_aic.c')
|
||||
src += Glob('port/ohci/usb_hc_ohci.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUVOTON_NUC980']):
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_EHCI_MCX']):
|
||||
path += [cwd + '/port/chipidea']
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/ehci/usb_glue_mcx.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUC980']):
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/ehci/usb_glue_nuc980.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUVOTON_MA35D0']):
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_EHCI_MA35D0']):
|
||||
src += Glob('port/ehci/usb_hc_ehci.c')
|
||||
src += Glob('port/ehci/usb_glue_ma35d0.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_EHCI_CUSTOM']):
|
||||
@@ -169,6 +187,26 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
|
||||
src += Glob('port/musb/usb_glue_bk.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_CUSTOM']):
|
||||
src += Glob('port/musb/usb_hc_musb.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_PUSB2']):
|
||||
path += [cwd + '/port/pusb2/rt-thread']
|
||||
src += Glob('port/pusb2/rt-thread/usb_hc_glue_phytium.c')
|
||||
if GetDepend(['ARCH_ARMV8']):
|
||||
LIBPATH = [cwd + '/port/pusb2']
|
||||
LIBS = ['libpusb2_hc_a64.a']
|
||||
if GetDepend(['ARCH_ARM_CORTEX_A']):
|
||||
LIBPATH = [cwd + '/port/pusb2']
|
||||
LIBS = ['libpusb2_hc_a32_softfp_neon.a']
|
||||
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_XHCI']):
|
||||
path += [cwd + '/port/xhci/phytium/rt-thread']
|
||||
src += Glob('port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c')
|
||||
src += Glob('port/xhci/phytium/rt-thread/usb_glue_phytium.c')
|
||||
if GetDepend(['ARCH_ARMV8']):
|
||||
LIBPATH = [cwd + '/port/xhci/phytium']
|
||||
LIBS = ['libxhci_a64.a']
|
||||
if GetDepend(['ARCH_ARM_CORTEX_A']):
|
||||
LIBPATH = [cwd + '/port/xhci/phytium']
|
||||
LIBS = ['libxhci_a32_softfp_neon.a']
|
||||
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM']):
|
||||
src += Glob('class/cdc/usbh_cdc_acm.c')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 3
|
||||
PATCHLEVEL = 1
|
||||
VERSION_MINOR = 4
|
||||
PATCHLEVEL = 0
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
||||
@@ -36,14 +36,16 @@ ${CMAKE_CURRENT_LIST_DIR}/class/audio
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/video
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/wireless
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/midi
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/adb
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/vendor/net
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi
|
||||
)
|
||||
|
||||
if(CONFIG_CHERRYUSB_DEVICE)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/core/usbd_core.c)
|
||||
if(CONFIG_CHERRYUSB_DEVICE_CDC)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbd_cdc.c)
|
||||
if(CONFIG_CHERRYUSB_DEVICE_CDC_ACM)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbd_cdc_acm.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_HID)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/hid/usbd_hid.c)
|
||||
@@ -69,6 +71,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
|
||||
if(CONFIG_CHERRYUSB_DEVICE_DFU)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/dfu/usbd_dfu.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_ADB)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/adb/usbd_adb.c)
|
||||
endif()
|
||||
|
||||
if(DEFINED CONFIG_CHERRYUSB_DEVICE_DCD)
|
||||
if("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "fsdev")
|
||||
@@ -97,6 +102,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
|
||||
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "musb_bk")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
|
||||
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "chipidea_mcx")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_dc_chipidea.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_glue_mcx.c)
|
||||
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "hpm")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpm/usb_dc_hpm.c)
|
||||
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "bl")
|
||||
@@ -121,6 +129,9 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
if(CONFIG_CHERRYUSB_HOST_CDC_ECM)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ecm.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_CDC_RNDIS)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_rndis.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_CDC_NCM)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ncm.c)
|
||||
endif()
|
||||
@@ -142,18 +153,10 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_VIDEO)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/video/usbh_video.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/chry_pool.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/usbh_uvc_queue.c)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_AUDIO)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/audio/usbh_audio.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_CDC_RNDIS)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_rndis.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_BLUETOOTH)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_bluetooth.c)
|
||||
|
||||
@@ -209,6 +212,9 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
if(CONFIG_CHERRYUSB_HOST_PL2303)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_pl2303.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_BL616)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi/usbh_bl616.c)
|
||||
endif()
|
||||
|
||||
if(DEFINED CONFIG_CHERRYUSB_HOST_HCD)
|
||||
if("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_bouffalo")
|
||||
@@ -226,6 +232,12 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_aic.c)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci)
|
||||
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_mcx")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
|
||||
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_mcx.c)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea)
|
||||
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_nuvoton")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c)
|
||||
#list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c)
|
||||
@@ -260,5 +272,21 @@ if(DEFINED CONFIG_CHERRYUSB_OSAL)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_rtthread.c)
|
||||
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "yoc")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_yoc.c)
|
||||
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf")
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/osal/idf)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/idf/usb_osal_idf.c)
|
||||
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "threadx")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_threadx.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_CHERRYRB)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb)
|
||||
endif()
|
||||
|
||||
if(CONFIG_CHERRYMP)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/usbh_uvc_queue.c)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp)
|
||||
endif()
|
||||
@@ -6,16 +6,10 @@
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
#define CHERRYUSB_VERSION 0x010301
|
||||
#define CHERRYUSB_VERSION_STR "v1.3.1"
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__)
|
||||
|
||||
#define usb_malloc(size) malloc(size)
|
||||
#define usb_free(ptr) free(ptr)
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
@@ -72,6 +66,10 @@
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */
|
||||
// #define CONFIG_USBDEV_MSC_POLLING
|
||||
|
||||
/* move msc read & write from isr to thread */
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_adb.h"
|
||||
|
||||
#define ADB_OUT_EP_IDX 0
|
||||
#define ADB_IN_EP_IDX 1
|
||||
|
||||
#define ADB_STATE_READ_MSG 0
|
||||
#define ADB_STATE_READ_DATA 1
|
||||
#define ADB_STATE_WRITE_MSG 2
|
||||
#define ADB_STATE_WRITE_DATA 3
|
||||
#define ADB_STATE_AWRITE_MSG 4
|
||||
#define ADB_STATE_AWRITE_DATA 5
|
||||
|
||||
#define MAX_PAYLOAD_V1 (4 * 1024)
|
||||
#define MAX_PAYLOAD_V2 (256 * 1024)
|
||||
#define MAX_PAYLOAD MAX_PAYLOAD_V1
|
||||
#define A_VERSION 0x01000000
|
||||
|
||||
#define A_SYNC 0x434e5953
|
||||
#define A_CNXN 0x4e584e43
|
||||
#define A_OPEN 0x4e45504f
|
||||
#define A_OKAY 0x59414b4f
|
||||
#define A_CLSE 0x45534c43
|
||||
#define A_WRTE 0x45545257
|
||||
#define A_AUTH 0x48545541
|
||||
|
||||
struct adb_msg {
|
||||
uint32_t command; /* command identifier constant (A_CNXN, ...) */
|
||||
uint32_t arg0; /* first argument */
|
||||
uint32_t arg1; /* second argument */
|
||||
uint32_t data_length; /* length of payload (0 is allowed) */
|
||||
uint32_t data_crc32; /* crc32 of data payload */
|
||||
uint32_t magic; /* command ^ 0xffffffff */
|
||||
};
|
||||
|
||||
struct adb_packet {
|
||||
struct adb_msg msg;
|
||||
uint8_t payload[MAX_PAYLOAD];
|
||||
};
|
||||
|
||||
struct usbd_adb {
|
||||
uint8_t state;
|
||||
uint8_t common_state;
|
||||
uint8_t write_state;
|
||||
bool writable;
|
||||
uint32_t localid;
|
||||
uint32_t shell_remoteid;
|
||||
uint32_t file_remoteid;
|
||||
} adb_client;
|
||||
|
||||
static struct usbd_endpoint adb_ep_data[2];
|
||||
|
||||
USB_NOCACHE_RAM_SECTION struct adb_packet tx_packet;
|
||||
USB_NOCACHE_RAM_SECTION struct adb_packet rx_packet;
|
||||
|
||||
static inline uint32_t adb_packet_checksum(struct adb_packet *packet)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < packet->msg.data_length; ++i) {
|
||||
sum += (uint32_t)(packet->payload[i]);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static uint32_t usbd_adb_get_remoteid(uint32_t localid)
|
||||
{
|
||||
if (localid == ADB_SHELL_LOALID) {
|
||||
return adb_client.shell_remoteid;
|
||||
} else {
|
||||
return adb_client.file_remoteid;
|
||||
}
|
||||
}
|
||||
|
||||
static void adb_send_msg(struct adb_packet *packet)
|
||||
{
|
||||
adb_client.common_state = ADB_STATE_WRITE_MSG;
|
||||
|
||||
packet->msg.data_crc32 = adb_packet_checksum(packet);
|
||||
packet->msg.magic = packet->msg.command ^ 0xffffffff;
|
||||
|
||||
usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg));
|
||||
}
|
||||
|
||||
static void adb_send_okay(struct adb_packet *packet, uint32_t localid)
|
||||
{
|
||||
packet->msg.command = A_OKAY;
|
||||
packet->msg.arg0 = localid;
|
||||
packet->msg.arg1 = usbd_adb_get_remoteid(localid);
|
||||
packet->msg.data_length = 0;
|
||||
|
||||
adb_send_msg(&tx_packet);
|
||||
}
|
||||
|
||||
static void adb_send_close(struct adb_packet *packet, uint32_t localid, uint32_t remoteid)
|
||||
{
|
||||
packet->msg.command = A_CLSE;
|
||||
packet->msg.arg0 = localid;
|
||||
packet->msg.arg1 = remoteid;
|
||||
packet->msg.data_length = 0;
|
||||
|
||||
adb_send_msg(&tx_packet);
|
||||
}
|
||||
|
||||
void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
(void)ep;
|
||||
|
||||
if (adb_client.common_state == ADB_STATE_READ_MSG) {
|
||||
if (nbytes != sizeof(struct adb_msg)) {
|
||||
USB_LOG_ERR("invalid adb msg size:%d\r\n", nbytes);
|
||||
return;
|
||||
}
|
||||
|
||||
USB_LOG_DBG("command:%x arg0:%x arg1:%x len:%d\r\n",
|
||||
rx_packet.msg.command,
|
||||
rx_packet.msg.arg0,
|
||||
rx_packet.msg.arg1,
|
||||
rx_packet.msg.data_length);
|
||||
|
||||
if (rx_packet.msg.data_length) {
|
||||
/* setup next out ep read transfer */
|
||||
adb_client.common_state = ADB_STATE_READ_DATA;
|
||||
usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, rx_packet.payload, rx_packet.msg.data_length);
|
||||
} else {
|
||||
if (rx_packet.msg.command == A_CLSE) {
|
||||
adb_client.writable = false;
|
||||
usbd_adb_notify_write_done();
|
||||
USB_LOG_INFO("Close remoteid:%x\r\n", rx_packet.msg.arg0);
|
||||
}
|
||||
adb_client.common_state = ADB_STATE_READ_MSG;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
|
||||
}
|
||||
} else if (adb_client.common_state == ADB_STATE_READ_DATA) {
|
||||
switch (rx_packet.msg.command) {
|
||||
case A_SYNC:
|
||||
|
||||
break;
|
||||
case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
|
||||
char *support_feature = "device::"
|
||||
"ro.product.name=cherryadb;"
|
||||
"ro.product.model=cherrysh;"
|
||||
"ro.product.device=cherryadb;"
|
||||
"features=cmd,shell_v1";
|
||||
|
||||
tx_packet.msg.command = A_CNXN;
|
||||
tx_packet.msg.arg0 = A_VERSION;
|
||||
tx_packet.msg.arg1 = MAX_PAYLOAD;
|
||||
tx_packet.msg.data_length = strlen(support_feature);
|
||||
memcpy(tx_packet.payload, support_feature, strlen(support_feature));
|
||||
|
||||
adb_send_msg(&tx_packet);
|
||||
|
||||
adb_client.writable = false;
|
||||
break;
|
||||
case A_OPEN: /* OPEN(local-id, 0, "destination") */
|
||||
rx_packet.payload[rx_packet.msg.data_length] = '\0';
|
||||
|
||||
if (strncmp((const char *)rx_packet.payload, "shell:", 6) == 0) {
|
||||
adb_client.localid = ADB_SHELL_LOALID;
|
||||
adb_client.shell_remoteid = rx_packet.msg.arg0;
|
||||
adb_send_okay(&tx_packet, ADB_SHELL_LOALID);
|
||||
|
||||
USB_LOG_INFO("Open shell service, remoteid:%x\r\n", rx_packet.msg.arg0);
|
||||
} else if (strncmp((const char *)rx_packet.payload, "sync:", 5) == 0) {
|
||||
adb_client.localid = ADB_FILE_LOALID;
|
||||
adb_client.file_remoteid = rx_packet.msg.arg0;
|
||||
adb_send_okay(&tx_packet, ADB_FILE_LOALID);
|
||||
USB_LOG_INFO("Open file service, remoteid:%x\r\n", rx_packet.msg.arg0);
|
||||
}
|
||||
break;
|
||||
case A_OKAY:
|
||||
|
||||
break;
|
||||
case A_CLSE:
|
||||
|
||||
break;
|
||||
case A_WRTE: /* WRITE(local-id, remote-id, "data") */
|
||||
if ((rx_packet.msg.arg0 == adb_client.shell_remoteid) && (rx_packet.msg.arg1 == ADB_SHELL_LOALID)) {
|
||||
adb_send_okay(&tx_packet, rx_packet.msg.arg1);
|
||||
} else if ((rx_packet.msg.arg0 == adb_client.file_remoteid) && (rx_packet.msg.arg1 == ADB_FILE_LOALID)) {
|
||||
adb_send_okay(&tx_packet, rx_packet.msg.arg1);
|
||||
} else {
|
||||
adb_send_close(&tx_packet, 0, rx_packet.msg.arg0);
|
||||
}
|
||||
break;
|
||||
case A_AUTH:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_adb_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
(void)ep;
|
||||
(void)nbytes;
|
||||
|
||||
if (adb_client.common_state == ADB_STATE_WRITE_MSG) {
|
||||
if (tx_packet.msg.data_length) {
|
||||
adb_client.common_state = ADB_STATE_WRITE_DATA;
|
||||
usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length);
|
||||
} else {
|
||||
if (rx_packet.msg.command == A_WRTE) {
|
||||
adb_client.writable = true;
|
||||
if (adb_client.localid == ADB_SHELL_LOALID) {
|
||||
usbd_adb_notify_shell_read(rx_packet.payload, rx_packet.msg.data_length);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
adb_client.common_state = ADB_STATE_READ_MSG;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
|
||||
}
|
||||
} else if (adb_client.common_state == ADB_STATE_WRITE_DATA) {
|
||||
adb_client.common_state = ADB_STATE_READ_MSG;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
|
||||
} else if (adb_client.write_state == ADB_STATE_AWRITE_MSG) {
|
||||
if (tx_packet.msg.data_length) {
|
||||
adb_client.write_state = ADB_STATE_AWRITE_DATA;
|
||||
usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length);
|
||||
} else {
|
||||
}
|
||||
} else if (adb_client.write_state == ADB_STATE_AWRITE_DATA) {
|
||||
usbd_adb_notify_write_done();
|
||||
}
|
||||
}
|
||||
|
||||
void adb_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
switch (event) {
|
||||
case USBD_EVENT_INIT:
|
||||
break;
|
||||
case USBD_EVENT_DEINIT:
|
||||
break;
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
adb_client.common_state = ADB_STATE_READ_MSG;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface *usbd_adb_init_intf(uint8_t busid, struct usbd_interface *intf, uint8_t in_ep, uint8_t out_ep)
|
||||
{
|
||||
(void)busid;
|
||||
|
||||
intf->class_interface_handler = NULL;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = adb_notify_handler;
|
||||
|
||||
adb_ep_data[ADB_OUT_EP_IDX].ep_addr = out_ep;
|
||||
adb_ep_data[ADB_OUT_EP_IDX].ep_cb = usbd_adb_bulk_out;
|
||||
adb_ep_data[ADB_IN_EP_IDX].ep_addr = in_ep;
|
||||
adb_ep_data[ADB_IN_EP_IDX].ep_cb = usbd_adb_bulk_in;
|
||||
|
||||
usbd_add_endpoint(busid, &adb_ep_data[ADB_OUT_EP_IDX]);
|
||||
usbd_add_endpoint(busid, &adb_ep_data[ADB_IN_EP_IDX]);
|
||||
|
||||
return intf;
|
||||
}
|
||||
|
||||
bool usbd_adb_can_write(void)
|
||||
{
|
||||
return adb_client.writable;
|
||||
}
|
||||
|
||||
int usbd_abd_write(uint32_t localid, const uint8_t *data, uint32_t len)
|
||||
{
|
||||
struct adb_packet *packet;
|
||||
|
||||
packet = &tx_packet;
|
||||
packet->msg.command = A_WRTE;
|
||||
packet->msg.arg0 = localid;
|
||||
packet->msg.arg1 = usbd_adb_get_remoteid(localid);
|
||||
packet->msg.data_length = len;
|
||||
memcpy(packet->payload, data, len);
|
||||
|
||||
packet->msg.data_crc32 = adb_packet_checksum(packet);
|
||||
packet->msg.magic = packet->msg.command ^ 0xffffffff;
|
||||
|
||||
adb_client.write_state = ADB_STATE_AWRITE_MSG;
|
||||
usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usbd_adb_close(uint32_t localid)
|
||||
{
|
||||
adb_send_close(&tx_packet, 0, usbd_adb_get_remoteid(localid));
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBD_ADB_H
|
||||
#define USBD_ADB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ADB_SHELL_LOALID 0x01
|
||||
#define ADB_FILE_LOALID 0x02
|
||||
|
||||
// clang-format off
|
||||
#define ADB_DESCRIPTOR_INIT(bFirstInterface, in_ep, out_ep, wMaxPacketSize) \
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(bFirstInterface, 0x00, 0x02, 0xff, 0x42, 0x01, 0x02), \
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x02, wMaxPacketSize, 0x00), \
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x02, wMaxPacketSize, 0x00)
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct usbd_interface *usbd_adb_init_intf(uint8_t busid, struct usbd_interface *intf, uint8_t in_ep, uint8_t out_ep);
|
||||
|
||||
void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len);
|
||||
void usbd_adb_notify_file_read(uint8_t *data, uint32_t len);
|
||||
void usbd_adb_notify_write_done(void);
|
||||
bool usbd_adb_can_write(void);
|
||||
int usbd_abd_write(uint32_t localid, const uint8_t *data, uint32_t len);
|
||||
void usbd_adb_close(uint32_t localid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBD_ADB_H */
|
||||
@@ -62,7 +62,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
|
||||
setup->bRequest);
|
||||
|
||||
uint8_t entity_id;
|
||||
uint8_t ep;
|
||||
uint8_t ep = 0;
|
||||
uint8_t subtype = 0x01;
|
||||
uint8_t control_selector;
|
||||
uint8_t ch;
|
||||
@@ -314,31 +314,56 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid,
|
||||
|
||||
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)ch;
|
||||
(void)volume;
|
||||
}
|
||||
|
||||
__WEAK int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)ch;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)ch;
|
||||
(void)mute;
|
||||
}
|
||||
|
||||
__WEAK bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)ch;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)sampling_freq;
|
||||
}
|
||||
|
||||
__WEAK uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sampling_freq_table)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)sampling_freq_table;
|
||||
}
|
||||
|
||||
@@ -456,20 +456,26 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
static int usbh_audio_data_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
(void)hport;
|
||||
(void)intf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_audio_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
(void)hport;
|
||||
(void)intf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbh_audio_run(struct usbh_audio *audio_class)
|
||||
{
|
||||
(void)audio_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_audio_stop(struct usbh_audio *audio_class)
|
||||
{
|
||||
(void)audio_class;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver audio_ctrl_class_driver = {
|
||||
|
||||
@@ -1,29 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBD_CDC_H
|
||||
#define USBD_CDC_H
|
||||
|
||||
#include "usb_cdc.h"
|
||||
// legacy for old version
|
||||
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Init cdc acm interface driver */
|
||||
struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf);
|
||||
|
||||
/* Setup request command callback api */
|
||||
void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
|
||||
void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
|
||||
void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr);
|
||||
void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts);
|
||||
void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBD_CDC_H */
|
||||
|
||||
+17
-1
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
const char *stop_name[] = { "1", "1.5", "2" };
|
||||
const char *parity_name[] = { "N", "O", "E", "M", "S" };
|
||||
@@ -85,6 +85,8 @@ static int cdc_acm_class_interface_request_handler(uint8_t busid, struct usb_set
|
||||
|
||||
struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf)
|
||||
{
|
||||
(void)busid;
|
||||
|
||||
intf->class_interface_handler = cdc_acm_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
@@ -95,10 +97,16 @@ struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interfa
|
||||
|
||||
__WEAK void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)line_coding;
|
||||
}
|
||||
|
||||
__WEAK void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
|
||||
line_coding->dwDTERate = 2000000;
|
||||
line_coding->bDataBits = 8;
|
||||
line_coding->bParityType = 0;
|
||||
@@ -107,12 +115,20 @@ __WEAK void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc
|
||||
|
||||
__WEAK void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)dtr;
|
||||
}
|
||||
|
||||
__WEAK void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)rts;
|
||||
}
|
||||
|
||||
__WEAK void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBD_CDC_ACM_H
|
||||
#define USBD_CDC_ACM_H
|
||||
|
||||
#include "usb_cdc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Init cdc acm interface driver */
|
||||
struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf);
|
||||
|
||||
/* Setup request command callback api */
|
||||
void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
|
||||
void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding);
|
||||
void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr);
|
||||
void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts);
|
||||
void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBD_CDC_ACM_H */
|
||||
@@ -79,6 +79,10 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
|
||||
"bRequest 0x%02x\r\n",
|
||||
setup->bRequest);
|
||||
|
||||
(void)busid;
|
||||
(void)data;
|
||||
(void)len;
|
||||
|
||||
g_cmd_intf = LO_BYTE(setup->wIndex);
|
||||
|
||||
switch (setup->bRequest) {
|
||||
@@ -105,6 +109,9 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
|
||||
|
||||
void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
||||
{
|
||||
(void)busid;
|
||||
(void)arg;
|
||||
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
g_current_net_status = 0;
|
||||
@@ -123,19 +130,23 @@ void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
||||
|
||||
void cdc_ecm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
(void)busid;
|
||||
|
||||
g_cdc_ecm_rx_data_length += nbytes;
|
||||
|
||||
if (nbytes < usbd_get_ep_mps(busid, ep)) {
|
||||
if (nbytes < usbd_get_ep_mps(0, ep)) {
|
||||
g_cdc_ecm_rx_data_buffer = g_cdc_ecm_rx_buffer;
|
||||
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
|
||||
} else {
|
||||
usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, ep));
|
||||
usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(0, ep));
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
(void)busid;
|
||||
|
||||
if ((nbytes % usbd_get_ep_mps(0, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(0, ep, NULL, 0);
|
||||
} else {
|
||||
@@ -145,6 +156,10 @@ void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
|
||||
void cdc_ecm_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)nbytes;
|
||||
|
||||
if (g_current_net_status == 1) {
|
||||
g_current_net_status = 2;
|
||||
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, g_connect_speed_table);
|
||||
@@ -242,4 +257,6 @@ void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2])
|
||||
|
||||
__WEAK void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
(void)buf;
|
||||
(void)len;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/ttyACM%d"
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[64];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbh_cdc_acm g_cdc_acm_class[CONFIG_USBHOST_MAX_CDC_ACM_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
@@ -57,9 +57,9 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
|
||||
setup->wIndex = cdc_acm_class->intf;
|
||||
setup->wLength = 7;
|
||||
|
||||
memcpy(g_cdc_acm_buf, line_coding, sizeof(struct cdc_line_coding));
|
||||
memcpy(g_cdc_acm_buf[cdc_acm_class->minor], line_coding, sizeof(struct cdc_line_coding));
|
||||
|
||||
return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf);
|
||||
return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]);
|
||||
}
|
||||
|
||||
int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
|
||||
@@ -78,11 +78,11 @@ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
|
||||
setup->wIndex = cdc_acm_class->intf;
|
||||
setup->wLength = 7;
|
||||
|
||||
ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf);
|
||||
ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(line_coding, g_cdc_acm_buf, sizeof(struct cdc_line_coding));
|
||||
memcpy(line_coding, g_cdc_acm_buf[cdc_acm_class->minor], sizeof(struct cdc_line_coding));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -231,20 +231,26 @@ int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *
|
||||
|
||||
static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
(void)hport;
|
||||
(void)intf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
(void)hport;
|
||||
(void)intf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
(void)cdc_acm_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
(void)cdc_acm_class;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver cdc_acm_class_driver = {
|
||||
|
||||
@@ -236,6 +236,7 @@ void usbh_cdc_ecm_rx_thread(void *argument)
|
||||
uint32_t g_cdc_ecm_rx_length;
|
||||
int ret;
|
||||
|
||||
(void)argument;
|
||||
USB_LOG_INFO("Create cdc ecm rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
@@ -306,10 +307,12 @@ int usbh_cdc_ecm_eth_output(uint32_t buflen)
|
||||
|
||||
__WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
|
||||
{
|
||||
(void)cdc_ecm_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
|
||||
{
|
||||
(void)cdc_ecm_class;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver cdc_ecm_class_driver = {
|
||||
|
||||
@@ -259,6 +259,7 @@ void usbh_cdc_ncm_rx_thread(void *argument)
|
||||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
@@ -330,7 +331,7 @@ find_class:
|
||||
#else
|
||||
if ((g_cdc_ncm_rx_length + (16 * 1024)) > CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) {
|
||||
#endif
|
||||
USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE\r\n");
|
||||
USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -386,10 +387,12 @@ int usbh_cdc_ncm_eth_output(uint32_t buflen)
|
||||
|
||||
__WEAK void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
|
||||
{
|
||||
(void)cdc_ncm_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
|
||||
{
|
||||
(void)cdc_ncm_class;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver cdc_ncm_class_driver = {
|
||||
|
||||
@@ -558,26 +558,24 @@ struct usb_hid_kbd_report
|
||||
};
|
||||
|
||||
/* Keyboard output report (1 byte) (HID B.1),
|
||||
* see USBHID_KBDOUT_* definitions
|
||||
* see HID_KBD_OUTPUT_* definitions
|
||||
*/
|
||||
|
||||
/* Mouse input report (HID B.2) */
|
||||
struct usb_hid_mouse_report
|
||||
{
|
||||
uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
|
||||
uint8_t xdisp; /* X displacement */
|
||||
uint8_t ydisp; /* y displacement */
|
||||
int8_t xdisp; /* X displacement */
|
||||
int8_t ydisp; /* y displacement */
|
||||
/* Device specific additional bytes may follow */
|
||||
#ifdef CONFIG_INPUT_MOUSE_WHEEL
|
||||
uint8_t wdisp; /* Wheel displacement */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Joystick input report (1 bytes) (HID D.1) */
|
||||
struct usb_hid_js_report
|
||||
{
|
||||
uint8_t xpos; /* X position */
|
||||
uint8_t ypos; /* X position */
|
||||
int8_t xpos; /* X position */
|
||||
int8_t ypos; /* X position */
|
||||
uint8_t buttons; /* See USBHID_JSIN_* definitions */
|
||||
uint8_t throttle; /* Throttle */
|
||||
};
|
||||
|
||||
@@ -50,6 +50,8 @@ static int hid_class_interface_request_handler(uint8_t busid, struct usb_setup_p
|
||||
|
||||
struct usbd_interface *usbd_hid_init_intf(uint8_t busid, struct usbd_interface *intf, const uint8_t *desc, uint32_t desc_len)
|
||||
{
|
||||
(void)busid;
|
||||
|
||||
intf->class_interface_handler = hid_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
@@ -60,30 +62,65 @@ struct usbd_interface *usbd_hid_init_intf(uint8_t busid, struct usbd_interface *
|
||||
return intf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Appendix G: HID Request Support Requirements
|
||||
*
|
||||
* The following table enumerates the requests that need to be supported by various types of HID class devices.
|
||||
* Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
|
||||
* ------------------------------------------------------------------------------------------
|
||||
* Boot Mouse Required Optional Optional Optional Required Required
|
||||
* Non-Boot Mouse Required Optional Optional Optional Optional Optional
|
||||
* Boot Keyboard Required Optional Required Required Required Required
|
||||
* Non-Boot Keybrd Required Optional Required Required Optional Optional
|
||||
* Other Device Required Optional Optional Optional Optional Optional
|
||||
*/
|
||||
|
||||
__WEAK void usbd_hid_get_report(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)report_id;
|
||||
(void)report_type;
|
||||
(*data[0]) = 0;
|
||||
*len = 1;
|
||||
}
|
||||
|
||||
__WEAK uint8_t usbd_hid_get_idle(uint8_t busid, uint8_t intf, uint8_t report_id)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)report_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK uint8_t usbd_hid_get_protocol(uint8_t busid, uint8_t intf)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_hid_set_report(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t *report, uint32_t report_len)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)report_id;
|
||||
(void)report_type;
|
||||
(void)report;
|
||||
(void)report_len;
|
||||
}
|
||||
|
||||
__WEAK void usbd_hid_set_idle(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t duration)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)report_id;
|
||||
(void)duration;
|
||||
}
|
||||
|
||||
__WEAK void usbd_hid_set_protocol(uint8_t busid, uint8_t intf, uint8_t protocol)
|
||||
{
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
(void)protocol;
|
||||
}
|
||||
@@ -12,7 +12,15 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/input%d"
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[128];
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
#define DESC_bDescriptorType 1 /** Descriptor type offset */
|
||||
|
||||
/* interface descriptor field offsets */
|
||||
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
|
||||
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(256, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
@@ -56,13 +64,13 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
setup->wValue = HID_DESCRIPTOR_TYPE_HID_REPORT << 8;
|
||||
setup->wIndex = hid_class->intf;
|
||||
setup->wLength = 128;
|
||||
setup->wLength = hid_class->report_size;
|
||||
|
||||
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf);
|
||||
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(buffer, g_hid_buf, ret - 8);
|
||||
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -100,11 +108,11 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
|
||||
setup->wIndex = hid_class->intf;
|
||||
setup->wLength = 1;
|
||||
|
||||
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf);
|
||||
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(buffer, g_hid_buf, 1);
|
||||
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -147,6 +155,7 @@ int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
|
||||
int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen)
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
int ret;
|
||||
|
||||
if (!hid_class || !hid_class->hport) {
|
||||
return -USB_ERR_INVAL;
|
||||
@@ -159,13 +168,21 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = buflen;
|
||||
|
||||
return usbh_control_transfer(hid_class->hport, setup, buffer);
|
||||
ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
uint8_t cur_iface = 0xff;
|
||||
uint8_t *p;
|
||||
bool found = false;
|
||||
|
||||
struct usbh_hid *hid_class = usbh_hid_class_alloc();
|
||||
if (hid_class == NULL) {
|
||||
@@ -178,6 +195,47 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
hport->config.intf[intf].priv = hid_class;
|
||||
|
||||
p = hport->raw_config_desc;
|
||||
while (p[DESC_bLength]) {
|
||||
switch (p[DESC_bDescriptorType]) {
|
||||
case USB_DESCRIPTOR_TYPE_INTERFACE:
|
||||
cur_iface = p[INTF_DESC_bInterfaceNumber];
|
||||
if (cur_iface == intf) {
|
||||
hid_class->protocol = p[7];
|
||||
struct usb_hid_descriptor *desc = (struct usb_hid_descriptor *)(p + 9);
|
||||
|
||||
if (desc->bDescriptorType != HID_DESCRIPTOR_TYPE_HID) {
|
||||
USB_LOG_ERR("HID descriptor not found\r\n");
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
if (desc->subdesc[0].bDescriptorType != HID_DESCRIPTOR_TYPE_HID_REPORT) {
|
||||
USB_LOG_ERR("HID report descriptor not found\r\n");
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
hid_class->report_size = desc->subdesc[0].wDescriptorLength;
|
||||
|
||||
if (hid_class->report_size > sizeof(g_hid_buf[hid_class->minor])) {
|
||||
USB_LOG_ERR("HID report descriptor too large\r\n");
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
found = true;
|
||||
goto found;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* skip to next descriptor */
|
||||
p += p[DESC_bLength];
|
||||
}
|
||||
|
||||
if (found == false) {
|
||||
USB_LOG_ERR("HID interface not found\r\n");
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
found:
|
||||
// /* 0x0 = boot protocol, 0x1 = report protocol */
|
||||
// ret = usbh_hid_set_protocol(hid_class, 0x1);
|
||||
// if (ret < 0) {
|
||||
@@ -239,10 +297,12 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
__WEAK void usbh_hid_run(struct usbh_hid *hid_class)
|
||||
{
|
||||
(void)hid_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_hid_stop(struct usbh_hid *hid_class)
|
||||
{
|
||||
(void)hid_class;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver hid_class_driver = {
|
||||
|
||||
@@ -16,6 +16,9 @@ struct usbh_hid {
|
||||
struct usbh_urb intout_urb; /* INTR OUT urb */
|
||||
|
||||
uint8_t report_desc[256];
|
||||
uint16_t report_size;
|
||||
|
||||
uint8_t protocol;
|
||||
uint8_t intf; /* interface number */
|
||||
uint8_t minor;
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
#define HUB_DESCRIPTOR_TYPE_HUB 0x29
|
||||
#define HUB_DESCRIPTOR_TYPE_HUB3 0x2A
|
||||
|
||||
#define HUB_MAX_DEPTH 5
|
||||
|
||||
#define HUB_SUBCLASS 0x00
|
||||
#define HUB_PROTOCOL_STT 0x01
|
||||
#define HUB_PROTOCOL_MTT 0x02
|
||||
|
||||
/* Hub class requests */
|
||||
#define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS
|
||||
#define HUB_REQUEST_CLEAR_FEATURE USB_REQUEST_CLEAR_FEATURE
|
||||
@@ -32,18 +38,26 @@
|
||||
#define HUB_PORT_FEATURE_SUSPEND (0x02)
|
||||
#define HUB_PORT_FEATURE_OVERCURRENT (0x03)
|
||||
#define HUB_PORT_FEATURE_RESET (0x04)
|
||||
#define HUB_PORT_FEATURE_L1 (0x05)
|
||||
#define HUB_PORT_FEATURE_POWER (0x08)
|
||||
#define HUB_PORT_FEATURE_LOWSPEED (0x09)
|
||||
#define HUB_PORT_FEATURE_HIGHSPEED (0x0a)
|
||||
#define HUB_PORT_FEATURE_L1 (0x05) /* USB 2.0 only */
|
||||
|
||||
#define HUB_PORT_FEATURE_POWER (0x08) /* USB 2.0 only */
|
||||
#define HUB_PORT_FEATURE_POWER_SS (0x09) /* USB 3.0 only */
|
||||
/* This is a bit tricky because HUB_PORT_FEATURE_POWER_SS and
|
||||
HUB_PORT_FEATURE_LOWSPEED share the same bit. */
|
||||
#define HUB_PORT_FEATURE_LOWSPEED (0x09) /* USB 2.0 only */
|
||||
#define HUB_PORT_FEATURE_HIGHSPEED (0x0a) /* USB 2.0 only */
|
||||
#define HUB_PORT_FEATURE_TEST (0x0b) /* USB 2.0 only */
|
||||
#define HUB_PORT_FEATURE_INDICATOR (0x0c) /* USB 2.0 only */
|
||||
|
||||
/* Port status change (wPortChange) */
|
||||
#define HUB_PORT_FEATURE_C_CONNECTION (0x10)
|
||||
#define HUB_PORT_FEATURE_C_ENABLE (0x11)
|
||||
#define HUB_PORT_FEATURE_C_SUSPEND (0x12)
|
||||
#define HUB_PORT_FEATURE_C_ENABLE (0x11) /* USB 2.0 only */
|
||||
#define HUB_PORT_FEATURE_C_SUSPEND (0x12) /* USB 2.0 only */
|
||||
#define HUB_PORT_FEATURE_C_OVER_CURREN (0x13)
|
||||
#define HUB_PORT_FEATURE_C_RESET (0x14)
|
||||
#define HUB_PORT_FEATURE_TEST (0x15)
|
||||
#define HUB_PORT_FEATURE_INDICATOR (0x16)
|
||||
#define HUB_PORT_FEATURE_C_PORTL1 (0x17)
|
||||
#define HUB_PORT_FEATURE_C_BH_RESET (0x15) /* USB 3.0 only */
|
||||
#define HUB_PORT_FEATURE_C_LINK_STATE (0x16) /* USB 3.0 only */
|
||||
#define HUB_PORT_FEATURE_C_CONFIG_ERR (0x17) /* USB 3.0 only */
|
||||
|
||||
/* Hub status */
|
||||
#define HUB_STATUS_LOCALPOWER (1 << 0)
|
||||
@@ -56,23 +70,42 @@
|
||||
/* Hub port status */
|
||||
#define HUB_PORT_STATUS_CONNECTION (1 << 0)
|
||||
#define HUB_PORT_STATUS_ENABLE (1 << 1)
|
||||
#define HUB_PORT_STATUS_SUSPEND (1 << 2)
|
||||
#define HUB_PORT_STATUS_SUSPEND (1 << 2) /* USB 2.0 only */
|
||||
#define HUB_PORT_STATUS_OVERCURRENT (1 << 3)
|
||||
#define HUB_PORT_STATUS_RESET (1 << 4)
|
||||
#define HUB_PORT_STATUS_L1 (1 << 5)
|
||||
#define HUB_PORT_STATUS_L1 (1 << 5) /* USB 2.0 only */
|
||||
|
||||
/* Port Link State (PORT_LINK_STATE), USB 3.0 only */
|
||||
#define HUB_PORT_STATUS_LS_U0 (0x00 << 5)
|
||||
#define HUB_PORT_STATUS_LS_U1 (0x01 << 5)
|
||||
#define HUB_PORT_STATUS_LS_U2 (0x02 << 5)
|
||||
#define HUB_PORT_STATUS_LS_U3 (0x03 << 5)
|
||||
#define HUB_PORT_STATUS_LS_SS_DISABLED (0x04 << 5)
|
||||
#define HUB_PORT_STATUS_LS_RX_DETECT (0x05 << 5)
|
||||
#define HUB_PORT_STATUS_LS_SS_INACTIVE (0x06 << 5)
|
||||
#define HUB_PORT_STATUS_LS_POLLING (0x07 << 5)
|
||||
#define HUB_PORT_STATUS_LS_RECOVERY (0x08 << 5)
|
||||
#define HUB_PORT_STATUS_LS_HOT_RESET (0x09 << 5)
|
||||
#define HUB_PORT_STATUS_LS_COMP_MOD (0x0a << 5)
|
||||
#define HUB_PORT_STATUS_LS_LOOPBACK (0x0b << 5)
|
||||
|
||||
#define HUB_PORT_STATUS_POWER (1 << 8)
|
||||
#define HUB_PORT_STATUS_LOW_SPEED (1 << 9)
|
||||
#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10)
|
||||
#define HUB_PORT_STATUS_TEST (1 << 11)
|
||||
#define HUB_PORT_STATUS_INDICATOR (1 << 12)
|
||||
#define HUB_PORT_STATUS_POWER_SS (1 << 9) /* USB 3.0 only */
|
||||
#define HUB_PORT_STATUS_LOW_SPEED (1 << 9) /* USB 2.0 only */
|
||||
#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) /* USB 2.0 only */
|
||||
#define HUB_PORT_STATUS_TEST (1 << 11) /* USB 2.0 only */
|
||||
#define HUB_PORT_STATUS_INDICATOR (1 << 12) /* USB 2.0 only */
|
||||
|
||||
/* Hub port status change */
|
||||
#define HUB_PORT_STATUS_C_CONNECTION (1 << 0)
|
||||
#define HUB_PORT_STATUS_C_ENABLE (1 << 1)
|
||||
#define HUB_PORT_STATUS_C_SUSPEND (1 << 2)
|
||||
#define HUB_PORT_STATUS_C_ENABLE (1 << 1) /* USB 2.0 only */
|
||||
#define HUB_PORT_STATUS_C_SUSPEND (1 << 2) /* USB 2.0 only */
|
||||
#define HUB_PORT_STATUS_C_OVERCURRENT (1 << 3)
|
||||
#define HUB_PORT_STATUS_C_RESET (1 << 4)
|
||||
#define HUB_PORT_STATUS_C_L1 (1 << 5)
|
||||
#define HUB_PORT_STATUS_C_L1 (1 << 5) /* USB 2.0 only */
|
||||
#define HUB_PORT_STATUS_C_BH_RESET (1 << 5) /* USB 3.0 only */
|
||||
#define HUB_PORT_STATUS_C_PORTLINK (1 << 6) /* USB 3.0 only */
|
||||
#define HUB_PORT_STATUS_C_CONFIGERR (1 << 7) /* USB 3.0 only */
|
||||
|
||||
/* Hub characteristics */
|
||||
#define HUB_CHAR_LPSM_SHIFT (0) /* Bits 0-1: Logical Power Switching Mode */
|
||||
@@ -106,6 +139,21 @@ struct usb_hub_descriptor {
|
||||
|
||||
#define USB_SIZEOF_HUB_DESC 9
|
||||
|
||||
/* Super speed Hub descriptor */
|
||||
struct usb_hub_ss_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bNbrPorts;
|
||||
uint16_t wHubCharacteristics;
|
||||
uint8_t bPwrOn2PwrGood;
|
||||
uint8_t bHubContrCurrent;
|
||||
uint8_t bHubHdrDecLat;
|
||||
uint16_t wHubDelay;
|
||||
uint8_t DeviceRemovable;
|
||||
} __PACKED;
|
||||
|
||||
#define USB_SIZEOF_HUB_SS_DESC 11
|
||||
|
||||
/* Hub status */
|
||||
struct hub_status {
|
||||
uint16_t wPortStatus;
|
||||
|
||||
@@ -55,9 +55,7 @@ static void usbh_hub_class_free(struct usbh_hub *hub_class)
|
||||
}
|
||||
memset(hub_class, 0, sizeof(struct usbh_hub));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
@@ -67,15 +65,7 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
|
||||
/* TODO: hub descriptor has some difference between USB 2.0 and USB 3.x,
|
||||
and we havn't handle the difference here */
|
||||
if ((hub->parent->speed == USB_SPEED_SUPER) ||
|
||||
(hub->parent->speed == USB_SPEED_SUPER_PLUS)) {
|
||||
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8;
|
||||
} else {
|
||||
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8;
|
||||
}
|
||||
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = USB_SIZEOF_HUB_DESC;
|
||||
@@ -87,8 +77,8 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
|
||||
memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_DESC);
|
||||
return ret;
|
||||
}
|
||||
#if 0
|
||||
static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
|
||||
|
||||
static int _usbh_hub_get_hub_ss_descriptor(struct usbh_hub *hub, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
int ret;
|
||||
@@ -96,20 +86,20 @@ static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
|
||||
setup = hub->parent->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = HUB_REQUEST_GET_STATUS;
|
||||
setup->wValue = 0;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8;
|
||||
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = 2;
|
||||
setup->wLength = USB_SIZEOF_HUB_SS_DESC;
|
||||
|
||||
ret = usbh_control_transfer(hub->parent, setup, g_hub_buf[hub->bus->busid]);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(buffer, g_hub_buf[hub->bus->busid], 2);
|
||||
memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_SS_DESC);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
|
||||
{
|
||||
@@ -180,6 +170,8 @@ static int _usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length)
|
||||
{
|
||||
(void)length;
|
||||
|
||||
if (desc->bLength != USB_SIZEOF_HUB_DESC) {
|
||||
USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength);
|
||||
return -1;
|
||||
@@ -199,6 +191,29 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_hub_ss_descriptor(struct usb_hub_ss_descriptor *desc, uint16_t length)
|
||||
{
|
||||
(void)length;
|
||||
|
||||
if (desc->bLength < USB_SIZEOF_HUB_SS_DESC) {
|
||||
USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength);
|
||||
return -1;
|
||||
} else if (desc->bDescriptorType != HUB_DESCRIPTOR_TYPE_HUB3) {
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
|
||||
@@ -311,22 +326,65 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
hub->hub_addr = hport->dev_addr;
|
||||
hub->parent = hport;
|
||||
hub->bus = hport->bus;
|
||||
hub->speed = hport->speed;
|
||||
|
||||
hport->self = hub;
|
||||
hport->config.intf[intf].priv = hub;
|
||||
|
||||
if (hport->depth > HUB_MAX_DEPTH) {
|
||||
USB_LOG_ERR("Hub depth(%d) is overflow\r\n", hport->depth);
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Super-Speed hubs need to know their depth to be able to
|
||||
* parse the bits of the route-string that correspond to
|
||||
* their downstream port number.
|
||||
*
|
||||
*/
|
||||
if ((hport->depth != 0) && (hport->speed == USB_SPEED_SUPER)) {
|
||||
ret = usbh_hub_set_depth(hub, hport->depth - 1);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Unable to set hub depth \r\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get hub descriptor. */
|
||||
if (hport->speed == USB_SPEED_SUPER) {
|
||||
ret = _usbh_hub_get_hub_ss_descriptor(hub, (uint8_t *)&hub->hub_ss_desc);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
parse_hub_ss_descriptor(&hub->hub_ss_desc, USB_SIZEOF_HUB_SS_DESC);
|
||||
hub->nports = hub->hub_ss_desc.bNbrPorts;
|
||||
hub->powerdelay = hub->hub_ss_desc.bPwrOn2PwrGood * 2;
|
||||
hub->tt_think = 0U;
|
||||
} else {
|
||||
ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC);
|
||||
hub->nports = hub->hub_desc.bNbrPorts;
|
||||
hub->powerdelay = hub->hub_desc.bPwrOn2PwrGood * 2;
|
||||
hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5);
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hub->child[port].port = port + 1;
|
||||
hub->child[port].parent = hub;
|
||||
hub->child[port].bus = hport->bus;
|
||||
}
|
||||
|
||||
if (hport->device_desc.bDeviceProtocol == HUB_PROTOCOL_MTT) {
|
||||
hub->ismtt = 1;
|
||||
} else {
|
||||
hub->ismtt = 0;
|
||||
}
|
||||
|
||||
ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
USBH_EP_INIT(hub->intin, ep_desc);
|
||||
@@ -334,28 +392,16 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hport->speed == USB_SPEED_SUPER) {
|
||||
uint16_t depth = 0;
|
||||
struct usbh_hubport *parent = hport->parent->parent;
|
||||
while (parent) {
|
||||
depth++;
|
||||
parent = parent->parent->parent;
|
||||
}
|
||||
|
||||
ret = usbh_hub_set_depth(hub, depth);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_POWER);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
usb_osal_msleep(hub->powerdelay);
|
||||
|
||||
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);
|
||||
if (ret < 0) {
|
||||
@@ -395,7 +441,7 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usb_osal_timer_delete(hub->int_timer);
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
child = &hub->child[port];
|
||||
usbh_hubport_release(child);
|
||||
child->parent = NULL;
|
||||
@@ -415,7 +461,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
{
|
||||
struct usbh_hubport *child;
|
||||
struct hub_port_status port_status;
|
||||
uint8_t portchange_index;
|
||||
uint16_t portchange_index;
|
||||
uint16_t portstatus;
|
||||
uint16_t portchange;
|
||||
uint16_t mask;
|
||||
@@ -429,11 +475,10 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
portchange_index = hub->int_buffer[0];
|
||||
hub->int_buffer[0] &= ~portchange_index;
|
||||
memcpy(&portchange_index, hub->int_buffer, 2);
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index);
|
||||
|
||||
if (!(portchange_index & (1 << (port + 1)))) {
|
||||
@@ -539,6 +584,11 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out device speed. This is a bit tricky because
|
||||
* HUB_PORT_STATUS_POWER_SS and HUB_PORT_STATUS_LOW_SPEED share the same bit.
|
||||
*/
|
||||
if (portstatus & HUB_PORT_STATUS_POWER) {
|
||||
if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) {
|
||||
speed = USB_SPEED_HIGH;
|
||||
} else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
|
||||
@@ -546,6 +596,12 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
} else {
|
||||
speed = USB_SPEED_FULL;
|
||||
}
|
||||
} else if (portstatus & HUB_PORT_STATUS_POWER_SS) {
|
||||
speed = USB_SPEED_SUPER;
|
||||
} else {
|
||||
USB_LOG_WRN("Port %u does not enable power\r\n", port + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
child = &hub->child[port];
|
||||
/** release child sources first */
|
||||
@@ -553,6 +609,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
|
||||
memset(child, 0, sizeof(struct usbh_hubport));
|
||||
child->parent = hub;
|
||||
child->depth = (hub->parent ? hub->parent->depth : 0) + 1;
|
||||
child->connected = true;
|
||||
child->port = port + 1;
|
||||
child->speed = speed;
|
||||
@@ -624,7 +681,7 @@ int usbh_hub_initialize(struct usbh_bus *bus)
|
||||
hub->is_roothub = true;
|
||||
hub->parent = NULL;
|
||||
hub->hub_addr = 1;
|
||||
hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
|
||||
hub->nports = CONFIG_USBHOST_MAX_RHPORTS;
|
||||
hub->int_buffer = bus->hcd.roothub_intbuf;
|
||||
hub->bus = bus;
|
||||
|
||||
@@ -652,7 +709,7 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
hub = &bus->hcd.roothub;
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hport = &hub->child[port];
|
||||
|
||||
usbh_hubport_release(hport);
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
|
||||
struct usbh_hub;
|
||||
|
||||
#define USBH_HUB_MAX_PORTS 4
|
||||
/* Maximum size of an interrupt IN transfer */
|
||||
#define USBH_HUB_INTIN_BUFSIZE ((USBH_HUB_MAX_PORTS + 8) >> 3)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "usb_scsi.h"
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
#include "usb_osal.h"
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
#include "chry_ringbuffer.h"
|
||||
#endif
|
||||
|
||||
#define MSD_OUT_EP_IDX 0
|
||||
@@ -50,6 +52,10 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_priv {
|
||||
usb_osal_mq_t usbd_msc_mq;
|
||||
usb_osal_thread_t usbd_msc_thread;
|
||||
uint32_t nbytes;
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
chry_ringbuffer_t msc_rb;
|
||||
uint8_t msc_rb_pool[2];
|
||||
uint32_t nbytes;
|
||||
#endif
|
||||
} g_usbd_msc[CONFIG_USBDEV_MAX_BUS];
|
||||
|
||||
@@ -94,9 +100,11 @@ static int msc_storage_class_interface_request_handler(uint8_t busid, struct usb
|
||||
|
||||
void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
switch (event) {
|
||||
case USBD_EVENT_INIT:
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
g_usbd_msc[busid].usbd_msc_mq = usb_osal_mq_create(1);
|
||||
if (g_usbd_msc[busid].usbd_msc_mq == NULL) {
|
||||
USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_mq\r\n");
|
||||
@@ -105,10 +113,12 @@ void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
||||
if (g_usbd_msc[busid].usbd_msc_thread == NULL) {
|
||||
USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_thread\r\n");
|
||||
}
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
chry_ringbuffer_init(&g_usbd_msc[busid].msc_rb, g_usbd_msc[busid].msc_rb_pool, sizeof(g_usbd_msc[busid].msc_rb_pool));
|
||||
#endif
|
||||
break;
|
||||
case USBD_EVENT_DEINIT:
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
if (g_usbd_msc[busid].usbd_msc_mq) {
|
||||
usb_osal_mq_delete(g_usbd_msc[busid].usbd_msc_mq);
|
||||
}
|
||||
@@ -500,6 +510,9 @@ static bool SCSI_readCapacity10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
|
||||
static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
(void)data;
|
||||
(void)len;
|
||||
|
||||
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
@@ -522,8 +535,10 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
return false;
|
||||
}
|
||||
g_usbd_msc[busid].stage = MSC_DATA_IN;
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
|
||||
return true;
|
||||
#else
|
||||
return SCSI_processRead(busid);
|
||||
@@ -532,6 +547,9 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
|
||||
static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
(void)data;
|
||||
(void)len;
|
||||
|
||||
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
@@ -554,8 +572,10 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
return false;
|
||||
}
|
||||
g_usbd_msc[busid].stage = MSC_DATA_IN;
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
|
||||
return true;
|
||||
#else
|
||||
return SCSI_processRead(busid);
|
||||
@@ -565,6 +585,10 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
|
||||
(void)data;
|
||||
(void)len;
|
||||
|
||||
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
@@ -594,6 +618,10 @@ static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
|
||||
(void)data;
|
||||
(void)len;
|
||||
|
||||
if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
@@ -803,6 +831,8 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
|
||||
|
||||
void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
(void)ep;
|
||||
|
||||
switch (g_usbd_msc[busid].stage) {
|
||||
case MSC_READ_CBW:
|
||||
if (SCSI_CBWDecode(busid, nbytes) == false) {
|
||||
@@ -815,9 +845,12 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
switch (g_usbd_msc[busid].cbw.CB[0]) {
|
||||
case SCSI_CMD_WRITE10:
|
||||
case SCSI_CMD_WRITE12:
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
g_usbd_msc[busid].nbytes = nbytes;
|
||||
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_OUT);
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
g_usbd_msc[busid].nbytes = nbytes;
|
||||
chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_OUT);
|
||||
#else
|
||||
if (SCSI_processWrite(busid, nbytes) == false) {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
@@ -835,13 +868,18 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
|
||||
void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
(void)ep;
|
||||
(void)nbytes;
|
||||
|
||||
switch (g_usbd_msc[busid].stage) {
|
||||
case MSC_DATA_IN:
|
||||
switch (g_usbd_msc[busid].cbw.CB[0]) {
|
||||
case SCSI_CMD_READ10:
|
||||
case SCSI_CMD_READ12:
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN);
|
||||
#else
|
||||
if (SCSI_processRead(busid) == false) {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
@@ -870,7 +908,7 @@ void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
static void usbdev_msc_thread(void *argument)
|
||||
{
|
||||
uintptr_t event;
|
||||
@@ -882,7 +920,26 @@ static void usbdev_msc_thread(void *argument)
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
USB_LOG_DBG("%d\r\n", event);
|
||||
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*/
|
||||
}
|
||||
} else if (event == MSC_DATA_IN) {
|
||||
if (SCSI_processRead(busid) == false) {
|
||||
usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(CONFIG_USBDEV_MSC_POLLING)
|
||||
void usbd_msc_polling(uint8_t busid)
|
||||
{
|
||||
uint8_t event;
|
||||
|
||||
if (chry_ringbuffer_read_byte(&g_usbd_msc[busid].msc_rb, &event)) {
|
||||
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*/
|
||||
@@ -932,7 +989,7 @@ void usbd_msc_set_readonly(uint8_t busid, bool readonly)
|
||||
g_usbd_msc[busid].readonly = readonly;
|
||||
}
|
||||
|
||||
bool usbd_msc_set_popup(uint8_t busid)
|
||||
bool usbd_msc_get_popup(uint8_t busid)
|
||||
{
|
||||
return g_usbd_msc[busid].popup;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@ int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *b
|
||||
int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length);
|
||||
|
||||
void usbd_msc_set_readonly(uint8_t busid, bool readonly);
|
||||
bool usbd_msc_set_popup(uint8_t busid);
|
||||
bool usbd_msc_get_popup(uint8_t busid);
|
||||
|
||||
void usbd_msc_polling(uint8_t busid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#define MSC_INQUIRY_TIMEOUT 500
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[64];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbh_msc g_msc_class[CONFIG_USBHOST_MAX_MSC_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
@@ -87,6 +87,8 @@ static void usbh_msc_cbw_dump(struct CBW *cbw)
|
||||
|
||||
static void usbh_msc_csw_dump(struct CSW *csw)
|
||||
{
|
||||
(void)csw;
|
||||
|
||||
USB_LOG_DBG("CSW:\r\n");
|
||||
USB_LOG_DBG(" signature: 0x%08x\r\n", (unsigned int)csw->dSignature);
|
||||
USB_LOG_DBG(" tag: 0x%08x\r\n", (unsigned int)csw->dTag);
|
||||
@@ -182,14 +184,14 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
cbw->bCBLength = SCSICMD_TESTUNITREADY_SIZEOF;
|
||||
cbw->CB[0] = SCSI_CMD_TESTUNITREADY;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL, MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
||||
@@ -197,7 +199,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
@@ -207,7 +209,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
||||
cbw->CB[0] = SCSI_CMD_REQUESTSENSE;
|
||||
cbw->CB[4] = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
||||
@@ -215,7 +217,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
@@ -225,7 +227,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
||||
cbw->CB[0] = SCSI_CMD_INQUIRY;
|
||||
cbw->CB[4] = SCSIRESP_INQUIRY_SIZEOF;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
||||
@@ -233,7 +235,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
@@ -242,7 +244,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
||||
cbw->bCBLength = SCSICMD_READCAPACITY10_SIZEOF;
|
||||
cbw->CB[0] = SCSI_CMD_READCAPACITY10;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message)
|
||||
@@ -250,11 +252,11 @@ static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
|
||||
memcpy(g_msc_buf, message, 31);
|
||||
memcpy(g_msc_buf[msc_class->sdchar - 'a'], message, 31);
|
||||
|
||||
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL, MSC_INQUIRY_TIMEOUT);
|
||||
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
|
||||
}
|
||||
|
||||
static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
@@ -274,12 +276,12 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
hport->config.intf[intf].priv = msc_class;
|
||||
|
||||
ret = usbh_msc_get_maxlun(msc_class, g_msc_buf);
|
||||
ret = usbh_msc_get_maxlun(msc_class, g_msc_buf[msc_class->sdchar - 'a']);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[0] + 1);
|
||||
USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[msc_class->sdchar - 'a'][0] + 1);
|
||||
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
|
||||
@@ -376,7 +378,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
@@ -387,7 +389,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
|
||||
SET_BE32(&cbw->CB[2], start_sector);
|
||||
SET_BE16(&cbw->CB[7], nsectors);
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
|
||||
@@ -395,7 +397,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
@@ -407,7 +409,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
|
||||
SET_BE32(&cbw->CB[2], start_sector);
|
||||
SET_BE16(&cbw->CB[7], nsectors);
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
|
||||
@@ -421,10 +423,12 @@ void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
|
||||
|
||||
__WEAK void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
(void)msc_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
{
|
||||
(void)msc_class;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver msc_class_driver = {
|
||||
|
||||
@@ -680,6 +680,7 @@ void usbh_asix_rx_thread(void *argument)
|
||||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
USB_LOG_INFO("Create asix rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
@@ -742,7 +743,7 @@ find_class:
|
||||
#else
|
||||
if ((g_asix_rx_length + (16 * 1024)) > CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE) {
|
||||
#endif
|
||||
USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE\r\n");
|
||||
USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -791,10 +792,12 @@ int usbh_asix_eth_output(uint32_t buflen)
|
||||
|
||||
__WEAK void usbh_asix_run(struct usbh_asix *asix_class)
|
||||
{
|
||||
(void)asix_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_asix_stop(struct usbh_asix *asix_class)
|
||||
{
|
||||
(void)asix_class;
|
||||
}
|
||||
|
||||
static const uint16_t asix_id_table[][2] = {
|
||||
|
||||
@@ -2140,6 +2140,7 @@ void usbh_rtl8152_rx_thread(void *argument)
|
||||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
@@ -2210,7 +2211,7 @@ find_class:
|
||||
#else
|
||||
if ((g_rtl8152_rx_length + (16 * 1024)) > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) {
|
||||
#endif
|
||||
USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE\r\n");
|
||||
USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -2248,10 +2249,12 @@ int usbh_rtl8152_eth_output(uint32_t buflen)
|
||||
|
||||
__WEAK void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
|
||||
{
|
||||
(void)rtl8152_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
|
||||
{
|
||||
(void)rtl8152_class;
|
||||
}
|
||||
|
||||
static const uint16_t rtl_id_table[][2] = {
|
||||
|
||||
@@ -349,10 +349,12 @@ int usbh_ch34x_bulk_out_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer
|
||||
|
||||
__WEAK void usbh_ch34x_run(struct usbh_ch34x *ch34x_class)
|
||||
{
|
||||
(void)ch34x_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class)
|
||||
{
|
||||
(void)ch34x_class;
|
||||
}
|
||||
|
||||
static const uint16_t ch34x_id_table[][2] = {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cp210x_buf[64];
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CP210X_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_CP210X_CLASS 1
|
||||
|
||||
static struct usbh_cp210x g_cp210x_class[CONFIG_USBHOST_MAX_CP210X_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
@@ -298,10 +298,12 @@ int usbh_cp210x_bulk_out_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buf
|
||||
|
||||
__WEAK void usbh_cp210x_run(struct usbh_cp210x *cp210x_class)
|
||||
{
|
||||
(void)cp210x_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class)
|
||||
{
|
||||
(void)cp210x_class;
|
||||
}
|
||||
|
||||
static const uint16_t cp210x_id_table[][2] = {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_ftdi_buf[64];
|
||||
|
||||
#define CONFIG_USBHOST_MAX_FTDI_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_FTDI_CLASS 1
|
||||
|
||||
static struct usbh_ftdi g_ftdi_class[CONFIG_USBHOST_MAX_FTDI_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
@@ -57,7 +57,7 @@ static void usbh_ftdi_caculate_baudrate(uint32_t *itdf_divisor, uint32_t actual_
|
||||
}
|
||||
int divisor = FTDI_USB_CLK / baudrate;
|
||||
int frac_bits = 0;
|
||||
for (int i = 0; i < sizeof(frac) / sizeof(frac[0]); i++) {
|
||||
for (uint8_t i = 0; i < sizeof(frac) / sizeof(frac[0]); i++) {
|
||||
if ((divisor & 0xF) == frac[i]) {
|
||||
frac_bits = i;
|
||||
break;
|
||||
@@ -370,10 +370,12 @@ int usbh_ftdi_bulk_out_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, u
|
||||
|
||||
__WEAK void usbh_ftdi_run(struct usbh_ftdi *ftdi_class)
|
||||
{
|
||||
(void)ftdi_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class)
|
||||
{
|
||||
(void)ftdi_class;
|
||||
}
|
||||
|
||||
static const uint16_t ftdi_id_table[][2] = {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_pl2303_buf[64];
|
||||
|
||||
#define CONFIG_USBHOST_MAX_PL2303_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_PL2303_CLASS 1
|
||||
|
||||
#define UT_WRITE_VENDOR_DEVICE (USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE)
|
||||
#define UT_READ_VENDOR_DEVICE (USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE)
|
||||
@@ -413,10 +413,12 @@ int usbh_pl2303_bulk_out_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buf
|
||||
|
||||
__WEAK void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class)
|
||||
{
|
||||
(void)pl2303_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
|
||||
{
|
||||
(void)pl2303_class;
|
||||
}
|
||||
|
||||
static const uint16_t pl2303_id_table[][2] = {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# BL616 USB WIFI
|
||||
|
||||
Usbwifi firmware please contact bouffalolab. You can purchase a module in the following ways:
|
||||
|
||||
- https://iot.mi.com/moduleBrowser.html
|
||||
- https://docs.ai-thinker.com/ai_m61
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBH_BL616_H
|
||||
#define USBH_BL616_H
|
||||
|
||||
#define USBWIFI_DATA_TYPE_CMD 0xA55A
|
||||
#define USBWIFI_DATA_TYPE_PKT 0x6996
|
||||
|
||||
#define USB_DATA_FLAG_AP_PKT (1u << 0)
|
||||
|
||||
typedef enum {
|
||||
BFLB_CMD_REBOOT = 0,
|
||||
BFLB_CMD_RESET,
|
||||
BFLB_CMD_HELLO,
|
||||
BFLB_CMD_PING,
|
||||
|
||||
BFLB_CMD_GET_MAC_ADDR,
|
||||
|
||||
// Scan
|
||||
BFLB_CMD_SCAN,
|
||||
BFLB_CMD_SCAN_RESULTS,
|
||||
|
||||
// STA
|
||||
BFLB_CMD_STA_CONNECT,
|
||||
BFLB_CMD_STA_DISCONNECT,
|
||||
BFLB_CMD_STA_CONNECTED_IND,
|
||||
BFLB_CMD_STA_DISCONNECTED_IND,
|
||||
BFLB_CMD_STA_IP_UPDATE_IND,
|
||||
BFLB_CMD_STA_SET_AUTO_RECONNECT,
|
||||
BFLB_CMD_STA_GET_LINK_STATUS,
|
||||
|
||||
// AP
|
||||
BFLB_CMD_AP_START,
|
||||
BFLB_CMD_AP_STOP,
|
||||
BFLB_CMD_AP_STARTED_IND,
|
||||
BFLB_CMD_AP_STOPPED_IND,
|
||||
BFLB_CMD_AP_GET_STA_LIST,
|
||||
|
||||
// Monitor
|
||||
BFLB_CMD_MONITOR_START,
|
||||
BFLB_CMD_MONITOR_STOP,
|
||||
BFLB_CMD_MONITOR_SET_CHANNEL,
|
||||
BFLB_CMD_MONITOR_GET_CHANNEL,
|
||||
|
||||
BFLB_CMD_SET_LPM_MODE,
|
||||
|
||||
// OTA
|
||||
BFLB_CMD_GET_DEV_VERSION,
|
||||
BFLB_CMD_OTA,
|
||||
|
||||
BFLB_CMD_EXT,
|
||||
|
||||
BFLB_CMD_USER_EXT,
|
||||
BFLB_CMD_UNLOAD_DRV,
|
||||
|
||||
BFLB_CMD_MAX,
|
||||
} bflb_cmd_t;
|
||||
|
||||
typedef enum {
|
||||
STATUS_OK,
|
||||
STATUS_NOMEM = 128,
|
||||
STATUS_INVALID_INPUT,
|
||||
STATUS_INVALID_MODE,
|
||||
STATUS_ERR_UNSPECIFIED,
|
||||
STATUS_NOT_IMPLEMENTED,
|
||||
} cmd_status_t;
|
||||
|
||||
typedef enum {
|
||||
RNM_WIFI_AUTH_UNKNOWN = 0,
|
||||
RNM_WIFI_AUTH_OPEN,
|
||||
RNM_WIFI_AUTH_WEP,
|
||||
RNM_WIFI_AUTH_WPA_PSK,
|
||||
RNM_WIFI_AUTH_WPA2_PSK,
|
||||
RNM_WIFI_AUTH_WPA_WPA2_PSK,
|
||||
RNM_WIFI_AUTH_WPA_ENTERPRISE,
|
||||
RNM_WIFI_AUTH_WPA3_SAE,
|
||||
RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE,
|
||||
RNM_WIFI_AUTH_MAX,
|
||||
} rnm_wifi_auth_mode_t;
|
||||
|
||||
typedef enum {
|
||||
RNM_WIFI_CIPHER_UNKNOWN = 0,
|
||||
RNM_WIFI_CIPHER_NONE,
|
||||
RNM_WIFI_CIPHER_WEP,
|
||||
RNM_WIFI_CIPHER_AES,
|
||||
RNM_WIFI_CIPHER_TKIP,
|
||||
RNM_WIFI_CIPHER_TKIP_AES,
|
||||
RNM_WIFI_CIPHER_MAX,
|
||||
} rnm_wifi_cipher_t;
|
||||
|
||||
/* common header */
|
||||
typedef struct {
|
||||
uint16_t cmd;
|
||||
// flag ACK is used by server to indicate a response to client
|
||||
#define RNM_MSG_FLAG_ACK (1 << 0)
|
||||
// flag TRANSPARENT is never transfered to peer but used locally
|
||||
#define RNM_MSG_FLAG_TRANSPARENT (1 << 1)
|
||||
// flag ASYNC is used by server to notify client events such as STA_CONNECTED
|
||||
#define RNM_MSG_FLAG_ASYNC (1 << 2)
|
||||
uint16_t flags;
|
||||
uint16_t status;
|
||||
uint16_t msg_id;
|
||||
uint16_t session_id;
|
||||
uint16_t msg_id_replying;
|
||||
} rnm_base_msg_t;
|
||||
|
||||
typedef struct {
|
||||
rnm_base_msg_t hdr;
|
||||
} rnm_ack_msg_t;
|
||||
|
||||
typedef struct {
|
||||
rnm_base_msg_t hdr;
|
||||
uint8_t sta_mac[6];
|
||||
uint8_t ap_mac[6];
|
||||
} rnm_mac_addr_ind_msg_t;
|
||||
|
||||
typedef struct {
|
||||
rnm_base_msg_t hdr;
|
||||
uint16_t ssid_len;
|
||||
uint8_t ssid[32];
|
||||
uint8_t password[64];
|
||||
} rnm_sta_connect_msg_t;
|
||||
|
||||
typedef struct {
|
||||
rnm_base_msg_t hdr;
|
||||
uint8_t ip4_addr[4];
|
||||
uint8_t ip4_mask[4];
|
||||
uint8_t ip4_gw[4];
|
||||
uint8_t ip4_dns1[4];
|
||||
uint8_t ip4_dns2[4];
|
||||
uint8_t gw_mac[6];
|
||||
} rnm_sta_ip_update_ind_msg_t;
|
||||
|
||||
struct bf1b_wifi_scan_record {
|
||||
uint8_t bssid[6];
|
||||
// TODO use compressed SSID encoding to save room
|
||||
uint8_t ssid[32 + 1];
|
||||
uint16_t channel;
|
||||
int8_t rssi;
|
||||
uint8_t auth_mode;
|
||||
uint8_t cipher;
|
||||
} __PACKED;
|
||||
|
||||
typedef struct {
|
||||
rnm_base_msg_t hdr;
|
||||
uint16_t num;
|
||||
struct bf1b_wifi_scan_record records[];
|
||||
} rnm_scan_ind_msg_t;
|
||||
|
||||
typedef enum {
|
||||
BL_MODE_NONE,
|
||||
BL_MODE_STA, // card is STA
|
||||
BL_MODE_AP, // card is AP
|
||||
BL_MODE_STA_AP, // card is STA&AP
|
||||
BL_MODE_SNIFFER, // card is sniffer
|
||||
BL_MODE_MAX,
|
||||
} bl_wifi_mode_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t type;
|
||||
uint16_t length;
|
||||
uint16_t flags;
|
||||
uint16_t payload_offset;
|
||||
uint32_t rsvd[8];
|
||||
uint8_t payload[];
|
||||
} __attribute__((aligned(4))) usb_data_t;
|
||||
|
||||
struct usbh_bl616 {
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
|
||||
struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
|
||||
|
||||
struct usbh_urb bulkout_urb;
|
||||
struct usbh_urb bulkin_urb;
|
||||
|
||||
uint8_t intf;
|
||||
|
||||
uint8_t sta_mac[6];
|
||||
uint8_t ap_mac[6];
|
||||
uint8_t mode;
|
||||
bool connect_status;
|
||||
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int usbh_bl616_wifi_sta_connect(const char *ssid,
|
||||
const int ssid_len,
|
||||
const char *password,
|
||||
const int pwd_len);
|
||||
|
||||
int usbh_bl616_wifi_sta_disconnect(void);
|
||||
int usbh_bl616_wifi_scan(void);
|
||||
|
||||
void usbh_bl616_sta_connect_callback(void);
|
||||
void usbh_bl616_sta_disconnect_callback(void);
|
||||
void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4]);
|
||||
|
||||
uint8_t *usbh_bl616_get_eth_txbuf(void);
|
||||
int usbh_bl616_eth_output(uint32_t buflen);
|
||||
void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen);
|
||||
void usbh_bl616_rx_thread(void *argument);
|
||||
|
||||
void usbh_bl616_run(struct usbh_bl616 *bl616_class);
|
||||
void usbh_bl616_stop(struct usbh_bl616 *bl616_class);
|
||||
|
||||
int wifi_sta_connect(int argc, char **argv);
|
||||
int wifi_scan(int argc, char **argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBH_BL616_H */
|
||||
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Till Harbaum
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_xbox.h"
|
||||
|
||||
#define DEV_FORMAT "/dev/xbox%d"
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_xbox_buf[128];
|
||||
|
||||
static struct usbh_xbox g_xbox_class[CONFIG_USBHOST_MAX_XBOX_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static struct usbh_xbox *usbh_xbox_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_XBOX_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_xbox_class[devno], 0, sizeof(struct usbh_xbox));
|
||||
g_xbox_class[devno].minor = devno;
|
||||
return &g_xbox_class[devno];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_xbox_class_free(struct usbh_xbox *xbox_class)
|
||||
{
|
||||
int devno = xbox_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(xbox_class, 0, sizeof(struct usbh_xbox));
|
||||
}
|
||||
|
||||
int usbh_xbox_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
|
||||
struct usbh_xbox *xbox_class = usbh_xbox_class_alloc();
|
||||
if (xbox_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc xbox_class\r\n");
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
xbox_class->hport = hport;
|
||||
xbox_class->intf = intf;
|
||||
|
||||
hport->config.intf[intf].priv = xbox_class;
|
||||
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
USBH_EP_INIT(xbox_class->intin, ep_desc);
|
||||
} else {
|
||||
USBH_EP_INIT(xbox_class->intout, ep_desc);
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, xbox_class->minor);
|
||||
|
||||
USB_LOG_INFO("Register XBOX Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
usbh_xbox_run(xbox_class);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_xbox_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
struct usbh_xbox *xbox_class = (struct usbh_xbox *)hport->config.intf[intf].priv;
|
||||
|
||||
if (xbox_class) {
|
||||
if (xbox_class->intin) {
|
||||
usbh_kill_urb(&xbox_class->intin_urb);
|
||||
}
|
||||
|
||||
if (xbox_class->intout) {
|
||||
usbh_kill_urb(&xbox_class->intout_urb);
|
||||
}
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister XBOX Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_xbox_stop(xbox_class);
|
||||
}
|
||||
|
||||
usbh_xbox_class_free(xbox_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
__WEAK void usbh_xbox_run(struct usbh_xbox *xbox_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_xbox_stop(struct usbh_xbox *xbox_class)
|
||||
{
|
||||
}
|
||||
|
||||
const struct usbh_class_driver xbox_class_driver = {
|
||||
.driver_name = "xbox",
|
||||
.connect = usbh_xbox_connect,
|
||||
.disconnect = usbh_xbox_disconnect
|
||||
};
|
||||
|
||||
static const uint16_t xbox_id_table[][2] = {
|
||||
{ 0x0079, 0x18d4 }, // GPD Win 2 X-Box Controller
|
||||
{ 0x03eb, 0xff01 }, // Wooting One (Legacy)
|
||||
{ 0x03eb, 0xff02 }, // Wooting Two (Legacy)
|
||||
{ 0x044f, 0xb326 }, // Thrustmaster Gamepad GP XID
|
||||
{ 0x045e, 0x028e }, // Microsoft X-Box 360 pad
|
||||
{ 0x045e, 0x028f }, // Microsoft X-Box 360 pad v2
|
||||
{ 0x046d, 0xc21d }, // Logitech Gamepad F310
|
||||
{ 0x046d, 0xc21e }, // Logitech Gamepad F510
|
||||
{ 0x046d, 0xc21f }, // Logitech Gamepad F710
|
||||
{ 0x046d, 0xc242 }, // Logitech Chillstream Controller
|
||||
{ 0x046d, 0xcaa3 }, // Logitech DriveFx Racing Wheel
|
||||
{ 0x056e, 0x2004 }, // Elecom JC-U3613M
|
||||
{ 0x06a3, 0xf51a }, // Saitek P3600
|
||||
{ 0x0738, 0x4716 }, // Mad Catz Wired Xbox 360 Controller
|
||||
{ 0x0738, 0x4718 }, // Mad Catz Street Fighter IV FightStick SE
|
||||
{ 0x0738, 0x4726 }, // Mad Catz Xbox 360 Controller
|
||||
{ 0x0738, 0x4736 }, // Mad Catz MicroCon Gamepad
|
||||
{ 0x0738, 0x4740 }, // Mad Catz Beat Pad
|
||||
{ 0x0738, 0x9871 }, // Mad Catz Portable Drum
|
||||
{ 0x0738, 0xb726 }, // Mad Catz Xbox controller - MW2
|
||||
{ 0x0738, 0xbeef }, // Mad Catz JOYTECH NEO SE Advanced GamePad
|
||||
{ 0x0738, 0xcb02 }, // Saitek Cyborg Rumble Pad - PC/Xbox 360
|
||||
{ 0x0738, 0xcb03 }, // Saitek P3200 Rumble Pad - PC/Xbox 360
|
||||
{ 0x0738, 0xcb29 }, // Saitek Aviator Stick AV8R02
|
||||
{ 0x0738, 0xf738 }, // Super SFIV FightStick TE S
|
||||
{ 0x07ff, 0xffff }, // Mad Catz GamePad
|
||||
{ 0x0e6f, 0x0113 }, // Afterglow AX.1 Gamepad for Xbox 360
|
||||
{ 0x0e6f, 0x011f }, // Rock Candy Gamepad Wired Controller
|
||||
{ 0x0e6f, 0x0131 }, // PDP EA Sports Controller
|
||||
{ 0x0e6f, 0x0133 }, // Xbox 360 Wired Controller
|
||||
{ 0x0e6f, 0x0201 }, // Pelican PL-3601 'TSZ' Wired Xbox 360 Controller
|
||||
{ 0x0e6f, 0x0213 }, // Afterglow Gamepad for Xbox 360
|
||||
{ 0x0e6f, 0x021f }, // Rock Candy Gamepad for Xbox 360
|
||||
{ 0x0e6f, 0x0301 }, // Logic3 Controller
|
||||
{ 0x0e6f, 0x0401 }, // Logic3 Controller
|
||||
{ 0x0e6f, 0x0413 }, // Afterglow AX.1 Gamepad for Xbox 360
|
||||
{ 0x0e6f, 0x0501 }, // PDP Xbox 360 Controller
|
||||
{ 0x0e6f, 0xf900 }, // PDP Afterglow AX.1
|
||||
{ 0x0f0d, 0x000a }, // Hori Co. DOA4 FightStick
|
||||
{ 0x0f0d, 0x000c }, // Hori PadEX Turbo
|
||||
{ 0x1038, 0x1430 }, // SteelSeries Stratus Duo
|
||||
{ 0x1038, 0x1431 }, // SteelSeries Stratus Duo
|
||||
{ 0x11c9, 0x55f0 }, // Nacon GC-100XF
|
||||
{ 0x1209, 0x2882 }, // Ardwiino Controller
|
||||
{ 0x12ab, 0x0301 }, // PDP AFTERGLOW AX.1
|
||||
{ 0x1430, 0x4748 }, // RedOctane Guitar Hero X-plorer
|
||||
{ 0x1430, 0xf801 }, // RedOctane Controller
|
||||
{ 0x146b, 0x0601 }, // BigBen Interactive XBOX 360 Controller
|
||||
{ 0x1532, 0x0037 }, // Razer Sabertooth
|
||||
{ 0x15e4, 0x3f00 }, // Power A Mini Pro Elite
|
||||
{ 0x15e4, 0x3f0a }, // Xbox Airflo wired controller
|
||||
{ 0x15e4, 0x3f10 }, // Batarang Xbox 360 controller
|
||||
{ 0x162e, 0xbeef }, // Joytech Neo-Se Take2
|
||||
{ 0x1689, 0xfd00 }, // Razer Onza Tournament Edition
|
||||
{ 0x1689, 0xfd01 }, // Razer Onza Classic Edition
|
||||
{ 0x1689, 0xfe00 }, // Razer Sabertooth
|
||||
{ 0x1949, 0x041a }, // Amazon Game Controller
|
||||
{ 0x1bad, 0x0002 }, // Harmonix Rock Band Guitar
|
||||
{ 0x1bad, 0xf016 }, // Mad Catz Xbox 360 Controller
|
||||
{ 0x1bad, 0xf021 }, // Mad Cats Ghost Recon FS GamePad
|
||||
{ 0x1bad, 0xf023 }, // MLG Pro Circuit Controller (Xbox)
|
||||
{ 0x1bad, 0xf025 }, // Mad Catz Call Of Duty
|
||||
{ 0x1bad, 0xf027 }, // Mad Catz FPS Pro
|
||||
{ 0x1bad, 0xf028 }, // Street Fighter IV FightPad
|
||||
{ 0x1bad, 0xf030 }, // Mad Catz Xbox 360 MC2 MicroCon Racing Wheel
|
||||
{ 0x1bad, 0xf036 }, // Mad Catz MicroCon GamePad Pro
|
||||
{ 0x1bad, 0xf038 }, // Street Fighter IV FightStick TE
|
||||
{ 0x1bad, 0xf501 }, // HoriPad EX2 Turbo
|
||||
{ 0x1bad, 0xf506 }, // Hori Real Arcade Pro.EX Premium VLX
|
||||
{ 0x1bad, 0xf900 }, // Harmonix Xbox 360 Controller
|
||||
{ 0x1bad, 0xf901 }, // Gamestop Xbox 360 Controller
|
||||
{ 0x1bad, 0xf903 }, // Tron Xbox 360 controller
|
||||
{ 0x1bad, 0xf904 }, // PDP Versus Fighting Pad
|
||||
{ 0x1bad, 0xfa01 }, // MadCatz GamePad
|
||||
{ 0x1bad, 0xfd00 }, // Razer Onza TE
|
||||
{ 0x1bad, 0xfd01 }, // Razer Onza
|
||||
{ 0x20d6, 0x2001 }, // BDA Xbox Series X Wired Controller
|
||||
{ 0x20d6, 0x281f }, // PowerA Wired Controller For Xbox 360
|
||||
{ 0x24c6, 0x5300 }, // PowerA MINI PROEX Controller
|
||||
{ 0x24c6, 0x5303 }, // Xbox Airflo wired controller
|
||||
{ 0x24c6, 0x530a }, // Xbox 360 Pro EX Controller
|
||||
{ 0x24c6, 0x531a }, // PowerA Pro Ex
|
||||
{ 0x24c6, 0x5397 }, // FUS1ON Tournament Controller
|
||||
{ 0x24c6, 0x5500 }, // Hori XBOX 360 EX 2 with Turbo
|
||||
{ 0x24c6, 0x5501 }, // Hori Real Arcade Pro VX-SA
|
||||
{ 0x24c6, 0x5506 }, // Hori SOULCALIBUR V Stick
|
||||
{ 0x24c6, 0x550d }, // Hori GEM Xbox controller
|
||||
{ 0x24c6, 0x5b00 }, // ThrustMaster Ferrari 458 Racing Wheel
|
||||
{ 0x24c6, 0x5b02 }, // Thrustmaster, Inc. GPX Controller
|
||||
{ 0x24c6, 0x5b03 }, // Thrustmaster Ferrari 458 Racing Wheel
|
||||
{ 0x24c6, 0x5d04 }, // Razer Sabertooth
|
||||
{ 0x24c6, 0xfafe }, // Rock Candy Gamepad for Xbox 360
|
||||
{ 0x2563, 0x058d }, // OneXPlayer Gamepad
|
||||
{ 0x2dc8, 0x3106 }, // 8BitDo Ultimate Wireless / Pro 2 Wired Controller
|
||||
{ 0x2dc8, 0x3109 }, // 8BitDo Ultimate Wireless Bluetooth
|
||||
{ 0x31e3, 0x1100 }, // Wooting One
|
||||
{ 0x31e3, 0x1200 }, // Wooting Two
|
||||
{ 0x31e3, 0x1210 }, // Wooting Lekker
|
||||
{ 0x31e3, 0x1220 }, // Wooting Two HE
|
||||
{ 0x31e3, 0x1230 }, // Wooting Two HE (ARM)
|
||||
{ 0x31e3, 0x1300 }, // Wooting 60HE (AVR)
|
||||
{ 0x31e3, 0x1310 }, // Wooting 60HE (ARM)
|
||||
{ 0x3285, 0x0607 }, // Nacon GC-100
|
||||
{ 0x413d, 0x2104 }, // Black Shark Green Ghost Gamepad
|
||||
{ 0x0000, 0x0000 } // end of list
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info xbox_custom_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_VEND_SPECIFIC,
|
||||
.subclass = 0x5d,
|
||||
.protocol = 0x01,
|
||||
.id_table = xbox_id_table,
|
||||
.class_driver = &xbox_class_driver
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Till Harbaum
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBH_XBOX_H
|
||||
#define USBH_XBOX_H
|
||||
|
||||
struct usbh_xbox {
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *intin; /* INTR IN endpoint */
|
||||
struct usb_endpoint_descriptor *intout; /* INTR OUT endpoint */
|
||||
struct usbh_urb intin_urb; /* INTR IN urb */
|
||||
struct usbh_urb intout_urb; /* INTR OUT urb */
|
||||
|
||||
uint8_t intf; /* interface number */
|
||||
uint8_t minor;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void usbh_xbox_run(struct usbh_xbox *xbox_class);
|
||||
void usbh_xbox_stop(struct usbh_xbox *xbox_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBH_XBOX_H */
|
||||
@@ -24,6 +24,8 @@ static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_pa
|
||||
{
|
||||
uint8_t control_selector = (uint8_t)(setup->wValue >> 8);
|
||||
|
||||
(void)busid;
|
||||
|
||||
switch (control_selector) {
|
||||
case VIDEO_VC_VIDEO_POWER_MODE_CONTROL:
|
||||
switch (setup->bRequest) {
|
||||
|
||||
@@ -495,20 +495,26 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
static int usbh_video_streaming_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
(void)hport;
|
||||
(void)intf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_video_streaming_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
(void)hport;
|
||||
(void)intf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbh_video_run(struct usbh_video *video_class)
|
||||
{
|
||||
(void)video_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_video_stop(struct usbh_video *video_class)
|
||||
{
|
||||
(void)video_class;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver video_ctrl_class_driver = {
|
||||
|
||||
@@ -102,6 +102,8 @@ static void rndis_notify_rsp(void)
|
||||
|
||||
static int rndis_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
(void)busid;
|
||||
|
||||
switch (setup->bRequest) {
|
||||
case CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
|
||||
rndis_encapsulated_cmd_handler(*data, setup->wLength);
|
||||
@@ -152,6 +154,8 @@ static int rndis_init_cmd_handler(uint8_t *data, uint32_t len)
|
||||
rndis_initialize_msg_t *cmd = (rndis_initialize_msg_t *)data;
|
||||
rndis_initialize_cmplt_t *resp;
|
||||
|
||||
(void)len;
|
||||
|
||||
resp = ((rndis_initialize_cmplt_t *)rndis_encapsulated_resp_buffer);
|
||||
resp->RequestId = cmd->RequestId;
|
||||
resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
@@ -177,6 +181,9 @@ static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len)
|
||||
{
|
||||
rndis_halt_msg_t *resp;
|
||||
|
||||
(void)data;
|
||||
(void)len;
|
||||
|
||||
resp = ((rndis_halt_msg_t *)rndis_encapsulated_resp_buffer);
|
||||
resp->MessageLength = 0;
|
||||
|
||||
@@ -192,6 +199,8 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
|
||||
uint8_t *infomation_buffer;
|
||||
uint32_t infomation_len = 0;
|
||||
|
||||
(void)len;
|
||||
|
||||
resp = ((rndis_query_cmplt_t *)rndis_encapsulated_resp_buffer);
|
||||
resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
resp->RequestId = cmd->RequestId;
|
||||
@@ -338,6 +347,8 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len)
|
||||
rndis_set_cmplt_t *resp;
|
||||
rndis_config_parameter_t *param;
|
||||
|
||||
(void)len;
|
||||
|
||||
resp = ((rndis_set_cmplt_t *)rndis_encapsulated_resp_buffer);
|
||||
resp->RequestId = cmd->RequestId;
|
||||
resp->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
@@ -394,6 +405,9 @@ static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len)
|
||||
// rndis_reset_msg_t *cmd = (rndis_reset_msg_t *)data;
|
||||
rndis_reset_cmplt_t *resp;
|
||||
|
||||
(void)data;
|
||||
(void)len;
|
||||
|
||||
resp = ((rndis_reset_cmplt_t *)rndis_encapsulated_resp_buffer);
|
||||
resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
resp->MessageLength = sizeof(rndis_reset_cmplt_t);
|
||||
@@ -412,6 +426,8 @@ static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len)
|
||||
rndis_keepalive_msg_t *cmd = (rndis_keepalive_msg_t *)data;
|
||||
rndis_keepalive_cmplt_t *resp;
|
||||
|
||||
(void)len;
|
||||
|
||||
resp = ((rndis_keepalive_cmplt_t *)rndis_encapsulated_resp_buffer);
|
||||
resp->RequestId = cmd->RequestId;
|
||||
resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
@@ -425,6 +441,9 @@ static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len)
|
||||
|
||||
static void rndis_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
||||
{
|
||||
(void)busid;
|
||||
(void)arg;
|
||||
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
|
||||
@@ -445,6 +464,9 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
rndis_data_packet_t *hdr;
|
||||
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
|
||||
hdr = (rndis_data_packet_t *)g_rndis_rx_buffer;
|
||||
g_rndis_rx_data_buffer = g_rndis_rx_buffer;
|
||||
if ((hdr->MessageType != REMOTE_NDIS_PACKET_MSG) || (nbytes < hdr->MessageLength)) {
|
||||
@@ -461,7 +483,9 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
|
||||
void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
(void)busid;
|
||||
|
||||
if ((nbytes % usbd_get_ep_mps(0, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(0, ep, NULL, 0);
|
||||
} else {
|
||||
@@ -471,6 +495,10 @@ void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
|
||||
void rndis_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)nbytes;
|
||||
|
||||
//USB_LOG_DBG("len:%d\r\n", nbytes);
|
||||
}
|
||||
|
||||
|
||||
@@ -365,14 +365,18 @@ delete :
|
||||
|
||||
__WEAK void usbh_bluetooth_hci_read_callback(uint8_t *data, uint32_t len)
|
||||
{
|
||||
(void)data;
|
||||
(void)len;
|
||||
}
|
||||
|
||||
__WEAK void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class)
|
||||
{
|
||||
(void)bluetooth_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_bluetooth_stop(struct usbh_bluetooth *bluetooth_class)
|
||||
{
|
||||
(void)bluetooth_class;
|
||||
}
|
||||
|
||||
static const struct usbh_class_driver bluetooth_class_driver = {
|
||||
|
||||
@@ -26,6 +26,7 @@ static struct usbh_rndis g_rndis_class;
|
||||
|
||||
static int usbh_rndis_get_notification(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
(void)rndis_class;
|
||||
// int ret;
|
||||
// struct usbh_urb *urb = &rndis_class->intin_urb;
|
||||
|
||||
@@ -460,6 +461,8 @@ void usbh_rndis_rx_thread(void *argument)
|
||||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
|
||||
USB_LOG_INFO("Create rndis rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
@@ -531,7 +534,7 @@ find_class:
|
||||
#else
|
||||
if ((g_rndis_rx_length + (16 * 1024)) > CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) {
|
||||
#endif
|
||||
USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE\r\n");
|
||||
USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -581,10 +584,12 @@ int usbh_rndis_eth_output(uint32_t buflen)
|
||||
|
||||
__WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
(void)rndis_class;
|
||||
}
|
||||
|
||||
__WEAK void usbh_rndis_stop(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
(void)rndis_class;
|
||||
}
|
||||
|
||||
static const struct usbh_class_driver rndis_class_driver = {
|
||||
|
||||
@@ -33,6 +33,13 @@ int usb_dc_deinit(uint8_t busid);
|
||||
*/
|
||||
int usbd_set_address(uint8_t busid, const uint8_t addr);
|
||||
|
||||
/**
|
||||
* @brief Set remote wakeup feature
|
||||
*
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbd_set_remote_wakeup(uint8_t busid);
|
||||
|
||||
/**
|
||||
* @brief Get USB device speed
|
||||
*
|
||||
|
||||
@@ -614,7 +614,7 @@ struct usb_webusb_url_descriptor {
|
||||
char URL[];
|
||||
} __PACKED;
|
||||
|
||||
struct usb_webusb_url_ex_descriptor {
|
||||
struct usb_webusb_descriptor {
|
||||
uint8_t vendor_code;
|
||||
const uint8_t *string;
|
||||
uint32_t string_len;
|
||||
|
||||
@@ -82,4 +82,31 @@ void usb_assert(const char *filename, int linenum);
|
||||
usb_assert(__FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define ___is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
|
||||
static inline void usb_hexdump(const void *ptr, uint32_t buflen)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)ptr;
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0; i < buflen; i += 16) {
|
||||
CONFIG_USB_PRINTF("%08X:", i);
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
if (i + j < buflen) {
|
||||
if ((j % 8) == 0) {
|
||||
CONFIG_USB_PRINTF(" ");
|
||||
}
|
||||
|
||||
CONFIG_USB_PRINTF("%02X ", buf[i + j]);
|
||||
} else
|
||||
CONFIG_USB_PRINTF(" ");
|
||||
CONFIG_USB_PRINTF(" ");
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
if (i + j < buflen)
|
||||
CONFIG_USB_PRINTF("%c", ___is_print(buf[i + j]) ? buf[i + j] : '.');
|
||||
CONFIG_USB_PRINTF("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USB_LOG_H */
|
||||
|
||||
@@ -58,4 +58,7 @@ void usb_osal_leave_critical_section(size_t flag);
|
||||
|
||||
void usb_osal_msleep(uint32_t delay);
|
||||
|
||||
void *usb_osal_malloc(size_t size);
|
||||
void usb_osal_free(void *ptr);
|
||||
|
||||
#endif /* USB_OSAL_H */
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USB_VERSION_H
|
||||
#define USB_VERSION_H
|
||||
|
||||
#ifdef CHERRYUSB_VERSION
|
||||
#warning "Please do not define CHERRYUSB_VERSION in usb_config.h"
|
||||
#undef CHERRYUSB_VERSION
|
||||
#endif
|
||||
#ifdef CHERRYUSB_VERSION_STR
|
||||
#warning "Please do not define CHERRYUSB_VERSION_STR in usb_config.h"
|
||||
#undef CHERRYUSB_VERSION_STR
|
||||
#endif
|
||||
|
||||
#define CHERRYUSB_VERSION 0x010400
|
||||
#define CHERRYUSB_VERSION_STR "v1.4.0"
|
||||
|
||||
#endif
|
||||
@@ -45,12 +45,18 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
|
||||
struct usb_msosv1_descriptor *msosv1_desc;
|
||||
struct usb_msosv2_descriptor *msosv2_desc;
|
||||
struct usb_bos_descriptor *bos_desc;
|
||||
struct usb_webusb_descriptor *webusb_url_desc;
|
||||
#endif
|
||||
/* Buffer used for storing standard, class and vendor request data */
|
||||
USB_MEM_ALIGNX uint8_t req_data[CONFIG_USBDEV_REQUEST_BUFFER_LEN];
|
||||
|
||||
/** Currently selected configuration */
|
||||
uint8_t configuration;
|
||||
uint8_t device_address;
|
||||
bool self_powered;
|
||||
bool remote_wakeup_support;
|
||||
bool remote_wakeup_enabled;
|
||||
bool is_suspend;
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
uint8_t speed;
|
||||
#endif
|
||||
@@ -174,6 +180,9 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
|
||||
break;
|
||||
}
|
||||
desc_len = ((desc[CONF_DESC_wTotalLength]) | (desc[CONF_DESC_wTotalLength + 1] << 8));
|
||||
|
||||
g_usbd_core[busid].self_powered = (desc[7] & USB_CONFIG_POWERED_MASK) ? true : false;
|
||||
g_usbd_core[busid].remote_wakeup_support = (desc[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false;
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_STRING:
|
||||
if (index == USB_OSDESC_STRING_DESC_INDEX) {
|
||||
@@ -336,6 +345,9 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
|
||||
*/
|
||||
*len = (p[CONF_DESC_wTotalLength]) |
|
||||
(p[CONF_DESC_wTotalLength + 1] << 8);
|
||||
|
||||
g_usbd_core[busid].self_powered = (p[7] & USB_CONFIG_POWERED_MASK) ? true : false;
|
||||
g_usbd_core[busid].remote_wakeup_support = (p[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false;
|
||||
} else {
|
||||
/* normally length is at offset 0 */
|
||||
*len = p[DESC_bLength];
|
||||
@@ -522,6 +534,12 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
|
||||
/* bit 0: self-powered */
|
||||
/* bit 1: remote wakeup */
|
||||
(*data)[0] = 0x00;
|
||||
if (g_usbd_core[busid].self_powered) {
|
||||
(*data)[0] |= USB_GETSTATUS_SELF_POWERED;
|
||||
}
|
||||
if (g_usbd_core[busid].remote_wakeup_enabled) {
|
||||
(*data)[0] |= USB_GETSTATUS_REMOTE_WAKEUP;
|
||||
}
|
||||
(*data)[1] = 0x00;
|
||||
*len = 2;
|
||||
break;
|
||||
@@ -530,8 +548,10 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
|
||||
case USB_REQUEST_SET_FEATURE:
|
||||
if (value == USB_FEATURE_REMOTE_WAKEUP) {
|
||||
if (setup->bRequest == USB_REQUEST_SET_FEATURE) {
|
||||
g_usbd_core[busid].remote_wakeup_enabled = true;
|
||||
g_usbd_core[busid].event_handler(busid, USBD_EVENT_SET_REMOTE_WAKEUP);
|
||||
} else {
|
||||
g_usbd_core[busid].remote_wakeup_enabled = false;
|
||||
g_usbd_core[busid].event_handler(busid, USBD_EVENT_CLR_REMOTE_WAKEUP);
|
||||
}
|
||||
} else if (value == USB_FEATURE_TEST_MODE) {
|
||||
@@ -543,6 +563,7 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
|
||||
break;
|
||||
|
||||
case USB_REQUEST_SET_ADDRESS:
|
||||
g_usbd_core[busid].device_address = value;
|
||||
usbd_set_address(busid, value);
|
||||
*len = 0;
|
||||
break;
|
||||
@@ -556,17 +577,20 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
|
||||
break;
|
||||
|
||||
case USB_REQUEST_GET_CONFIGURATION:
|
||||
*data = (uint8_t *)&g_usbd_core[busid].configuration;
|
||||
(*data)[0] = g_usbd_core[busid].configuration;
|
||||
*len = 1;
|
||||
break;
|
||||
|
||||
case USB_REQUEST_SET_CONFIGURATION:
|
||||
value &= 0xFF;
|
||||
|
||||
if (!usbd_set_configuration(busid, value, 0)) {
|
||||
if (value == 0) {
|
||||
g_usbd_core[busid].configuration = 0;
|
||||
} else if (!usbd_set_configuration(busid, value, 0)) {
|
||||
ret = false;
|
||||
} else {
|
||||
g_usbd_core[busid].configuration = value;
|
||||
g_usbd_core[busid].is_suspend = false;
|
||||
usbd_class_event_notify_handler(busid, USBD_EVENT_CONFIGURED, NULL);
|
||||
g_usbd_core[busid].event_handler(busid, USBD_EVENT_CONFIGURED);
|
||||
}
|
||||
@@ -600,6 +624,16 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
|
||||
uint8_t type = HI_BYTE(setup->wValue);
|
||||
uint8_t intf_num = LO_BYTE(setup->wIndex);
|
||||
bool ret = true;
|
||||
const uint8_t *p;
|
||||
uint32_t desc_len = 0;
|
||||
uint32_t current_desc_len = 0;
|
||||
uint8_t cur_iface = 0xFF;
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed);
|
||||
#else
|
||||
p = (uint8_t *)g_usbd_core[busid].descriptors;
|
||||
#endif
|
||||
|
||||
/* Only when device is configured, then interface requests can be valid. */
|
||||
if (!is_device_configured(busid)) {
|
||||
@@ -614,7 +648,39 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
|
||||
break;
|
||||
|
||||
case USB_REQUEST_GET_DESCRIPTOR:
|
||||
if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */
|
||||
if (type == 0x21) { /* HID_DESCRIPTOR_TYPE_HID */
|
||||
while (p[DESC_bLength] != 0U) {
|
||||
switch (p[DESC_bDescriptorType]) {
|
||||
case USB_DESCRIPTOR_TYPE_CONFIGURATION:
|
||||
current_desc_len = 0;
|
||||
desc_len = (p[CONF_DESC_wTotalLength]) |
|
||||
(p[CONF_DESC_wTotalLength + 1] << 8);
|
||||
|
||||
break;
|
||||
|
||||
case USB_DESCRIPTOR_TYPE_INTERFACE:
|
||||
cur_iface = p[INTF_DESC_bInterfaceNumber];
|
||||
break;
|
||||
case 0x21:
|
||||
if (cur_iface == intf_num) {
|
||||
*data = (uint8_t *)p;
|
||||
//memcpy(*data, p, p[DESC_bLength]);
|
||||
*len = p[DESC_bLength];
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* skip to next descriptor */
|
||||
p += p[DESC_bLength];
|
||||
current_desc_len += p[DESC_bLength];
|
||||
if (current_desc_len >= desc_len && desc_len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */
|
||||
for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) {
|
||||
struct usbd_interface *intf = g_usbd_core[busid].intf[i];
|
||||
|
||||
@@ -663,6 +729,7 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet
|
||||
{
|
||||
uint8_t ep = (uint8_t)setup->wIndex;
|
||||
bool ret = true;
|
||||
uint8_t stalled;
|
||||
|
||||
/* Only when device is configured, then endpoint requests can be valid. */
|
||||
if (!is_device_configured(busid)) {
|
||||
@@ -671,7 +738,12 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet
|
||||
|
||||
switch (setup->bRequest) {
|
||||
case USB_REQUEST_GET_STATUS:
|
||||
usbd_ep_is_stalled(busid, ep, &stalled);
|
||||
if (stalled) {
|
||||
(*data)[0] = 0x01;
|
||||
} else {
|
||||
(*data)[0] = 0x00;
|
||||
}
|
||||
(*data)[1] = 0x00;
|
||||
*len = 2;
|
||||
break;
|
||||
@@ -841,10 +913,12 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (g_usbd_core[busid].descriptors->webusb_url_descriptor) {
|
||||
}
|
||||
|
||||
if (g_usbd_core[busid].descriptors->webusb_url_descriptor) {
|
||||
if (setup->bRequest == g_usbd_core[busid].descriptors->webusb_url_descriptor->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
|
||||
case WEBUSB_REQUEST_GET_URL:
|
||||
desclen = g_usbd_core[busid].descriptors->webusb_url_descriptor->string_len;
|
||||
*data = (uint8_t *)g_usbd_core[busid].descriptors->webusb_url_descriptor->string;
|
||||
//memcpy(*data, g_usbd_core[busid].descriptors->webusb_url_descriptor->string, desclen);
|
||||
@@ -897,6 +971,22 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_usbd_core[busid].webusb_url_desc) {
|
||||
if (setup->bRequest == g_usbd_core[busid].webusb_url_desc->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case WEBUSB_REQUEST_GET_URL:
|
||||
desclen = g_usbd_core[busid].webusb_url_desc->string_len;
|
||||
*data = (uint8_t *)g_usbd_core[busid].webusb_url_desc->string;
|
||||
//memcpy(*data, g_usbd_core[busid].webusb_url_desc->string, desclen);
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) {
|
||||
struct usbd_interface *intf = g_usbd_core[busid].intf[i];
|
||||
@@ -985,17 +1075,22 @@ void usbd_event_disconnect_handler(uint8_t busid)
|
||||
|
||||
void usbd_event_resume_handler(uint8_t busid)
|
||||
{
|
||||
g_usbd_core[busid].is_suspend = false;
|
||||
g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESUME);
|
||||
}
|
||||
|
||||
void usbd_event_suspend_handler(uint8_t busid)
|
||||
{
|
||||
if (g_usbd_core[busid].device_address > 0) {
|
||||
g_usbd_core[busid].is_suspend = true;
|
||||
g_usbd_core[busid].event_handler(busid, USBD_EVENT_SUSPEND);
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_event_reset_handler(uint8_t busid)
|
||||
{
|
||||
usbd_set_address(busid, 0);
|
||||
g_usbd_core[busid].device_address = 0;
|
||||
g_usbd_core[busid].configuration = 0;
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
g_usbd_core[busid].speed = USB_SPEED_UNKNOWN;
|
||||
@@ -1091,6 +1186,8 @@ void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
|
||||
{
|
||||
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
|
||||
|
||||
(void)ep;
|
||||
|
||||
g_usbd_core[busid].ep0_data_buf += nbytes;
|
||||
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
|
||||
|
||||
@@ -1130,6 +1227,8 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
|
||||
{
|
||||
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
|
||||
|
||||
(void)ep;
|
||||
|
||||
if (nbytes > 0) {
|
||||
g_usbd_core[busid].ep0_data_buf += nbytes;
|
||||
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
|
||||
@@ -1213,6 +1312,11 @@ void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc)
|
||||
{
|
||||
g_usbd_core[busid].bos_desc = desc;
|
||||
}
|
||||
|
||||
void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc)
|
||||
{
|
||||
g_usbd_core[busid].webusb_url_desc = desc;
|
||||
}
|
||||
#endif
|
||||
|
||||
void usbd_add_interface(uint8_t busid, struct usbd_interface *intf)
|
||||
@@ -1256,7 +1360,30 @@ bool usb_device_is_configured(uint8_t busid)
|
||||
return g_usbd_core[busid].configuration;
|
||||
}
|
||||
|
||||
int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
|
||||
bool usb_device_is_suspend(uint8_t busid)
|
||||
{
|
||||
return g_usbd_core[busid].is_suspend;
|
||||
}
|
||||
|
||||
int usbd_send_remote_wakeup(uint8_t busid)
|
||||
{
|
||||
if (g_usbd_core[busid].remote_wakeup_support && g_usbd_core[busid].remote_wakeup_enabled && g_usbd_core[busid].is_suspend) {
|
||||
return usbd_set_remote_wakeup(busid);
|
||||
} else {
|
||||
if (!g_usbd_core[busid].remote_wakeup_support) {
|
||||
USB_LOG_ERR("device does not support remote wakeup\r\n");
|
||||
}
|
||||
if (!g_usbd_core[busid].remote_wakeup_enabled) {
|
||||
USB_LOG_ERR("device remote wakeup is not enabled\r\n");
|
||||
}
|
||||
if (!g_usbd_core[busid].is_suspend) {
|
||||
USB_LOG_ERR("device is not in suspend state\r\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
|
||||
{
|
||||
int ret;
|
||||
struct usbd_bus *bus;
|
||||
@@ -1279,9 +1406,9 @@ int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint
|
||||
|
||||
int usbd_deinitialize(uint8_t busid)
|
||||
{
|
||||
g_usbd_core[busid].intf_offset = 0;
|
||||
usb_dc_deinit(busid);
|
||||
usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
|
||||
g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT);
|
||||
usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
|
||||
usb_dc_deinit(busid);
|
||||
g_usbd_core[busid].intf_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user