mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-10-07 00:59:00 +08:00
update(cherryusb): update to v1.4.2
Signed-off-by: sakumisu <1203593632@qq.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
@@ -38,6 +38,8 @@ if RT_USING_CHERRYUSB
|
||||
bool "dwc2_gd"
|
||||
config RT_CHERRYUSB_DEVICE_DWC2_HC
|
||||
bool "dwc2_hc"
|
||||
config RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE
|
||||
bool "dwc2_kendryte"
|
||||
config RT_CHERRYUSB_DEVICE_DWC2_CUSTOM
|
||||
bool "dwc2_custom"
|
||||
config RT_CHERRYUSB_DEVICE_MUSB_ES
|
||||
@@ -182,6 +184,8 @@ if RT_USING_CHERRYUSB
|
||||
bool "dwc2_st"
|
||||
config RT_CHERRYUSB_HOST_DWC2_ESP
|
||||
bool "dwc2_esp"
|
||||
config RT_CHERRYUSB_HOST_DWC2_KENDRYTE
|
||||
bool "dwc2_kendryte"
|
||||
config RT_CHERRYUSB_HOST_DWC2_CUSTOM
|
||||
bool "dwc2_custom"
|
||||
config RT_CHERRYUSB_HOST_MUSB_ES
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
# CherryUSB
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">CherryUSB</h1>
|
||||
<p align="center">
|
||||
<a href="https://github.com/cherry-embedded/CherryUSB/releases"><img src="https://img.shields.io/github/release/cherry-embedded/CherryUSB.svg"><a>
|
||||
<a href="https://github.com/cherry-embedded/CherryUSB/blob/master/LICENSE"><img src="https://img.shields.io/github/license/cherry-embedded/CherryUSB.svg?style=flat-square"></a>
|
||||
<a href="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml"><img src="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml/badge.svg"> </a>
|
||||
<a href="https://discord.com/invite/wFfvrSAey8"><img src="https://img.shields.io/badge/Discord-blue?logo=discord&style=flat-square"> </a>
|
||||
</p>
|
||||
|
||||
[中文版](./README_zh.md)
|
||||
<p align="center">
|
||||
<a href="./README_zh.md">中文</a>
|
||||
|
|
||||
<a href="./README.md">English</a>
|
||||
</p>
|
||||
|
||||
CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP.
|
||||
|
||||
@@ -103,6 +113,7 @@ CherryUSB Host Stack has the following functions:
|
||||
- Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm)
|
||||
- Support Vendor class (serial, net, wifi)
|
||||
- Support USB modeswitch
|
||||
- Support Android Open Accessory
|
||||
- Support multi host with the same USB IP
|
||||
|
||||
The CherryUSB Host stack also provides the lsusb function, which allows you to view information about all mounted devices, including those on external hubs, with the help of a shell plugin.
|
||||
@@ -149,7 +160,7 @@ Only standard and commercial USB IP are listed.
|
||||
|
||||
| IP | device | host | Support status |
|
||||
|:----------------:|:----------:|:--------:|:--------------:|
|
||||
| OHCI(intel) | none | OHCI | × |
|
||||
| OHCI(intel) | none | OHCI | √ |
|
||||
| EHCI(intel) | none | EHCI | √ |
|
||||
| XHCI(intel) | none | XHCI | √ |
|
||||
| UHCI(intel) | none | UHCI | × |
|
||||
@@ -186,6 +197,7 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/canmv_k230)|v1.2.0 | 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 |
|
||||
@@ -212,4 +224,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8.
|
||||
|
||||
Thanks to the following companies for their support (in no particular order).
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
# CherryUSB
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">CherryUSB</h1>
|
||||
<p align="center">
|
||||
<a href="https://github.com/cherry-embedded/CherryUSB/releases"><img src="https://img.shields.io/github/release/cherry-embedded/CherryUSB.svg"><a>
|
||||
<a href="https://github.com/cherry-embedded/CherryUSB/blob/master/LICENSE"><img src="https://img.shields.io/github/license/cherry-embedded/CherryUSB.svg?style=flat-square"></a>
|
||||
<a href="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml"><img src="https://github.com/cherry-embedded/CherryUSB/actions/workflows/deploy-docs.yml/badge.svg"> </a>
|
||||
<a href="https://discord.com/invite/wFfvrSAey8"><img src="https://img.shields.io/badge/Discord-blue?logo=discord&style=flat-square"> </a>
|
||||
</p>
|
||||
|
||||
[English](./README.md)
|
||||
<p align="center">
|
||||
<a href="./README_zh.md">中文</a>
|
||||
|
|
||||
<a href="./README.md">English</a>
|
||||
</p>
|
||||
|
||||
CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的 USB 主从协议栈。
|
||||
|
||||
@@ -103,6 +113,7 @@ CherryUSB Host 协议栈当前实现以下功能:
|
||||
- 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能)
|
||||
- 支持 Vendor 类 class (serial, net, wifi)
|
||||
- 支持 USB modeswitch
|
||||
- 支持 Android Open Accessory
|
||||
- 支持相同 USB IP 的多主机
|
||||
|
||||
同时,CherryUSB Host 协议栈还提供了 lsusb 的功能,借助 shell 插件可以查看所有挂载设备的信息,包括外部 hub 上的设备的信息。
|
||||
@@ -149,7 +160,7 @@ x 受以下宏影响:
|
||||
|
||||
| IP | device | host | Support status |
|
||||
|:----------------:|:----------:|:--------:|:--------------:|
|
||||
| OHCI(intel) | none | OHCI | × |
|
||||
| OHCI(intel) | none | OHCI | √ |
|
||||
| EHCI(intel) | none | EHCI | √ |
|
||||
| XHCI(intel) | none | XHCI | √ |
|
||||
| UHCI(intel) | none | UHCI | × |
|
||||
@@ -187,6 +198,7 @@ CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和
|
||||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/canmv_k230)|v1.2.0 | 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 |
|
||||
@@ -214,4 +226,4 @@ CherryUSB 微信群:与我联系后邀请加入
|
||||
|
||||
感谢以下企业支持(顺序不分先后)。
|
||||
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" />
|
||||
<img src="docs/assets/bouffalolab.jpg" width="100" height="80"/> <img src="docs/assets/hpmicro.jpg" width="100" height="80" /> <img src="docs/assets/eastsoft.jpg" width="100" height="80" /> <img src="docs/assets/rtthread.jpg" width="100" height="80" /> <img src="docs/assets/sophgo.jpg" width="100" height="80" /> <img src="docs/assets/phytium.jpg" width="100" height="80" /> <img src="docs/assets/thead.jpg" width="100" height="80" /> <img src="docs/assets/nuvoton.jpg" width="100" height="80" /> <img src="docs/assets/artinchip.jpg" width="100" height="80" /> <img src="docs/assets/bekencorp.jpg" width="100" height="80" /> <img src="docs/assets/nxp.png" width="100" height="80" /> <img src="docs/assets/espressif.png" width="100" height="80" /> <img src="docs/assets/canaan.jpg" width="100" height="80" />
|
||||
|
||||
@@ -45,6 +45,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_HC']):
|
||||
src += Glob('port/dwc2/usb_dc_dwc2.c')
|
||||
src += Glob('port/dwc2/usb_glue_hc.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE']):
|
||||
src += Glob('port/dwc2/usb_dc_dwc2.c')
|
||||
src += Glob('port/dwc2/usb_glue_kendryte.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_CUSTOM']):
|
||||
src += Glob('port/dwc2/usb_dc_dwc2.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_ES']):
|
||||
@@ -177,6 +180,9 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_DWC2_ESP']):
|
||||
src += Glob('port/dwc2/usb_hc_dwc2.c')
|
||||
src += Glob('port/dwc2/usb_glue_esp.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_DWC2_KENDRYTE']):
|
||||
src += Glob('port/dwc2/usb_hc_dwc2.c')
|
||||
src += Glob('port/dwc2/usb_glue_kendryte.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_DWC2_CUSTOM']):
|
||||
src += Glob('port/dwc2/usb_hc_dwc2.c')
|
||||
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_STANDARD']):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 4
|
||||
PATCHLEVEL = 1
|
||||
PATCHLEVEL = 2
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
||||
@@ -40,6 +40,7 @@ ${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
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/aoa
|
||||
)
|
||||
|
||||
if(CONFIG_CHERRYUSB_DEVICE)
|
||||
@@ -218,6 +219,9 @@ if(CONFIG_CHERRYUSB_HOST)
|
||||
if(CONFIG_CHERRYUSB_HOST_BL616)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi/usbh_bl616.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST_AOA)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/aoa/usbh_aoa.c)
|
||||
endif()
|
||||
|
||||
if(DEFINED CONFIG_CHERRYUSB_HOST_HCD)
|
||||
if("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_bouffalo")
|
||||
@@ -294,4 +298,9 @@ endif()
|
||||
if(CONFIG_CHERRYMP)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool.c)
|
||||
list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp)
|
||||
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool_osal_freertos.c)
|
||||
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "rtthread")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool_osal_rtthread.c)
|
||||
endif()
|
||||
endif()
|
||||
@@ -208,6 +208,9 @@
|
||||
#define CONFIG_USBDEV_EP_NUM 8
|
||||
#endif
|
||||
|
||||
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. */
|
||||
// #define CONFIG_USB_HS
|
||||
|
||||
/* ---------------- FSDEV Configuration ---------------- */
|
||||
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USB_AOA_H
|
||||
#define USB_AOA_H
|
||||
|
||||
//AOA 1.0
|
||||
#define AOA_ACCESSORY_VENDOR_ID 0x18D1
|
||||
#define AOA_ACCESSORY_PRODUCT_ID 0x2D00
|
||||
#define AOA_ACCESSORY_ADB_PRODUCT_ID 0x2D01
|
||||
|
||||
//AOA 2.0
|
||||
#define AOA_AUDIO_PRODUCT_ID 0x2D02
|
||||
#define AOA_AUDIO_ADB_PRODUCT_ID 0x2D03
|
||||
#define AOA_ACCESSORY_AUDIO_PRODUCT_ID 0x2D04
|
||||
#define AOA_ACCESSORY_AUDIO_ADB_PRODUCT_ID 0x2D05
|
||||
|
||||
//AOA 1.0
|
||||
#define AOA_ACCESSORY_GET_PROTOCOL 51
|
||||
#define AOA_ACCESSORY_SEND_STRING 52
|
||||
#define AOA_ACCESSORY_START 53
|
||||
|
||||
//AOA 2.0
|
||||
#define AOA_ACCESSORY_REGISTER_HID 54
|
||||
#define AOA_ACCESSORY_UNREGISTER_HID 55
|
||||
#define AOA_ACCESSORY_SET_HID_REPORT_DESC 56
|
||||
#define AOA_ACCESSORY_SEND_HID_EVENT 57
|
||||
#define AOA_ACCESSORY_SET_AUDIO_MODE 58
|
||||
|
||||
#define AOA_ACCESSORY_STRING_MANUFACTURER 0
|
||||
#define AOA_ACCESSORY_STRING_MODEL 1
|
||||
#define AOA_ACCESSORY_STRING_DESCRIPTION 2
|
||||
#define AOA_ACCESSORY_STRING_VERSION 3
|
||||
#define AOA_ACCESSORY_STRING_URI 4
|
||||
#define AOA_ACCESSORY_STRING_SERIAL 5
|
||||
|
||||
struct aoa_string_info {
|
||||
char acc_manufacturer[64];
|
||||
char acc_model[64];
|
||||
char acc_description[64];
|
||||
char acc_version[64];
|
||||
char acc_uri[64];
|
||||
char acc_serial[64];
|
||||
};
|
||||
|
||||
#endif /* USB_AOA_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBH_AOA_H
|
||||
#define USBH_AOA_H
|
||||
|
||||
#include "usb_aoa.h"
|
||||
|
||||
struct usbh_aoa {
|
||||
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 minor;
|
||||
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int usbh_aoa_switch(struct usbh_hubport *hport, struct aoa_string_info *info);
|
||||
int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *report, uint32_t report_len);
|
||||
int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len);
|
||||
|
||||
void usbh_aoa_run(struct usbh_aoa *aoa_class);
|
||||
void usbh_aoa_stop(struct usbh_aoa *aoa_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBH_AOA_H */
|
||||
@@ -648,6 +648,18 @@ struct audio_cs_if_ac_feature_unit_descriptor {
|
||||
|
||||
#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + (ch + 1) * n)
|
||||
|
||||
struct audio_cs_if_ac_selector_unit_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bUnitID;
|
||||
uint8_t bNrInPins;
|
||||
uint8_t baSourceID[1];
|
||||
uint8_t iSelector;
|
||||
} __PACKED;
|
||||
|
||||
#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(n) (6 + n)
|
||||
|
||||
struct audio_cs_if_as_general_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
|
||||
@@ -136,27 +136,26 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
|
||||
memcpy(&volume, *data, *len);
|
||||
if (volume < 0x8000) {
|
||||
volume_db = volume / 256;
|
||||
} else if (volume > 0x8000) {
|
||||
volume_db = (0xffff - volume + 1) / -256;
|
||||
} else {
|
||||
volume_db = (volume - 0x10000) / 256;
|
||||
}
|
||||
volume_db += 128; /* 0 ~ 255 */
|
||||
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%04x\r\n", ep, ch, volume);
|
||||
USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
|
||||
usbd_audio_set_volume(busid, ep, ch, volume_db);
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
volume_db = usbd_audio_get_volume(busid, ep, ch);
|
||||
volume_db -= 128;
|
||||
if (volume_db >= 0) {
|
||||
volume = volume_db * 256;
|
||||
} else {
|
||||
volume = volume_db * 256 + 0xffff + 1;
|
||||
volume = volume_db * 256 + 0x10000;
|
||||
}
|
||||
USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
|
||||
memcpy(*data, &volume, 2);
|
||||
*len = 2;
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_MIN:
|
||||
(*data)[0] = 0x00; /* -2560/256 dB */
|
||||
(*data)[1] = 0xdb;
|
||||
(*data)[0] = 0x00; /* -100 dB */
|
||||
(*data)[1] = 0x9c;
|
||||
*len = 2;
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_MAX:
|
||||
@@ -165,7 +164,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
|
||||
*len = 2;
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_RES:
|
||||
(*data)[0] = 0x00; /* -256/256 dB */
|
||||
(*data)[0] = 0x00; /* 1 dB */
|
||||
(*data)[1] = 0x01;
|
||||
*len = 2;
|
||||
break;
|
||||
@@ -178,22 +177,31 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
|
||||
case AUDIO_REQUEST_CUR:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
volume_db = usbd_audio_get_volume(busid, ep, ch);
|
||||
volume = volume_db;
|
||||
if (volume_db >= 0) {
|
||||
volume = volume_db * 256;
|
||||
} else {
|
||||
volume = volume_db * 256 + 0x10000;
|
||||
}
|
||||
USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
|
||||
memcpy(*data, &volume, 2);
|
||||
*len = 2;
|
||||
} else {
|
||||
memcpy(&volume, *data, *len);
|
||||
volume_db = volume;
|
||||
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%02x\r\n", ep, ch, volume);
|
||||
if (volume < 0x8000) {
|
||||
volume_db = volume / 256;
|
||||
} else {
|
||||
volume_db = (volume - 0x10000) / 256;
|
||||
}
|
||||
USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
|
||||
usbd_audio_set_volume(busid, ep, ch, volume_db);
|
||||
}
|
||||
break;
|
||||
case AUDIO_REQUEST_RANGE:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
*((uint16_t *)(*data + 0)) = 1;
|
||||
*((uint16_t *)(*data + 2)) = 0;
|
||||
*((uint16_t *)(*data + 4)) = 100;
|
||||
*((uint16_t *)(*data + 6)) = 1;
|
||||
*((uint16_t *)(*data + 2)) = 0x9c00; /* MIN -100 dB */
|
||||
*((uint16_t *)(*data + 4)) = 0x0000; /* MAX 0 dB */
|
||||
*((uint16_t *)(*data + 6)) = 0x100; /* RES 1 dB */
|
||||
*len = 8;
|
||||
} else {
|
||||
}
|
||||
@@ -312,12 +320,12 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid,
|
||||
return intf;
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume)
|
||||
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db)
|
||||
{
|
||||
(void)busid;
|
||||
(void)ep;
|
||||
(void)ch;
|
||||
(void)volume;
|
||||
(void)volume_db;
|
||||
}
|
||||
|
||||
__WEAK int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch)
|
||||
|
||||
@@ -27,7 +27,7 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid, struct usbd_interface
|
||||
void usbd_audio_open(uint8_t busid, uint8_t intf);
|
||||
void usbd_audio_close(uint8_t busid, uint8_t intf);
|
||||
|
||||
void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume);
|
||||
void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db);
|
||||
int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch);
|
||||
void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute);
|
||||
bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,11 @@ struct usbh_audio_as_msg {
|
||||
uint8_t output_terminal_id;
|
||||
uint8_t ep_attr;
|
||||
uint8_t num_of_altsetting;
|
||||
uint16_t volume_min;
|
||||
uint16_t volume_max;
|
||||
uint16_t volume_res;
|
||||
uint16_t volume_cur;
|
||||
bool mute;
|
||||
struct audio_cs_if_as_general_descriptor as_general;
|
||||
struct audio_cs_if_as_format_type_descriptor as_format[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS];
|
||||
};
|
||||
@@ -43,7 +48,6 @@ struct usbh_audio {
|
||||
uint16_t bcdADC;
|
||||
uint8_t bInCollection;
|
||||
uint8_t stream_intf_num;
|
||||
struct usbh_audio_ac_msg ac_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS];
|
||||
struct usbh_audio_as_msg as_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS];
|
||||
|
||||
void *user_data;
|
||||
@@ -55,7 +59,7 @@ extern "C" {
|
||||
|
||||
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution);
|
||||
int usbh_audio_close(struct usbh_audio *audio_class, const char *name);
|
||||
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume);
|
||||
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db);
|
||||
int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute);
|
||||
|
||||
void usbh_audio_run(struct usbh_audio *audio_class);
|
||||
|
||||
@@ -524,7 +524,7 @@ struct cdc_ncm_ndp16 {
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x08, 0x00, /* wMaxPacketSize */ \
|
||||
0x10, /* bInterval */ \
|
||||
0x05, /* bInterval */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
|
||||
@@ -596,7 +596,7 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x10, 0x00, /* wMaxPacketSize */ \
|
||||
0x10, /* bInterval */ \
|
||||
0x05, /* bInterval */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
|
||||
|
||||
@@ -7,17 +7,21 @@
|
||||
#include "usbd_cdc_ecm.h"
|
||||
|
||||
#define CDC_ECM_OUT_EP_IDX 0
|
||||
#define CDC_ECM_IN_EP_IDX 1
|
||||
#define CDC_ECM_INT_EP_IDX 2
|
||||
#define CDC_ECM_IN_EP_IDX 1
|
||||
#define CDC_ECM_INT_EP_IDX 2
|
||||
|
||||
/* Ethernet Maximum Segment size, typically 1514 bytes */
|
||||
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1536U
|
||||
|
||||
/* Describe EndPoints configuration */
|
||||
static struct usbd_endpoint cdc_ecm_ep_data[3];
|
||||
|
||||
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
|
||||
#endif
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16];
|
||||
|
||||
volatile uint8_t *g_cdc_ecm_rx_data_buffer = NULL;
|
||||
volatile uint32_t g_cdc_ecm_rx_data_length = 0;
|
||||
volatile uint32_t g_cdc_ecm_tx_data_length = 0;
|
||||
|
||||
@@ -68,8 +72,10 @@ void usbd_cdc_ecm_send_notify(uint8_t notifycode, uint8_t value, uint32_t *speed
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytes2send) {
|
||||
usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send);
|
||||
if (usb_device_is_configured(0)) {
|
||||
if (bytes2send) {
|
||||
usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,11 +99,11 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
|
||||
* bit3 Broadcast
|
||||
* bit4 Multicast
|
||||
*/
|
||||
if (g_current_net_status == 0) {
|
||||
g_current_net_status = 1;
|
||||
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
g_connect_speed_table[0] = 100000000; /* 100 Mbps */
|
||||
g_connect_speed_table[1] = 100000000; /* 100 Mbps */
|
||||
usbd_cdc_ecm_set_connect(true, g_connect_speed_table);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled CDC ECM Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
@@ -117,10 +123,11 @@ void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
||||
g_current_net_status = 0;
|
||||
g_cdc_ecm_rx_data_length = 0;
|
||||
g_cdc_ecm_tx_data_length = 0;
|
||||
g_cdc_ecm_rx_data_buffer = NULL;
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
|
||||
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -132,14 +139,8 @@ 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(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(0, ep));
|
||||
}
|
||||
g_cdc_ecm_rx_data_length = nbytes;
|
||||
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_data_length);
|
||||
}
|
||||
|
||||
void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
@@ -150,6 +151,7 @@ void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(0, ep, NULL, 0);
|
||||
} else {
|
||||
usbd_cdc_ecm_data_send_done(g_cdc_ecm_tx_data_length);
|
||||
g_cdc_ecm_tx_data_length = 0;
|
||||
}
|
||||
}
|
||||
@@ -160,14 +162,20 @@ void cdc_ecm_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
(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);
|
||||
if (g_current_net_status == 2) {
|
||||
g_current_net_status = 3;
|
||||
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE, 0, g_connect_speed_table);
|
||||
} else {
|
||||
g_current_net_status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return -USB_ERR_NODEV;
|
||||
}
|
||||
|
||||
if (g_cdc_ecm_tx_data_length > 0) {
|
||||
return -USB_ERR_BUSY;
|
||||
}
|
||||
@@ -175,14 +183,17 @@ int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len)
|
||||
g_cdc_ecm_tx_data_length = len;
|
||||
|
||||
USB_LOG_DBG("txlen:%d\r\n", g_cdc_ecm_tx_data_length);
|
||||
return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, g_cdc_ecm_tx_data_length);
|
||||
return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, len);
|
||||
}
|
||||
|
||||
void usbd_cdc_ecm_start_read_next(void)
|
||||
int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return -USB_ERR_NODEV;
|
||||
}
|
||||
|
||||
g_cdc_ecm_rx_data_length = 0;
|
||||
g_cdc_ecm_rx_data_buffer = NULL;
|
||||
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, g_cdc_ecm_rx_buffer, usbd_get_ep_mps(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
|
||||
return usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, buf, len);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
@@ -190,19 +201,19 @@ struct pbuf *usbd_cdc_ecm_eth_rx(void)
|
||||
{
|
||||
struct pbuf *p;
|
||||
|
||||
if (g_cdc_ecm_rx_data_buffer == NULL) {
|
||||
if (g_cdc_ecm_rx_data_length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_data_length, PBUF_POOL);
|
||||
if (p == NULL) {
|
||||
usbd_cdc_ecm_start_read_next();
|
||||
usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
|
||||
return NULL;
|
||||
}
|
||||
usb_memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
|
||||
p->len = g_cdc_ecm_rx_data_length;
|
||||
|
||||
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_data_length);
|
||||
usbd_cdc_ecm_start_read_next();
|
||||
usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -250,13 +261,24 @@ struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const
|
||||
return intf;
|
||||
}
|
||||
|
||||
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2])
|
||||
void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2])
|
||||
{
|
||||
memcpy(g_connect_speed_table, speed, 8);
|
||||
if (connect) {
|
||||
g_current_net_status = 2;
|
||||
memcpy(g_connect_speed_table, speed, 8);
|
||||
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL);
|
||||
} else {
|
||||
g_current_net_status = 1;
|
||||
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_DISCONNECTED, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
__WEAK void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len)
|
||||
__WEAK void usbd_cdc_ecm_data_recv_done(uint32_t len)
|
||||
{
|
||||
(void)len;
|
||||
}
|
||||
|
||||
__WEAK void usbd_cdc_ecm_data_send_done(uint32_t len)
|
||||
{
|
||||
(void)buf;
|
||||
(void)len;
|
||||
}
|
||||
|
||||
@@ -12,21 +12,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Ethernet Maximum Segment size, typically 1514 bytes */
|
||||
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U
|
||||
|
||||
/* Init cdc ecm interface driver */
|
||||
struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const uint8_t int_ep, const uint8_t out_ep, const uint8_t in_ep);
|
||||
|
||||
/* Setup request command callback api */
|
||||
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2]);
|
||||
void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2]);
|
||||
|
||||
/* Api for eth only without any net stack */
|
||||
uint8_t *usbd_cdc_ecm_get_tx_buffer(void);
|
||||
void usbd_cdc_ecm_send_done(void);
|
||||
void usbd_cdc_ecm_data_recv_done(uint32_t len);
|
||||
void usbd_cdc_ecm_data_send_done(uint32_t len);
|
||||
int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len);
|
||||
void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len);
|
||||
void usbd_cdc_ecm_start_read_next(void);
|
||||
int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len);
|
||||
|
||||
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
#include "lwip/netif.h"
|
||||
|
||||
@@ -267,18 +267,18 @@ const struct usbh_class_driver cdc_data_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
|
||||
.class = USB_DEVICE_CLASS_CDC,
|
||||
.subclass = CDC_ABSTRACT_CONTROL_MODEL,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
|
||||
.bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = NULL,
|
||||
.class_driver = &cdc_acm_class_driver
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = USB_DEVICE_CLASS_CDC_DATA,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = NULL,
|
||||
.class_driver = &cdc_data_class_driver
|
||||
};
|
||||
|
||||
@@ -323,9 +323,9 @@ const struct usbh_class_driver cdc_ecm_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cdc_ecm_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_CDC,
|
||||
.subclass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL,
|
||||
.protocol = CDC_COMMON_PROTOCOL_NONE,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
|
||||
.bInterfaceSubClass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE,
|
||||
.id_table = NULL,
|
||||
.class_driver = &cdc_ecm_class_driver
|
||||
};
|
||||
@@ -403,9 +403,9 @@ const struct usbh_class_driver cdc_ncm_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cdc_ncm_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_CDC,
|
||||
.subclass = CDC_NETWORK_CONTROL_MODEL,
|
||||
.protocol = CDC_COMMON_PROTOCOL_NONE,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_CDC,
|
||||
.bInterfaceSubClass = CDC_NETWORK_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE,
|
||||
.id_table = NULL,
|
||||
.class_driver = &cdc_ncm_class_driver
|
||||
};
|
||||
|
||||
@@ -303,9 +303,9 @@ const struct usbh_class_driver hid_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info hid_custom_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = USB_DEVICE_CLASS_HID,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_HID,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = NULL,
|
||||
.class_driver = &hid_class_driver
|
||||
};
|
||||
|
||||
@@ -734,9 +734,9 @@ const struct usbh_class_driver hub_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info hub_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = USB_DEVICE_CLASS_HUB,
|
||||
.subclass = 0,
|
||||
.protocol = 0,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_HUB,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.id_table = NULL,
|
||||
.class_driver = &hub_class_driver
|
||||
};
|
||||
|
||||
@@ -443,9 +443,9 @@ const struct usbh_class_driver msc_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info msc_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_MASS_STORAGE,
|
||||
.subclass = MSC_SUBCLASS_SCSI,
|
||||
.protocol = MSC_PROTOCOL_BULK_ONLY,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_MASS_STORAGE,
|
||||
.bInterfaceSubClass = MSC_SUBCLASS_SCSI,
|
||||
.bInterfaceProtocol = MSC_PROTOCOL_BULK_ONLY,
|
||||
.id_table = NULL,
|
||||
.class_driver = &msc_class_driver
|
||||
};
|
||||
|
||||
@@ -89,9 +89,9 @@ static const struct usbh_class_driver xxx_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info xxx_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = 0,
|
||||
.subclass = 0,
|
||||
.protocol = 0,
|
||||
.bInterfaceClass = 0,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.id_table = NULL,
|
||||
.class_driver = &xxx_class_driver
|
||||
};
|
||||
|
||||
@@ -817,9 +817,9 @@ static const struct usbh_class_driver asix_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info asix_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = asix_id_table,
|
||||
.class_driver = &asix_class_driver
|
||||
};
|
||||
@@ -2272,9 +2272,9 @@ static const struct usbh_class_driver rtl8152_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info rtl8152_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = rtl_id_table,
|
||||
.class_driver = &rtl8152_class_driver
|
||||
};
|
||||
|
||||
@@ -370,9 +370,9 @@ const struct usbh_class_driver ch34x_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = ch34x_id_table,
|
||||
.class_driver = &ch34x_class_driver
|
||||
};
|
||||
@@ -319,9 +319,9 @@ const struct usbh_class_driver cp210x_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = cp210x_id_table,
|
||||
.class_driver = &cp210x_class_driver
|
||||
};
|
||||
@@ -392,9 +392,9 @@ const struct usbh_class_driver ftdi_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = ftdi_id_table,
|
||||
.class_driver = &ftdi_class_driver
|
||||
};
|
||||
@@ -440,9 +440,9 @@ const struct usbh_class_driver pl2303_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info pl2303_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = pl2303_id_table,
|
||||
.class_driver = &pl2303_class_driver
|
||||
};
|
||||
@@ -504,9 +504,9 @@ static const struct usbh_class_driver bl616_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info bl616_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = bl616_id_table,
|
||||
.class_driver = &bl616_class_driver
|
||||
};
|
||||
|
||||
@@ -220,9 +220,9 @@ static const uint16_t xbox_id_table[][2] = {
|
||||
|
||||
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,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_VEND_SPECIFIC,
|
||||
.bInterfaceSubClass = 0x5d,
|
||||
.bInterfaceProtocol = 0x01,
|
||||
.id_table = xbox_id_table,
|
||||
.class_driver = &xbox_class_driver
|
||||
};
|
||||
|
||||
@@ -18,10 +18,20 @@ struct usbd_video_priv {
|
||||
uint8_t power_mode;
|
||||
uint8_t error_code;
|
||||
struct video_entity_info info[3];
|
||||
uint8_t *ep_buffer;
|
||||
uint8_t *ep_buf0;
|
||||
uint8_t *ep_buf1;
|
||||
bool ep_buf0_ready;
|
||||
bool ep_buf1_ready;
|
||||
uint32_t ep_buf0_len;
|
||||
uint32_t ep_buf1_len;
|
||||
uint8_t ep_buf_idx;
|
||||
bool stream_finish;
|
||||
uint32_t max_packets;
|
||||
uint8_t *stream_buf;
|
||||
uint32_t stream_len;
|
||||
uint32_t stream_offset;
|
||||
uint8_t stream_frameid;
|
||||
uint32_t stream_headerlen;
|
||||
} g_usbd_video[CONFIG_USBDEV_MAX_BUS];
|
||||
|
||||
static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
@@ -741,6 +751,43 @@ static void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dw
|
||||
g_usbd_video[busid].commit.bPreferedVersion = 0;
|
||||
g_usbd_video[busid].commit.bMinVersion = 0;
|
||||
g_usbd_video[busid].commit.bMaxVersion = 0;
|
||||
|
||||
g_usbd_video[busid].stream_frameid = 0;
|
||||
g_usbd_video[busid].stream_headerlen = 2;
|
||||
}
|
||||
|
||||
static uint32_t usbd_video_prepare_ep_buf_data(uint8_t busid, uint32_t remain, uint8_t *ep_buf)
|
||||
{
|
||||
struct video_payload_header *header;
|
||||
uint32_t len;
|
||||
uint32_t offset;
|
||||
|
||||
len = MIN(remain, (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen) * g_usbd_video[busid].max_packets);
|
||||
offset = 0;
|
||||
while (len > 0) {
|
||||
header = (struct video_payload_header *)&ep_buf[offset];
|
||||
header->bHeaderLength = g_usbd_video[busid].stream_headerlen;
|
||||
header->headerInfoUnion.bmheaderInfo = 0;
|
||||
header->headerInfoUnion.headerInfoBits.endOfHeader = 1;
|
||||
header->headerInfoUnion.headerInfoBits.endOfFrame = 0;
|
||||
header->headerInfoUnion.headerInfoBits.frameIdentifier = g_usbd_video[busid].stream_frameid;
|
||||
|
||||
uint32_t len2 = MIN(len, g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen);
|
||||
|
||||
usb_memcpy(&ep_buf[offset + g_usbd_video[busid].stream_headerlen],
|
||||
&g_usbd_video[busid].stream_buf[g_usbd_video[busid].stream_offset],
|
||||
len2);
|
||||
|
||||
g_usbd_video[busid].stream_offset += len2;
|
||||
len -= len2;
|
||||
offset += (len2 + g_usbd_video[busid].stream_headerlen);
|
||||
|
||||
if (g_usbd_video[busid].stream_offset == g_usbd_video[busid].stream_len) {
|
||||
header->headerInfoUnion.headerInfoBits.endOfFrame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
struct usbd_interface *usbd_video_init_intf(uint8_t busid,
|
||||
@@ -770,74 +817,68 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid,
|
||||
|
||||
bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep)
|
||||
{
|
||||
struct video_payload_header *header = (struct video_payload_header *)g_usbd_video[busid].ep_buffer;
|
||||
uint32_t remain;
|
||||
uint32_t len;
|
||||
bool last_packet = false;
|
||||
|
||||
header->bHeaderLength = 2;
|
||||
header->headerInfoUnion.headerInfoBits.endOfHeader = 1;
|
||||
|
||||
remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset;
|
||||
|
||||
len = MIN(remain, g_usbd_video[busid].probe.dwMaxPayloadTransferSize - header->bHeaderLength);
|
||||
memcpy(&g_usbd_video[busid].ep_buffer[header->bHeaderLength],
|
||||
&g_usbd_video[busid].stream_buf[g_usbd_video[busid].stream_offset],
|
||||
len);
|
||||
|
||||
g_usbd_video[busid].stream_offset += len;
|
||||
|
||||
if (g_usbd_video[busid].stream_offset == g_usbd_video[busid].stream_len) {
|
||||
last_packet = true;
|
||||
header->headerInfoUnion.headerInfoBits.endOfFrame = 1;
|
||||
if (g_usbd_video[busid].ep_buf1_ready && (g_usbd_video[busid].ep_buf_idx == 0)) { /* callback: buf1 ready and buf0 was sent */
|
||||
g_usbd_video[busid].ep_buf0_ready = false;
|
||||
g_usbd_video[busid].ep_buf_idx = 1;
|
||||
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf1, g_usbd_video[busid].ep_buf1_len);
|
||||
} else if (g_usbd_video[busid].ep_buf0_ready && (g_usbd_video[busid].ep_buf_idx == 1)) { /* callback: buf0 ready and buf1 was sent */
|
||||
g_usbd_video[busid].ep_buf1_ready = false;
|
||||
g_usbd_video[busid].ep_buf_idx = 0;
|
||||
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len);
|
||||
} else {
|
||||
if (g_usbd_video[busid].stream_finish) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buffer, len + header->bHeaderLength);
|
||||
return last_packet;
|
||||
if (!g_usbd_video[busid].ep_buf0_ready) {
|
||||
remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset;
|
||||
if (remain == 0) {
|
||||
g_usbd_video[busid].stream_frameid ^= 1;
|
||||
g_usbd_video[busid].stream_finish = true;
|
||||
} else {
|
||||
g_usbd_video[busid].ep_buf0_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf0);
|
||||
g_usbd_video[busid].ep_buf0_ready = true;
|
||||
if (!g_usbd_video[busid].ep_buf1_ready) {
|
||||
g_usbd_video[busid].ep_buf_idx = 0;
|
||||
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_usbd_video[busid].ep_buf1_ready) {
|
||||
remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset;
|
||||
if (remain == 0) {
|
||||
g_usbd_video[busid].stream_frameid ^= 1;
|
||||
g_usbd_video[busid].stream_finish = true;
|
||||
} else {
|
||||
g_usbd_video[busid].ep_buf1_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf1);
|
||||
g_usbd_video[busid].ep_buf1_ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buffer, uint8_t *buf, uint32_t len)
|
||||
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len)
|
||||
{
|
||||
if (usb_device_is_configured(busid) == 0) {
|
||||
if ((usb_device_is_configured(busid) == 0) || (stream_len == 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_usbd_video[busid].ep_buffer = ep_buffer;
|
||||
g_usbd_video[busid].stream_buf = buf;
|
||||
g_usbd_video[busid].stream_len = len;
|
||||
g_usbd_video[busid].ep_buf0 = ep_buf0;
|
||||
g_usbd_video[busid].ep_buf1 = ep_buf1;
|
||||
g_usbd_video[busid].ep_buf0_ready = false;
|
||||
g_usbd_video[busid].ep_buf1_ready = false;
|
||||
g_usbd_video[busid].ep_buf_idx = 0;
|
||||
g_usbd_video[busid].stream_finish = false;
|
||||
g_usbd_video[busid].max_packets = ep_bufsize / g_usbd_video[busid].probe.dwMaxPayloadTransferSize;
|
||||
g_usbd_video[busid].stream_buf = stream_buf;
|
||||
g_usbd_video[busid].stream_len = stream_len;
|
||||
g_usbd_video[busid].stream_offset = 0;
|
||||
|
||||
struct video_payload_header *header = (struct video_payload_header *)g_usbd_video[busid].ep_buffer;
|
||||
|
||||
header->headerInfoUnion.headerInfoBits.frameIdentifier ^= 1;
|
||||
header->headerInfoUnion.headerInfoBits.endOfFrame = 0;
|
||||
|
||||
usbd_video_stream_split_transfer(busid, ep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len)
|
||||
{
|
||||
uint32_t packets;
|
||||
uint32_t last_packet_size;
|
||||
uint32_t picture_pos = 0;
|
||||
static uint8_t uvc_header[2] = { 0x02, 0x80 };
|
||||
|
||||
packets = (input_len + (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2)) / (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2);
|
||||
last_packet_size = input_len - ((packets - 1) * (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2));
|
||||
|
||||
for (size_t i = 0; i < packets; i++) {
|
||||
output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i] = uvc_header[0];
|
||||
output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i + 1] = uvc_header[1];
|
||||
if (i == (packets - 1)) {
|
||||
memcpy(&output[2 + g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i], &input[picture_pos], last_packet_size);
|
||||
output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i + 1] |= (1 << 1);
|
||||
} else {
|
||||
memcpy(&output[2 + g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i], &input[picture_pos], g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2);
|
||||
picture_pos += g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2;
|
||||
}
|
||||
}
|
||||
uvc_header[1] ^= 1;
|
||||
*out_len = (input_len + 2 * packets);
|
||||
return packets;
|
||||
}
|
||||
@@ -22,9 +22,7 @@ void usbd_video_open(uint8_t busid, uint8_t intf);
|
||||
void usbd_video_close(uint8_t busid, uint8_t intf);
|
||||
|
||||
bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep);
|
||||
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buffer, uint8_t *buf, uint32_t len);
|
||||
|
||||
uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len);
|
||||
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -531,18 +531,18 @@ const struct usbh_class_driver video_streaming_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info video_ctrl_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_VIDEO,
|
||||
.subclass = VIDEO_SC_VIDEOCONTROL,
|
||||
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_VIDEO,
|
||||
.bInterfaceSubClass = VIDEO_SC_VIDEOCONTROL,
|
||||
.bInterfaceProtocol = VIDEO_PC_PROTOCOL_UNDEFINED,
|
||||
.id_table = NULL,
|
||||
.class_driver = &video_ctrl_class_driver
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info video_streaming_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_VIDEO,
|
||||
.subclass = VIDEO_SC_VIDEOSTREAMING,
|
||||
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_VIDEO,
|
||||
.bInterfaceSubClass = VIDEO_SC_VIDEOSTREAMING,
|
||||
.bInterfaceProtocol = VIDEO_PC_PROTOCOL_UNDEFINED,
|
||||
.id_table = NULL,
|
||||
.class_driver = &video_streaming_class_driver
|
||||
};
|
||||
|
||||
@@ -478,7 +478,7 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
g_rndis_rx_data_buffer += hdr->DataOffset + sizeof(rndis_generic_msg_t);
|
||||
g_rndis_rx_data_length = hdr->DataLength;
|
||||
|
||||
usbd_rndis_data_recv_done();
|
||||
usbd_rndis_data_recv_done(g_rndis_rx_data_length);
|
||||
}
|
||||
|
||||
void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
@@ -489,6 +489,7 @@ void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(0, ep, NULL, 0);
|
||||
} else {
|
||||
usbd_rndis_data_send_done(g_rndis_tx_data_length);
|
||||
g_rndis_tx_data_length = 0;
|
||||
}
|
||||
}
|
||||
@@ -592,3 +593,13 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
||||
|
||||
return intf;
|
||||
}
|
||||
|
||||
__WEAK void usbd_rndis_data_recv_done(uint32_t len)
|
||||
{
|
||||
(void)len;
|
||||
}
|
||||
|
||||
__WEAK void usbd_rndis_data_send_done(uint32_t len)
|
||||
{
|
||||
(void)len;
|
||||
}
|
||||
@@ -18,7 +18,8 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
||||
const uint8_t in_ep,
|
||||
const uint8_t int_ep, uint8_t mac[6]);
|
||||
|
||||
void usbd_rndis_data_recv_done(void);
|
||||
void usbd_rndis_data_recv_done(uint32_t len);
|
||||
void usbd_rndis_data_send_done(uint32_t len);
|
||||
|
||||
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
struct pbuf *usbd_rndis_eth_rx(void);
|
||||
|
||||
@@ -393,18 +393,18 @@ static const uint16_t bluetooth_id_table[][2] = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_h4_nrf_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = 0xff,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.bInterfaceClass = 0xff,
|
||||
.bInterfaceSubClass = 0x00,
|
||||
.bInterfaceProtocol = 0x00,
|
||||
.id_table = bluetooth_id_table,
|
||||
.class_driver = &bluetooth_class_driver
|
||||
};
|
||||
#else
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_WIRELESS,
|
||||
.subclass = 0x01,
|
||||
.protocol = 0x01,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_WIRELESS,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01,
|
||||
.id_table = NULL,
|
||||
.class_driver = &bluetooth_class_driver
|
||||
};
|
||||
|
||||
@@ -600,9 +600,9 @@ static const struct usbh_class_driver rndis_class_driver = {
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_WIRELESS,
|
||||
.subclass = 0x01,
|
||||
.protocol = 0x03,
|
||||
.bInterfaceClass = USB_DEVICE_CLASS_WIRELESS,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x03,
|
||||
.id_table = NULL,
|
||||
.class_driver = &rndis_class_driver
|
||||
};
|
||||
|
||||
@@ -88,6 +88,8 @@ static inline void usb_hexdump(const void *ptr, uint32_t buflen)
|
||||
unsigned char *buf = (unsigned char *)ptr;
|
||||
uint32_t i, j;
|
||||
|
||||
(void)buf;
|
||||
|
||||
for (i = 0; i < buflen; i += 16) {
|
||||
CONFIG_USB_PRINTF("%08X:", i);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#undef CHERRYUSB_VERSION_STR
|
||||
#endif
|
||||
|
||||
#define CHERRYUSB_VERSION 0x010401
|
||||
#define CHERRYUSB_VERSION_STR "v1.4.1"
|
||||
#define CHERRYUSB_VERSION 0x010402
|
||||
#define CHERRYUSB_VERSION_STR "v1.4.2"
|
||||
|
||||
#endif
|
||||
@@ -64,6 +64,7 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
|
||||
bool test_req;
|
||||
#endif
|
||||
struct usbd_interface *intf[16];
|
||||
uint8_t intf_altsetting[16];
|
||||
uint8_t intf_offset;
|
||||
|
||||
struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM];
|
||||
@@ -98,6 +99,7 @@ static bool is_device_configured(uint8_t busid)
|
||||
* This function sets endpoint configuration according to one specified in USB
|
||||
* endpoint descriptor and then enables it for data transfers.
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] ep Endpoint descriptor byte array
|
||||
*
|
||||
* @return true if successfully configured and enabled
|
||||
@@ -125,6 +127,7 @@ static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descripto
|
||||
* This function cancels transfers that are associated with endpoint and
|
||||
* disabled endpoint itself.
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] ep Endpoint descriptor byte array
|
||||
*
|
||||
* @return true if successfully deconfigured and disabled
|
||||
@@ -144,6 +147,7 @@ static bool usbd_reset_endpoint(uint8_t busid, const struct usb_endpoint_descrip
|
||||
* This function parses the list of installed USB descriptors and attempts
|
||||
* to find the specified USB descriptor.
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] type_index Type and index of the descriptor
|
||||
* @param [out] data Descriptor data
|
||||
* @param [out] len Descriptor length
|
||||
@@ -370,6 +374,7 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da
|
||||
* index and alternate setting by parsing the installed USB descriptor list.
|
||||
* A configuration index of 0 unconfigures the device.
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] config_index Configuration index
|
||||
* @param [in] alt_setting Alternate setting number
|
||||
*
|
||||
@@ -439,6 +444,7 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t
|
||||
/**
|
||||
* @brief set USB interface
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] iface Interface index
|
||||
* @param [in] alt_setting Alternate setting number
|
||||
*
|
||||
@@ -494,7 +500,6 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
|
||||
goto find_end;
|
||||
} else if (cur_alt_setting == alt_setting) {
|
||||
ret = usbd_set_endpoint(busid, ep_desc);
|
||||
goto find_end;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
@@ -522,6 +527,7 @@ find_end:
|
||||
/**
|
||||
* @brief handle a standard device request
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] setup The setup packet
|
||||
* @param [in,out] data Data buffer
|
||||
* @param [in,out] len Pointer to data length
|
||||
@@ -617,6 +623,7 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet *
|
||||
/**
|
||||
* @brief handle a standard interface request
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] setup The setup packet
|
||||
* @param [in,out] data Data buffer
|
||||
* @param [in,out] len Pointer to data length
|
||||
@@ -703,11 +710,12 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
|
||||
ret = false;
|
||||
break;
|
||||
case USB_REQUEST_GET_INTERFACE:
|
||||
(*data)[0] = 0;
|
||||
(*data)[0] = g_usbd_core[busid].intf_altsetting[intf_num];
|
||||
*len = 1;
|
||||
break;
|
||||
|
||||
case USB_REQUEST_SET_INTERFACE:
|
||||
g_usbd_core[busid].intf_altsetting[intf_num] = LO_BYTE(setup->wValue);
|
||||
usbd_set_interface(busid, setup->wIndex, setup->wValue);
|
||||
*len = 0;
|
||||
break;
|
||||
@@ -723,6 +731,7 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
|
||||
/**
|
||||
* @brief handle a standard endpoint request
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] setup The setup packet
|
||||
* @param [in,out] data Data buffer
|
||||
* @param [in,out] len Pointer to data length
|
||||
@@ -787,6 +796,7 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet
|
||||
/**
|
||||
* @brief handle standard requests (list in chapter 9)
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] setup The setup packet
|
||||
* @param [in,out] data Data buffer
|
||||
* @param [in,out] len Pointer to data length
|
||||
@@ -830,8 +840,7 @@ static int usbd_standard_request_handler(uint8_t busid, struct usb_setup_packet
|
||||
/**
|
||||
* @brief handler for class requests
|
||||
*
|
||||
* If a custom request handler was installed, this handler is called first.
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] setup The setup packet
|
||||
* @param [in,out] data Data buffer
|
||||
* @param [in,out] len Pointer to data length
|
||||
@@ -863,8 +872,7 @@ static int usbd_class_request_handler(uint8_t busid, struct usb_setup_packet *se
|
||||
/**
|
||||
* @brief handler for vendor requests
|
||||
*
|
||||
* If a custom request handler was installed, this handler is called first.
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] setup The setup packet
|
||||
* @param [in,out] data Data buffer
|
||||
* @param [in,out] len Pointer to data length
|
||||
@@ -1006,6 +1014,7 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s
|
||||
/**
|
||||
* @brief handle setup request( standard/class/vendor/other)
|
||||
*
|
||||
* @param [in] busid busid
|
||||
* @param [in] setup The setup packet
|
||||
* @param [in,out] data Data buffer
|
||||
* @param [in,out] len Pointer to data length
|
||||
@@ -1167,7 +1176,7 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
|
||||
#ifdef CONFIG_USBDEV_EP0_INDATA_NO_COPY
|
||||
g_usbd_core[busid].ep0_data_buf = buf;
|
||||
#else
|
||||
memcpy(g_usbd_core[busid].ep0_data_buf, buf, g_usbd_core[busid].ep0_data_buf_residue);
|
||||
usb_memcpy(g_usbd_core[busid].ep0_data_buf, buf, g_usbd_core[busid].ep0_data_buf_residue);
|
||||
#endif
|
||||
} else {
|
||||
/* use memcpy(*data, xxx, len); has copied into ep0 buffer, we do nothing */
|
||||
|
||||
@@ -93,19 +93,22 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
|
||||
struct usbh_class_info *index = NULL;
|
||||
|
||||
for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) {
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->class == class)) {
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->bInterfaceClass == class)) {
|
||||
continue;
|
||||
}
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_SUBCLASS) && !(index->subclass == subclass)) {
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_SUBCLASS) && !(index->bInterfaceSubClass == subclass)) {
|
||||
continue;
|
||||
}
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->protocol == protocol)) {
|
||||
if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) {
|
||||
continue;
|
||||
}
|
||||
if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) {
|
||||
/* scan id table */
|
||||
uint32_t i;
|
||||
for (i = 0; index->id_table[i][0] && index->id_table[i][0] != vid && index->id_table[i][1] != pid; i++) {
|
||||
for (i = 0; index->id_table[i][0]; i++) {
|
||||
if (index->id_table[i][0] == vid && index->id_table[i][1] == pid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* do not match, continue next */
|
||||
if (!index->id_table[i][0]) {
|
||||
@@ -831,6 +834,37 @@ static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *
|
||||
}
|
||||
}
|
||||
|
||||
static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
struct usbh_hub *hub_next;
|
||||
|
||||
if (hub->index == hub_index) {
|
||||
hport = &hub->child[hub_port - 1];
|
||||
return hport;
|
||||
} else {
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hport = &hub->child[port];
|
||||
if (hport->connected) {
|
||||
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
|
||||
if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
|
||||
if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
|
||||
hub_next = hport->config.intf[itf].priv;
|
||||
|
||||
if (hub_next && hub_next->connected) {
|
||||
hport = usbh_list_all_hubport(hub_next, hub_index, hub_port);
|
||||
if (hport) {
|
||||
return hport;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void *usbh_find_class_instance(const char *devname)
|
||||
{
|
||||
usb_slist_t *bus_list;
|
||||
@@ -855,6 +889,23 @@ void *usbh_find_class_instance(const char *devname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port)
|
||||
{
|
||||
struct usbh_hub *hub;
|
||||
struct usbh_bus *bus;
|
||||
struct usbh_hubport *hport;
|
||||
size_t flags;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
bus = &g_usbhost_bus[busid];
|
||||
hub = &bus->hcd.roothub;
|
||||
|
||||
hport = usbh_list_all_hubport(hub, hub_index, hub_port);
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return hport;
|
||||
}
|
||||
|
||||
int lsusb(int argc, char **argv)
|
||||
{
|
||||
usb_slist_t *bus_list;
|
||||
|
||||
@@ -61,9 +61,9 @@ extern "C" {
|
||||
|
||||
struct usbh_class_info {
|
||||
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
|
||||
uint8_t class; /* Base device class code */
|
||||
uint8_t subclass; /* Sub-class, depends on base class. Eg. */
|
||||
uint8_t protocol; /* Protocol, depends on base class. Eg. */
|
||||
uint8_t bInterfaceClass; /* Base device class code */
|
||||
uint8_t bInterfaceSubClass; /* Sub-class, depends on base class. Eg. */
|
||||
uint8_t bInterfaceProtocol; /* Protocol, depends on base class. Eg. */
|
||||
const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */
|
||||
const struct usbh_class_driver *class_driver;
|
||||
};
|
||||
@@ -275,6 +275,7 @@ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsett
|
||||
int usbh_initialize(uint8_t busid, uintptr_t reg_base);
|
||||
int usbh_deinitialize(uint8_t busid);
|
||||
void *usbh_find_class_instance(const char *devname);
|
||||
struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port);
|
||||
|
||||
int lsusb(int argc, char **argv);
|
||||
|
||||
|
||||
@@ -332,14 +332,15 @@ void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
|
||||
*/
|
||||
void hid_mouse_test(uint8_t busid)
|
||||
{
|
||||
if(usb_device_is_configured(busid) == false) {
|
||||
return;
|
||||
}
|
||||
/*!< move mouse pointer */
|
||||
mouse_cfg.x += 10;
|
||||
mouse_cfg.y = 0;
|
||||
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
hid_state = HID_STATE_BUSY;
|
||||
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
|
||||
while (hid_state == HID_STATE_BUSY) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_ecm.h"
|
||||
|
||||
#ifndef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
#error "Please enable CONFIG_USBDEV_CDC_ECM_USING_LWIP for this demo"
|
||||
#endif
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
@@ -222,12 +226,12 @@ void cdc_ecm_lwip_init(void)
|
||||
while (!netif_is_up(netif)) {
|
||||
}
|
||||
|
||||
// while (dhserv_init(&dhcp_config)) {}
|
||||
while (dhserv_init(&dhcp_config)) {}
|
||||
|
||||
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
|
||||
while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
|
||||
}
|
||||
|
||||
void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len)
|
||||
void usbd_cdc_ecm_data_recv_done(uint32_t len)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_rndis.h"
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
#error "Please enable CONFIG_USBDEV_RNDIS_USING_LWIP for this demo"
|
||||
#endif
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
@@ -170,7 +174,7 @@ rt_err_t rt_usbd_rndis_eth_tx(rt_device_t dev, struct pbuf *p)
|
||||
return usbd_rndis_eth_tx(p);
|
||||
}
|
||||
|
||||
void usbd_rndis_data_recv_done(void)
|
||||
void usbd_rndis_data_recv_done(uint32_t len)
|
||||
{
|
||||
eth_device_ready(&rndis_dev);
|
||||
}
|
||||
@@ -258,12 +262,12 @@ void rndis_lwip_init(void)
|
||||
while (!netif_is_up(netif)) {
|
||||
}
|
||||
|
||||
// while (dhserv_init(&dhcp_config)) {}
|
||||
while (dhserv_init(&dhcp_config)) {}
|
||||
|
||||
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
|
||||
while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
|
||||
}
|
||||
|
||||
void usbd_rndis_data_recv_done(void)
|
||||
void usbd_rndis_data_recv_done(uint32_t len)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -236,12 +236,13 @@ void hid_keyboard_test(uint8_t busid)
|
||||
{
|
||||
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
memcpy(write_buffer, sendbuffer, 8);
|
||||
int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
|
||||
if (ret < 0) {
|
||||
if(usb_device_is_configured(busid) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(write_buffer, sendbuffer, 8);
|
||||
hid_state = HID_STATE_BUSY;
|
||||
usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
|
||||
while (hid_state == HID_STATE_BUSY) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,14 +304,15 @@ void draw_circle(uint8_t *buf)
|
||||
/* https://cps-check.com/cn/polling-rate-check */
|
||||
void hid_mouse_test(uint8_t busid)
|
||||
{
|
||||
if(usb_device_is_configured(busid) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
while (counter < 1000) {
|
||||
draw_circle((uint8_t *)&mouse_cfg);
|
||||
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
hid_state = HID_STATE_BUSY;
|
||||
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
|
||||
while (hid_state == HID_STATE_BUSY) {
|
||||
}
|
||||
|
||||
|
||||
@@ -307,6 +307,10 @@ void hid_mouse_test(uint8_t busid)
|
||||
static uint32_t count = 1000;
|
||||
int ret;
|
||||
|
||||
if(usb_device_is_configured(busid) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if (gpio_read_pin(GPIO_PIN) == 1) {
|
||||
// ret = usbd_send_remote_wakeup(busid);
|
||||
// if (ret < 0) {
|
||||
@@ -317,11 +321,8 @@ void hid_mouse_test(uint8_t busid)
|
||||
|
||||
while (count) {
|
||||
draw_circle((uint8_t *)&mouse_cfg);
|
||||
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
hid_state = HID_STATE_BUSY;
|
||||
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
|
||||
while (hid_state == HID_STATE_BUSY) {
|
||||
}
|
||||
|
||||
|
||||
@@ -254,38 +254,38 @@ delete:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_CDC_ACM
|
||||
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
#if TEST_USBH_CDC_ACM
|
||||
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_HID
|
||||
void usbh_hid_run(struct usbh_hid *hid_class)
|
||||
{
|
||||
#if TEST_USBH_HID
|
||||
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usbh_hid_stop(struct usbh_hid *hid_class)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_MSC
|
||||
void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
#if TEST_USBH_MSC
|
||||
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_AUDIO
|
||||
#error "commercial charge"
|
||||
@@ -294,3 +294,26 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
#if TEST_USBH_VIDEO
|
||||
#error "commercial charge"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include "usbh_aoa.h"
|
||||
|
||||
static struct aoa_string_info deviceinfo = {
|
||||
.acc_manufacturer = "CherryUSB",
|
||||
.acc_model = "CherryUSB",
|
||||
.acc_description = "Android Open Accessory CherryUSB",
|
||||
.acc_version = "1.0",
|
||||
.acc_uri = "http://developer.android.com/tools/adk/index.html",
|
||||
.acc_serial = "CherryUSB"
|
||||
};
|
||||
|
||||
int aoa_switch(int argc, char **argv)
|
||||
{
|
||||
struct usbh_hubport *hport = usbh_find_hubport(0, 1, 1);
|
||||
|
||||
usbh_aoa_switch(hport, &deviceinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHELL_CMD_EXPORT_ALIAS(aoa_switch, aoa_switch, aoa_switch);
|
||||
#endif
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "usbd_hid.h"
|
||||
#include "cherryusb_mjpeg.h"
|
||||
|
||||
#define MAX_PACKETS_IN_ONE_TRANSFER 1
|
||||
|
||||
#define VIDEO_IN_EP 0x81
|
||||
#define VIDEO_INT_EP 0x86
|
||||
|
||||
@@ -267,7 +269,7 @@ static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_read_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_write_buffer[AUDIO_IN_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[40 * 1024];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
|
||||
|
||||
volatile bool video_tx_flag = 0;
|
||||
volatile bool audio_tx_flag = 0;
|
||||
@@ -331,8 +333,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
|
||||
video_iso_tx_busy = false;
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
video_iso_tx_busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct usbd_endpoint video_in_ep = {
|
||||
@@ -458,56 +462,30 @@ void hid_keyboard_test(uint8_t busid)
|
||||
{
|
||||
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
memcpy(hid_write_buffer, sendbuffer, 8);
|
||||
int ret = usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8);
|
||||
if (ret < 0) {
|
||||
if(usb_device_is_configured(busid) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(hid_write_buffer, sendbuffer, 8);
|
||||
hid_state = HID_STATE_BUSY;
|
||||
usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8);
|
||||
while (hid_state == HID_STATE_BUSY) {
|
||||
}
|
||||
}
|
||||
|
||||
void video_test(uint8_t busid)
|
||||
{
|
||||
uint32_t out_len;
|
||||
uint32_t packets;
|
||||
memset(video_packet_buffer, 0, sizeof(video_packet_buffer));
|
||||
|
||||
(void)packets;
|
||||
memset(video_packet_buffer, 0, 40 * 1024);
|
||||
while (1) {
|
||||
if (video_tx_flag) {
|
||||
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), video_packet_buffer, &out_len);
|
||||
#if 1
|
||||
video_iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, video_packet_buffer, out_len);
|
||||
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[0][0], &video_packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
|
||||
while (video_iso_tx_busy) {
|
||||
if (video_tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* dwc2 must use this method */
|
||||
for (uint32_t i = 0; i < packets; i++) {
|
||||
if (i == (packets - 1)) {
|
||||
video_iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
|
||||
while (video_iso_tx_busy) {
|
||||
if (video_tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
video_iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
|
||||
while (video_iso_tx_busy) {
|
||||
if (video_tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "usbd_video.h"
|
||||
#include "cherryusb_h264.h"
|
||||
|
||||
#define MAX_PACKETS_IN_ONE_TRANSFER 1
|
||||
|
||||
#define VIDEO_IN_EP 0x81
|
||||
#define VIDEO_INT_EP 0x83
|
||||
|
||||
@@ -180,8 +182,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
|
||||
iso_tx_busy = false;
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct usbd_endpoint video_in_ep = {
|
||||
@@ -202,7 +206,7 @@ void video_init(uint8_t busid, uintptr_t reg_base)
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][40 * 1024];
|
||||
|
||||
void video_test(uint8_t busid)
|
||||
{
|
||||
@@ -210,40 +214,16 @@ void video_test(uint8_t busid)
|
||||
uint32_t packets;
|
||||
|
||||
(void)packets;
|
||||
memset(packet_buffer, 0, 40 * 1024);
|
||||
memset(packet_buffer, 0, sizeof(packet_buffer));
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264), packet_buffer, &out_len);
|
||||
#if 1
|
||||
iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
|
||||
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264));
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* dwc2 must use this method */
|
||||
for (uint32_t i = 0; i < packets; i++) {
|
||||
if (i == (packets - 1)) {
|
||||
iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "usbd_video.h"
|
||||
#include "cherryusb_mjpeg.h"
|
||||
|
||||
#define VIDEO_STREAM_SPLIT_ENABLE 1
|
||||
#define MAX_PACKETS_IN_ONE_TRANSFER 1
|
||||
|
||||
#define VIDEO_IN_EP 0x81
|
||||
#define VIDEO_INT_EP 0x83
|
||||
@@ -182,14 +182,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
#if VIDEO_STREAM_SPLIT_ENABLE
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
}
|
||||
#else
|
||||
iso_tx_busy = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct usbd_endpoint video_in_ep = {
|
||||
@@ -210,42 +206,21 @@ void video_init(uint8_t busid, uintptr_t reg_base)
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
#if VIDEO_STREAM_SPLIT_ENABLE
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[MAX_PAYLOAD_SIZE];
|
||||
#else
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
|
||||
#endif
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
|
||||
|
||||
void video_test(uint8_t busid)
|
||||
{
|
||||
uint32_t out_len;
|
||||
uint32_t packets;
|
||||
|
||||
(void)packets;
|
||||
(void)out_len;
|
||||
memset(packet_buffer, 0, sizeof(packet_buffer));
|
||||
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
#if VIDEO_STREAM_SPLIT_ENABLE
|
||||
iso_tx_busy = true;
|
||||
usbd_video_stream_start_write(busid, VIDEO_IN_EP, packet_buffer, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
|
||||
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), packet_buffer, &out_len);
|
||||
|
||||
iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "usbd_video.h"
|
||||
#include "cherryusb_yuyv.h"
|
||||
|
||||
#define MAX_PACKETS_IN_ONE_TRANSFER 1
|
||||
|
||||
#define VIDEO_IN_EP 0x81
|
||||
#define VIDEO_INT_EP 0x83
|
||||
|
||||
@@ -182,8 +184,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
|
||||
|
||||
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
|
||||
iso_tx_busy = false;
|
||||
if (usbd_video_stream_split_transfer(busid, ep)) {
|
||||
/* one frame has done */
|
||||
iso_tx_busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct usbd_endpoint video_in_ep = {
|
||||
@@ -204,48 +208,21 @@ void video_init(uint8_t busid, uintptr_t reg_base)
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
|
||||
|
||||
void video_test(uint8_t busid)
|
||||
{
|
||||
uint32_t out_len;
|
||||
uint32_t packets;
|
||||
memset(packet_buffer, 0, sizeof(packet_buffer));
|
||||
|
||||
(void)packets;
|
||||
memset(packet_buffer, 0, 40 * 1024);
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv), packet_buffer, &out_len);
|
||||
#if 1
|
||||
iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
|
||||
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv));
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* dwc2 must use this method */
|
||||
for (uint32_t i = 0; i < packets; i++) {
|
||||
if (i == (packets - 1)) {
|
||||
iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iso_tx_busy = true;
|
||||
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
|
||||
while (iso_tx_busy) {
|
||||
if (tx_flag == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,12 +371,13 @@ void hid_keyboard_test(uint8_t busid)
|
||||
{
|
||||
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
memcpy(write_buffer, sendbuffer, 8);
|
||||
int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
|
||||
if (ret < 0) {
|
||||
if(usb_device_is_configured(busid) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(write_buffer, sendbuffer, 8);
|
||||
hid_state = HID_STATE_BUSY;
|
||||
usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
|
||||
while (hid_state == HID_STATE_BUSY) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
version: "1.4.2"
|
||||
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
|
||||
tags:
|
||||
- usb
|
||||
- usb-device
|
||||
- usb-host
|
||||
- cdc_acm
|
||||
- cdc_ecm
|
||||
- cdc_ncm
|
||||
- hid
|
||||
- msc
|
||||
- rndis
|
||||
- uvc
|
||||
- uac
|
||||
- winusb
|
||||
url: https://github.com/cherry-embedded/CherryUSB
|
||||
repository: https://github.com/cherry-embedded/CherryUSB.git
|
||||
documentation: https://cherryusb.readthedocs.io/
|
||||
issues: https://github.com/cherry-embedded/CherryUSB/issues
|
||||
dependencies:
|
||||
idf: ">=5.0"
|
||||
targets:
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
- esp32p4
|
||||
@@ -6,10 +6,6 @@
|
||||
#error must enable RT_USING_TIMER_SOFT to support timer callback in thread
|
||||
#endif
|
||||
|
||||
#if IDLE_THREAD_STACK_SIZE < 2048
|
||||
#error "IDLE_THREAD_STACK_SIZE must be >= 2048"
|
||||
#endif
|
||||
|
||||
#if RT_TIMER_THREAD_STACK_SIZE < 2048
|
||||
#error "RT_TIMER_THREAD_STACK_SIZE must be >= 2048"
|
||||
#endif
|
||||
|
||||
@@ -101,6 +101,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_remote_wakeup(uint8_t busid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(uint8_t busid)
|
||||
{
|
||||
return USB_SPEED_FULL;
|
||||
|
||||
@@ -101,6 +101,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_remote_wakeup(uint8_t busid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(uint8_t busid)
|
||||
{
|
||||
return USB_SPEED_HIGH;
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2024 HPMicro
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usb_chipidea_reg.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "fsl_common.h"
|
||||
|
||||
|
||||
@@ -20,6 +20,11 @@ If you are using more than one port, all ip parameters must be the same(like fif
|
||||
|
||||
## GD32
|
||||
|
||||
CONFIG_USBDEV_EP_NUM 必须为4 或者 6,并删除 usb_dc_dwc2.c 中 while(1){}
|
||||
|
||||
当 CONFIG_USBDEV_EP_NUM 为4 时,fifo_num 不得大于 320 字
|
||||
当 CONFIG_USBDEV_EP_NUM 为6 时,fifo_num 不得大于 1280 字
|
||||
|
||||
- GD32F30X_CL
|
||||
- GD32F405、GD32F407
|
||||
- GD32F450
|
||||
|
||||
@@ -136,10 +136,12 @@ static inline int dwc2_reset(uint8_t busid)
|
||||
|
||||
do {
|
||||
if (++count > 200000U) {
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
} while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
|
||||
|
||||
USB_OTG_GLB->GRSTCTL &= ~USB_OTG_GRSTCTL_CSRST;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -478,7 +480,7 @@ static inline uint32_t dwc2_get_inep_intstatus(uint8_t busid, uint8_t epnum)
|
||||
|
||||
msk = USB_OTG_DEV->DIEPMSK;
|
||||
emp = USB_OTG_DEV->DIEPEMPMSK;
|
||||
msk |= ((emp >> (epnum & 0x07)) & 0x1U) << 7;
|
||||
msk |= ((emp >> (epnum & 0x0F)) & 0x1U) << 7;
|
||||
|
||||
tmpreg = USB_OTG_INEP((uint32_t)epnum)->DIEPINT;
|
||||
USB_OTG_INEP((uint32_t)epnum)->DIEPINT = tmpreg;
|
||||
@@ -790,7 +792,7 @@ int usbd_ep_close(uint8_t busid, const uint8_t ep)
|
||||
} while ((USB_OTG_OUTEP(ep_idx)->DOEPINT & USB_OTG_DOEPINT_EPDISD) != USB_OTG_DOEPINT_EPDISD);
|
||||
|
||||
/* Clear and unmask endpoint disabled interrupt */
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPINT |= USB_OTG_DOEPINT_EPDISD;
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPINT = USB_OTG_DOEPINT_EPDISD;
|
||||
}
|
||||
|
||||
USB_OTG_DEV->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep_idx & 0x07)) << 16));
|
||||
@@ -810,7 +812,7 @@ int usbd_ep_close(uint8_t busid, const uint8_t ep)
|
||||
} while ((USB_OTG_INEP(ep_idx)->DIEPINT & USB_OTG_DIEPINT_EPDISD) != USB_OTG_DIEPINT_EPDISD);
|
||||
|
||||
/* Clear and unmask endpoint disabled interrupt */
|
||||
USB_OTG_INEP(ep_idx)->DIEPINT |= USB_OTG_DIEPINT_EPDISD;
|
||||
USB_OTG_INEP(ep_idx)->DIEPINT = USB_OTG_DIEPINT_EPDISD;
|
||||
}
|
||||
|
||||
USB_OTG_DEV->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep_idx & 0x07)));
|
||||
@@ -1161,17 +1163,17 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
||||
}
|
||||
if (gint_status & USB_OTG_GINTSTS_ENUMDNE) {
|
||||
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_ENUMDNE;
|
||||
USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_ENUMDNE;
|
||||
dwc2_set_turnaroundtime(busid, SystemCoreClock, dwc2_get_devspeed(busid));
|
||||
|
||||
USB_OTG_DEV->DCTL |= USB_OTG_DCTL_CGINAK;
|
||||
}
|
||||
if (gint_status & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) {
|
||||
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_PXFR_INCOMPISOOUT;
|
||||
USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_PXFR_INCOMPISOOUT;
|
||||
}
|
||||
|
||||
if (gint_status & USB_OTG_GINTSTS_IISOIXFR) {
|
||||
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_IISOIXFR;
|
||||
USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_IISOIXFR;
|
||||
}
|
||||
|
||||
if (gint_status & USB_OTG_GINTSTS_SOF) {
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "stdint.h"
|
||||
#include "usb_dwc2_reg.h"
|
||||
|
||||
extern unsigned int system_core_clock;
|
||||
|
||||
uint32_t SystemCoreClock;
|
||||
/* you can find this config in function: usb_global_init, file:at32fxxx_usb.c, for example:
|
||||
*
|
||||
* usbx->gccfg_bit.pwrdown = TRUE;
|
||||
@@ -17,6 +20,7 @@
|
||||
|
||||
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
SystemCoreClock = system_core_clock;
|
||||
#ifdef CONFIG_USB_HS
|
||||
return ((1 << 16) | (1 << 21));
|
||||
#else
|
||||
@@ -35,6 +39,7 @@ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
|
||||
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
SystemCoreClock = system_core_clock;
|
||||
#ifdef CONFIG_USB_HS
|
||||
return ((1 << 16) | (1 << 21));
|
||||
#else
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include "stdint.h"
|
||||
#include "usb_dwc2_reg.h"
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM != 4 && CONFIG_USBDEV_EP_NUM != 6
|
||||
#error "gd32 only has 4 endpoints for pa11/pa12 and 6 endpoints for pb14/pb15"
|
||||
#endif
|
||||
|
||||
/* you can find this config in function:usb_core_init, file:drv_usb_core.c, for example:
|
||||
*
|
||||
* usb_regs->gr->GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN;
|
||||
|
||||
@@ -166,6 +166,8 @@ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
USB_OTG_GLB->GCCFG = (1 << 23);
|
||||
usb_hsphy_init(25000000U);
|
||||
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
|
||||
#elif __has_include("stm32h7rsxx.h")
|
||||
return (1 << 21);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@@ -192,6 +194,8 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
USB_OTG_GLB->GCCFG = (1 << 23);
|
||||
usb_hsphy_init(25000000U);
|
||||
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
|
||||
#elif __has_include("stm32h7rsxx.h")
|
||||
return (1 << 21);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -215,6 +215,12 @@ static inline void dwc2_chan_char_init(struct usbh_bus *bus, uint8_t ch_num, uin
|
||||
regval |= USB_OTG_HCCHAR_EPDIR;
|
||||
}
|
||||
|
||||
if ((usbh_get_port_speed(bus, 0) == USB_SPEED_HIGH) && (speed != USB_SPEED_HIGH)) {
|
||||
USB_LOG_ERR("Do not support LS/FS device on HS hub\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/* LS device plugged to HUB */
|
||||
if ((speed == USB_SPEED_LOW) && (usbh_get_port_speed(bus, 0) != USB_SPEED_LOW)) {
|
||||
regval |= USB_OTG_HCCHAR_LSDEV;
|
||||
@@ -1131,4 +1137,4 @@ void USBH_IRQHandler(uint8_t busid)
|
||||
USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_HCINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,19 @@
|
||||
#include <hal_syscfg.h>
|
||||
#include "usbh_core.h"
|
||||
#include "usb_hc_ehci.h"
|
||||
#include "usb_hc_ohci.h"
|
||||
|
||||
#if !defined(CONFIG_USB_EHCI_CONFIGFLAG)
|
||||
#error "aic ehci must define CONFIG_USB_EHCI_CONFIGFLAG"
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_USB_EHCI_WITH_OHCI)
|
||||
#error "aic must define CONFIG_USB_EHCI_WITH_OHCI for ls/fs device"
|
||||
#endif
|
||||
|
||||
#if CONFIG_USB_OHCI_HCOR_OFFSET != 0x400
|
||||
#error "aic CONFIG_USB_OHCI_HCOR_OFFSET must be 0x400"
|
||||
#endif
|
||||
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
|
||||
@@ -117,21 +130,12 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
aicos_request_irq(config[i].irq_num + 1, (irq_handler_t)aic_ohci_isr,
|
||||
0, "usb_host_ohci", bus);
|
||||
aicos_irq_enable(config[i].irq_num);
|
||||
aicos_irq_enable(config[i].irq_num + 1);
|
||||
}
|
||||
|
||||
uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
|
||||
{
|
||||
/* Defined by individual manufacturers */
|
||||
uint32_t regval;
|
||||
|
||||
regval = EHCI_HCOR->portsc[port-1];
|
||||
if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE)
|
||||
return USB_SPEED_LOW;
|
||||
|
||||
if (regval & EHCI_PORTSC_PE)
|
||||
return USB_SPEED_HIGH;
|
||||
else
|
||||
return USB_SPEED_FULL;
|
||||
return USB_SPEED_HIGH;
|
||||
}
|
||||
|
||||
void usb_ehci_dcache_clean(uintptr_t addr, uint32_t len)
|
||||
@@ -149,7 +153,7 @@ void usb_ehci_dcache_clean_invalidate(uintptr_t addr, uint32_t len)
|
||||
aicos_dcache_clean_invalid_range((size_t *)addr, len);
|
||||
}
|
||||
|
||||
int usbh_init(void)
|
||||
int __usbh_init(void)
|
||||
{
|
||||
#if defined(AIC_USING_USB0_HOST) || defined(AIC_USING_USB1_HOST)
|
||||
int bus_id = 0;
|
||||
@@ -171,11 +175,5 @@ int usbh_init(void)
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
INIT_ENV_EXPORT(usbh_init);
|
||||
|
||||
#if defined (RT_USING_FINSH)
|
||||
#include <finsh.h>
|
||||
|
||||
MSH_CMD_EXPORT_ALIAS(lsusb, lsusb, list usb device);
|
||||
#endif
|
||||
INIT_ENV_EXPORT(__usbh_init);
|
||||
#endif
|
||||
@@ -35,6 +35,11 @@ static void usb_host_mode_init(USB_Type *ptr)
|
||||
/* Set parallel transceiver width */
|
||||
ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
|
||||
|
||||
#ifdef CONFIG_USB_HOST_FORCE_FULL_SPEED
|
||||
/* Set usb forced to full speed mode */
|
||||
ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK;
|
||||
#endif
|
||||
|
||||
/* Not use interrupt threshold. */
|
||||
ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
|
||||
}
|
||||
@@ -53,7 +58,7 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
#endif
|
||||
}
|
||||
|
||||
usb_phy_init((USB_Type *)(bus->hcd.reg_base));
|
||||
usb_phy_init((USB_Type *)(bus->hcd.reg_base), true);
|
||||
intc_m_enable_irq(_hcd_irqnum[bus->hcd.hcd_id]);
|
||||
}
|
||||
|
||||
@@ -86,18 +91,18 @@ uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
|
||||
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbh0)
|
||||
void isr_usbh0(void)
|
||||
{
|
||||
USBH_IRQHandler(_hcd_busid[0]);
|
||||
}
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbh0)
|
||||
|
||||
#ifdef HPM_USB1_BASE
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1)
|
||||
void isr_usbh1(void)
|
||||
{
|
||||
USBH_IRQHandler(_hcd_busid[1]);
|
||||
}
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbh_core.h"
|
||||
#include "fsl_common.h"
|
||||
#include "usb_chipidea_reg.h"
|
||||
|
||||
@@ -952,6 +952,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u
|
||||
|
||||
while (!(EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_OWNER)) {
|
||||
}
|
||||
USB_LOG_INFO("Switch port %u to OHCI\r\n", port);
|
||||
return ohci_roothub_control(bus, setup, buf);
|
||||
}
|
||||
#endif
|
||||
@@ -1063,7 +1064,9 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u
|
||||
|
||||
while (!(EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_OWNER)) {
|
||||
}
|
||||
return ohci_roothub_control(bus, setup, buf);
|
||||
|
||||
USB_LOG_INFO("Switch port %u to OHCI\r\n", port);
|
||||
return -USB_ERR_NOTSUPP;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -154,7 +154,8 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
|
||||
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
|
||||
wEpRegVal = USB_EP_ISOCHRONOUS;
|
||||
break;
|
||||
USB_LOG_ERR("Do not support iso in fsdev\r\n");
|
||||
return -1;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -128,8 +128,6 @@ int usbd_set_remote_wakeup(uint8_t busid)
|
||||
}
|
||||
|
||||
usb_force_port_resume(ptr);
|
||||
while (ptr->PORTSC1 & USB_PORTSC1_FPR_MASK) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -362,18 +360,18 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
|
||||
#if !defined(USBD_USE_CUSTOM_ISR) || !USBD_USE_CUSTOM_ISR
|
||||
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbd0)
|
||||
void isr_usbd0(void)
|
||||
{
|
||||
USBD_IRQHandler(_dcd_busid[0]);
|
||||
}
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbd0)
|
||||
|
||||
#ifdef HPM_USB1_BASE
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbd1)
|
||||
void isr_usbd1(void)
|
||||
{
|
||||
USBD_IRQHandler(_dcd_busid[1]);
|
||||
}
|
||||
SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbd1)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
# Note
|
||||
|
||||
This OHCI is a companion controller of EHCI.
|
||||
This OHCI is a companion controller of EHCI. But you can use OHCI only without CONFIG_USB_EHCI_WITH_OHCI definition.
|
||||
|
||||
**And you need to pay for using OHCI driver**.
|
||||
|
||||
## Support Chip List
|
||||
|
||||
### AllwinnerTech
|
||||
|
||||
- F133
|
||||
- F133(EHCI + OHCI)
|
||||
|
||||
### Nuvoton
|
||||
|
||||
- Nuvoton all series
|
||||
- Nuvoton all series(EHCI + OHCI, OHCI only)
|
||||
|
||||
### Artinchip
|
||||
|
||||
- d13x, d21x
|
||||
- d13x, d21x(EHCI + OHCI)
|
||||
|
||||
### NXP
|
||||
|
||||
- LPC4X/LPC5X(OHCI only)
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "fsl_device_registers.h"
|
||||
#include "fsl_power.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
#if defined(CONFIG_USB_EHCI_WITH_OHCI)
|
||||
#error "lpc does not have ehci"
|
||||
#endif
|
||||
|
||||
void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
#if ((defined FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT))
|
||||
SYSMPU_Enable(SYSMPU, 0);
|
||||
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
|
||||
|
||||
NVIC_ClearPendingIRQ(USB0_IRQn);
|
||||
NVIC_ClearPendingIRQ(USB0_NEEDCLK_IRQn);
|
||||
|
||||
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB0 Phy */
|
||||
|
||||
RESET_PeripheralReset(kUSB0D_RST_SHIFT_RSTn);
|
||||
RESET_PeripheralReset(kUSB0HSL_RST_SHIFT_RSTn);
|
||||
RESET_PeripheralReset(kUSB0HMR_RST_SHIFT_RSTn);
|
||||
|
||||
CLOCK_EnableUsbfs0HostClock(kCLOCK_UsbfsSrcPll1, 48000000U);
|
||||
|
||||
NVIC_SetPriority(USB0_IRQn, 3);
|
||||
EnableIRQ(USB0_IRQn);
|
||||
}
|
||||
|
||||
|
||||
void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
DisableIRQ(USB0_IRQn);
|
||||
}
|
||||
|
||||
void USB0_IRQHandler(void)
|
||||
{
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
USBH_IRQHandler(0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,38 @@
|
||||
|
||||
#define OHCI_HCOR ((struct ohci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_OHCI_HCOR_OFFSET))
|
||||
|
||||
#define OHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x0F)
|
||||
#define OHCI_ADDR2ED(x) ((struct ohci_ed_hw *)(uintptr_t)((uint32_t)(x) & ~0x0F))
|
||||
#define OHCI_ADDR2TD(x) ((struct ohci_td_hw *)(uintptr_t)((uint32_t)(x) & ~0x0F))
|
||||
|
||||
#ifndef CONFIG_USB_OHCI_ED_NUM
|
||||
#define CONFIG_USB_OHCI_ED_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#endif
|
||||
#ifndef CONFIG_USB_OHCI_TD_NUM
|
||||
#define CONFIG_USB_OHCI_TD_NUM 3
|
||||
#endif
|
||||
|
||||
struct ohci_ed_hw;
|
||||
struct ohci_td_hw {
|
||||
struct ohci_gtd hw;
|
||||
struct usbh_urb *urb;
|
||||
uint32_t buf_start;
|
||||
uint32_t length;
|
||||
} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
|
||||
|
||||
struct ohci_ed_hw {
|
||||
struct ohci_ed hw;
|
||||
struct ohci_td_hw td_pool[CONFIG_USB_OHCI_TD_NUM];
|
||||
uint32_t td_count;
|
||||
uint8_t ed_type;
|
||||
usb_osal_sem_t waitsem;
|
||||
} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
|
||||
|
||||
struct ohci_hcd {
|
||||
bool ohci_ed_used[CONFIG_USB_OHCI_ED_NUM];
|
||||
uint8_t n_ports;
|
||||
};
|
||||
|
||||
int ohci_init(struct usbh_bus *bus);
|
||||
int ohci_deinit(struct usbh_bus *bus);
|
||||
uint16_t ohci_get_frame_number(struct usbh_bus *bus);
|
||||
|
||||
@@ -95,10 +95,10 @@
|
||||
/* HcControl: HC control (7.1.2) */
|
||||
|
||||
#define OHCI_CTRL_CBSR (3 << 0) /* Bit 0: Control/bulk service ratio */
|
||||
#define OHCI_CTRL_PLE (1 << 2) /* Bit 1: Periodic list enable */
|
||||
#define OHCI_CTRL_IE (1 << 3) /* Bit 2: Isochronous enable */
|
||||
#define OHCI_CTRL_CLE (1 << 4) /* Bit 3: Control list enable */
|
||||
#define OHCI_CTRL_BLE (1 << 5) /* Bit 4: Bulk list enable */
|
||||
#define OHCI_CTRL_PLE (1 << 2) /* Bit 2: Periodic list enable */
|
||||
#define OHCI_CTRL_IE (1 << 3) /* Bit 3: Isochronous enable */
|
||||
#define OHCI_CTRL_CLE (1 << 4) /* Bit 4: Control list enable */
|
||||
#define OHCI_CTRL_BLE (1 << 5) /* Bit 5: Bulk list enable */
|
||||
#define OHCI_CTRL_HCFS_SHIFT (6) /* Bits 6-7: Host controller functional state */
|
||||
#define OHCI_CTRL_HCFS_MASK (3 << OHCI_CTRL_HCFS_SHIFT)
|
||||
# define OHCI_CTRL_HCFS_RESET (0 << OHCI_CTRL_HCFS_SHIFT)
|
||||
@@ -261,9 +261,9 @@
|
||||
# define ED_CONTROL_D_IN (2 << ED_CONTROL_D_SHIFT) /* IN */
|
||||
# define ED_CONTROL_D_TD2 (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */
|
||||
|
||||
#define ED_CONTROL_S (1 << 13) /* Bit 13: Speed (low) */
|
||||
#define ED_CONTROL_K (1 << 14) /* Bit 14: Skip */
|
||||
#define ED_CONTROL_F (1 << 15) /* Bit 15: Format (isochronous) */
|
||||
#define ED_CONTROL_SPPED_LOW (1 << 13) /* Bit 13: Speed (low) */
|
||||
#define ED_CONTROL_SKIP (1 << 14) /* Bit 14: Skip */
|
||||
#define ED_CONTROL_FORMAT_ISO (1 << 15) /* Bit 15: Format (isochronous) */
|
||||
#define ED_CONTROL_MPS_SHIFT (16) /* Bits 16-26: Maximum packet size */
|
||||
#define ED_CONTROL_MPS_MASK (0x7ff << ED_CONTROL_MPS_SHIFT)
|
||||
|
||||
@@ -406,7 +406,7 @@ struct ohci_hcor
|
||||
|
||||
/* Endpoint Descriptor Offsets (4.2.1) */
|
||||
|
||||
struct ohci_ed_s
|
||||
struct ohci_ed
|
||||
{
|
||||
volatile uint32_t ctrl; /* ED status/control bits */
|
||||
volatile uint32_t tailp; /* TD Queue Tail Pointer (TailP) */
|
||||
@@ -416,7 +416,7 @@ struct ohci_ed_s
|
||||
|
||||
/* General Transfer Descriptor (4.3.1) */
|
||||
|
||||
struct ohci_gtd_s
|
||||
struct ohci_gtd
|
||||
{
|
||||
volatile uint32_t ctrl; /* TD status/control bits */
|
||||
volatile uint32_t cbp; /* Current Buffer Pointer (CBP) */
|
||||
@@ -426,7 +426,7 @@ struct ohci_gtd_s
|
||||
|
||||
/* Isochronous Transfer Descriptor Offsets (4.3.2) */
|
||||
|
||||
struct ohci_itd_s
|
||||
struct ohci_itd
|
||||
{
|
||||
volatile uint32_t ctrl; /* TD status/control bits */
|
||||
volatile uint32_t bp0; /* Buffer page 0 (BP0 */
|
||||
@@ -437,7 +437,7 @@ struct ohci_itd_s
|
||||
|
||||
/* Host Controller Communications Area Format (4.4.1) */
|
||||
|
||||
struct ohci_hcca_s
|
||||
struct ohci_hcca
|
||||
{
|
||||
/* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user