diff --git a/components/drivers/usb/cherryusb/CherryUSB.svg b/components/drivers/usb/cherryusb/CherryUSB.svg index c1ed4782122..91de329f8d8 100644 --- a/components/drivers/usb/cherryusb/CherryUSB.svg +++ b/components/drivers/usb/cherryusb/CherryUSB.svg @@ -1,3 +1,3 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/Kconfig b/components/drivers/usb/cherryusb/Kconfig index 6f6789d0029..67c6ad543a1 100644 --- a/components/drivers/usb/cherryusb/Kconfig +++ b/components/drivers/usb/cherryusb/Kconfig @@ -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 diff --git a/components/drivers/usb/cherryusb/README.md b/components/drivers/usb/cherryusb/README.md index bbea73f2f46..e56946a7722 100644 --- a/components/drivers/usb/cherryusb/README.md +++ b/components/drivers/usb/cherryusb/README.md @@ -1,6 +1,16 @@ -# CherryUSB - -[中文版](./README_zh.md) +
+ + + + +
+ + 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). - + diff --git a/components/drivers/usb/cherryusb/README_zh.md b/components/drivers/usb/cherryusb/README_zh.md index 1e8b54398ee..50d2b6f672b 100644 --- a/components/drivers/usb/cherryusb/README_zh.md +++ b/components/drivers/usb/cherryusb/README_zh.md @@ -1,6 +1,16 @@ -# CherryUSB - -[English](./README.md) ++ + + + +
+ + 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 微信群:与我联系后邀请加入 感谢以下企业支持(顺序不分先后)。 - + diff --git a/components/drivers/usb/cherryusb/SConscript b/components/drivers/usb/cherryusb/SConscript index e8e69705b00..58d0aa01c2c 100644 --- a/components/drivers/usb/cherryusb/SConscript +++ b/components/drivers/usb/cherryusb/SConscript @@ -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']): diff --git a/components/drivers/usb/cherryusb/VERSION b/components/drivers/usb/cherryusb/VERSION index 82894229cf1..340d4aefcd5 100644 --- a/components/drivers/usb/cherryusb/VERSION +++ b/components/drivers/usb/cherryusb/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 1 VERSION_MINOR = 4 -PATCHLEVEL = 1 +PATCHLEVEL = 2 VERSION_TWEAK = 0 EXTRAVERSION = 0 diff --git a/components/drivers/usb/cherryusb/cherryusb.cmake b/components/drivers/usb/cherryusb/cherryusb.cmake index 81e4f8262c0..271717008ca 100644 --- a/components/drivers/usb/cherryusb/cherryusb.cmake +++ b/components/drivers/usb/cherryusb/cherryusb.cmake @@ -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() \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/cherryusb_config_template.h b/components/drivers/usb/cherryusb/cherryusb_config_template.h index 30869b437a1..e7d5230f1c5 100644 --- a/components/drivers/usb/cherryusb/cherryusb_config_template.h +++ b/components/drivers/usb/cherryusb/cherryusb_config_template.h @@ -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 diff --git a/components/drivers/usb/cherryusb/class/aoa/usb_aoa.h b/components/drivers/usb/cherryusb/class/aoa/usb_aoa.h new file mode 100644 index 00000000000..6b6c715c2a6 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/aoa/usb_aoa.h @@ -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 */ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c b/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c new file mode 100644 index 00000000000..20cef52cf31 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_aoa.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_aoa" +#include "usb_log.h" + +#define DEV_FORMAT "/dev/aoa" + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_aoa_buffer[128]; + +static struct usbh_aoa g_aoa_class; + +int usbh_aoa_switch(struct usbh_hubport *hport, struct aoa_string_info *info) +{ + struct usb_setup_packet *setup; + int ret; + + setup = hport->setup; + + if (setup == NULL) { + return -USB_ERR_INVAL; + } + + USB_LOG_INFO("Try switch into aoa mode\r\n"); + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_GET_PROTOCOL; + setup->wValue = 0; + setup->wIndex = 0; + setup->wLength = 2; + + ret = usbh_control_transfer(hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + + USB_LOG_INFO("AOA version: v%d.%d\r\n", g_aoa_buffer[0], g_aoa_buffer[1]); + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SEND_STRING; + setup->wValue = 0; + setup->wIndex = AOA_ACCESSORY_STRING_MANUFACTURER; + setup->wLength = strlen(info->acc_manufacturer) + 1; + + memcpy(g_aoa_buffer, info->acc_manufacturer, strlen(info->acc_manufacturer)); + ret = usbh_control_transfer(hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SEND_STRING; + setup->wValue = 0; + setup->wIndex = AOA_ACCESSORY_STRING_MODEL; + setup->wLength = strlen(info->acc_model) + 1; + + memcpy(g_aoa_buffer, info->acc_model, strlen(info->acc_model)); + ret = usbh_control_transfer(hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SEND_STRING; + setup->wValue = 0; + setup->wIndex = AOA_ACCESSORY_STRING_DESCRIPTION; + setup->wLength = strlen(info->acc_description) + 1; + + memcpy(g_aoa_buffer, info->acc_description, strlen(info->acc_description)); + ret = usbh_control_transfer(hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SEND_STRING; + setup->wValue = 0; + setup->wIndex = AOA_ACCESSORY_STRING_VERSION; + setup->wLength = strlen(info->acc_version) + 1; + + memcpy(g_aoa_buffer, info->acc_version, strlen(info->acc_version)); + ret = usbh_control_transfer(hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SEND_STRING; + setup->wValue = 0; + setup->wIndex = AOA_ACCESSORY_STRING_URI; + setup->wLength = strlen(info->acc_uri) + 1; + + memcpy(g_aoa_buffer, info->acc_uri, strlen(info->acc_uri)); + ret = usbh_control_transfer(hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SEND_STRING; + setup->wValue = 0; + setup->wIndex = AOA_ACCESSORY_STRING_SERIAL; + setup->wLength = strlen(info->acc_serial) + 1; + + memcpy(g_aoa_buffer, info->acc_serial, strlen(info->acc_serial)); + ret = usbh_control_transfer(hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_START; + setup->wValue = 0; + setup->wIndex = 0; + setup->wLength = 0; + + ret = usbh_control_transfer(hport, setup, NULL); + if (ret < 0) { + return ret; + } + + USB_LOG_INFO("Switch into aoa mode success, wait usb device restart...\r\n"); + return 0; +} + +int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *report, uint32_t report_len) +{ + struct usb_setup_packet *setup; + int ret; + uint8_t len; + uint32_t offset; + + if (!aoa_class || !aoa_class->hport) { + return -USB_ERR_INVAL; + } + setup = aoa_class->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_REGISTER_HID; + setup->wValue = id; + setup->wIndex = report_len; + setup->wLength = 0; + + ret = usbh_control_transfer(aoa_class->hport, setup, NULL); + if (ret < 0) { + return ret; + } + + offset = 0; + while (report_len > 0) { + len = report_len > 64 ? 64 : report_len; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SET_HID_REPORT_DESC; + setup->wValue = id; + setup->wIndex = offset; + setup->wLength = len; + + memcpy(g_aoa_buffer, report + offset, len); + ret = usbh_control_transfer(aoa_class->hport, setup, g_aoa_buffer); + if (ret < 0) { + return ret; + } + offset += len; + report_len -= len; + } + return ret; +} + +int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len) +{ + struct usb_setup_packet *setup; + int ret; + uint8_t len; + uint32_t offset; + + if (!aoa_class || !aoa_class->hport) { + return -USB_ERR_INVAL; + } + setup = aoa_class->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = AOA_ACCESSORY_SEND_HID_EVENT; + setup->wValue = id; + setup->wIndex = 0; + setup->wLength = event_len; + + memcpy(g_aoa_buffer, event, event_len); + return usbh_control_transfer(aoa_class->hport, setup, event); +} + +static int usbh_aoa_connect(struct usbh_hubport *hport, uint8_t intf) +{ + struct usb_endpoint_descriptor *ep_desc; + int ret = 0; + + struct usbh_aoa *aoa_class = &g_aoa_class; + + memset(aoa_class, 0, sizeof(struct usbh_aoa)); + + aoa_class->hport = hport; + aoa_class->intf = intf; + + hport->config.intf[intf].priv = aoa_class; + + for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { + ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; + + if (ep_desc->bEndpointAddress & 0x80) { + USBH_EP_INIT(aoa_class->bulkin, ep_desc); + } else { + USBH_EP_INIT(aoa_class->bulkout, ep_desc); + } + } + + strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN); + + USB_LOG_INFO("Register AOA Class:%s\r\n", hport->config.intf[intf].devname); + + usbh_aoa_run(aoa_class); + return 0; +} + +static int usbh_aoa_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + int ret = 0; + + struct usbh_aoa *aoa_class = (struct usbh_aoa *)hport->config.intf[intf].priv; + + if (aoa_class) { + if (aoa_class->bulkin) { + usbh_kill_urb(&aoa_class->bulkin_urb); + } + + if (aoa_class->bulkout) { + usbh_kill_urb(&aoa_class->bulkout_urb); + } + + if (hport->config.intf[intf].devname[0] != '\0') { + USB_LOG_INFO("Unregister AOA Class:%s\r\n", hport->config.intf[intf].devname); + usbh_aoa_stop(aoa_class); + } + + memset(aoa_class, 0, sizeof(struct usbh_aoa)); + } + + return ret; +} + +__WEAK void usbh_aoa_run(struct usbh_aoa *aoa_class) +{ + (void)aoa_class; +} + +__WEAK void usbh_aoa_stop(struct usbh_aoa *aoa_class) +{ + (void)aoa_class; +} + +static const uint16_t aoa_id_table[][2] = { + { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_PRODUCT_ID }, + { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_ADB_PRODUCT_ID }, + { AOA_ACCESSORY_VENDOR_ID, AOA_AUDIO_PRODUCT_ID }, + { AOA_ACCESSORY_VENDOR_ID, AOA_AUDIO_ADB_PRODUCT_ID }, + { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_AUDIO_PRODUCT_ID }, + { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_AUDIO_ADB_PRODUCT_ID }, + { 0, 0 }, +}; + +const struct usbh_class_driver aoa_class_driver = { + .driver_name = "aoa", + .connect = usbh_aoa_connect, + .disconnect = usbh_aoa_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info aoa_intf_class_info = { + .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0x00, + .id_table = aoa_id_table, + .class_driver = &aoa_class_driver +}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.h b/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.h new file mode 100644 index 00000000000..3b184e8b980 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.h @@ -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 */ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/audio/usb_audio.h b/components/drivers/usb/cherryusb/class/audio/usb_audio.h index 1aced20ff4f..ff7a9fe2a95 100644 --- a/components/drivers/usb/cherryusb/class/audio/usb_audio.h +++ b/components/drivers/usb/cherryusb/class/audio/usb_audio.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; diff --git a/components/drivers/usb/cherryusb/class/audio/usbd_audio.c b/components/drivers/usb/cherryusb/class/audio/usbd_audio.c index 4ff3767abff..458f1c191f7 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbd_audio.c +++ b/components/drivers/usb/cherryusb/class/audio/usbd_audio.c @@ -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) diff --git a/components/drivers/usb/cherryusb/class/audio/usbd_audio.h b/components/drivers/usb/cherryusb/class/audio/usbd_audio.h index 442405a2f97..75a0b17dcda 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbd_audio.h +++ b/components/drivers/usb/cherryusb/class/audio/usbd_audio.h @@ -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); diff --git a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c index 9e838bbae0f..6d8b4559e10 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c +++ b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c @@ -184,18 +184,21 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) return ret; } -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) { struct usb_setup_packet *setup; int ret; uint8_t feature_id = 0xff; + uint8_t intf; uint16_t volume_hex; + int volume_min_db; + int volume_max_db; if (!audio_class || !audio_class->hport) { return -USB_ERR_INVAL; } - if (volume > 100) { + if ((volume_db > 127) || (volume_db < -127)) { return -USB_ERR_INVAL; } @@ -204,20 +207,102 @@ int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { feature_id = audio_class->as_msg_table[i].feature_terminal_id; + intf = audio_class->as_msg_table[i].stream_intf; } } + if (feature_id == 0xff) { + return -USB_ERR_NODEV; + } + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = AUDIO_REQUEST_GET_CUR; + setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; + setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; + setup->wLength = 2; + + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); + if (ret < 0) { + return ret; + } + + memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_cur, g_audio_buf, 2); + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = AUDIO_REQUEST_GET_MIN; + setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; + setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; + setup->wLength = 2; + + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); + if (ret < 0) { + return ret; + } + + memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min, g_audio_buf, 2); + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = AUDIO_REQUEST_GET_MAX; + setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; + setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; + setup->wLength = 2; + + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); + if (ret < 0) { + return ret; + } + memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max, g_audio_buf, 2); + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = AUDIO_REQUEST_GET_RES; + setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; + setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; + setup->wLength = 2; + + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); + if (ret < 0) { + return ret; + } + memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_res, g_audio_buf, 2); + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = AUDIO_REQUEST_SET_CUR; setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; setup->wLength = 2; - volume_hex = -0xDB00 / 100 * volume + 0xdb00; + if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min < 0x8000) { + volume_min_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min / 256; + } else { + volume_min_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min - 0x10000) / 256; + } + + if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max < 0x8000) { + volume_max_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max / 256; + } else { + volume_max_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max - 0x10000) / 256; + } - memcpy(g_audio_buf, &volume_hex, 2); - ret = usbh_control_transfer(audio_class->hport, setup, NULL); + USB_LOG_INFO("Get ch:%d dB range: %d dB ~ %d dB\r\n", volume_min_db, volume_max_db); + if (volume_db >= 0) { + volume_hex = volume_db * 256; + if (volume_hex > audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max) { + return -USB_ERR_RANGE; + } + } else { + volume_hex = volume_db * 256 + 0x10000; + if (volume_hex < audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min) { + return -USB_ERR_RANGE; + } + } + + memcpy(g_audio_buf, &volume_hex, 2); + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); + if (ret < 0) { + return ret; + } + audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_cur = volume_hex; return ret; } @@ -226,6 +311,7 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ struct usb_setup_packet *setup; int ret; uint8_t feature_id = 0xff; + uint8_t intf = 0xff; if (!audio_class || !audio_class->hport) { return -USB_ERR_INVAL; @@ -235,9 +321,14 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { feature_id = audio_class->as_msg_table[i].feature_terminal_id; + intf = audio_class->as_msg_table[i].stream_intf; } } + if (feature_id == 0xff) { + return -USB_ERR_NODEV; + } + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = AUDIO_REQUEST_SET_CUR; setup->wValue = (AUDIO_FU_CONTROL_MUTE << 8) | ch; @@ -246,7 +337,10 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ memcpy(g_audio_buf, &mute, 1); ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - + if (ret < 0) { + return ret; + } + audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].mute = mute; return ret; } @@ -286,13 +380,14 @@ void usbh_audio_list_module(struct usbh_audio *audio_class) static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) { int ret; - uint8_t cur_iface = 0xff; - uint8_t cur_iface_count = 0xff; - uint8_t cur_alt_setting = 0xff; + uint8_t cur_iface = 0; + uint8_t cur_iface_count = 0; + uint8_t cur_alt_setting = 0; uint8_t input_offset = 0; uint8_t output_offset = 0; uint8_t feature_unit_offset = 0; uint8_t *p; + struct usbh_audio_ac_msg ac_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS]; struct usbh_audio *audio_class = usbh_audio_class_alloc(); if (audio_class == NULL) { @@ -327,26 +422,24 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) case AUDIO_CONTROL_INPUT_TERMINAL: { struct audio_cs_if_ac_input_terminal_descriptor *desc = (struct audio_cs_if_ac_input_terminal_descriptor *)p; - memcpy(&audio_class->ac_msg_table[input_offset].ac_input, desc, sizeof(struct audio_cs_if_ac_input_terminal_descriptor)); + memcpy(&ac_msg_table[input_offset].ac_input, desc, sizeof(struct audio_cs_if_ac_input_terminal_descriptor)); input_offset++; } break; case AUDIO_CONTROL_OUTPUT_TERMINAL: { struct audio_cs_if_ac_output_terminal_descriptor *desc = (struct audio_cs_if_ac_output_terminal_descriptor *)p; - memcpy(&audio_class->ac_msg_table[output_offset].ac_output, desc, sizeof(struct audio_cs_if_ac_output_terminal_descriptor)); + memcpy(&ac_msg_table[output_offset].ac_output, desc, sizeof(struct audio_cs_if_ac_output_terminal_descriptor)); output_offset++; } break; case AUDIO_CONTROL_FEATURE_UNIT: { struct audio_cs_if_ac_feature_unit_descriptor *desc = (struct audio_cs_if_ac_feature_unit_descriptor *)p; - memcpy(&audio_class->ac_msg_table[feature_unit_offset].ac_feature_unit, desc, desc->bLength); + memcpy(&ac_msg_table[feature_unit_offset].ac_feature_unit, desc, desc->bLength); feature_unit_offset++; } break; - case AUDIO_CONTROL_PROCESSING_UNIT: - - break; default: - break; + USB_LOG_ERR("Do not support %02x subtype\r\n", p[DESC_bDescriptorSubType]); + return -USB_ERR_NOTSUPP; } } else if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) { switch (p[DESC_bDescriptorSubType]) { @@ -383,7 +476,12 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) } if ((input_offset != output_offset) && (input_offset != feature_unit_offset)) { - USB_LOG_ERR("Audio descriptor is invalid\r\n"); + USB_LOG_ERR("Audio control descriptor is invalid\r\n"); + return -USB_ERR_INVAL; + } + + if (cur_iface_count == 0xff) { + USB_LOG_ERR("Audio descriptor must have iad descriptor\r\n"); return -USB_ERR_INVAL; } @@ -392,21 +490,21 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { /* Search 0x0101 in input or output desc */ for (uint8_t streamidx = 0; streamidx < audio_class->stream_intf_num; streamidx++) { - if (audio_class->as_msg_table[i].as_general.bTerminalLink == audio_class->ac_msg_table[streamidx].ac_input.bTerminalID) { + if (audio_class->as_msg_table[i].as_general.bTerminalLink == ac_msg_table[streamidx].ac_input.bTerminalID) { /* INPUT --> FEATURE UNIT --> OUTPUT */ - audio_class->as_msg_table[i].input_terminal_id = audio_class->ac_msg_table[streamidx].ac_input.bTerminalID; + audio_class->as_msg_table[i].input_terminal_id = ac_msg_table[streamidx].ac_input.bTerminalID; /* Search input terminal id in feature desc */ for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) { - if (audio_class->ac_msg_table[streamidx].ac_input.bTerminalID == audio_class->ac_msg_table[featureidx].ac_feature_unit.bSourceID) { - audio_class->as_msg_table[i].feature_terminal_id = audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID; + if (ac_msg_table[streamidx].ac_input.bTerminalID == ac_msg_table[featureidx].ac_feature_unit.bSourceID) { + audio_class->as_msg_table[i].feature_terminal_id = ac_msg_table[featureidx].ac_feature_unit.bUnitID; /* Search feature unit id in output desc */ for (uint8_t outputid = 0; outputid < audio_class->stream_intf_num; outputid++) { - if (audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID == audio_class->ac_msg_table[outputid].ac_output.bSourceID) { - audio_class->as_msg_table[i].output_terminal_id = audio_class->ac_msg_table[outputid].ac_output.bTerminalID; + if (ac_msg_table[featureidx].ac_feature_unit.bUnitID == ac_msg_table[outputid].ac_output.bSourceID) { + audio_class->as_msg_table[i].output_terminal_id = ac_msg_table[outputid].ac_output.bTerminalID; - switch (audio_class->ac_msg_table[outputid].ac_output.wTerminalType) { + switch (ac_msg_table[outputid].ac_output.wTerminalType) { case AUDIO_OUTTERM_SPEAKER: audio_class->as_msg_table[i].stream_name = "speaker"; break; @@ -426,21 +524,21 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) break; } } - } else if (audio_class->as_msg_table[i].as_general.bTerminalLink == audio_class->ac_msg_table[streamidx].ac_output.bTerminalID) { + } else if (audio_class->as_msg_table[i].as_general.bTerminalLink == ac_msg_table[streamidx].ac_output.bTerminalID) { /* OUTPUT --> FEATURE UNIT --> INPUT */ - audio_class->as_msg_table[i].output_terminal_id = audio_class->ac_msg_table[streamidx].ac_output.bTerminalID; + audio_class->as_msg_table[i].output_terminal_id = ac_msg_table[streamidx].ac_output.bTerminalID; /* Search output terminal id in feature desc */ for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) { - if (audio_class->ac_msg_table[streamidx].ac_output.bSourceID == audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID) { - audio_class->as_msg_table[i].feature_terminal_id = audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID; + if (ac_msg_table[streamidx].ac_output.bSourceID == ac_msg_table[featureidx].ac_feature_unit.bUnitID) { + audio_class->as_msg_table[i].feature_terminal_id = ac_msg_table[featureidx].ac_feature_unit.bUnitID; /* Search feature unit id in input desc */ for (uint8_t inputid = 0; inputid < audio_class->stream_intf_num; inputid++) { - if (audio_class->ac_msg_table[featureidx].ac_feature_unit.bSourceID == audio_class->ac_msg_table[inputid].ac_input.bTerminalID) { - audio_class->as_msg_table[i].input_terminal_id = audio_class->ac_msg_table[inputid].ac_input.bTerminalID; + if (ac_msg_table[featureidx].ac_feature_unit.bSourceID == ac_msg_table[inputid].ac_input.bTerminalID) { + audio_class->as_msg_table[i].input_terminal_id = ac_msg_table[inputid].ac_input.bTerminalID; - switch (audio_class->ac_msg_table[inputid].ac_input.wTerminalType) { + switch (ac_msg_table[inputid].ac_input.wTerminalType) { case AUDIO_INTERM_MIC: audio_class->as_msg_table[i].stream_name = "mic"; break; @@ -458,6 +556,13 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) } } + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + if (audio_class->as_msg_table[i].stream_name == NULL) { + USB_LOG_ERR("Audio stream search fail\r\n"); + return -USB_ERR_NODEV; + } + } + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { ret = usbh_audio_close(audio_class, audio_class->as_msg_table[i].stream_name); if (ret < 0) { @@ -537,18 +642,18 @@ const struct usbh_class_driver audio_streaming_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info audio_ctrl_intf_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, - .class = USB_DEVICE_CLASS_AUDIO, - .subclass = AUDIO_SUBCLASS_AUDIOCONTROL, - .protocol = 0x00, + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, + .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOCONTROL, + .bInterfaceProtocol = 0x00, .id_table = NULL, .class_driver = &audio_ctrl_class_driver }; CLASS_INFO_DEFINE const struct usbh_class_info audio_streaming_intf_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, - .class = USB_DEVICE_CLASS_AUDIO, - .subclass = AUDIO_SUBCLASS_AUDIOSTREAMING, - .protocol = 0x00, + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, + .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = 0x00, .id_table = NULL, .class_driver = &audio_streaming_class_driver }; diff --git a/components/drivers/usb/cherryusb/class/audio/usbh_audio.h b/components/drivers/usb/cherryusb/class/audio/usbh_audio.h index d6eeeffb020..2e583ac0be5 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbh_audio.h +++ b/components/drivers/usb/cherryusb/class/audio/usbh_audio.h @@ -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); diff --git a/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h index eb2b286269b..d1546eec575 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h +++ b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h @@ -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 */ \ diff --git a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c index 29e82ceeaee..5ae10a207c3 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c @@ -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]) +{ + 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(uint32_t len) { - memcpy(g_connect_speed_table, speed, 8); + (void)len; } -__WEAK void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len) +__WEAK void usbd_cdc_ecm_data_send_done(uint32_t len) { - (void)buf; (void)len; } diff --git a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h index 8d9e5c9fe00..3e0284e3288 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h +++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h @@ -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" diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c index ceb5ad0c2dc..53666b32f03 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c index 76cfb41aa39..c4743e56d30 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c @@ -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 }; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c index 094241aab58..f9f3c533819 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c index de1ddc07488..0fd58abb153 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c +++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c index 2bcf4ddb48d..9dae3966075 100644 --- a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c +++ b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c index 1327175fce5..96cb53d2630 100644 --- a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c +++ b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/template/usbh_xxx.c b/components/drivers/usb/cherryusb/class/template/usbh_xxx.c index 78d531fc3cf..4456b3c4a1d 100644 --- a/components/drivers/usb/cherryusb/class/template/usbh_xxx.c +++ b/components/drivers/usb/cherryusb/class/template/usbh_xxx.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c index e8c7eb15378..66c1f078033 100644 --- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c +++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c @@ -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 }; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c index 778ab264794..10fc0483982 100644 --- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c +++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c index d0de5b4cf2d..3bee462db81 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c @@ -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 }; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c index 4cd06b95be4..6f41b41be37 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c @@ -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 }; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c index 4ed698390c3..82defaab7fd 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c @@ -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 }; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c index 42c963db4e1..01ee700fb83 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c @@ -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 }; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c index 34cbcf87e4c..9275faacc63 100644 --- a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c +++ b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c index ecfb4651901..0c3339c9fc5 100644 --- a/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c +++ b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/video/usbd_video.c b/components/drivers/usb/cherryusb/class/video/usbd_video.c index a1a42cdcf1e..dae28eb544a 100644 --- a/components/drivers/usb/cherryusb/class/video/usbd_video.c +++ b/components/drivers/usb/cherryusb/class/video/usbd_video.c @@ -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); + 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; + } + } - g_usbd_video[busid].stream_offset += len; + 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].stream_offset == g_usbd_video[busid].stream_len) { - last_packet = true; - header->headerInfoUnion.headerInfoBits.endOfFrame = 1; + 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; + } } - usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buffer, len + header->bHeaderLength); - return last_packet; + 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; -} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/video/usbd_video.h b/components/drivers/usb/cherryusb/class/video/usbd_video.h index 24855c897d4..a2a98bb8c01 100644 --- a/components/drivers/usb/cherryusb/class/video/usbd_video.h +++ b/components/drivers/usb/cherryusb/class/video/usbd_video.h @@ -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 } diff --git a/components/drivers/usb/cherryusb/class/video/usbh_video.c b/components/drivers/usb/cherryusb/class/video/usbh_video.c index 043eb1d6bde..7379151250d 100644 --- a/components/drivers/usb/cherryusb/class/video/usbh_video.c +++ b/components/drivers/usb/cherryusb/class/video/usbh_video.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c index 61bcd290d13..43849706ea2 100644 --- a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c +++ b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c @@ -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; +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h index 8a9581f68d1..72b89eab890 100644 --- a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h +++ b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h @@ -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); diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c index 9f78866ab5a..991f09579b3 100644 --- a/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c +++ b/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c index fa53f8400b0..e9eaff0114d 100644 --- a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c +++ b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c @@ -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 }; diff --git a/components/drivers/usb/cherryusb/common/usb_log.h b/components/drivers/usb/cherryusb/common/usb_log.h index 9074ed9752b..8c798c7cb44 100644 --- a/components/drivers/usb/cherryusb/common/usb_log.h +++ b/components/drivers/usb/cherryusb/common/usb_log.h @@ -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); diff --git a/components/drivers/usb/cherryusb/common/usb_version.h b/components/drivers/usb/cherryusb/common/usb_version.h index b68b8f69790..d207af9dc23 100644 --- a/components/drivers/usb/cherryusb/common/usb_version.h +++ b/components/drivers/usb/cherryusb/common/usb_version.h @@ -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 \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/core/usbd_core.c b/components/drivers/usb/cherryusb/core/usbd_core.c index ea471e54985..d7fb351775f 100644 --- a/components/drivers/usb/cherryusb/core/usbd_core.c +++ b/components/drivers/usb/cherryusb/core/usbd_core.c @@ -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 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting /** * @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 */ diff --git a/components/drivers/usb/cherryusb/core/usbh_core.c b/components/drivers/usb/cherryusb/core/usbh_core.c index d4de88e54f7..cb36f97eea8 100644 --- a/components/drivers/usb/cherryusb/core/usbh_core.c +++ b/components/drivers/usb/cherryusb/core/usbh_core.c @@ -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; diff --git a/components/drivers/usb/cherryusb/core/usbh_core.h b/components/drivers/usb/cherryusb/core/usbh_core.h index 6674fcb4953..eaddb304329 100644 --- a/components/drivers/usb/cherryusb/core/usbh_core.h +++ b/components/drivers/usb/cherryusb/core/usbh_core.h @@ -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); diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c index 32bd9109a56..148f324c37a 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c @@ -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) { } } diff --git a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c index 1d70aaa5553..9147c92320f 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c @@ -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) { } diff --git a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c index 310788360c1..a83a75551aa 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c @@ -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) { } diff --git a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c index 7527f396d81..4d1afc3056d 100644 --- a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c @@ -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) { } } diff --git a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c index e6d24d7cb9e..564d1718bba 100644 --- a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c @@ -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) { } diff --git a/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c index b528c4a11dd..786c3240394 100644 --- a/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c @@ -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) { } diff --git a/components/drivers/usb/cherryusb/demo/usb_host.c b/components/drivers/usb/cherryusb/demo/usb_host.c index 7198418893b..817103d5c08 100644 --- a/components/drivers/usb/cherryusb/demo/usb_host.c +++ b/components/drivers/usb/cherryusb/demo/usb_host.c @@ -254,38 +254,38 @@ static void usbh_msc_thread(void *argument) } #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 \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c index 85a5146d4b3..6a4116222a0 100644 --- a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c +++ b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c @@ -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 } } } \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/video_static_h264_template.c b/components/drivers/usb/cherryusb/demo/video_static_h264_template.c index 376068edac8..e325964a2fd 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_h264_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_h264_template.c @@ -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 } } } \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c b/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c index 51a4422613f..1d2ae01ba4b 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c @@ -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 } } } \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c b/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c index f90344d17e8..4ba71701c48 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c @@ -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 } } } \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c index 04ec1dd25ac..52570879974 100644 --- a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c +++ b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c @@ -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) { } } diff --git a/components/drivers/usb/cherryusb/idf_component.yml b/components/drivers/usb/cherryusb/idf_component.yml new file mode 100644 index 00000000000..a500a240473 --- /dev/null +++ b/components/drivers/usb/cherryusb/idf_component.yml @@ -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 \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c b/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c index be16ea1495b..b20e17d8755 100644 --- a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c +++ b/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c @@ -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 diff --git a/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c b/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c index 4b4b72d497c..7aabd411fcd 100644 --- a/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c +++ b/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c @@ -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; diff --git a/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c b/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c index 758ffd77f37..a8d3036a357 100644 --- a/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c +++ b/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c @@ -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; diff --git a/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c b/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c index 3d1971653d6..c6b6c0fee57 100644 --- a/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c +++ b/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c @@ -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" diff --git a/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c b/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c index 29bb2d292c0..3f9b46b6af0 100644 --- a/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c +++ b/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "usbd_core.h" #include "fsl_common.h" diff --git a/components/drivers/usb/cherryusb/port/dwc2/README.md b/components/drivers/usb/cherryusb/port/dwc2/README.md index faf9ab5a1a9..3218b31cd56 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/README.md +++ b/components/drivers/usb/cherryusb/port/dwc2/README.md @@ -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 diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c b/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c index 72006abd5fe..6054a334a67 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c @@ -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) { diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c index 137b1d87046..8d45f651394 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c @@ -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 diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c index 7121ac9dbd2..f3fa4d92f7a 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c @@ -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; diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c index f73dc5e9528..4dff31f83f4 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c @@ -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 diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c b/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c index 9b0fc66015b..09f55170a5c 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c @@ -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; } } -} +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c b/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c index 9fc87c39b70..500bc02a40d 100644 --- a/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c +++ b/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c @@ -9,6 +9,19 @@ #include