From 84a05ef9152c741c1f3a8e18d98865a5a1a62ea2 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Tue, 28 Apr 2026 10:29:26 +0800 Subject: [PATCH 1/2] update(cherryusb): update to v1.6.1 Signed-off-by: sakumisu <1203593632@qq.com> --- components/drivers/usb/cherryusb/Kconfig | 38 +- components/drivers/usb/cherryusb/README.md | 140 ++-- components/drivers/usb/cherryusb/README_zh.md | 110 ++- components/drivers/usb/cherryusb/SConscript | 24 +- components/drivers/usb/cherryusb/VERSION | 2 +- .../drivers/usb/cherryusb/cherryusb.cmake | 24 +- .../usb/cherryusb/cherryusb_config_template.h | 1 + .../usb/cherryusb/class/adb/usbd_adb.c | 6 +- .../usb/cherryusb/class/audio/usb_audio.h | 8 +- .../usb/cherryusb/class/audio/usbd_audio.c | 16 +- .../usb/cherryusb/class/audio/usbh_audio.c | 25 +- .../drivers/usb/cherryusb/class/cdc/usb_cdc.h | 26 +- .../usb/cherryusb/class/cdc/usbd_cdc_acm.c | 3 +- .../usb/cherryusb/class/cdc/usbd_cdc_ecm.c | 1 - .../drivers/usb/cherryusb/class/dfu/usb_dfu.h | 57 +- .../usb/cherryusb/class/dfu/usbd_dfu.c | 736 +++++++----------- .../usb/cherryusb/class/dfu/usbd_dfu.h | 14 +- .../cherryusb/class/gamepad/usbd_gamepad.c | 10 +- .../usb/cherryusb/class/hid/usbd_hid.c | 1 - .../usb/cherryusb/class/hid/usbh_hid.c | 422 +++------- .../usb/cherryusb/class/hid/usbh_hid.h | 93 +-- .../usb/cherryusb/class/hub/usbh_hub.c | 49 +- .../usb/cherryusb/class/msc/usbd_msc.c | 12 +- .../usb/cherryusb/class/serial/usbh_ch34x.c | 2 +- .../usb/cherryusb/class/serial/usbh_ftdi.c | 2 +- .../usb/cherryusb/class/serial/usbh_serial.c | 106 +-- .../usb/cherryusb/class/serial/usbh_serial.h | 9 +- .../class/vendor/display/usbd_display.c | 172 ++++ .../class/vendor/display/usbd_display.h | 51 ++ .../usb/cherryusb/class/video/usbd_video.c | 23 - .../usb/cherryusb/class/video/usbh_video.c | 19 +- .../usb/cherryusb/class/video/usbh_video.h | 12 +- .../usb/cherryusb/class/wireless/usbd_rndis.c | 5 - .../usb/cherryusb/common/usb_mempool.h | 148 ++++ .../drivers/usb/cherryusb/common/usb_osal.h | 1 + .../usb/cherryusb/common/usb_ringbuffer.h | 494 ++++++++++++ .../usb/cherryusb/common/usb_version.h | 4 +- .../drivers/usb/cherryusb/core/usbd_core.c | 7 +- .../drivers/usb/cherryusb/core/usbd_core.h | 2 + .../drivers/usb/cherryusb/core/usbh_core.c | 15 +- .../drivers/usb/cherryusb/core/usbh_core.h | 4 +- .../drivers/usb/cherryusb/core/usbotg_core.c | 2 +- .../cherryusb/demo/adb/usbd_adb_template.c | 2 +- .../demo/audio_v1_mic_multichan_template.c | 2 +- .../audio_v1_mic_speaker_multichan_template.c | 2 +- .../demo/audio_v2_mic_multichan_template.c | 2 +- .../audio_v2_mic_speaker_multichan_template.c | 2 +- .../audio_v2_speaker_multichan_template.c | 2 +- .../demo/bootuf2/msc_bootuf2_template.c | 2 +- .../cherryusb/demo/cdc_acm_hid_msc_template.c | 80 +- .../cherryusb/demo/cdc_acm_mavlink_template.c | 2 +- .../usb/cherryusb/demo/cdc_acm_msc_template.c | 2 +- .../cherryusb/demo/cdc_acm_multi_template.c | 2 +- .../demo/cdc_acm_rttchardev_template.c | 2 +- .../usb/cherryusb/demo/cdc_acm_template.c | 2 +- .../usb/cherryusb/demo/cdc_ecm_template.c | 4 +- .../usb/cherryusb/demo/cdc_rndis_template.c | 2 +- .../usb/cherryusb/demo/dfu_st_cubemx_main.c | 372 --------- ...with_st_tool_template.c => dfu_template.c} | 61 +- .../usb/cherryusb/demo/display/README.md | 3 + .../demo/display/usbdisplay_template.c | 145 ++++ .../usb/cherryusb/demo/gamepad_template.c | 2 +- .../demo/hid_custom_inout_template.c | 2 +- .../cherryusb/demo/hid_keyboard_template.c | 2 +- .../usb/cherryusb/demo/hid_mouse_template.c | 82 +- .../demo/hid_remote_wakeup_template.c | 80 +- .../usb/cherryusb/demo/midi_template.c | 2 +- .../usb/cherryusb/demo/msc_ram_template.c | 53 +- .../demo/video_audiov1_hid_template.c | 2 +- .../demo/video_static_h264_template.c | 2 +- .../demo/video_static_mjpeg_template.c | 2 +- .../demo/video_static_yuyv_template.c | 2 +- .../usb/cherryusb/demo/webusb_hid_template.c | 2 +- .../usb/cherryusb/demo/winusb1.0_template.c | 2 +- .../cherryusb/demo/winusb2.0_cdc_template.c | 2 +- .../usb/cherryusb/demo/winusb2.0_template.c | 2 +- .../drivers/usb/cherryusb/idf_component.yml | 2 +- .../usb/cherryusb/osal/usb_osal_rtthread.c | 5 + .../cherryusb/platform/rtthread/usb_check.c | 35 - .../usb/cherryusb/platform/rtthread/usb_msh.c | 53 -- .../platform/rtthread/usbd_adb_shell.c | 156 ---- .../cherryusb/platform/rtthread/usbd_serial.c | 275 ------- .../cherryusb/platform/rtthread/usbh_dfs.c | 191 ----- .../cherryusb/platform/rtthread/usbh_lwip.c | 469 ----------- .../cherryusb/port/chipidea/usb_dc_chipidea.c | 2 +- .../usb/cherryusb/port/dwc2/usb_dc_dwc2.c | 14 +- .../cherryusb/port/dwc2/usb_glue_infineon.c | 4 +- .../usb/cherryusb/port/dwc2/usb_hc_dwc2.c | 13 +- .../usb/cherryusb/port/hpmicro/usb_dc_hpm.c | 45 +- .../drivers/usb/cherryusb/port/musb/README.md | 1 + .../usb/cherryusb/port/musb/usb_hc_musb.c | 15 +- 91 files changed, 2090 insertions(+), 3016 deletions(-) create mode 100644 components/drivers/usb/cherryusb/class/vendor/display/usbd_display.c create mode 100644 components/drivers/usb/cherryusb/class/vendor/display/usbd_display.h create mode 100644 components/drivers/usb/cherryusb/common/usb_mempool.h create mode 100644 components/drivers/usb/cherryusb/common/usb_ringbuffer.h delete mode 100644 components/drivers/usb/cherryusb/demo/dfu_st_cubemx_main.c rename components/drivers/usb/cherryusb/demo/{dfu_with_st_tool_template.c => dfu_template.c} (64%) create mode 100644 components/drivers/usb/cherryusb/demo/display/README.md create mode 100644 components/drivers/usb/cherryusb/demo/display/usbdisplay_template.c delete mode 100644 components/drivers/usb/cherryusb/platform/rtthread/usb_check.c delete mode 100644 components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c delete mode 100644 components/drivers/usb/cherryusb/platform/rtthread/usbd_adb_shell.c delete mode 100644 components/drivers/usb/cherryusb/platform/rtthread/usbd_serial.c delete mode 100644 components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c delete mode 100644 components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c diff --git a/components/drivers/usb/cherryusb/Kconfig b/components/drivers/usb/cherryusb/Kconfig index 35a8e15f285..0cbb76d9cd8 100644 --- a/components/drivers/usb/cherryusb/Kconfig +++ b/components/drivers/usb/cherryusb/Kconfig @@ -139,11 +139,26 @@ if RT_USING_CHERRYUSB prompt "Enable usb dfu device" default n + config RT_CHERRYUSB_DEVICE_DISPLAY + bool + prompt "Enable usb display device" + default n + config RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV bool prompt "Enable chardev for cdc acm device" default n + config RT_CHERRYUSB_DEVICE_MSC_BLKDEV + bool + prompt "Enable blkdev for msc device" + default n + + config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME + string "usb device msc block device name" + depends on RT_CHERRYUSB_DEVICE_MSC_BLKDEV + default "sd0" + config CONFIG_USBDEV_REQUEST_BUFFER_LEN int prompt "Set device control transfer max buffer size" @@ -184,7 +199,7 @@ if RT_USING_CHERRYUSB config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV bool prompt "msc_blkdev" - depends on RT_CHERRYUSB_DEVICE_MSC + depends on RT_CHERRYUSB_DEVICE_MSC && RT_CHERRYUSB_DEVICE_MSC_BLKDEV config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD bool prompt "hid_keyboard" @@ -221,6 +236,10 @@ if RT_USING_CHERRYUSB bool prompt "cdc_ncm" depends on RT_CHERRYUSB_DEVICE_CDC_NCM + config RT_CHERRYUSB_DEVICE_TEMPLATE_DFU + bool + prompt "dfu" + depends on RT_CHERRYUSB_DEVICE_DFU config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC bool prompt "cdc_acm_msc" @@ -243,6 +262,10 @@ if RT_USING_CHERRYUSB bool prompt "webusb_hid" depends on RT_CHERRYUSB_DEVICE_HID + config RT_CHERRYUSB_DEVICE_TEMPLATE_DISPLAY + bool + prompt "display" + depends on RT_CHERRYUSB_DEVICE_DISPLAY config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB bool prompt "adb" @@ -253,11 +276,6 @@ if RT_USING_CHERRYUSB depends on RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV endchoice - config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME - string "usb device msc block device name" - depends on RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV - default "sd0" - endif menuconfig RT_CHERRYUSB_HOST @@ -470,22 +488,22 @@ if RT_USING_CHERRYUSB default "/" menu "Select USB host template, please select class driver first" - config CONFIG_TEST_USBH_SERIAL + config RT_TEST_USBH_SERIAL bool prompt "demo for test seial, cannot enable this demo, you can use rt-thread device api to test" default n depends on CONFIG_USBHOST_SERIAL - config CONFIG_TEST_USBH_HID + config RT_TEST_USBH_HID int prompt "demo for test hid" default 0 depends on RT_CHERRYUSB_HOST_HID - config CONFIG_TEST_USBH_MSC + config RT_TEST_USBH_MSC bool prompt "demo for test msc, cannot enable this demo, you can use rt-thread dfs api to test" default n depends on RT_CHERRYUSB_HOST_MSC - config CONFIG_TEST_USBH_NET + config RT_TEST_USBH_NET bool prompt "demo for test net, cannot enable this demo, you can use lwip api to test" default n diff --git a/components/drivers/usb/cherryusb/README.md b/components/drivers/usb/cherryusb/README.md index d514f1fb08d..d01977788c6 100644 --- a/components/drivers/usb/cherryusb/README.md +++ b/components/drivers/usb/cherryusb/README.md @@ -14,31 +14,31 @@ CherryUSB is a tiny and beautiful, high performance and portable USB host and de ## Why choose CherryUSB -### Easy to study USB +### Easy to Learn USB -In order to make it easier for users to learn USB basics, enumeration, driver loading and IP drivers, the code has been written with the following advantages: +To facilitate user learning of USB fundamentals, enumeration, driver loading, and IP drivers, the written code has the following advantages: -- Lean code, simple logic, no complex C syntax -- Tree-based programming with cascading code -- Class-drivers and porting-drivers are templating and simplification -- Clear API classification (slave: initialisation, registration api, command callback api, data sending and receiving api; host: initialisation, lookup api, data sending and receiving api) +- Streamlined code with simple logic and no complex C language syntax +- Tree-structured programming with progressive code layers +- Templated and simplified Class drivers and porting drivers +- Clear API categorization (Device: initialization, class registration, command callbacks, data transmission; Host: initialization, class discovery, data transmission) -### Easy to use USB +### Easy to Use USB -In order to facilitate the use of the USB interface and to take into account the fact that users have learned about uart and dma, the following advantages have been designed for the data sending and receiving class of interface: +To facilitate user interaction with USB interfaces, considering users’ familiarity with UART and DMA, the designed data transmission interface has the following advantages: -- Equivalent to using uart tx dma/uart rx dma -- There is no limit to the length of send and receive, the user does not need to care about the USB packetization process (the porting driver does it) +- Equivalent to using UART TX DMA/UART RX DMA +- No length restrictions on transmission/reception; users don’t need to worry about USB packetization (porting drivers handle packetization) -### Easy to bring out USB performance +### Easy to Achieve USB Performance -Taking into account USB performance issues and trying to achieve the theoretical bandwidth of the USB hardware, the design of the data transceiver class interface has the following advantages: +Considering USB performance requirements to reach theoretical USB hardware bandwidth, the designed data transmission interface has the following advantages: -- Porting drivers directly to registers, no abstraction layer encapsulation +- Porting drivers directly interface with registers without abstraction layer encapsulation - Memory zero copy -- If IP has DMA then uses DMA mode (DMA with hardware packetization) -- Unlimited length make it easier to interface with hardware DMA and take advantage of DMA -- Packetization is handled in interrupt +- DMA mode used when IP supports DMA (DMA provides hardware packetization functionality) +- No length restrictions, facilitating hardware DMA interfacing and maximizing DMA advantages +- Packetization handled in interrupt context Performance show:https://cherryusb.cherry-embedded.org/show/ @@ -70,11 +70,13 @@ CherryUSB Device Stack has the following functions: - Support Mass Storage Class (MSC) - Support USB VIDEO CLASS (UVC1.0, UVC1.5) - Support USB AUDIO CLASS (UAC1.0, UAC2.0) +- Support Remote NDIS (RNDIS) - Support Device Firmware Upgrade CLASS (DFU) - Support USB MIDI CLASS (MIDI) -- Support Remote NDIS (RNDIS) - Support Media Transfer Protocol (MTP) +- Support Test and Measurement Class (TMC) - Support WINUSB1.0, WINUSB2.0, WEBUSB, BOS +- Support Vendor display ([xfz1986_usb_graphic_driver](https://github.com/chuanjinpang/win10_idd_xfz1986_usb_graphic_driver_display)) - Support Vendor class - Support UF2 - Support Android Debug Bridge (Only support shell) @@ -84,15 +86,18 @@ CherryUSB Device Stack resource usage (GCC 10.2 with -O2, disable log): | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:| -|usbd_core.c | ~4500 | (512(default) + 320) * bus | 0 | 0 | -|usbd_cdc_acm.c | ~900 | 0 | 0 | 0 | -|usbd_msc.c | ~5000 | (128 + 512(default)) * bus | 16 * bus | 0 | -|usbd_hid.c | ~300 | 0 | 0 | 0 | -|usbd_audio.c | ~4000 | 0 | 0 | 0 | -|usbd_video.c | ~7000 | 0 | 132 * bus | 0 | -|usbd_rndis.c | ~2500 | 2 * 1580(default)+156+8 | 80 | 0 | -|usbd_cdc_ecm.c | ~900 | 2 * 1514(default)+16 | 42 | 0 | +|usbd_core.c | ~4000 | (512(default) + 320) * bus | 8 | 0 | +|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 | +|usbd_msc.c | ~3200 | (128 + 512(default)) * bus | 16 * bus | 0 | +|usbd_hid.c | ~200 | 0 | 0 | 0 | +|usbd_audio.c | ~1300 | 0 | 8 * bus | 0 | +|usbd_video.c | ~2500 | 0 | 124 * bus | 0 | +|usbd_rndis.c | ~2000 | 2 * 1580(default)+156+8 | 76 | 0 | +|usbd_cdc_ecm.c | ~1500 | 2 * 1514(default)+16 | 42 | 0 | |usbd_mtp.c | ~9000 | 2048(default)+128 | sizeof(struct mtp_object) * n| 0 | +|usbd_dfu.c | ~800 | 0 | 1 | 0 | + +![usbdevice_usage](docs/assets/usbdevice_usage.png) ## Host Stack Overview @@ -111,6 +116,7 @@ CherryUSB Host Stack has the following functions: - Support USB Video CLASS (UVC1.0, UVC1.5) - Support USB Audio CLASS (UAC1.0) - Support Remote NDIS (RNDIS) +- Support Device Firmware Upgrade CLASS (DFU) - Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm) - Support Vendor Serial Class(CH34X、CP210X、PL2303、FTDI、GSM) - Support Vendor network Class(RTL8152、AX88772) @@ -124,19 +130,27 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2, disable log): | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:| -|usbh_core.c | ~4500 | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc | -|usbh_hub.c | ~3500 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 | -|usbh_cdc_acm.c | ~600 | 7 * x | 4 + sizeof(struct usbh_cdc_acm) * x | 0 | -|usbh_msc.c | ~2000 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 | -|usbh_hid.c | ~800 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 | -|usbh_video.c | ~5000 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 | -|usbh_audio.c | ~4000 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 | +|usbh_core.c | ~4000 | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc | +|usbh_hub.c | ~3000 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 | +|usbh_msc.c | ~1500 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 | +|usbh_hid.c | ~2000 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 | +|usbh_video.c | ~2500 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 | +|usbh_audio.c | ~3000 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 | |usbh_rndis.c | ~3000 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 | |usbh_cdc_ecm.c | ~1500 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 | |usbh_cdc_ncm.c | ~2000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1| 0 | |usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 | -|usbh_asix.c | ~7000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_asix) * 1 | 0 | -|usbh_rtl8152.c | ~9000 | 16K+ 2K(default) + 2 + 32 | sizeof(struct usbh_rtl8152) * 1 | 0 | +|usbh_asix.c | ~3500 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_asix) * 1 | 0 | +|usbh_rtl8152.c | ~5500 | 16K+ 2K(default) + 2 + 32 | sizeof(struct usbh_rtl8152) * 1 | 0 | +|usbh_serial.c | ~3000 | (512 * 2 + 32 * 2) * x | sizeof(struct usbh_serial) * x (2048 default) | 0 | +|usbh_cdc_acm.c | ~1000 | 0 | 0 | 0 | +|usbh_ch340.c | ~1200 | 0 | 0 | 0 | +|usbh_ftdi.c | ~1200 | 0 | 0 | 0 | +|usbh_cp2102.c | ~2200 | 0 | 0 | 0 | +|usbh_pl2303.c | ~2500 | 0 | 0 | 0 | +|usbh_gsm.c | ~300 | 0 | 0 | 0 | + +![usbhost_usage](docs/assets/usbhost_usage.png) Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affected by the following macros: @@ -176,55 +190,35 @@ Only standard and commercial USB IP are listed. | CDNS3(cadence) | CDNS3 | XHCI | × | | DWC3(synopsys) | DWC3 | XHCI | × | -## Documentation Tutorial - -Quickly start, USB basic concepts, API manual, Class basic concepts and examples, see [CherryUSB Documentation Tutorial](https://cherryusb.readthedocs.io/). - -## Video Tutorial - -CherryUSB Cheese (>= V1.4.3): https://www.bilibili.com/cheese/play/ss707687201 . - -## Descriptor Generator Tool +## Resources -Cherry Descriptor: https://desc.cherry-embedded.org/en +### Getting Started -## Demo Repo +- 📖 [CherryUSB Documentation](https://cherryusb.readthedocs.io/en/latest/) +- 💻 [CherryUSB Demo Repo](https://cherryusb.readthedocs.io/en/latest/quick_start/demo.html) +- 📺 [CherryUSB Cheese(>= V1.4.3)](https://www.bilibili.com/cheese/play/ss707687201) -| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note | -|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:| -|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official | -|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community | -|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official | -|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | -|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | -|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official | -|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official | -|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official | -|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official | -|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community | -|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing | -|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing | -|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update | -|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official | -|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official | -|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update | +### Tools -## Package Support +- 🌐 [Cherry Descriptor Generator](https://desc.cherry-embedded.org/en) +- 🔧 [CDC Speed Test](https://github.com/cherry-embedded/CherryUSB/blob/master/tools/test_srcipts/test_cdc_speed.py) +- 🔧 [HID Custom Test](https://github.com/cherry-embedded/CherryUSB/blob/master/tools/test_srcipts/test_hid_inout.py) -CherryUSB package is available as follows: +### Community Or Commercial Support -- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB) -- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook) -- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb) +- 💬 [CherryUSB QQ Group](https://qm.qq.com/q/w3GnM4bkfA) +- 💬 [CherryUSB discord](https://discord.com/invite/wFfvrSAey8) +- 🙋🏽 [Commercial Support](https://cherryusb.readthedocs.io/en/latest/support/index.html) -## Commercial Support +### Package Support -Refer to https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html. +- 🌐 [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB) +- 🌐 [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook) +- 🌐 [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb) -## Contact +### Mirror URL -CherryUSB discord: https://discord.com/invite/wFfvrSAey8. +- [AtomGit](https://atomgit.com/cherry-embedded/CherryUSB) ## Company Support diff --git a/components/drivers/usb/cherryusb/README_zh.md b/components/drivers/usb/cherryusb/README_zh.md index cf76f3ea281..59d11a0612f 100644 --- a/components/drivers/usb/cherryusb/README_zh.md +++ b/components/drivers/usb/cherryusb/README_zh.md @@ -70,11 +70,13 @@ CherryUSB Device 协议栈当前实现以下功能: - 支持 Mass Storage Class (MSC) - 支持 USB VIDEO CLASS (UVC1.0、UVC1.5) - 支持 USB AUDIO CLASS (UAC1.0、UAC2.0) +- 支持 Remote NDIS (RNDIS) - 支持 Device Firmware Upgrade CLASS (DFU) - 支持 USB MIDI CLASS (MIDI) -- 支持 Remote NDIS (RNDIS) - 支持 Media Transfer Protocol (MTP) +- 支持 Test and Measurement Class (TMC) - 支持 WINUSB1.0、WINUSB2.0、WEBUSB、BOS +- 支持 Vendor display ([xfz1986_usb_graphic_driver](https://github.com/chuanjinpang/win10_idd_xfz1986_usb_graphic_driver_display)) - 支持 Vendor 类 class - 支持 UF2 - 支持 Android Debug Bridge (Only support shell) @@ -84,15 +86,16 @@ CherryUSB Device 协议栈资源占用说明(GCC 10.2 with -O2): | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:| -|usbd_core.c | ~4500 | (512(default) + 320) * bus | 0 | 0 | -|usbd_cdc_acm.c | ~900 | 0 | 0 | 0 | -|usbd_msc.c | ~5000 | (128 + 512(default)) * bus | 16 * bus | 0 | -|usbd_hid.c | ~300 | 0 | 0 | 0 | -|usbd_audio.c | ~4000 | 0 | 0 | 0 | -|usbd_video.c | ~7000 | 0 | 132 * bus | 0 | -|usbd_rndis.c | ~2500 | 2 * 1580(default)+156+8 | 80 | 0 | -|usbd_cdc_ecm.c | ~900 | 2 * 1514(default)+16 | 42 | 0 | +|usbd_core.c | ~4000 | (512(default) + 320) * bus | 8 | 0 | +|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 | +|usbd_msc.c | ~3200 | (128 + 512(default)) * bus | 16 * bus | 0 | +|usbd_hid.c | ~200 | 0 | 0 | 0 | +|usbd_audio.c | ~1300 | 0 | 8 * bus | 0 | +|usbd_video.c | ~2500 | 0 | 124 * bus | 0 | +|usbd_rndis.c | ~2000 | 2 * 1580(default)+156+8 | 76 | 0 | +|usbd_cdc_ecm.c | ~1500 | 2 * 1514(default)+16 | 42 | 0 | |usbd_mtp.c | ~9000 | 2048(default)+128 | sizeof(struct mtp_object) * n| 0 | +|usbd_dfu.c | ~800 | 0 | 1 | 0 | ## Host 协议栈简介 @@ -108,9 +111,10 @@ CherryUSB Host 协议栈当前实现以下功能: - 支持 Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM) - 支持 Human Interface Device (HID) - 支持 Mass Storage Class (MSC) -- Support USB Video CLASS (UVC1.0、UVC1.5) -- Support USB Audio CLASS (UAC1.0) +- 支持 USB Video CLASS (UVC1.0、UVC1.5) +- 支持 USB Audio CLASS (UAC1.0) - 支持 Remote NDIS (RNDIS) +- 支持 Device Firmware Upgrade CLASS (DFU) - 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能) - 支持 Vendor Serial 类(CH34X、CP210X、PL2303、FTDI、GSM) - 支持 Vendor network 类(RTL8152、AX88772) @@ -124,19 +128,25 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2,关闭 log) | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:| -|usbh_core.c | ~4500 | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc | -|usbh_hub.c | ~3500 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 | -|usbh_cdc_acm.c | ~600 | 7 * x | 4 + sizeof(struct usbh_cdc_acm) * x | 0 | -|usbh_msc.c | ~2000 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 | -|usbh_hid.c | ~800 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 | -|usbh_video.c | ~5000 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 | -|usbh_audio.c | ~4000 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 | +|usbh_core.c | ~4000 | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc | +|usbh_hub.c | ~3000 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 | +|usbh_msc.c | ~1500 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 | +|usbh_hid.c | ~2000 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 | +|usbh_video.c | ~2500 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 | +|usbh_audio.c | ~3000 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 | |usbh_rndis.c | ~3000 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 | |usbh_cdc_ecm.c | ~1500 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 | |usbh_cdc_ncm.c | ~2000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1| 0 | |usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 | -|usbh_asix.c | ~7000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_asix) * 1 | 0 | -|usbh_rtl8152.c | ~9000 | 16K+ 2K(default) + 2 + 32 | sizeof(struct usbh_rtl8152) * 1 | 0 | +|usbh_asix.c | ~3500 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_asix) * 1 | 0 | +|usbh_rtl8152.c | ~5500 | 16K+ 2K(default) + 2 + 32 | sizeof(struct usbh_rtl8152) * 1 | 0 | +|usbh_serial.c | ~3000 | (512 * 2 + 32 * 2) * x | sizeof(struct usbh_serial) * x (2048 default) | 0 | +|usbh_cdc_acm.c | ~1000 | 0 | 0 | 0 | +|usbh_ch340.c | ~1200 | 0 | 0 | 0 | +|usbh_ftdi.c | ~1200 | 0 | 0 | 0 | +|usbh_cp2102.c | ~2200 | 0 | 0 | 0 | +|usbh_pl2303.c | ~2500 | 0 | 0 | 0 | +|usbh_gsm.c | ~300 | 0 | 0 | 0 | 其中,`sizeof(struct usbh_hub)` 和 `sizeof(struct usbh_hubport)` 受以下宏影响: @@ -176,57 +186,35 @@ x 受以下宏影响: | CDNS3(cadence) | CDNS3 | XHCI | × | | DWC3(synopsys) | DWC3 | XHCI | × | -## 文档教程 - -CherryUSB 快速入门、USB 基本概念、API 手册、Class 基本概念和例程,参考 [CherryUSB Documentation Tutorial](https://cherryusb.readthedocs.io/)。 - -## 视频教程 - -CherryUSB 课程(>= V1.4.3):https://www.bilibili.com/cheese/play/ss707687201 。 - -## 描述符生成工具 - -Cherry Descriptor: https://desc.cherry-embedded.org/zh +## Resources -## 示例仓库 +### 快速开始 -| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note | -|:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:| -|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official | -|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community | -|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official | -|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | -|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | -|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official | -|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official | -|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official | -|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official | -|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community | -|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing | -|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing | -|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update | -|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official | -|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official | -|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update | +- 📖 [CherryUSB Documentation](https://cherryusb.readthedocs.io/zh-cn/latest/) +- 💻 [CherryUSB Demo Repo](https://cherryusb.readthedocs.io/zh-cn/latest/quick_start/demo.html) +- 📺 [CherryUSB Cheese(>= V1.4.3)](https://www.bilibili.com/cheese/play/ss707687201) -## 软件包支持 +### 工具 -CherryUSB 软件包可以通过以下方式获取: +- 🌐 [Cherry Descriptor Generator](https://desc.cherry-embedded.org/zh) +- 🔧 [CDC Speed Test](https://github.com/cherry-embedded/CherryUSB/blob/master/tools/test_srcipts/test_cdc_speed.py) +- 🔧 [HID Custom Test](https://github.com/cherry-embedded/CherryUSB/blob/master/tools/test_srcipts/test_hid_inout.py) -- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB) -- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook) -- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb) +### 社区 Or 商业支持 -## 商业支持 +- 💬 [CherryUSB QQ Group](https://qm.qq.com/q/w3GnM4bkfA) +- 💬 [CherryUSB discord](https://discord.com/invite/wFfvrSAey8) +- 🙋🏽 [Commercial Support](https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html) -参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html 。 +### 软件包 -## 联系 +- 🌐 [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB) +- 🌐 [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook) +- 🌐 [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb) -CherryUSB QQ群:642693751 +### 镜像仓库 -CherryUSB 微信群:与我联系后邀请加入 +- [AtomGit](https://atomgit.com/cherry-embedded/CherryUSB) ## 支持企业 diff --git a/components/drivers/usb/cherryusb/SConscript b/components/drivers/usb/cherryusb/SConscript index b134dec2ad7..c516414c331 100644 --- a/components/drivers/usb/cherryusb/SConscript +++ b/components/drivers/usb/cherryusb/SConscript @@ -17,6 +17,8 @@ path += [cwd + '/class/dfu'] path += [cwd + '/class/serial'] path += [cwd + '/class/vendor/net'] path += [cwd + '/class/vendor/wifi'] +path += [cwd + '/class/vendor/display'] +path += [cwd + '/class/vendor/xbox'] src = [] LIBS = [] @@ -136,13 +138,17 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): src += Glob('class/cdc/usbd_cdc_ncm.c') if GetDepend(['RT_CHERRYUSB_DEVICE_DFU']): src += Glob('class/dfu/usbd_dfu.c') + if GetDepend(['RT_CHERRYUSB_DEVICE_DISPLAY']): + src += Glob('class/vendor/display/usbd_display.c') if GetDepend(['RT_CHERRYUSB_DEVICE_ADB']): src += Glob('class/adb/usbd_adb.c') src += Glob('platform/rtthread/usbd_adb_shell.c') if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV']): - src += Glob('platform/rtthread/usbd_serial.c') + src += Glob('platform/rtthread/rt_usbd_serial.c') + if GetDepend(['PKG_CHERRYUSB_DEVICE_MSC_BLKDEV']): + src += Glob('platform/rtthread/rt_usbd_msc.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM']): src += Glob('demo/cdc_acm_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_MSC']) or GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV']): @@ -165,6 +171,8 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): src += Glob('demo/cdc_ecm_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM']): src += Glob('demo/cdc_ncm_template.c') + if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_DFU']): + src += Glob('demo/dfu_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC']): src += Glob('demo/cdc_acm_msc_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID']): @@ -177,6 +185,8 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): src += Glob('demo/winusb2.0_cdc_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID']): src += Glob('demo/webusb_hid_template.c') + if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_DISPLAY']): + src += Glob('demo/display/usbdisplay_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_ADB']): src += Glob('demo/adb/usbd_adb_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV']): @@ -313,6 +323,8 @@ if GetDepend(['RT_CHERRYUSB_HOST']): src += Glob('class/serial/usbh_cp210x.c') if GetDepend(['RT_CHERRYUSB_HOST_PL2303']): src += Glob('class/serial/usbh_pl2303.c') + if GetDepend(['RT_CHERRYUSB_HOST_XBOX']): + src += Glob('class/vendor/xbox/usbh_xbox.c') if GetDepend(['RT_TEST_USBH_HID']): CPPDEFINES+=['CONFIG_TEST_USBH_HID'] @@ -325,20 +337,20 @@ if GetDepend(['RT_CHERRYUSB_HOST']): or GetDepend(['RT_CHERRYUSB_HOST_PL2303']) \ or GetDepend(['RT_CHERRYUSB_HOST_GSM']): src += Glob('class/serial/usbh_serial.c') - src += Glob('platform/rtthread/usbh_rtserial.c') + src += Glob('platform/rtthread/rt_usbh_serial.c') if GetDepend('RT_USING_DFS') and GetDepend(['RT_CHERRYUSB_HOST_MSC']): - src += Glob('platform/rtthread/usbh_dfs.c') + src += Glob('platform/rtthread/rt_usbh_msc.c') if GetDepend('RT_CHERRYUSB_HOST_CDC_ECM') \ or GetDepend('RT_CHERRYUSB_HOST_CDC_RNDIS') \ or GetDepend('RT_CHERRYUSB_HOST_CDC_NCM') \ or GetDepend('RT_CHERRYUSB_HOST_ASIX') \ or GetDepend('RT_CHERRYUSB_HOST_RTL8152'): - src += Glob('platform/rtthread/usbh_lwip.c') + src += Glob('platform/rtthread/rt_usbh_lwip.c') -src += Glob('platform/rtthread/usb_msh.c') -src += Glob('platform/rtthread/usb_check.c') +src += Glob('platform/rtthread/rt_usb_msh.c') +src += Glob('platform/rtthread/rt_usb_check.c') group = DefineGroup('UsbStack', src, depend = ['RT_USING_CHERRYUSB'], LIBS = LIBS, LIBPATH=LIBPATH, CPPPATH = path, CPPDEFINES = CPPDEFINES) diff --git a/components/drivers/usb/cherryusb/VERSION b/components/drivers/usb/cherryusb/VERSION index bf6627b8a1b..77b8ba1405c 100644 --- a/components/drivers/usb/cherryusb/VERSION +++ b/components/drivers/usb/cherryusb/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 1 VERSION_MINOR = 6 -PATCHLEVEL = 0 +PATCHLEVEL = 1 VERSION_TWEAK = 0 EXTRAVERSION = 0 diff --git a/components/drivers/usb/cherryusb/cherryusb.cmake b/components/drivers/usb/cherryusb/cherryusb.cmake index 69573249366..b705e00f9e6 100644 --- a/components/drivers/usb/cherryusb/cherryusb.cmake +++ b/components/drivers/usb/cherryusb/cherryusb.cmake @@ -27,6 +27,7 @@ # set(CONFIG_CHERRYUSB_HOST_ASIX 1) # set(CONFIG_CHERRYUSB_HOST_RTL8152 1) # set(CONFIG_CHERRYUSB_HOST_DWC2_ST 1) +# set(CONFIG_CHERRYUSB_HOST_XBOX 1) # set(CONFIG_CHERRYUSB_OSAL "freertos") # cmake-format: on @@ -50,6 +51,8 @@ list( ${CMAKE_CURRENT_LIST_DIR}/class/serial ${CMAKE_CURRENT_LIST_DIR}/class/vendor/net ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi + ${CMAKE_CURRENT_LIST_DIR}/class/vendor/display + ${CMAKE_CURRENT_LIST_DIR}/class/vendor/xbox ${CMAKE_CURRENT_LIST_DIR}/class/aoa ${CMAKE_CURRENT_LIST_DIR}/class/gamepad ) @@ -89,6 +92,9 @@ if(CONFIG_CHERRYUSB_DEVICE) if(CONFIG_CHERRYUSB_DEVICE_GAMEPAD) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/gamepad/usbd_gamepad.c) endif() + if(CONFIG_CHERRYUSB_DEVICE_DISPLAY) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/display/usbd_display.c) + endif() if(CONFIG_CHERRYUSB_DEVICE_FSDEV_ST) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/fsdev/usb_dc_fsdev.c) @@ -256,6 +262,9 @@ if(CONFIG_CHERRYUSB_HOST) if(CONFIG_CHERRYUSB_HOST_AOA) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/aoa/usbh_aoa.c) endif() + if(CONFIG_CHERRYUSB_HOST_XBOX) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/xbox/usbh_xbox.c) + endif() if(CONFIG_CHERRYUSB_HOST_CDC_ACM OR CONFIG_CHERRYUSB_HOST_CH34X @@ -371,18 +380,3 @@ if(DEFINED CONFIG_CHERRYUSB_OSAL) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_zephyr.c) endif() endif() - -if(CONFIG_CHERRYRB) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c) - list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb) -endif() - -if(CONFIG_CHERRYMP) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool.c) - list(APPEND cherryusb_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() diff --git a/components/drivers/usb/cherryusb/cherryusb_config_template.h b/components/drivers/usb/cherryusb/cherryusb_config_template.h index 9f069005288..7d3b8287d29 100644 --- a/components/drivers/usb/cherryusb/cherryusb_config_template.h +++ b/components/drivers/usb/cherryusb/cherryusb_config_template.h @@ -162,6 +162,7 @@ #define CONFIG_USBHOST_MAX_MSC_CLASS 2 #define CONFIG_USBHOST_MAX_AUDIO_CLASS 1 #define CONFIG_USBHOST_MAX_VIDEO_CLASS 1 +//#define CONFIG_USBHOST_MAX_XBOX_CLASS 2 #define CONFIG_USBHOST_DEV_NAMELEN 16 diff --git a/components/drivers/usb/cherryusb/class/adb/usbd_adb.c b/components/drivers/usb/cherryusb/class/adb/usbd_adb.c index 417439a87cc..cf7dbe881ec 100644 --- a/components/drivers/usb/cherryusb/class/adb/usbd_adb.c +++ b/components/drivers/usb/cherryusb/class/adb/usbd_adb.c @@ -114,10 +114,8 @@ void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) (void)ep; if (adb_client.common_state == ADB_STATE_READ_MSG) { - if (nbytes != sizeof(struct adb_msg)) { - USB_LOG_ERR("invalid adb msg size:%d\r\n", (unsigned int)nbytes); - return; - } + USB_ASSERT(nbytes == sizeof(struct adb_msg)); + USB_ASSERT(rx_packet.msg.data_length <= sizeof(rx_packet.payload)); USB_LOG_DBG("command:%x arg0:%x arg1:%x len:%d\r\n", rx_packet.msg.command, diff --git a/components/drivers/usb/cherryusb/class/audio/usb_audio.h b/components/drivers/usb/cherryusb/class/audio/usb_audio.h index 6c25c3de21d..68334044806 100644 --- a/components/drivers/usb/cherryusb/class/audio/usb_audio.h +++ b/components/drivers/usb/cherryusb/class/audio/usb_audio.h @@ -642,7 +642,7 @@ struct audio_cs_if_ac_feature_unit_descriptor { uint8_t bUnitID; uint8_t bSourceID; uint8_t bControlSize; - uint8_t bmaControls[1]; + uint8_t bmaControls[33]; // variable uint8_t iFeature; } __PACKED; @@ -1318,10 +1318,10 @@ struct audio_v2_control_range3_param_block { // clang-format on -#define AUDIO_V2_AS_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) +#define AUDIO_V2_AS_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) #define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_LEN (0x09) -#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08) -#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) +#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08) +#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) #define AUDIO_SAMPLE_FREQ_NUM(num) (uint8_t)(num), (uint8_t)((num >> 8)) #define AUDIO_SAMPLE_FREQ_3B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) diff --git a/components/drivers/usb/cherryusb/class/audio/usbd_audio.c b/components/drivers/usb/cherryusb/class/audio/usbd_audio.c index 2f8130e36b4..9e4e2ac02f6 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbd_audio.c +++ b/components/drivers/usb/cherryusb/class/audio/usbd_audio.c @@ -32,7 +32,7 @@ static int audio_class_endpoint_request_handler(uint8_t busid, struct usb_setup_ case AUDIO_EP_CONTROL_SAMPLING_FEQ: switch (setup->bRequest) { case AUDIO_REQUEST_SET_CUR: - memcpy((uint8_t *)&sampling_freq, *data, *len); + memcpy((uint8_t *)&sampling_freq, *data, 3); USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); usbd_audio_set_sampling_freq(busid, ep, sampling_freq); break; @@ -49,7 +49,6 @@ static int audio_class_endpoint_request_handler(uint8_t busid, struct usb_setup_ break; default: - USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); return -1; } return 0; @@ -109,7 +108,6 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup *len = 1; break; default: - USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); return -1; } } else { @@ -124,7 +122,6 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup } break; default: - //USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); return -1; } } @@ -133,7 +130,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup if (g_usbd_audio[busid].uac_version < 0x0200) { switch (setup->bRequest) { case AUDIO_REQUEST_SET_CUR: - memcpy(&volume, *data, *len); + memcpy(&volume, *data, 2); if (volume < 0x8000) { volume_db = volume / 256; } else { @@ -169,7 +166,6 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup *len = 2; break; default: - USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); return -1; } } else { @@ -186,7 +182,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup memcpy(*data, &volume, 2); *len = 2; } else { - memcpy(&volume, *data, *len); + memcpy(&volume, *data, 2); if (volume < 0x8000) { volume_db = volume / 256; } else { @@ -207,14 +203,12 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup } break; default: - //USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); return -1; } } break; default: - USB_LOG_WRN("Unhandled Audio Class cs 0x%02x \r\n", control_selector); return -1; } break; @@ -229,7 +223,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup USB_LOG_DBG("Get ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); *len = 4; } else { - memcpy(&sampling_freq, *data, setup->wLength); + memcpy(&sampling_freq, *data, 4); USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); usbd_audio_set_sampling_freq(busid, ep, sampling_freq); } @@ -247,7 +241,6 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup } break; default: - //USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); return -1; } break; @@ -261,7 +254,6 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup break; default: - //USB_LOG_WRN("Unhandled Audio Class cs 0x%02x \r\n", control_selector); return -1; } break; diff --git a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c index 4aed30fe876..22f1f19a47a 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c +++ b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c @@ -59,7 +59,7 @@ int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t s uint16_t mps; int ret; uint8_t intf = 0xff; - uint8_t altsetting = 1; + uint8_t altsetting = 0xff; if (!audio_class || !audio_class->hport) { return -USB_ERR_INVAL; @@ -88,9 +88,11 @@ int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t s } } } - return -USB_ERR_NODEV; freq_found: + if(altsetting == 0xff) { + return -USB_ERR_NODEV; + } setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = USB_REQUEST_SET_INTERFACE; @@ -150,9 +152,11 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { intf = audio_class->as_msg_table[i].stream_intf; + goto intf_found; } } +intf_found: if (intf == 0xff) { return -USB_ERR_NODEV; } @@ -208,9 +212,11 @@ int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint 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; + goto feature_found; } } +feature_found: if (feature_id == 0xff) { return -USB_ERR_NODEV; } @@ -322,9 +328,11 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ 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; + goto feature_found; } } +feature_found: if (feature_id == 0xff) { return -USB_ERR_NODEV; } @@ -404,6 +412,7 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) switch (p[DESC_bDescriptorType]) { case USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION: cur_iface_count = p[3]; + USB_ASSERT(cur_iface_count <= CONFIG_USBHOST_AUDIO_MAX_STREAMS); break; case USB_DESCRIPTOR_TYPE_INTERFACE: cur_iface = p[INTF_DESC_bInterfaceNumber]; @@ -422,18 +431,26 @@ 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; + USB_ASSERT(input_offset < CONFIG_USBHOST_AUDIO_MAX_STREAMS); + 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; + USB_ASSERT(output_offset < CONFIG_USBHOST_AUDIO_MAX_STREAMS); + 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; + USB_ASSERT(feature_unit_offset < CONFIG_USBHOST_AUDIO_MAX_STREAMS); + USB_ASSERT(desc->bControlSize == 1); + USB_ASSERT(desc->bLength <= sizeof(struct audio_cs_if_ac_feature_unit_descriptor)); + memcpy(&ac_msg_table[feature_unit_offset].ac_feature_unit, desc, desc->bLength); feature_unit_offset++; } break; @@ -452,6 +469,9 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) } break; case AUDIO_STREAMING_FORMAT_TYPE: { struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p; + + USB_ASSERT(desc->bSamFreqType == 1); + audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].num_of_altsetting = (cur_alt_setting + 1); memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_format[cur_alt_setting], desc, desc->bLength); } break; @@ -464,6 +484,7 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) { if (p[DESC_bDescriptorSubType] == AUDIO_ENDPOINT_GENERAL) { struct audio_cs_ep_ep_general_descriptor *desc = (struct audio_cs_ep_ep_general_descriptor *)p; + audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].ep_attr = desc->bmAttributes; } } diff --git a/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h index 6a8e807d3c7..a21bc3b2fc9 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h +++ b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h @@ -550,8 +550,8 @@ struct cdc_ncm_ndp16 { #define DBVAL_BE(x) ((x >> 24) & 0xFF), ((x >> 16) & 0xFF), ((x >> 8) & 0xFF), (x & 0xFF) -/*Length of template descriptor: 71 bytes*/ -#define CDC_ECM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 7 + 9 + 7 + 7) +/*Length of template descriptor: 79 bytes*/ +#define CDC_ECM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 7 + 9 + 9 + 7 + 7) // clang-format off #define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \ /* Interface Associate */ \ @@ -600,6 +600,15 @@ struct cdc_ncm_ndp16 { USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ 0x00, /* bAlternateSetting */ \ + 0x00, /* bNumEndpoints */ \ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ + 0x00, /* bInterfaceSubClass */ \ + 0x00, /* bInterfaceProtocol */ \ + 0x00, /* iInterface */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ + 0x01, /* bAlternateSetting */ \ 0x02, /* bNumEndpoints */ \ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ 0x00, /* bInterfaceSubClass */ \ @@ -619,8 +628,8 @@ struct cdc_ncm_ndp16 { 0x00 /* bInterval */ // clang-format on -/*Length of template descriptor: 77 bytes*/ -#define CDC_NCM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 7 + 7) +/*Length of template descriptor: 86 bytes*/ +#define CDC_NCM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 9 + 7 + 7) // clang-format off #define CDC_NCM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \ /* Interface Associate */ \ @@ -674,6 +683,15 @@ struct cdc_ncm_ndp16 { USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ 0x00, /* bAlternateSetting */ \ + 0x00, /* bNumEndpoints */ \ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ + 0x00, /* bInterfaceSubClass */ \ + 0x00, /* bInterfaceProtocol */ \ + 0x00, /* iInterface */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ + 0x01, /* bAlternateSetting */ \ 0x02, /* bNumEndpoints */ \ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ 0x00, /* bInterfaceSubClass */ \ diff --git a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c index a2fb87b65fd..0c911c6c579 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c @@ -39,7 +39,7 @@ static int cdc_acm_class_interface_request_handler(uint8_t busid, struct usb_set /* 4 - Space */ /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ /*******************************************************************************/ - memcpy(&line_coding, *data, setup->wLength); + memcpy(&line_coding, *data, 7); USB_LOG_DBG("Set intf:%d linecoding <%d %d %s %s>\r\n", intf_num, (unsigned int)line_coding.dwDTERate, @@ -76,7 +76,6 @@ static int cdc_acm_class_interface_request_handler(uint8_t busid, struct usb_set usbd_cdc_acm_send_break(busid, intf_num); break; default: - USB_LOG_WRN("Unhandled CDC Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } 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 2a4b77724c3..dde409071eb 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c @@ -106,7 +106,6 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set #endif break; default: - USB_LOG_WRN("Unhandled CDC ECM Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } diff --git a/components/drivers/usb/cherryusb/class/dfu/usb_dfu.h b/components/drivers/usb/cherryusb/class/dfu/usb_dfu.h index f1ccba88cfb..fd1069609fe 100644 --- a/components/drivers/usb/cherryusb/class/dfu/usb_dfu.h +++ b/components/drivers/usb/cherryusb/class/dfu/usb_dfu.h @@ -23,7 +23,7 @@ #define DFU_PROTOCOL_RUNTIME 0x01 /** DFU Class DFU mode Protocol */ -#define DFU_PROTOCOL_MODE 0x02 +#define DFU_PROTOCOL_DFU 0x02 /** * @brief DFU Class Specific Requests @@ -76,21 +76,23 @@ #define DFU_STATE_DFU_UPLOAD_IDLE 9U #define DFU_STATE_DFU_ERROR 10U -/** DFU Manifestation State */ -#define DFU_MANIFEST_COMPLETE 0U -#define DFU_MANIFEST_IN_PROGRESS 1U +/* Define DFU application notification signals. */ +#define DFU_NOTIFICATION_BEGIN_DOWNLOAD 0x1u +#define DFU_NOTIFICATION_END_DOWNLOAD 0x2u +#define DFU_NOTIFICATION_ABORT_DOWNLOAD 0x3u +#define DFU_NOTIFICATION_BEGIN_UPLOAD 0x5u +#define DFU_NOTIFICATION_END_UPLOAD 0x6u +#define DFU_NOTIFICATION_ABORT_UPLOAD 0x7u -/** Special Commands with Download Request */ -#define DFU_CMD_GETCOMMANDS 0U -#define DFU_CMD_SETADDRESSPOINTER 0x21U -#define DFU_CMD_ERASE 0x41U -#define DFU_MEDIA_ERASE 0x00U -#define DFU_MEDIA_PROGRAM 0x01U +/* Define DFU application notification signals. */ +#define DFU_MEDIA_STATUS_OK 0 +#define DFU_MEDIA_STATUS_BUSY 1 +#define DFU_MEDIA_STATUS_ERROR 2 -/** Other defines */ -/* Bit Detach capable = bit 3 in bmAttributes field */ -#define DFU_DETACH_MASK (1U << 3) -#define DFU_MANIFEST_MASK (1U << 2) +/** Special Commands with Download Request for STM32, wValue = 0 */ +#define DFU_SPECIAL_CMD_SET_ADDRESS_POINTER 0x21U +#define DFU_SPECIAL_CMD_ERASE 0x41U +#define DFU_SPECIAL_READ_UNPROTECT 0x92U /** Run-Time Functional Descriptor */ struct dfu_runtime_descriptor { @@ -103,35 +105,36 @@ struct dfu_runtime_descriptor { } __PACKED; /**\brief Payload packet to response in DFU_GETSTATUS request */ -struct dfu_info { - uint8_t bStatus; /**<\brief An indication of the status resulting from the +struct dfu_status { + uint8_t bStatus; /**<\brief An indication of the status resulting from the * execution of the most recent request.*/ - uint8_t bPollTimeout; /**<\brief Minimum time (LSB) in ms, that the host should wait + uint32_t bwPollTimeout; /**<\brief Minimum time in ms, that the host should wait * before sending a subsequent DFU_GETSTATUS request.*/ - uint16_t wPollTimeout; /**<\brief Minimum time (MSB) in ms, that the host should wait - * before sending a subsequent DFU_GETSTATUS request.*/ - uint8_t bState; /**<\brief An indication of the state that the device is going + uint8_t bState; /**<\brief An indication of the state that the device is going * to enter immediately following transmission of this response.*/ - uint8_t iString; /**<\brief Index of the status string descriptor.*/ + uint8_t iString; /**<\brief Index of the status string descriptor.*/ }; +#define DFU_DESCRIPTOR_LEN 18 + // clang-format off -#define DFU_DESCRIPTOR_INIT() \ +#define DFU_DESCRIPTOR_INIT(str_idx) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ 0x00, /* bInterfaceNumber */ \ 0x00, /* bAlternateSetting */ \ 0x00, /* bNumEndpoints Default Control Pipe only */ \ USB_DEVICE_CLASS_APP_SPECIFIC, /* bInterfaceClass */ \ - 0x01, /* bInterfaceSubClass Device Firmware Upgrade */ \ - 0x02, /* bInterfaceProtocol DFU mode */ \ - 0x04, /* iInterface */ /*!< Device Firmware Update Functional Descriptor */ \ + DFU_SUBCLASS_DFU, /* bInterfaceSubClass Device Firmware Upgrade */ \ + DFU_PROTOCOL_DFU, /* bInterfaceProtocol DFU mode */ \ + str_idx, /* iInterface */ \ + /*!< Device Firmware Update Functional Descriptor */ \ 0x09, /* bLength */ \ 0x21, /* DFU Functional Descriptor */ \ 0x0B, /* bmAttributes */ \ WBVAL(0x00ff), /* wDetachTimeOut */ \ - WBVAL(USBD_DFU_XFER_SIZE), /* wTransferSize */ \ - WBVAL(0x011a) /* bcdDFUVersion */ + WBVAL(CONFIG_USBDEV_REQUEST_BUFFER_LEN), /* wTransferSize */ \ + WBVAL(DFU_VERSION) /* bcdDFUVersion */ // clang-format on #endif /* USB_DFU_H */ diff --git a/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c b/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c index 2da382884b8..4c3e432ca03 100644 --- a/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c +++ b/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c @@ -1,465 +1,313 @@ /* - * Copyright (c) 2022, sakumisu + * Copyright (c) 2022 ~ 2026, sakumisu * * SPDX-License-Identifier: Apache-2.0 */ #include "usbd_core.h" #include "usbd_dfu.h" -/** Modify the following three parameters according to different platforms */ -#ifndef USBD_DFU_XFER_SIZE -#define USBD_DFU_XFER_SIZE 1024 -#endif - -#ifndef USBD_DFU_APP_DEFAULT_ADD -#define USBD_DFU_APP_DEFAULT_ADD 0x8004000 -#endif - -#ifndef FLASH_PROGRAM_TIME -#define FLASH_PROGRAM_TIME 50 -#endif - -#ifndef FLASH_ERASE_TIME -#define FLASH_ERASE_TIME 50 -#endif - struct usbd_dfu_priv { - struct dfu_info info; - union { - uint32_t d32[USBD_DFU_XFER_SIZE / 4U]; - uint8_t d8[USBD_DFU_XFER_SIZE]; - } buffer; - - uint32_t wblock_num; - uint32_t wlength; - uint32_t data_ptr; - uint32_t alt_setting; - - uint8_t dev_status[6]; - uint8_t ReservedForAlign[2]; - uint8_t dev_state; - uint8_t manif_state; - uint8_t firmwar_flag; + uint8_t dfu_state; } g_usbd_dfu; -static void dfu_reset(void) -{ - memset(&g_usbd_dfu, 0, sizeof(g_usbd_dfu)); - - g_usbd_dfu.alt_setting = 0U; - g_usbd_dfu.data_ptr = USBD_DFU_APP_DEFAULT_ADD; - g_usbd_dfu.wblock_num = 0U; - g_usbd_dfu.wlength = 0U; - - g_usbd_dfu.manif_state = DFU_MANIFEST_COMPLETE; - g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE; - - g_usbd_dfu.dev_status[0] = DFU_STATUS_OK; - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = DFU_STATE_DFU_IDLE; - g_usbd_dfu.dev_status[5] = 0U; -} - -static uint16_t dfu_getstatus(uint32_t add, uint8_t cmd, uint8_t *buffer) -{ - switch (cmd) { - case DFU_MEDIA_PROGRAM: - buffer[1] = (uint8_t)FLASH_PROGRAM_TIME; - buffer[2] = (uint8_t)(FLASH_PROGRAM_TIME << 8); - buffer[3] = 0; - break; - - case DFU_MEDIA_ERASE: - buffer[1] = (uint8_t)FLASH_ERASE_TIME; - buffer[2] = (uint8_t)(FLASH_ERASE_TIME << 8); - buffer[3] = 0; - default: - - break; - } - return (0); -} +const char *usbd_dfu_state_string[] = { + "APP_IDLE", + "APP_DETACH", + "DFU_IDLE", + "DFU_DNLOAD_SYNC", + "DFU_DNLOAD_BUSY", + "DFU_DNLOAD_IDLE", + "DFU_MANIFEST_SYNC", + "DFU_MANIFEST", + "DFU_MANIFEST_WAIT_RESET", + "DFU_UPLOAD_IDLE", + "DFU_ERROR" +}; -static void dfu_request_detach(void) +static int dfu_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { - if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) { - /* Update the state machine */ - g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE; - g_usbd_dfu.dev_status[0] = DFU_STATUS_OK; - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; /*bwPollTimeout=0ms*/ - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - g_usbd_dfu.dev_status[5] = 0U; /*iString*/ - g_usbd_dfu.wblock_num = 0U; - g_usbd_dfu.wlength = 0U; - } -} + USB_LOG_DBG("DFU Class request: " + "bRequest 0x%02x\r\n", + setup->bRequest); -static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) -{ - struct usb_setup_packet *req = setup; - uint32_t addr; - /* Data setup request */ - if (req->wLength > 0U) { - if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) { - /* Update the global length and block number */ - g_usbd_dfu.wblock_num = req->wValue; - g_usbd_dfu.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE); - - /* DFU Get Command */ - if (g_usbd_dfu.wblock_num == 0U) { - /* Update the state machine */ - g_usbd_dfu.dev_state = (g_usbd_dfu.wlength > 3U) ? DFU_STATE_DFU_IDLE : DFU_STATE_DFU_UPLOAD_IDLE; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - - /* Store the values of all supported commands */ - g_usbd_dfu.buffer.d8[0] = DFU_CMD_GETCOMMANDS; - g_usbd_dfu.buffer.d8[1] = DFU_CMD_SETADDRESSPOINTER; - g_usbd_dfu.buffer.d8[2] = DFU_CMD_ERASE; - - /* Send the status data over EP0 */ - memcpy(*data, g_usbd_dfu.buffer.d8, 3); - *len = 3; - } else if (g_usbd_dfu.wblock_num > 1U) { - g_usbd_dfu.dev_state = DFU_STATE_DFU_UPLOAD_IDLE; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - - addr = ((g_usbd_dfu.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + g_usbd_dfu.data_ptr; - - /* Return the physical address where data are stored */ - dfu_read_flash((uint8_t *)addr, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength); - - /* Send the status data over EP0 */ - memcpy(*data, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength); - *len = g_usbd_dfu.wlength; - } else /* unsupported g_usbd_dfu.wblock_num */ - { - g_usbd_dfu.dev_state = DFU_STATUS_ERR_STALLEDPKT; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - - /* Call the error management function (command will be NAKed */ - USB_LOG_ERR("Dfu_request_upload unsupported g_usbd_dfu.wblock_num\r\n"); + USB_LOG_DBG("dfu state:%s\r\n", usbd_dfu_state_string[g_usbd_dfu.dfu_state]); + + switch (g_usbd_dfu.dfu_state) { + case DFU_STATE_APP_IDLE: + switch (setup->bRequest) { + case DFU_REQUEST_DETACH: + break; + case DFU_REQUEST_GETSTATUS: + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; } - } - /* Unsupported state */ - else { - g_usbd_dfu.wlength = 0U; - g_usbd_dfu.wblock_num = 0U; - - /* Call the error management function (command will be NAKed */ - USB_LOG_ERR("Dfu_request_upload unsupported state\r\n"); - } - } - /* No Data setup request */ - else { - g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - } -} - -static void dfu_request_dnload(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) -{ - /* Data setup request */ - struct usb_setup_packet *req = setup; - if (req->wLength > 0U) { - if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE)) { - /* Update the global length and block number */ - g_usbd_dfu.wblock_num = req->wValue; - g_usbd_dfu.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE); - - /* Update the state machine */ - g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_SYNC; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - - /*!< Data has received complete */ - memcpy((uint8_t *)g_usbd_dfu.buffer.d8, (uint8_t *)*data, g_usbd_dfu.wlength); - /*!< Set flag = 1 Write the firmware to the flash in the next dfu_request_getstatus */ - g_usbd_dfu.firmwar_flag = 1; - } - /* Unsupported state */ - else { - USB_LOG_ERR("Dfu_request_dnload unsupported state\r\n"); - } - } - /* 0 Data DNLOAD request */ - else { - /* End of DNLOAD operation*/ - if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE)) { - g_usbd_dfu.manif_state = DFU_MANIFEST_IN_PROGRESS; - g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST_SYNC; - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - } else { - /* Call the error management function (command will be NAKed */ - USB_LOG_ERR("Dfu_request_dnload End of DNLOAD operation but dev_state %02x \r\n", g_usbd_dfu.dev_state); - } - } -} - -static int8_t dfu_getstatus_special_handler(void) -{ - uint32_t addr; - if (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_BUSY) { - /* Decode the Special Command */ - if (g_usbd_dfu.wblock_num == 0U) { - if (g_usbd_dfu.wlength == 1U) { - if (g_usbd_dfu.buffer.d8[0] == DFU_CMD_GETCOMMANDS) { - /* Nothing to do */ - } - } else if (g_usbd_dfu.wlength == 5U) { - if (g_usbd_dfu.buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER) { - g_usbd_dfu.data_ptr = g_usbd_dfu.buffer.d8[1]; - g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[2] << 8; - g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[3] << 16; - g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[4] << 24; - } else if (g_usbd_dfu.buffer.d8[0] == DFU_CMD_ERASE) { - g_usbd_dfu.data_ptr = g_usbd_dfu.buffer.d8[1]; - g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[2] << 8; - g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[3] << 16; - g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[4] << 24; - - USB_LOG_DBG("Erase start add %08x \r\n", g_usbd_dfu.data_ptr); - /*!< Erase */ - dfu_erase_flash(g_usbd_dfu.data_ptr); - } else { + break; + case DFU_STATE_APP_DETACH: + switch (setup->bRequest) { + case DFU_REQUEST_GETSTATUS: + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: return -1; - } - } else { - /* Reset the global length and block number */ - g_usbd_dfu.wlength = 0U; - g_usbd_dfu.wblock_num = 0U; - /* Call the error management function (command will be NAKed) */ - USB_LOG_ERR("Reset the global length and block number\r\n"); } - } - /* Regular Download Command */ - else { - if (g_usbd_dfu.wblock_num > 1U) { - /* Decode the required address */ - addr = ((g_usbd_dfu.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + g_usbd_dfu.data_ptr; - - /* Perform the write operation */ - /* Write flash */ - USB_LOG_DBG("Write start add %08x length %d\r\n", addr, g_usbd_dfu.wlength); - dfu_write_flash(g_usbd_dfu.buffer.d8, (uint8_t *)addr, g_usbd_dfu.wlength); + break; + case DFU_STATE_DFU_IDLE: + switch (setup->bRequest) { + case DFU_REQUEST_DNLOAD: + /* We received a DOWNLOAD command. Check the length field of the request. If it is 0, + we are done with the transfer. */ + if (setup->wLength == 0) { + usbd_dfu_end_load(); + g_usbd_dfu.dfu_state = DFU_STATE_DFU_MANIFEST_SYNC; + } else { + usbd_dfu_begin_load(); + if (usbd_dfu_write(setup->wValue, *data, setup->wLength) < 0) { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_ERROR; + return -1; + } else { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_DNLOAD_SYNC; + } + } + break; + case DFU_REQUEST_UPLOAD: + usbd_dfu_begin_load(); + + uint16_t actual_length; + if (usbd_dfu_read(setup->wValue, *data, setup->wLength, &actual_length) < 0) { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_ERROR; + return -1; + } else { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_UPLOAD_IDLE; + } + *len = actual_length; + break; + case DFU_REQUEST_ABORT: + g_usbd_dfu.dfu_state = DFU_STATE_DFU_IDLE; + break; + case DFU_REQUEST_GETSTATUS: + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; } - } - - /* Reset the global length and block number */ - g_usbd_dfu.wlength = 0U; - g_usbd_dfu.wblock_num = 0U; - - /* Update the state machine */ - g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_SYNC; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - } - return 0; -} - -static void dfu_request_getstatus(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) -{ - /*!< Determine whether to leave DFU mode */ - if (g_usbd_dfu.manif_state == DFU_MANIFEST_IN_PROGRESS && - g_usbd_dfu.dev_state == DFU_STATE_DFU_MANIFEST_SYNC && - g_usbd_dfu.dev_status[1] == 0U && - g_usbd_dfu.dev_status[2] == 0U && - g_usbd_dfu.dev_status[3] == 0U && - g_usbd_dfu.dev_status[4] == g_usbd_dfu.dev_state) { - g_usbd_dfu.manif_state = DFU_MANIFEST_COMPLETE; - - if ((0x0B & DFU_MANIFEST_MASK) != 0U) { - g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST_SYNC; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - return; - } else { - g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST_WAIT_RESET; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - /* Generate system reset to allow jumping to the user code */ - dfu_leave(); - } - } - - switch (g_usbd_dfu.dev_state) { + break; case DFU_STATE_DFU_DNLOAD_SYNC: - if (g_usbd_dfu.wlength != 0U) { - g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_BUSY; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - - if ((g_usbd_dfu.wblock_num == 0U) && (g_usbd_dfu.buffer.d8[0] == DFU_CMD_ERASE)) { - dfu_getstatus(g_usbd_dfu.data_ptr, DFU_MEDIA_ERASE, g_usbd_dfu.dev_status); - } else { - dfu_getstatus(g_usbd_dfu.data_ptr, DFU_MEDIA_PROGRAM, g_usbd_dfu.dev_status); - } - } else /* (g_usbd_dfu.wlength==0)*/ - { - g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_IDLE; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; + switch (setup->bRequest) { + case DFU_REQUEST_GETSTATUS: + g_usbd_dfu.dfu_state = DFU_STATE_DFU_DNLOAD_BUSY; + + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; } break; - - case DFU_STATE_DFU_MANIFEST_SYNC: - if (g_usbd_dfu.manif_state == DFU_MANIFEST_IN_PROGRESS) { - g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST; - - g_usbd_dfu.dev_status[1] = 1U; /*bwPollTimeout = 1ms*/ - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - } else { - if ((g_usbd_dfu.manif_state == DFU_MANIFEST_COMPLETE) && - ((0x0B & DFU_MANIFEST_MASK) != 0U)) { - g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE; - - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - } + case DFU_STATE_DFU_DNLOAD_BUSY: + switch (setup->bRequest) { + case DFU_REQUEST_GETSTATUS: + g_usbd_dfu.dfu_state = DFU_STATE_DFU_DNLOAD_IDLE; + + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; } break; - - default: - break; - } - - /* Send the status data over EP0 */ - memcpy(*data, g_usbd_dfu.dev_status, 6); - *len = 6; - - if (g_usbd_dfu.firmwar_flag == 1) { - if (dfu_getstatus_special_handler() != 0) { - USB_LOG_ERR("dfu_getstatus_special_handler error \r\n"); - } - g_usbd_dfu.firmwar_flag = 0; - } -} - -static void dfu_request_clrstatus(void) -{ - if (g_usbd_dfu.dev_state == DFU_STATE_DFU_ERROR) { - g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE; - g_usbd_dfu.dev_status[0] = DFU_STATUS_OK; /* bStatus */ - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; /* bwPollTimeout=0ms */ - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; /* bState */ - g_usbd_dfu.dev_status[5] = 0U; /* iString */ - } else { - /* State Error */ - g_usbd_dfu.dev_state = DFU_STATE_DFU_ERROR; - g_usbd_dfu.dev_status[0] = DFU_STATUS_ERR_UNKNOWN; /* bStatus */ - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; /* bwPollTimeout=0ms */ - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; /* bState */ - g_usbd_dfu.dev_status[5] = 0U; /* iString */ - } -} - -static void dfu_request_getstate(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) -{ - /* Return the current state of the DFU interface */ - (*data)[0] = g_usbd_dfu.dev_state; - *len = 1; -} - -void dfu_request_abort(void) -{ - if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) || - (g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) { - g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE; - g_usbd_dfu.dev_status[0] = DFU_STATUS_OK; - g_usbd_dfu.dev_status[1] = 0U; - g_usbd_dfu.dev_status[2] = 0U; - g_usbd_dfu.dev_status[3] = 0U; /* bwPollTimeout=0ms */ - g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; - g_usbd_dfu.dev_status[5] = 0U; /* iString */ - g_usbd_dfu.wblock_num = 0U; - g_usbd_dfu.wlength = 0U; - } -} - -static int dfu_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) -{ - USB_LOG_DBG("DFU Class request: " - "bRequest 0x%02x\r\n", - setup->bRequest); - - switch (setup->bRequest) { - case DFU_REQUEST_DETACH: - dfu_request_detach(); - break; - case DFU_REQUEST_DNLOAD: - dfu_request_dnload(setup, data, len); - break; - case DFU_REQUEST_UPLOAD: - dfu_request_upload(setup, data, len); + case DFU_STATE_DFU_DNLOAD_IDLE: + switch (setup->bRequest) { + case DFU_REQUEST_DNLOAD: + /* We received a DOWNLOAD command. Check the length field of the request. If it is 0, + we are done with the transfer. */ + if (setup->wLength == 0) { + usbd_dfu_end_load(); + g_usbd_dfu.dfu_state = DFU_STATE_DFU_MANIFEST_SYNC; + } else { + if (usbd_dfu_write(setup->wValue, *data, setup->wLength) < 0) { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_ERROR; + return -1; + } else { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_DNLOAD_SYNC; + } + } + + break; + case DFU_REQUEST_ABORT: + g_usbd_dfu.dfu_state = DFU_STATE_DFU_IDLE; + break; + case DFU_REQUEST_GETSTATUS: + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; + } break; - case DFU_REQUEST_GETSTATUS: - dfu_request_getstatus(setup, data, len); + case DFU_STATE_DFU_UPLOAD_IDLE: + switch (setup->bRequest) { + case DFU_REQUEST_UPLOAD: { + uint16_t actual_length; + if (usbd_dfu_read(setup->wValue, *data, setup->wLength, &actual_length) < 0) { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_ERROR; + return -1; + } else { + if (actual_length < setup->wLength) { + usbd_dfu_end_load(); + g_usbd_dfu.dfu_state = DFU_STATE_DFU_IDLE; + } else { + g_usbd_dfu.dfu_state = DFU_STATE_DFU_UPLOAD_IDLE; + } + } + } break; + case DFU_REQUEST_ABORT: + g_usbd_dfu.dfu_state = DFU_STATE_DFU_IDLE; + break; + case DFU_REQUEST_GETSTATUS: + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; + } break; - case DFU_REQUEST_CLRSTATUS: - dfu_request_clrstatus(); + case DFU_STATE_DFU_MANIFEST_SYNC: + switch (setup->bRequest) { + case DFU_REQUEST_GETSTATUS: + g_usbd_dfu.dfu_state = DFU_STATE_DFU_MANIFEST_WAIT_RESET; + + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; + } break; - case DFU_REQUEST_GETSTATE: - dfu_request_getstate(setup, data, len); + case DFU_STATE_DFU_MANIFEST_WAIT_RESET: + switch (setup->bRequest) { + case DFU_REQUEST_GETSTATUS: + + (*data)[0] = DFU_STATUS_OK; /* bStatus */ + (*data)[1] = 0; + (*data)[2] = 0; + (*data)[3] = 0; + (*data)[4] = g_usbd_dfu.dfu_state; + (*data)[5] = 0; /* iString */ + *len = 6; + + usbd_dfu_reset(); + + break; + case DFU_REQUEST_GETSTATE: + (*data)[0] = g_usbd_dfu.dfu_state; + *len = 1; + break; + + default: + return -1; + } break; - case DFU_REQUEST_ABORT: - dfu_request_abort(); + case DFU_STATE_DFU_ERROR: + switch (setup->bRequest) { + case DFU_REQUEST_CLRSTATUS: + g_usbd_dfu.dfu_state = DFU_STATE_DFU_IDLE; + break; + + default: + return -1; + } break; + default: - USB_LOG_WRN("Unhandled DFU Class bRequest 0x%02x\r\n", setup->bRequest); + USB_LOG_WRN("Invalid dfu state %s\r\n", usbd_dfu_state_string[g_usbd_dfu.dfu_state]); return -1; } - return 0; } @@ -467,7 +315,7 @@ static void dfu_notify_handler(uint8_t busid, uint8_t event, void *arg) { switch (event) { case USBD_EVENT_RESET: - dfu_reset(); + g_usbd_dfu.dfu_state = DFU_STATE_DFU_IDLE; break; default: break; @@ -484,21 +332,29 @@ struct usbd_interface *usbd_dfu_init_intf(struct usbd_interface *intf) return intf; } -__WEAK uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len) +uint8_t usbd_dfu_get_state(void) { - return dest; + return g_usbd_dfu.dfu_state; } -__WEAK uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len) +__WEAK void usbd_dfu_begin_load(void) { - return 0; } -__WEAK uint16_t dfu_erase_flash(uint32_t add) +__WEAK void usbd_dfu_end_load(void) +{ +} + +__WEAK void usbd_dfu_reset(void) { - return 0; } -__WEAK void dfu_leave(void) +__WEAK int usbd_dfu_write(uint16_t value, const uint8_t *data, uint16_t length) { + return 0; } + +__WEAK int usbd_dfu_read(uint16_t value, const uint8_t *data, uint16_t length, uint16_t *actual_length) +{ + return 0; +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.h b/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.h index 9081d0dda1c..cec005c1c47 100644 --- a/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.h +++ b/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, sakumisu + * Copyright (c) 2022 ~ 2026, sakumisu * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,12 +14,14 @@ extern "C" { /* Init dfu interface driver */ struct usbd_interface *usbd_dfu_init_intf(struct usbd_interface *intf); +uint8_t usbd_dfu_get_state(void); + +void usbd_dfu_begin_load(void); +void usbd_dfu_end_load(void); +void usbd_dfu_reset(void); +int usbd_dfu_write(uint16_t value, const uint8_t *data, uint16_t length); +int usbd_dfu_read(uint16_t value, const uint8_t *data, uint16_t length, uint16_t *actual_length); -/* Interface functions that need to be implemented by the user */ -uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len); -uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len); -uint16_t dfu_erase_flash(uint32_t add); -void dfu_leave(void); #ifdef __cplusplus } #endif diff --git a/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c b/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c index 8ffbfda8a3a..37eb040c342 100644 --- a/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c +++ b/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c @@ -13,11 +13,11 @@ static int xinput_vendor_class_request_handler(uint8_t busid, struct usb_setup_p { struct xinput_in_report xinput_report; - memset(&xinput_report, 0, sizeof(xinput_report)); + memset(&xinput_report, 0, sizeof(struct xinput_in_report)); xinput_report.report_size = 20; - memcpy(*data, &xinput_report, sizeof(xinput_report)); - *len = sizeof(xinput_report); + memcpy(*data, &xinput_report, sizeof(struct xinput_in_report)); + *len = sizeof(struct xinput_in_report); return 0; } @@ -26,7 +26,7 @@ int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *repor struct xinput_in_report *xinput_report; xinput_report = (struct xinput_in_report *)gamepad_report_buffer; - memset(xinput_report, 0, sizeof(xinput_report)); + memset(xinput_report, 0, sizeof(struct xinput_in_report)); xinput_report->report_size = 20; if (report->buttons & USB_GAMEPAD_BUTTON_DU) @@ -105,7 +105,7 @@ int usbd_gamepad_switch_send_report(uint8_t ep, struct usb_gamepad_report *repor struct switch_in_report *switch_report; switch_report = (struct switch_in_report *)gamepad_report_buffer; - memset(switch_report, 0, sizeof(switch_report)); + memset(switch_report, 0, sizeof(struct switch_in_report)); if (report->buttons & USB_GAMEPAD_BUTTON_S1) switch_report->buttons |= SWITCH_MASK_MINUS; diff --git a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c index fed749f2f4b..ad8dfa22ab6 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c +++ b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c @@ -41,7 +41,6 @@ static int hid_class_interface_request_handler(uint8_t busid, struct usb_setup_p break; default: - USB_LOG_WRN("Unhandled HID Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c index 4fd1a91a014..7dddf915576 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c +++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c @@ -296,40 +296,29 @@ static uint32_t hid_get_itemval(const uint8_t *data, unsigned int idx, unsigned return value; } -struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_len, uint32_t max_usages) +int usbh_hid_parse_report_descriptor(const uint8_t *report_data, uint32_t report_size, struct usbh_hid_report_info *report_info) { + struct usbh_hid_report_item_attribute current_item_attr = { 0 }; + struct usbh_hid_report_item *current_item = NULL; + uint32_t itemtag, itemtype, itemsize, itemval; + uint16_t temp_usage; + uint32_t total_report_size[3] = { 0 }; /* input, output, feature */ uint32_t i = 0; - uint32_t itemtag, itemtype, itemsize; - uint32_t itemval; - struct hid_report_field field; - uint32_t usage_page = 0, usage = 0, usage_min = 0, usage_max = 0, flags = 0; - uint32_t *usages; - struct hid_report *hid_report; - - hid_report = usb_osal_malloc(sizeof(struct hid_report)); - if (!hid_report) { - USB_LOG_ERR("hid report malloc failed\r\n"); - return NULL; - } - - usages = usb_osal_malloc(sizeof(uint32_t) * max_usages); - if (!usages) { - USB_LOG_ERR("hid usages malloc failed\r\n"); - goto err; - } - memset(hid_report, 0, sizeof(struct hid_report)); - memset(&field, 0, sizeof(struct hid_report_field)); + memset(report_info, 0, sizeof(struct usbh_hid_report_info)); + memset(¤t_item_attr, 0, sizeof(struct usbh_hid_report_item_attribute)); + current_item_attr.usage_min = 0xffff; + current_item_attr.usage_max = 0; - while (i < report_len) { - itemtag = data[i] & HID_TAG_MASK; - itemtype = data[i] & HID_TYPE_MASK; - itemsize = data[i] & HID_SIZE_MASK; + while (i < report_size) { + itemtag = report_data[i] & HID_TAG_MASK; + itemtype = report_data[i] & HID_TYPE_MASK; + itemsize = report_data[i] & HID_SIZE_MASK; if (itemsize == 3) /* HID spec: 6.2.2.2 - Short Items */ itemsize = 4; - itemval = hid_get_itemval(data, i, itemsize); + itemval = hid_get_itemval(report_data, i, itemsize); USB_LOG_DBG("itemtype 0x%02x, itemtag 0x%02x, itemsize %d, itemval 0x%08x\r\n", itemtype, itemtag, itemsize, itemval); @@ -338,88 +327,37 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le case HID_ITEMTYPE_MAIN: switch (itemtag) { case HID_MAINITEM_TAG_INPUT: - if ((flags & HID_REPORT_FLAG_REQUIRED_MASK) != HID_REPORT_FLAG_REQUIRED_MASK) - goto err; - - if (hid_report->input_count >= CONFIG_USBHOST_HID_MAX_INPUT) { - USB_LOG_ERR("hid input fields exceed max limit\r\n"); + case HID_MAINITEM_TAG_OUTPUT: + case HID_MAINITEM_TAG_FEATURE: + if (report_info->report_item_count == CONFIG_USB_HID_MAX_REPORT_ITEMS) { goto err; } - field.flags = flags; - field.properties = itemval; - field.usage_page = usage_page; - memcpy(&hid_report->input_fields[hid_report->input_count], &field, sizeof(struct hid_report_field)); - if (field.usage_count > 0) { - hid_report->input_fields[hid_report->input_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count); - if (!hid_report->input_fields[hid_report->input_count].usages) { - USB_LOG_ERR("hid input usages malloc failed\r\n"); - goto err; - } - memcpy(hid_report->input_fields[hid_report->input_count].usages, usages, sizeof(uint32_t) * field.usage_count); - } - - hid_report->input_count++; - - /* only keep the global items */ - flags &= HID_REPORT_FLAG_GLOBAL_MASK; - memset(&field, 0, sizeof(struct hid_report_field)); - break; - case HID_MAINITEM_TAG_OUTPUT: - if ((flags & HID_REPORT_FLAG_REQUIRED_MASK) != HID_REPORT_FLAG_REQUIRED_MASK) - goto err; + current_item = &report_info->report_items[report_info->report_item_count]; + current_item->report_flags = itemval; - if (hid_report->output_count >= CONFIG_USBHOST_HID_MAX_OUTPUT) { - USB_LOG_ERR("hid output fields exceed max limit\r\n"); - goto err; + if (itemtag == HID_MAINITEM_TAG_INPUT) { + current_item->report_type = HID_REPORT_INPUT; + } else if (itemtag == HID_MAINITEM_TAG_OUTPUT) { + current_item->report_type = HID_REPORT_OUTPUT; + } else { + current_item->report_type = HID_REPORT_FEATURE; } - field.flags = flags; - field.properties = itemval; - field.usage_page = usage_page; - memcpy(&hid_report->output_fields[hid_report->output_count], &field, sizeof(struct hid_report_field)); - if (field.usage_count > 0) { - hid_report->output_fields[hid_report->output_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count); - if (!hid_report->output_fields[hid_report->output_count].usages) { - USB_LOG_ERR("hid output usages malloc failed\r\n"); - goto err; - } - memcpy(hid_report->output_fields[hid_report->output_count].usages, usages, sizeof(uint32_t) * field.usage_count); - } + current_item->report_bit_offset = total_report_size[current_item->report_type - 1]; + total_report_size[current_item->report_type - 1] += current_item_attr.report_size * current_item_attr.report_count; - hid_report->output_count++; + memcpy(¤t_item->attribute, ¤t_item_attr, sizeof(struct usbh_hid_report_item_attribute)); + report_info->report_item_count++; - /* only keep the global items */ - flags &= HID_REPORT_FLAG_GLOBAL_MASK; - memset(&field, 0, sizeof(struct hid_report_field)); + // reset for next item + current_item_attr.usage_min = 0xffff; + current_item_attr.usage_max = 0; break; case HID_MAINITEM_TAG_COLLECTION: - memset(&field, 0, sizeof(struct hid_report_field)); - break; - case HID_MAINITEM_TAG_FEATURE: - - if (hid_report->feature_count >= CONFIG_USBHOST_HID_MAX_FEATURE) { - USB_LOG_ERR("hid feature fields exceed max limit\r\n"); - goto err; - } - - field.flags = flags; - field.properties = itemval; - field.usage_page = usage_page; - memcpy(&hid_report->feature_fields[hid_report->feature_count], &field, sizeof(struct hid_report_field)); - if (field.usage_count > 0) { - hid_report->feature_fields[hid_report->feature_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count); - if (!hid_report->feature_fields[hid_report->feature_count].usages) { - USB_LOG_ERR("hid feature usages malloc failed\r\n"); - goto err; - } - memcpy(hid_report->feature_fields[hid_report->feature_count].usages, usages, sizeof(uint32_t) * field.usage_count); - } - - hid_report->feature_count++; - - memset(&field, 0, sizeof(struct hid_report_field)); - + // reset for next item + current_item_attr.usage_min = 0xffff; + current_item_attr.usage_max = 0; break; case HID_MAINITEM_TAG_ENDCOLLECTION: break; @@ -430,33 +368,34 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le case HID_ITEMTYPE_GLOBAL: switch (itemtag) { case HID_GLOBALITEM_TAG_USAGE_PAGE: - usage_page = itemval; - - if (usage_page > UINT16_MAX) - goto err; - - flags |= HID_REPORT_FLAG_USAGE_PAGE; + current_item_attr.usage_page = (uint16_t)itemval; break; case HID_GLOBALITEM_TAG_LOGICAL_MIN: - field.logical_min = (int32_t)itemval; - flags |= HID_REPORT_FLAG_LOGICAL_MIN; + current_item_attr.logical_min = itemval; break; case HID_GLOBALITEM_TAG_LOGICAL_MAX: - field.logical_max = (int32_t)itemval; - flags |= HID_REPORT_FLAG_LOGICAL_MAX; + current_item_attr.logical_max = itemval; + break; + case HID_GLOBALITEM_TAG_PHYSICAL_MIN: + current_item_attr.physical_min = itemval; + break; + case HID_GLOBALITEM_TAG_PHYSICAL_MAX: + current_item_attr.physical_max = itemval; + break; + case HID_GLOBALITEM_TAG_UNIT_EXP: + current_item_attr.unit_exponent = itemval; + break; + case HID_GLOBALITEM_TAG_UNIT: + current_item_attr.unit = itemval; break; case HID_GLOBALITEM_TAG_REPORT_SIZE: - field.report_size = itemval; - flags |= HID_REPORT_FLAG_REPORT_SIZE; + current_item_attr.report_size = itemval; break; case HID_GLOBALITEM_TAG_REPORT_COUNT: - field.report_count = itemval; - flags |= HID_REPORT_FLAG_REPORT_COUNT; + current_item_attr.report_count = itemval; break; case HID_GLOBALITEM_TAG_REPORT_ID: - hid_report->uses_report_id = true; - field.report_id = itemval; - flags |= HID_REPORT_FLAG_REPORT_ID; + current_item_attr.report_id = itemval; break; default: goto err; @@ -465,64 +404,20 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le case HID_ITEMTYPE_LOCAL: switch (itemtag) { case HID_LOCALITEM_TAG_USAGE: - usage = itemval; - /* Extended usage (size 4) combines both usage page and id */ - if (itemsize != 4) { - if (!(flags & HID_REPORT_FLAG_USAGE_PAGE)) - goto err; - usage |= usage_page << 16; + if (itemsize == 4) { + temp_usage = (uint16_t)(itemval >> 16); + } else { + temp_usage = (uint16_t)itemval; } - - usages[field.usage_count++] = usage; + current_item_attr.usage_min = MIN(current_item_attr.usage_min, temp_usage); + current_item_attr.usage_max = MAX(current_item_attr.usage_max, temp_usage); break; case HID_LOCALITEM_TAG_USAGE_MIN: - usage_min = itemval; - if (itemsize == 4) { - /* Usage max must be extended as well */ - flags |= HID_REPORT_FLAG_EXTENDED_USAGE; - } else { - if (!(flags & HID_REPORT_FLAG_USAGE_PAGE)) - goto err; - usage_min |= usage_page << 16; - } - field.usage_min = usage_min; - flags |= HID_REPORT_FLAG_USAGE_MIN; + current_item_attr.usage_min = (uint16_t)itemval; break; case HID_LOCALITEM_TAG_USAGE_MAX: - if (!(flags & HID_REPORT_FLAG_USAGE_MIN)) - goto err; - - usage_max = itemval; - if (flags & HID_REPORT_FLAG_EXTENDED_USAGE) { - /* Fail if max is not extended usage (HID spec 6.2.2.8) */ - if (itemsize != 4) - goto err; - } else if (itemsize == 4) { - /* Fail because min wasn't extended, but max is */ - goto err; - } else { - if (!(flags & HID_REPORT_FLAG_USAGE_PAGE)) - goto err; - usage_max |= usage_page << 16; - } - - /* Usage min and max must be on the same page */ - if (USAGE_PAGE(usage_min) != USAGE_PAGE(usage_max)) { - goto err; - } - - if (usage_min > usage_max) { - goto err; - } - - for (uint32_t j = usage_min; j <= usage_max; j++) { - usages[field.usage_count++] = j; - } - - field.usage_max = usage_max; - flags |= HID_REPORT_FLAG_USAGE_MAX; - flags &= ~(HID_REPORT_FLAG_USAGE_MIN | HID_REPORT_FLAG_EXTENDED_USAGE); + current_item_attr.usage_max = (uint16_t)itemval; break; default: goto err; @@ -534,127 +429,83 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le i += (1 + itemsize); } - usb_osal_free(usages); - return hid_report; + + return 0; err: - if (hid_report) { - usb_osal_free(hid_report); + return -1; +} - for (uint32_t j = 0; j < hid_report->input_count; j++) - usb_osal_free(hid_report->input_fields[j].usages); +int usbh_hid_report_convert(struct usbh_hid_report_item *item, const uint8_t *report_buf, uint32_t *output1, uint8_t **output2, uint32_t *output_len) +{ + const uint8_t *src; + uint32_t bits_len = item->attribute.report_size * item->attribute.report_count; - for (uint32_t j = 0; j < hid_report->output_count; j++) - usb_osal_free(hid_report->output_fields[j].usages); + if(bits_len == 0) { + return -1; + } - for (uint32_t j = 0; j < hid_report->feature_count; j++) - usb_osal_free(hid_report->feature_fields[j].usages); + if (item->report_flags & HID_MAINITEM_CONSTANT) { + return -1; } - if (usages) - usb_osal_free(usages); - return NULL; -} + if (item->attribute.report_id > 0) { + if (report_buf[0] != item->attribute.report_id) { + return -2; /* report id mismatch */ + } -void usbh_hid_report_free(struct hid_report *hid_report) -{ - if (hid_report) { - for (uint32_t j = 0; j < hid_report->input_count; j++) - usb_osal_free(hid_report->input_fields[j].usages); + src = report_buf + 1; /* skip report id */ + } else { + src = report_buf; + } - for (uint32_t j = 0; j < hid_report->output_count; j++) - usb_osal_free(hid_report->output_fields[j].usages); + if ((bits_len < 32) && (bits_len % 8 != 0)) { + *output1 = 0; - for (uint32_t j = 0; j < hid_report->feature_count; j++) - usb_osal_free(hid_report->feature_fields[j].usages); + for (uint32_t i = 0; i < bits_len; i++) { + *output1 |= ((src[item->report_bit_offset / 8] >> ((item->report_bit_offset % 8) + i)) & 0x01) << i; + } + + *output2 = NULL; + *output_len = (bits_len + 7) / 8; + return 0; + } else if (bits_len % 8 == 0) { + if (item->report_bit_offset % 8 != 0) { + /* currently do not support item that is not byte aligned */ + return -3; + } - usb_osal_free(hid_report); + uint32_t byte_len = bits_len / 8; + *output2 = (uint8_t *)src + item->report_bit_offset / 8; + *output_len = byte_len; + return 0; } + return -4; } -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_report_buf[2048]; - -static const char *hid_property_string(uint32_t value) +static void usbh_hid_item_info_print(struct usbh_hid_report_item *item) { - uint32_t off = 0; - static char buffer[160]; - - memset(buffer, 0, sizeof(buffer)); - - if (value & HID_MAINITEM_CONSTANT) - off += snprintf(buffer + off, sizeof(buffer) - off, "Constant, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Data, "); - - if (value & HID_MAINITEM_VARIABLE) - off += snprintf(buffer + off, sizeof(buffer) - off, "Variable, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Array, "); - - if (value & HID_MAINITEM_RELATIVE) - off += snprintf(buffer + off, sizeof(buffer) - off, "Relative, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Absolute, "); - - if (value & HID_MAINITEM_WRAP) - off += snprintf(buffer + off, sizeof(buffer) - off, "Wrap, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "NoWrap, "); - - if (value & HID_MAINITEM_NONLINEAR) - off += snprintf(buffer + off, sizeof(buffer) - off, "NonLinear, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Linear, "); - - if (value & HID_MAINITEM_NOPREFERRED) - off += snprintf(buffer + off, sizeof(buffer) - off, "NoPreferred, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Preferred, "); - - if (value & HID_MAINITEM_NULLSTATE) - off += snprintf(buffer + off, sizeof(buffer) - off, "NullState, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "NoNullState, "); - - if (value & HID_MAINITEM_VOLATILE) - off += snprintf(buffer + off, sizeof(buffer) - off, "Volatile, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "NonVolatile, "); - - if (value & HID_MAINITEM_BUFFEREDBYTES) - off += snprintf(buffer + off, sizeof(buffer) - off, "BufferedBytes"); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "BitField"); - - return buffer; - + USB_LOG_RAW("Item Type: %s\r\n", (unsigned int)item->report_type == HID_REPORT_INPUT ? "Input" : + (unsigned int)item->report_type == HID_REPORT_OUTPUT ? "Output" : + "Feature"); + USB_LOG_RAW("Usage Page: 0x%04x\r\n", (unsigned int)item->attribute.usage_page); + USB_LOG_RAW("Report ID: 0x%04x\r\n", (unsigned int)item->attribute.report_id); + USB_LOG_RAW("Report Size: %ubit\r\n", (unsigned int)item->attribute.report_size); + USB_LOG_RAW("Report Count: %u\r\n", (unsigned int)item->attribute.report_count); + USB_LOG_RAW("Usages(0x%04x ~ 0x%04x)\r\n", (unsigned int)item->attribute.usage_min, (unsigned int)item->attribute.usage_max); + USB_LOG_RAW("Logical Min: %d\r\n", item->attribute.logical_min); + USB_LOG_RAW("Logical Max: %d\r\n", item->attribute.logical_max); + USB_LOG_RAW("Properties: 0x%04x\r\n", (unsigned int)item->report_flags); + USB_LOG_RAW("Bit Offset: 0x%04x\r\n", (unsigned int)item->report_bit_offset); + USB_LOG_RAW("\r\n"); } -static void usbh_hid_field_info_print(uint32_t idx, struct hid_report_field *field) -{ - USB_LOG_RAW(" Field %u:\r\n", idx); - USB_LOG_RAW(" Usage Page: 0x%04x\r\n", (unsigned int)field->usage_page); - USB_LOG_RAW(" Report ID: %u\r\n", (unsigned int)field->report_id); - USB_LOG_RAW(" Report Size: %ubit\r\n", (unsigned int)field->report_size); - USB_LOG_RAW(" Report Count: %u\r\n", (unsigned int)field->report_count); - USB_LOG_RAW(" Logical Min: %d\r\n", field->logical_min); - USB_LOG_RAW(" Logical Max: %d\r\n", field->logical_max); - USB_LOG_RAW(" Usage Count: %u\r\n", (unsigned int)field->usage_count); - if (field->usage_count > 0) { - if (field->usage_count == 1) { - USB_LOG_RAW(" Usage: 0x%04x\r\n", USAGE_ID(field->usages[0])); - } else { - USB_LOG_RAW(" Usages(0x%04x ~ 0x%04x)\r\n", USAGE_ID(field->usage_min), USAGE_ID(field->usage_max)); - } - } - USB_LOG_RAW(" Flags: 0x%04x\r\n", (unsigned int)field->flags); - USB_LOG_RAW(" Properties: 0x%04x(%s)\r\n", (unsigned int)field->properties, hid_property_string(field->properties)); -} +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_report_desc_buf[2048]; int lshid(int argc, char **argv) { struct usbh_hid *hid_class; - struct hid_report *hid_report; int ret; + struct usbh_hid_report_info report_info = { 0 }; if (argc < 2) { USB_LOG_ERR("please input correct command: lshid path\r\n"); @@ -667,43 +518,28 @@ int lshid(int argc, char **argv) return -1; } - if (hid_class->report_size > sizeof(g_hid_report_buf)) { + if (hid_class->report_size > sizeof(g_hid_report_desc_buf)) { USB_LOG_ERR("hid report buffer is too small\r\n"); return -1; } - ret = usbh_hid_get_report_descriptor(hid_class, g_hid_report_buf, hid_class->report_size); + ret = usbh_hid_get_report_descriptor(hid_class, g_hid_report_desc_buf, hid_class->report_size); if (ret < 0) { USB_LOG_ERR("get hid report descriptor failed, errcode: %d\r\n", ret); return -1; } - hid_report = usbh_hid_report_parse(g_hid_report_buf, hid_class->report_size, 1024); - if (hid_report) { - USB_LOG_RAW("HID report parsed successfully\r\n"); - - USB_LOG_RAW("Input fields: %u\r\n", (unsigned int)hid_report->input_count); - for (uint32_t i = 0; i < hid_report->input_count; i++) { - struct hid_report_field *field = &hid_report->input_fields[i]; - usbh_hid_field_info_print(i, field); - } - - USB_LOG_RAW("Output fields: %u\r\n", (unsigned int)hid_report->output_count); - for (uint32_t i = 0; i < hid_report->output_count; i++) { - struct hid_report_field *field = &hid_report->output_fields[i]; - usbh_hid_field_info_print(i, field); - } - - USB_LOG_RAW("Feature fields: %u\r\n", (unsigned int)hid_report->feature_count); - for (uint32_t i = 0; i < hid_report->feature_count; i++) { - struct hid_report_field *field = &hid_report->feature_fields[i]; - usbh_hid_field_info_print(i, field); - } + ret = usbh_hid_parse_report_descriptor(g_hid_report_desc_buf, hid_class->report_size, &report_info); + if (ret < 0) { + USB_LOG_ERR("parse hid report descriptor failed\r\n"); + return -1; + } - usbh_hid_report_free(hid_report); - } else { - USB_LOG_ERR("HID report parsed failed\r\n"); + USB_LOG_INFO("HID report item count: %u\r\n", report_info.report_item_count); + for (uint32_t i = 0; i < report_info.report_item_count; i++) { + usbh_hid_item_info_print(&report_info.report_items[i]); } + return 0; } diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h index fa5c7663afe..26b22555204 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h +++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h @@ -8,80 +8,37 @@ #include "usb_hid.h" -/* local items */ -#define HID_REPORT_FLAG_USAGE_MIN (1 << 0) -#define HID_REPORT_FLAG_USAGE_MAX (1 << 1) - -/* global items */ -#define HID_REPORT_FLAG_REPORT_ID (1 << 2) -#define HID_REPORT_FLAG_REPORT_COUNT (1 << 3) -#define HID_REPORT_FLAG_REPORT_SIZE (1 << 4) -#define HID_REPORT_FLAG_LOGICAL_MIN (1 << 5) -#define HID_REPORT_FLAG_LOGICAL_MAX (1 << 6) -#define HID_REPORT_FLAG_USAGE_PAGE (1 << 7) - -/* main items */ -#define HID_REPORT_FLAG_INPUT (1 << 8) -#define HID_REPORT_FLAG_OUTPUT (1 << 9) -#define HID_REPORT_FLAG_FEATURE (1 << 10) - -#define HID_REPORT_FLAG_EXTENDED_USAGE (1 << 11) - -/* masks */ - -#define HID_REPORT_FLAG_GLOBAL_MASK (HID_REPORT_FLAG_REPORT_ID | \ - HID_REPORT_FLAG_REPORT_COUNT | \ - HID_REPORT_FLAG_REPORT_SIZE | \ - HID_REPORT_FLAG_LOGICAL_MIN | \ - HID_REPORT_FLAG_LOGICAL_MAX | \ - HID_REPORT_FLAG_USAGE_PAGE) - -#define HID_REPORT_FLAG_REQUIRED_MASK (HID_REPORT_FLAG_REPORT_COUNT | \ - HID_REPORT_FLAG_REPORT_SIZE | \ - HID_REPORT_FLAG_LOGICAL_MIN | \ - HID_REPORT_FLAG_LOGICAL_MAX) - -#define USAGE_ID(usage) (usage & 0x0000FFFF) -#define USAGE_PAGE(usage) ((usage & 0xFFFF0000) >> 16) - -#ifndef CONFIG_USBHOST_HID_MAX_INPUT -#define CONFIG_USBHOST_HID_MAX_INPUT 16 +#ifndef CONFIG_USB_HID_MAX_REPORT_ITEMS +#define CONFIG_USB_HID_MAX_REPORT_ITEMS 16 #endif -#ifndef CONFIG_USBHOST_HID_MAX_OUTPUT -#define CONFIG_USBHOST_HID_MAX_OUTPUT 16 -#endif - -#ifndef CONFIG_USBHOST_HID_MAX_FEATURE -#define CONFIG_USBHOST_HID_MAX_FEATURE 16 -#endif - -struct hid_report_field { - uint32_t *usages; /* usage page + usage */ - uint32_t usage_count; - uint32_t usage_page; - - uint32_t report_id; /* optional */ - uint32_t report_count; - uint32_t report_size; +struct usbh_hid_report_item_attribute { + uint16_t usage_page; + uint16_t usage_min; + uint16_t usage_max; int32_t logical_min; int32_t logical_max; - uint32_t properties; + uint32_t physical_min; + uint32_t physical_max; + uint32_t unit_exponent; + uint32_t unit; + uint32_t report_count; + uint8_t report_size; + uint8_t report_id; +}; - uint32_t usage_min; - uint32_t usage_max; +struct usbh_hid_report_item { + uint8_t report_type; /* input, output, feature */ + uint16_t report_flags; + uint32_t report_bit_offset; - uint32_t flags; + struct usbh_hid_report_item_attribute attribute; }; -struct hid_report { - bool uses_report_id; - uint32_t input_count; - struct hid_report_field input_fields[CONFIG_USBHOST_HID_MAX_INPUT]; - uint32_t output_count; - struct hid_report_field output_fields[CONFIG_USBHOST_HID_MAX_OUTPUT]; - uint32_t feature_count; - struct hid_report_field feature_fields[CONFIG_USBHOST_HID_MAX_FEATURE]; +struct usbh_hid_report_info { + struct usbh_hid_report_item report_items[CONFIG_USB_HID_MAX_REPORT_ITEMS]; + uint32_t report_item_count; + bool using_report_id; }; struct usbh_hid { @@ -112,8 +69,8 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol); int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen); int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen); -struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_len, uint32_t max_usages); -void usbh_hid_report_free(struct hid_report *hid_report); +int usbh_hid_parse_report_descriptor(const uint8_t *report_data, uint32_t report_size, struct usbh_hid_report_info *report_info); +int usbh_hid_report_convert(struct usbh_hid_report_item *item, const uint8_t *report_buf, uint32_t *output1, uint8_t **output2, uint32_t *output_len); void usbh_hid_run(struct usbh_hid *hid_class); void usbh_hid_stop(struct usbh_hid *hid_class); diff --git a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c index 910aa0c2cd2..5538de864bf 100644 --- a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c +++ b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c @@ -642,6 +642,7 @@ static void usbh_hub_events(struct usbh_hub *hub) child->speed = speed; child->bus = hub->bus; child->mutex = usb_osal_mutex_create(); + USB_ASSERT(child->mutex != NULL); USB_LOG_INFO("New %s device on Bus %u, Hub %u, Port %u connected\r\n", speed_table[speed], hub->bus->busid, hub->index, port + 1); @@ -677,21 +678,35 @@ static void usbh_hub_events(struct usbh_hub *hub) static void usbh_hub_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) { struct usbh_hub *hub; + struct usbh_hubport *hport; int ret = 0; struct usbh_bus *bus = (struct usbh_bus *)CONFIG_USB_OSAL_THREAD_GET_ARGV; - usb_hc_init(bus); bus->event_handler(bus->busid, USB_HUB_INDEX_ANY, USB_HUB_PORT_ANY, USB_INTERFACE_ANY, USBH_EVENT_INIT); + usb_hc_init(bus); + while (1) { ret = usb_osal_mq_recv(bus->hub_mq, (uintptr_t *)&hub, USB_OSAL_WAITING_FOREVER); if (ret < 0) { continue; } - usb_osal_mutex_take(bus->mutex); + if (hub == NULL) { + break; + } usbh_hub_events(hub); - usb_osal_mutex_give(bus->mutex); } + + hub = &bus->hcd.roothub; + for (uint8_t port = 0; port < hub->nports; port++) { + hport = &hub->child[port]; + + usbh_hubport_release(hport); + } + usb_hc_deinit(bus); + usb_osal_mq_delete(bus->hub_mq); + usb_osal_sem_give(bus->hub_sem); + usb_osal_thread_delete(NULL); } void usbh_hub_thread_wakeup(struct usbh_hub *hub) @@ -720,9 +735,9 @@ int usbh_hub_initialize(struct usbh_bus *bus) return -1; } - bus->mutex = usb_osal_mutex_create(); - if (bus->mutex == NULL) { - USB_LOG_ERR("Failed to create bus mutex\r\n"); + bus->hub_sem = usb_osal_sem_create(0); + if (bus->hub_sem == NULL) { + USB_LOG_ERR("Failed to create hub sem\r\n"); return -1; } @@ -737,24 +752,18 @@ int usbh_hub_initialize(struct usbh_bus *bus) int usbh_hub_deinitialize(struct usbh_bus *bus) { - struct usbh_hubport *hport; - struct usbh_hub *hub; - - usb_osal_mutex_take(bus->mutex); - hub = &bus->hcd.roothub; - for (uint8_t port = 0; port < hub->nports; port++) { - hport = &hub->child[port]; - - usbh_hubport_release(hport); + if (!bus->hub_mq || !bus->hub_sem) { + return -USB_ERR_INVAL; } - usb_hc_deinit(bus); + usb_osal_mq_send(bus->hub_mq, (uintptr_t)NULL); + usb_osal_sem_take(bus->hub_sem, USB_OSAL_WAITING_FOREVER); + usb_osal_sem_delete(bus->hub_sem); + bus->hub_mq = NULL; + bus->hub_sem = NULL; - usb_osal_thread_delete(bus->hub_thread); - usb_osal_mq_delete(bus->hub_mq); + bus->event_handler(bus->busid, USB_HUB_INDEX_ANY, USB_HUB_PORT_ANY, USB_INTERFACE_ANY, USBH_EVENT_DEINIT); - usb_osal_mutex_give(bus->mutex); - usb_osal_mutex_delete(bus->mutex); return 0; } diff --git a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c index af0a685bc28..8afd68e2622 100644 --- a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c +++ b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c @@ -69,7 +69,6 @@ static void usdb_msc_set_max_lun(uint8_t busid) static void usbd_msc_reset(uint8_t busid) { g_usbd_msc[busid].stage = MSC_READ_CBW; - g_usbd_msc[busid].readonly = false; } static int msc_storage_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) @@ -89,7 +88,6 @@ static int msc_storage_class_interface_request_handler(uint8_t busid, struct usb break; default: - USB_LOG_WRN("Unhandled MSC Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } @@ -153,8 +151,8 @@ static void usbd_msc_send_csw(uint8_t busid, uint8_t CSW_Status) g_usbd_msc[busid].csw.bStatus = CSW_Status; /* updating the State Machine , so that we wait CSW when this - * transfer is complete, ie when we get a bulk in callback - */ + * transfer is complete, ie when we get a bulk in callback + */ g_usbd_msc[busid].stage = MSC_WAIT_CSW; USB_LOG_DBG("Send csw\r\n"); @@ -166,8 +164,8 @@ static void usbd_msc_send_info(uint8_t busid, uint8_t *buffer, uint8_t size) size = MIN(size, g_usbd_msc[busid].cbw.dDataLength); /* updating the State Machine , so that we send CSW when this - * transfer is complete, ie when we get a bulk in callback - */ + * transfer is complete, ie when we get a bulk in callback + */ g_usbd_msc[busid].stage = MSC_SEND_CSW; usbd_ep_start_write(busid, mass_ep_data[busid][MSD_IN_EP_IDX].ep_addr, buffer, size); @@ -290,7 +288,7 @@ static bool SCSI_inquiry(uint8_t busid, uint8_t **data, uint32_t *len) 0x00, 0x80, 0x00, - 0x08, + (0x08 - 4U), 0x20, /* Put Product Serial number */ 0x20, 0x20, diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c b/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c index 4e31a1afa3b..4595bcae066 100644 --- a/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c +++ b/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c @@ -8,7 +8,7 @@ #include "usbh_ch34x.h" #undef USB_DBG_TAG -#define USB_DBG_TAG "usbh_ch43x" +#define USB_DBG_TAG "usbh_ch34x" #include "usb_log.h" struct usbh_ch34x { diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c b/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c index 16debf37f1d..c2d3a77bfa5 100644 --- a/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c +++ b/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c @@ -404,4 +404,4 @@ CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = { .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/serial/usbh_serial.c b/components/drivers/usb/cherryusb/class/serial/usbh_serial.c index d6361b211a3..3e17b12fdea 100644 --- a/components/drivers/usb/cherryusb/class/serial/usbh_serial.c +++ b/components/drivers/usb/cherryusb/class/serial/usbh_serial.c @@ -14,8 +14,6 @@ #define DEV_FORMAT_VENDOR "/dev/ttyUSB%d" #define DEV_FORMAT_CDC_ACM "/dev/ttyACM%d" -#define CONFIG_USBHOST_MAX_SERIAL_CLASS 4 - static struct usbh_serial g_serial_class[CONFIG_USBHOST_MAX_SERIAL_CLASS]; static uint32_t g_devinuse = 0; @@ -23,94 +21,6 @@ static uint32_t g_cdcacm_devinuse = 0; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_serial_iobuffer[CONFIG_USBHOST_MAX_SERIAL_CLASS][USB_ALIGN_UP((USBH_SERIAL_RX2_NOCACHE_OFFSET + USBH_SERIAL_RX2_NOCACHE_SIZE), CONFIG_USB_ALIGN_SIZE)]; -/* refer to cherryrb */ -static int usbh_serial_ringbuffer_init(usbh_serial_ringbuf_t *rb, void *pool, uint32_t size) -{ - if (NULL == rb) { - return -1; - } - - if (NULL == pool) { - return -1; - } - - if ((size < 2) || (size & (size - 1))) { - return -1; - } - - rb->in = 0; - rb->out = 0; - rb->mask = size - 1; - rb->pool = pool; - - return 0; -} - -static void usbh_serial_ringbuffer_reset(usbh_serial_ringbuf_t *rb) -{ - rb->in = 0; - rb->out = 0; -} - -static uint32_t usbh_serial_ringbuffer_get_used(usbh_serial_ringbuf_t *rb) -{ - return rb->in - rb->out; -} - -static uint32_t usbh_serial_ringbuffer_write(usbh_serial_ringbuf_t *rb, void *data, uint32_t size) -{ - uint32_t unused; - uint32_t offset; - uint32_t remain; - - unused = (rb->mask + 1) - (rb->in - rb->out); - - if (size > unused) { - size = unused; - } - - offset = rb->in & rb->mask; - - remain = rb->mask + 1 - offset; - remain = remain > size ? size : remain; - - memcpy(((uint8_t *)(rb->pool)) + offset, data, remain); - memcpy(rb->pool, (uint8_t *)data + remain, size - remain); - - rb->in += size; - - return size; -} - -static uint32_t usbh_serial_ringbuffer_peek(usbh_serial_ringbuf_t *rb, void *data, uint32_t size) -{ - uint32_t used; - uint32_t offset; - uint32_t remain; - - used = rb->in - rb->out; - if (size > used) { - size = used; - } - - offset = rb->out & rb->mask; - - remain = rb->mask + 1 - offset; - remain = remain > size ? size : remain; - - memcpy(data, ((uint8_t *)(rb->pool)) + offset, remain); - memcpy((uint8_t *)data + remain, rb->pool, size - remain); - - return size; -} - -static uint32_t usbh_serial_ringbuffer_read(usbh_serial_ringbuf_t *rb, void *data, uint32_t size) -{ - size = usbh_serial_ringbuffer_peek(rb, data, size); - rb->out += size; - return size; -} - static struct usbh_serial *usbh_serial_alloc(bool is_cdcacm) { uint8_t devno; @@ -193,9 +103,9 @@ static void usbh_serial_callback(void *arg, int nbytes) return; } - usbh_serial_ringbuffer_write(&serial->rx_rb, - &serial->iobuffer[(serial->rx_buf_index ? USBH_SERIAL_RX2_NOCACHE_OFFSET : USBH_SERIAL_RX_NOCACHE_OFFSET) + serial->driver->ignore_rx_header], - (nbytes - serial->driver->ignore_rx_header)); + usb_ringbuffer_write(&serial->rx_rb, + &serial->iobuffer[(serial->rx_buf_index ? USBH_SERIAL_RX2_NOCACHE_OFFSET : USBH_SERIAL_RX_NOCACHE_OFFSET) + serial->driver->ignore_rx_header], + (nbytes - serial->driver->ignore_rx_header)); if (serial->rx_complete_callback) { serial->rx_complete_callback(serial, nbytes - serial->driver->ignore_rx_header); @@ -319,7 +229,7 @@ struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags) } } - usbh_serial_ringbuffer_init(&serial->rx_rb, serial->rx_rb_pool, CONFIG_USBHOST_SERIAL_RX_SIZE); + usb_ringbuffer_init(&serial->rx_rb, serial->rx_rb_pool, CONFIG_USBHOST_SERIAL_RX_SIZE); serial->ref_count++; serial->open_flags = open_flags; @@ -454,7 +364,7 @@ int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg) return ret; } - usbh_serial_ringbuffer_reset(&serial->rx_rb); + usb_ringbuffer_reset(&serial->rx_rb); usb_osal_sem_reset(serial->rx_complete_sem); serial->rx_buf_index = 0; usbh_bulk_urb_fill(&serial->bulkin_urb, serial->hport, serial->bulkin, &serial->iobuffer[serial->rx_buf_index ? USBH_SERIAL_RX2_NOCACHE_OFFSET : USBH_SERIAL_RX_NOCACHE_OFFSET], serial->bulkin->wMaxPacketSize, @@ -561,9 +471,9 @@ int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen) } if (serial->open_flags & USBH_SERIAL_O_NONBLOCK) { - return usbh_serial_ringbuffer_read(&serial->rx_rb, buffer, buflen); + return usb_ringbuffer_read(&serial->rx_rb, buffer, buflen); } else { - if (usbh_serial_ringbuffer_get_used(&serial->rx_rb) == 0) { + if (usb_ringbuffer_get_used(&serial->rx_rb) == 0) { ret = usb_osal_sem_take(serial->rx_complete_sem, serial->rx_timeout_ms == 0 ? USB_OSAL_WAITING_FOREVER : serial->rx_timeout_ms); if (ret < 0) { return ret; @@ -572,7 +482,7 @@ int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen) return serial->rx_errorcode; } } - return usbh_serial_ringbuffer_read(&serial->rx_rb, buffer, buflen); + return usb_ringbuffer_read(&serial->rx_rb, buffer, buflen); } } diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_serial.h b/components/drivers/usb/cherryusb/class/serial/usbh_serial.h index 033ab705ede..06a31709614 100644 --- a/components/drivers/usb/cherryusb/class/serial/usbh_serial.h +++ b/components/drivers/usb/cherryusb/class/serial/usbh_serial.h @@ -67,13 +67,6 @@ extern "C" { #endif -typedef struct { - uint32_t in; /*!< Define the write pointer. */ - uint32_t out; /*!< Define the read pointer. */ - uint32_t mask; /*!< Define the write and read pointer mask. */ - void *pool; /*!< Define the memory pointer. */ -} usbh_serial_ringbuf_t; - /* * Counters of the input lines (CTS, DSR, RI, CD) interrupts */ @@ -143,7 +136,7 @@ struct usbh_serial { const struct usbh_serial_driver *driver; - usbh_serial_ringbuf_t rx_rb; + usb_ringbuffer_t rx_rb; uint8_t rx_rb_pool[CONFIG_USBHOST_SERIAL_RX_SIZE]; usb_osal_sem_t rx_complete_sem; uint8_t rx_buf_index; diff --git a/components/drivers/usb/cherryusb/class/vendor/display/usbd_display.c b/components/drivers/usb/cherryusb/class/vendor/display/usbd_display.c new file mode 100644 index 00000000000..181da6e5aef --- /dev/null +++ b/components/drivers/usb/cherryusb/class/vendor/display/usbd_display.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "usbd_core.h" +#include "usbd_display.h" + +struct usbd_display_priv { + struct usb_mempool pool; + struct usbd_endpoint out_ep; + struct usbd_endpoint in_ep; + struct usbd_display_frame *current_frame; +} g_usbd_display; + +int usbd_display_frame_create(struct usbd_display_frame *frame, uint32_t count) +{ + return usb_mempool_create(&g_usbd_display.pool, frame, sizeof(struct usbd_display_frame), count); +} + +struct usbd_display_frame *usbd_display_frame_alloc(void) +{ + return (struct usbd_display_frame *)usb_mempool_alloc(&g_usbd_display.pool); +} + +int usbd_display_frame_free(struct usbd_display_frame *frame) +{ + return usb_mempool_free(&g_usbd_display.pool, (uintptr_t *)frame); +} + +int usbd_display_frame_send(struct usbd_display_frame *frame) +{ + return usb_mempool_send(&g_usbd_display.pool, (uintptr_t *)frame); +} + +int usbd_display_frame_recv(struct usbd_display_frame **frame, uint32_t timeout) +{ + return usb_mempool_recv(&g_usbd_display.pool, (uintptr_t **)frame, timeout); +} + +uint8_t usb_dispay_dummy[512]; +volatile uint32_t usb_display_buf_offset; +volatile bool usb_display_ignore_frame; + +static void display_notify_handler(uint8_t busid, uint8_t event, void *arg) +{ + switch (event) { + case USBD_EVENT_RESET: + break; + case USBD_EVENT_CONFIGURED: + usb_display_buf_offset = 0; + usb_display_ignore_frame = true; + g_usbd_display.current_frame = NULL; + usb_mempool_reset(&g_usbd_display.pool); + usbd_ep_start_read(busid, g_usbd_display.out_ep.ep_addr, usb_dispay_dummy, usbd_get_ep_mps(0, g_usbd_display.out_ep.ep_addr)); + break; + default: + break; + } +} + +void usbd_display_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + if (usb_display_ignore_frame) { + // alloc frame for next at the end of current frame + if ((nbytes % usbd_get_ep_mps(0, g_usbd_display.out_ep.ep_addr)) || (nbytes == 0)) { + if (g_usbd_display.current_frame == NULL) { + g_usbd_display.current_frame = usbd_display_frame_alloc(); + if (g_usbd_display.current_frame) { + usb_display_ignore_frame = false; + usb_display_buf_offset = 0; + + goto get_frame; + } else { + goto drop_frame; + } + } else { + usb_display_ignore_frame = false; + usb_display_buf_offset = 0; + + goto get_frame; + } + } else { + goto drop_frame; + } + } else { + struct usbd_disp_frame_header *header = (struct usbd_disp_frame_header *)&g_usbd_display.current_frame->frame_buf[0]; + struct usbd_display_frame *frame; + + if (header->payload_total > g_usbd_display.current_frame->frame_bufsize) { + USB_LOG_ERR("frame overflow, drop it\r\n"); + usb_display_ignore_frame = true; + + goto drop_frame; + } + + usb_display_buf_offset += nbytes; + + if ((nbytes % usbd_get_ep_mps(0, g_usbd_display.out_ep.ep_addr)) || (nbytes == 0)) { + frame = g_usbd_display.current_frame; + g_usbd_display.current_frame = NULL; + + frame->frame_format = header->type; + frame->frame_size = header->payload_total; + usbd_display_frame_send(frame); + + g_usbd_display.current_frame = usbd_display_frame_alloc(); + if (g_usbd_display.current_frame) { + usb_display_ignore_frame = false; + usb_display_buf_offset = 0; + + goto get_frame; + } else { + usb_display_ignore_frame = true; + + goto drop_frame; + } + } else { + goto get_frame; + } + } + return; + +drop_frame: + // drop current frame + usbd_ep_start_read(busid, g_usbd_display.out_ep.ep_addr, usb_dispay_dummy, usbd_get_ep_mps(0, g_usbd_display.out_ep.ep_addr)); + return; +get_frame: + usbd_ep_start_read(busid, g_usbd_display.out_ep.ep_addr, &g_usbd_display.current_frame->frame_buf[usb_display_buf_offset], 16384); + return; +} + +void usbd_display_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ +} + +struct usbd_interface *usbd_display_init_intf(struct usbd_interface *intf, + const uint8_t out_ep, + const uint8_t in_ep, + struct usbd_display_frame *frame, + uint32_t count) +{ + intf->class_interface_handler = NULL; + intf->class_endpoint_handler = NULL; + intf->vendor_handler = NULL; + intf->notify_handler = display_notify_handler; + + g_usbd_display.out_ep.ep_addr = out_ep; + g_usbd_display.out_ep.ep_cb = usbd_display_bulk_out; + g_usbd_display.in_ep.ep_addr = in_ep; + g_usbd_display.in_ep.ep_cb = usbd_display_bulk_in; + usbd_add_endpoint(0, &g_usbd_display.out_ep); + usbd_add_endpoint(0, &g_usbd_display.in_ep); + + for (uint32_t i = 0; i < count; i++) { + USB_ASSERT_MSG(frame[i].frame_bufsize % 16384, "frame_bufsize must be the multiple of 16384"); + } + + usbd_display_frame_create(frame, count); + return intf; +} + +int usbd_display_dequeue(struct usbd_display_frame **frame, uint32_t timeout) +{ + return usbd_display_frame_recv(frame, timeout); +} + +int usbd_display_enqueue(struct usbd_display_frame *frame) +{ + return usbd_display_frame_free(frame); +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/display/usbd_display.h b/components/drivers/usb/cherryusb/class/vendor/display/usbd_display.h new file mode 100644 index 00000000000..9b7c47e14a5 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/vendor/display/usbd_display.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBD_DISPLAY_H +#define USBD_DISPLAY_H + +#define USBD_DISPLAY_TYPE_RGB565 0 +#define USBD_DISPLAY_TYPE_RGB888 1 +#define USBD_DISPLAY_TYPE_YUV420 2 +#define USBD_DISPLAY_TYPE_JPG 3 + +struct usbd_disp_frame_header { + uint16_t crc16; //payload crc16 + uint8_t type; //raw rgb,yuv,jpg,other + uint8_t cmd; + uint16_t x; //32bit + uint16_t y; + uint16_t width; //32bit + uint16_t height; + uint32_t frame_id : 10; + uint32_t payload_total : 22; //payload max 4MB +} __PACKED; + +struct usbd_display_frame { + uint8_t *frame_buf; + uint32_t frame_bufsize; + uint32_t frame_format; + uint32_t frame_size; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Init display interface driver */ +struct usbd_interface *usbd_display_init_intf(struct usbd_interface *intf, + const uint8_t out_ep, + const uint8_t in_ep, + struct usbd_display_frame *frame, + uint32_t count); + +int usbd_display_dequeue(struct usbd_display_frame **frame, uint32_t timeout); +int usbd_display_enqueue(struct usbd_display_frame *frame); + +#ifdef __cplusplus +} +#endif + +#endif /* USBD_DISPLAY_H */ diff --git a/components/drivers/usb/cherryusb/class/video/usbd_video.c b/components/drivers/usb/cherryusb/class/video/usbd_video.c index a4e53162d58..3ed6ff889bb 100644 --- a/components/drivers/usb/cherryusb/class/video/usbd_video.c +++ b/components/drivers/usb/cherryusb/class/video/usbd_video.c @@ -44,7 +44,6 @@ static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_pa case VIDEO_REQUEST_GET_INFO: break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } @@ -58,7 +57,6 @@ static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_pa case VIDEO_REQUEST_GET_INFO: break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } @@ -91,7 +89,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 1; break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -127,7 +124,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 4; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -163,7 +159,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -199,7 +194,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -235,7 +229,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -247,16 +240,13 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; default: - USB_LOG_WRN("Unhandled Video Class control selector 0x%02x\r\n", control_selector); return -1; } } else { - USB_LOG_WRN("Unhandled Video Class wTerminalType 0x%02x\r\n", entity_info->wTerminalType); return -2; } break; @@ -298,7 +288,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -337,7 +326,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -373,7 +361,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -409,7 +396,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -440,7 +426,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -471,7 +456,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -502,7 +486,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -538,7 +521,6 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 2; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -550,13 +532,11 @@ static int usbd_video_control_unit_terminal_request_handler(uint8_t busid, struc *len = 1; } break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; default: g_usbd_video[busid].error_code = 0x06; - USB_LOG_WRN("Unhandled Video Class control selector 0x%02x\r\n", control_selector); return -1; } break; @@ -606,7 +586,6 @@ static int usbd_video_stream_request_handler(uint8_t busid, struct usb_setup_pac break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -638,7 +617,6 @@ static int usbd_video_stream_request_handler(uint8_t busid, struct usb_setup_pac break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; @@ -653,7 +631,6 @@ static int usbd_video_stream_request_handler(uint8_t busid, struct usb_setup_pac *len = 1; break; default: - USB_LOG_WRN("Unhandled Video Class bRequest 0x%02x\r\n", setup->bRequest); return -1; } break; diff --git a/components/drivers/usb/cherryusb/class/video/usbh_video.c b/components/drivers/usb/cherryusb/class/video/usbh_video.c index 18acbda37ab..8b7863cc3c0 100644 --- a/components/drivers/usb/cherryusb/class/video/usbh_video.c +++ b/components/drivers/usb/cherryusb/class/video/usbh_video.c @@ -174,12 +174,13 @@ int usbh_video_open(struct usbh_video *video_class, frameidx = j + 1; dwDefaultFrameInterval = video_class->format[i].frame[j].dwDefaultFrameInterval; found = true; - break; + goto dev_found; } } } } +dev_found: if (found == false) { return -USB_ERR_NODEV; } @@ -437,6 +438,9 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) format_index = p[DESC_bFormatIndex]; num_of_frames = p[DESC_bNumFrameDescriptors]; + USB_ASSERT(format_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + video_class->format[format_index - 1].num_of_frames = num_of_frames; video_class->format[format_index - 1].format_type = USBH_VIDEO_FORMAT_UNCOMPRESSED; break; @@ -444,12 +448,20 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) format_index = p[DESC_bFormatIndex]; num_of_frames = p[DESC_bNumFrameDescriptors]; + USB_ASSERT(format_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + video_class->format[format_index - 1].num_of_frames = num_of_frames; video_class->format[format_index - 1].format_type = USBH_VIDEO_FORMAT_MJPEG; break; case VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_SUBTYPE: frame_index = p[DESC_bFrameIndex]; + USB_ASSERT(format_index != 0); + USB_ASSERT(frame_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + USB_ASSERT(frame_index <= CONFIG_USBHOST_VIDEO_MAX_FRAMES); + video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wWidth; video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wHeight; video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->dwDefaultFrameInterval; @@ -457,6 +469,11 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) case VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE: frame_index = p[DESC_bFrameIndex]; + USB_ASSERT(format_index != 0); + USB_ASSERT(frame_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + USB_ASSERT(frame_index <= CONFIG_USBHOST_VIDEO_MAX_FRAMES); + video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wWidth; video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wHeight; video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->dwDefaultFrameInterval; diff --git a/components/drivers/usb/cherryusb/class/video/usbh_video.h b/components/drivers/usb/cherryusb/class/video/usbh_video.h index 9edce49b93d..b1ae438a5ec 100644 --- a/components/drivers/usb/cherryusb/class/video/usbh_video.h +++ b/components/drivers/usb/cherryusb/class/video/usbh_video.h @@ -11,6 +11,14 @@ #define USBH_VIDEO_FORMAT_UNCOMPRESSED 0 #define USBH_VIDEO_FORMAT_MJPEG 1 +#ifndef CONFIG_USBHOST_VIDEO_MAX_FRAMES +#define CONFIG_USBHOST_VIDEO_MAX_FRAMES 12 +#endif + +#ifndef CONFIG_USBHOST_VIDEO_MAX_FORMATS +#define CONFIG_USBHOST_VIDEO_MAX_FORMATS 3 +#endif + struct usbh_video_resolution { uint16_t wWidth; uint16_t wHeight; @@ -18,7 +26,7 @@ struct usbh_video_resolution { }; struct usbh_video_format { - struct usbh_video_resolution frame[12]; + struct usbh_video_resolution frame[CONFIG_USBHOST_VIDEO_MAX_FRAMES]; uint8_t format_type; uint8_t num_of_frames; }; @@ -55,7 +63,7 @@ struct usbh_video { uint16_t bcdVDC; uint8_t num_of_intf_altsettings; uint8_t num_of_formats; - struct usbh_video_format format[3]; + struct usbh_video_format format[CONFIG_USBHOST_VIDEO_MAX_FORMATS]; void *user_data; }; diff --git a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c index 2b93e479ebf..dffeb20e033 100644 --- a/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c +++ b/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c @@ -365,14 +365,9 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len) switch (cmd->Oid) { case OID_GEN_RNDIS_CONFIG_PARAMETER: - param = (rndis_config_parameter_t *)((uint8_t *)&(cmd->RequestId) + cmd->InformationBufferOffset); - USB_LOG_WRN("RNDIS cfg param: NameOfs=%d, NameLen=%d, ValueOfs=%d, ValueLen=%d\r\n", - param->ParameterNameOffset, param->ParameterNameLength, - param->ParameterValueOffset, param->ParameterValueLength); break; case OID_GEN_CURRENT_PACKET_FILTER: if (cmd->InformationBufferLength < sizeof(g_usbd_rndis.net_filter)) { - USB_LOG_WRN("PACKET_FILTER!\r\n"); resp->Status = RNDIS_STATUS_INVALID_DATA; } else { uint32_t *filter; diff --git a/components/drivers/usb/cherryusb/common/usb_mempool.h b/components/drivers/usb/cherryusb/common/usb_mempool.h new file mode 100644 index 00000000000..d14d69d57e2 --- /dev/null +++ b/components/drivers/usb/cherryusb/common/usb_mempool.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2022, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USB_MEMPOOL_H +#define USB_MEMPOOL_H + +#include "usb_osal.h" +#include "usb_ringbuffer.h" + +#ifndef CONFIG_USB_MEMPOOL_MAX_BLOCK_COUNT +#define CONFIG_USB_MEMPOOL_MAX_BLOCK_COUNT 16 +#endif + +struct usb_mempool { + usb_ringbuffer_t in; + usb_ringbuffer_t out; + usb_osal_sem_t out_sem; + + void *block; + uint32_t block_size; + uint32_t block_count; + uint8_t in_buf[sizeof(uintptr_t) * CONFIG_USB_MEMPOOL_MAX_BLOCK_COUNT]; + uint8_t out_buf[sizeof(uintptr_t) * CONFIG_USB_MEMPOOL_MAX_BLOCK_COUNT]; +}; + +#define usb_mempool_osal_sem_create(max_count) usb_osal_sem_create_counting(max_count) +#define usb_mempool_osal_sem_delete(sem) usb_osal_sem_delete(sem) +#define usb_mempool_osal_sem_take(sem, timeout) usb_osal_sem_take(sem, timeout) +#define usb_mempool_osal_sem_give(sem) usb_osal_sem_give(sem) + +#ifdef __cplusplus +extern "C" { +#endif + +static inline int usb_mempool_create(struct usb_mempool *pool, void *block, uint32_t block_size, uint32_t block_count) +{ + uintptr_t *item; + uint32_t addr; + + if (block_count > CONFIG_USB_MEMPOOL_MAX_BLOCK_COUNT) { + return -1; + } + + if (block_size % 4) { + return -1; + } + + if (usb_ringbuffer_init(&pool->in, pool->in_buf, sizeof(uintptr_t) * block_count) == -1) { + return -1; + } + + if (usb_ringbuffer_init(&pool->out, pool->out_buf, sizeof(uintptr_t) * block_count) == -1) { + return -1; + } + + pool->out_sem = usb_mempool_osal_sem_create(block_count); + if (pool->out_sem == NULL) { + return -1; + } + + pool->block = block; + pool->block_size = block_size; + pool->block_count = block_count; + + for (uint32_t i = 0; i < pool->block_count; i++) { + item = (uintptr_t *)((uint8_t *)pool->block + i * pool->block_size); + addr = (uintptr_t)item; + usb_ringbuffer_write(&pool->in, &addr, sizeof(uintptr_t)); + } + + return 0; +} + +static inline void usb_mempool_delete(struct usb_mempool *pool) +{ + usb_ringbuffer_reset(&pool->in); + usb_ringbuffer_reset(&pool->out); + usb_mempool_osal_sem_delete(pool->out_sem); +} + +static inline uintptr_t *usb_mempool_alloc(struct usb_mempool *pool) +{ + uintptr_t *addr; + uint32_t len; + + len = usb_ringbuffer_read(&pool->in, (uintptr_t *)&addr, sizeof(uintptr_t)); + if (len == 0) { + return NULL; + } else { + return addr; + } +} + +static inline int usb_mempool_free(struct usb_mempool *pool, uintptr_t *item) +{ + uintptr_t addr; + + addr = (uintptr_t)item; + return usb_ringbuffer_write(&pool->in, &addr, sizeof(uintptr_t)); +} + +static inline int usb_mempool_send(struct usb_mempool *pool, uintptr_t *item) +{ + uintptr_t addr; + + addr = (uintptr_t)item; + usb_ringbuffer_write(&pool->out, &addr, sizeof(uintptr_t)); + return usb_mempool_osal_sem_give(pool->out_sem); +} + +static inline int usb_mempool_recv(struct usb_mempool *pool, uintptr_t **item, uint32_t timeout) +{ + uint32_t len; + int ret; + + ret = usb_mempool_osal_sem_take(pool->out_sem, timeout); + if (ret < 0) { + return -1; + } + + len = usb_ringbuffer_read(&pool->out, (uintptr_t *)item, sizeof(uintptr_t)); + if (len == 0) { + return -1; + } else { + return 0; + } +} + +static inline void usb_mempool_reset(struct usb_mempool *pool) +{ + uintptr_t *item; + + usb_ringbuffer_reset(&pool->in); + usb_ringbuffer_reset(&pool->out); + + for (uint32_t i = 0; i < pool->block_count; i++) { + item = (uintptr_t *)((uint8_t *)pool->block + i * pool->block_size); + usb_mempool_free(pool, item); + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/drivers/usb/cherryusb/common/usb_osal.h b/components/drivers/usb/cherryusb/common/usb_osal.h index 1975f208bfb..70e2afe7543 100644 --- a/components/drivers/usb/cherryusb/common/usb_osal.h +++ b/components/drivers/usb/cherryusb/common/usb_osal.h @@ -45,6 +45,7 @@ void usb_osal_thread_delete(usb_osal_thread_t thread); void usb_osal_thread_schedule_other(void); usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count); +usb_osal_sem_t usb_osal_sem_create_counting(uint32_t max_count); void usb_osal_sem_delete(usb_osal_sem_t sem); int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout); int usb_osal_sem_give(usb_osal_sem_t sem); diff --git a/components/drivers/usb/cherryusb/common/usb_ringbuffer.h b/components/drivers/usb/cherryusb/common/usb_ringbuffer.h new file mode 100644 index 00000000000..3a0afe92bdc --- /dev/null +++ b/components/drivers/usb/cherryusb/common/usb_ringbuffer.h @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2022, Egahp + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USB_RINGBUFFER_H +#define USB_RINGBUFFER_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t in; /*!< Define the write pointer. */ + uint32_t out; /*!< Define the read pointer. */ + uint32_t mask; /*!< Define the write and read pointer mask. */ + void *pool; /*!< Define the memory pointer. */ +} usb_ringbuffer_t; + +/***************************************************************************** +* @brief init ringbuffer +* +* @param[in] rb ringbuffer instance +* @param[in] pool memory pool address +* @param[in] size memory size in byte, +* must be power of 2 !!! +* +* @retval int 0:Success -1:Error +*****************************************************************************/ +static inline int usb_ringbuffer_init(usb_ringbuffer_t *rb, void *pool, uint32_t size) +{ + if (NULL == rb) { + return -1; + } + + if (NULL == pool) { + return -1; + } + + if ((size < 2) || (size & (size - 1))) { + return -1; + } + + rb->in = 0; + rb->out = 0; + rb->mask = size - 1; + rb->pool = pool; + + return 0; +} + +/***************************************************************************** +* @brief reset ringbuffer, clean all data, +* should be add lock in multithread +* +* @param[in] rb ringbuffer instance +* +*****************************************************************************/ +static inline void usb_ringbuffer_reset(usb_ringbuffer_t *rb) +{ + rb->in = 0; + rb->out = 0; +} + +/***************************************************************************** +* @brief reset ringbuffer, clean all data, +* should be add lock in multithread, +* in single read thread not need lock +* +* @param[in] rb ringbuffer instance +* +*****************************************************************************/ +static inline void usb_ringbuffer_reset_read(usb_ringbuffer_t *rb) +{ + rb->out = rb->in; +} + +/***************************************************************************** +* @brief get ringbuffer total size in byte +* +* @param[in] rb ringbuffer instance +* +* @retval uint32_t total size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_get_size(usb_ringbuffer_t *rb) +{ + return rb->mask + 1; +} + +/***************************************************************************** +* @brief get ringbuffer used size in byte +* +* @param[in] rb ringbuffer instance +* +* @retval uint32_t used size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_get_used(usb_ringbuffer_t *rb) +{ + return rb->in - rb->out; +} + +/***************************************************************************** +* @brief get ringbuffer free size in byte +* +* @param[in] rb ringbuffer instance +* +* @retval uint32_t free size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_get_free(usb_ringbuffer_t *rb) +{ + return (rb->mask + 1) - (rb->in - rb->out); +} + +/***************************************************************************** +* @brief check if ringbuffer is full +* +* @param[in] rb ringbuffer instance +* +* @retval true full +* @retval false not full +*****************************************************************************/ +static inline bool usb_ringbuffer_check_full(usb_ringbuffer_t *rb) +{ + return usb_ringbuffer_get_used(rb) > rb->mask; +} + +/***************************************************************************** +* @brief check if ringbuffer is empty +* +* @param[in] rb ringbuffer instance +* +* @retval true empty +* @retval false not empty +*****************************************************************************/ +static inline bool usb_ringbuffer_check_empty(usb_ringbuffer_t *rb) +{ + return rb->in == rb->out; +} + +/***************************************************************************** +* @brief write one byte to ringbuffer, +* should be add lock in multithread, +* in single write thread not need lock +* +* @param[in] rb ringbuffer instance +* @param[in] byte data +* +* @retval true Success +* @retval false ringbuffer is full +*****************************************************************************/ +static inline bool usb_ringbuffer_write_byte(usb_ringbuffer_t *rb, uint8_t byte) +{ + if (usb_ringbuffer_check_full(rb)) { + return false; + } + + ((uint8_t *)(rb->pool))[rb->in & rb->mask] = byte; + rb->in++; + return true; +} + +/***************************************************************************** +* @brief overwrite one byte to ringbuffer, drop oldest data, +* should be add lock always +* +* @param[in] rb ringbuffer instance +* @param[in] byte data +* +* @retval true Success +* @retval false always return true +*****************************************************************************/ +static inline bool usb_ringbuffer_overwrite_byte(usb_ringbuffer_t *rb, uint8_t byte) +{ + if (usb_ringbuffer_check_full(rb)) { + rb->out++; + } + + ((uint8_t *)(rb->pool))[rb->in & rb->mask] = byte; + rb->in++; + return true; +} + +/***************************************************************************** +* @brief peek one byte from ringbuffer, +* should be add lock in multithread, +* in single read thread not need lock +* +* @param[in] rb ringbuffer instance +* @param[in] byte pointer to save data +* +* @retval true Success +* @retval false ringbuffer is empty +*****************************************************************************/ +static inline bool usb_ringbuffer_peek_byte(usb_ringbuffer_t *rb, uint8_t *byte) +{ + if (usb_ringbuffer_check_empty(rb)) { + return false; + } + + *byte = ((uint8_t *)(rb->pool))[rb->out & rb->mask]; + return true; +} + +/***************************************************************************** +* @brief read one byte from ringbuffer, +* should be add lock in multithread, +* in single read thread not need lock +* +* @param[in] rb ringbuffer instance +* @param[in] byte pointer to save data +* +* @retval true Success +* @retval false ringbuffer is empty +*****************************************************************************/ +static inline bool usb_ringbuffer_read_byte(usb_ringbuffer_t *rb, uint8_t *byte) +{ + bool ret; + ret = usb_ringbuffer_peek_byte(rb, byte); + rb->out += ret; + return ret; +} + +/***************************************************************************** +* @brief drop one byte from ringbuffer, +* should be add lock in multithread, +* in single read thread not need lock +* +* @param[in] rb ringbuffer instance +* +* @retval true Success +* @retval false ringbuffer is empty +*****************************************************************************/ +static inline bool usb_ringbuffer_drop_byte(usb_ringbuffer_t *rb) +{ + if (usb_ringbuffer_check_empty(rb)) { + return false; + } + + rb->out += 1; + return true; +} + +/***************************************************************************** +* @brief write data to ringbuffer, +* should be add lock in multithread, +* in single write thread not need lock +* +* @param[in] rb ringbuffer instance +* @param[in] data data pointer +* @param[in] size size in byte +* +* @retval uint32_t actual write size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_write(usb_ringbuffer_t *rb, void *data, uint32_t size) +{ + uint32_t unused; + uint32_t offset; + uint32_t remain; + + unused = (rb->mask + 1) - (rb->in - rb->out); + + if (size > unused) { + size = unused; + } + + offset = rb->in & rb->mask; + + remain = rb->mask + 1 - offset; + remain = remain > size ? size : remain; + + memcpy(((uint8_t *)(rb->pool)) + offset, data, remain); + memcpy(rb->pool, (uint8_t *)data + remain, size - remain); + + rb->in += size; + + return size; +} + +/***************************************************************************** +* @brief write data to ringbuffer, +* should be add lock always +* +* @param[in] rb ringbuffer instance +* @param[in] data data pointer +* @param[in] size size in byte +* +* @retval uint32_t actual write size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_overwrite(usb_ringbuffer_t *rb, void *data, uint32_t size) +{ + uint32_t unused; + uint32_t offset; + uint32_t remain; + + unused = (rb->mask + 1) - (rb->in - rb->out); + + if (size > unused) { + if (size > (rb->mask + 1)) { + size = rb->mask + 1; + } + + rb->out += size - unused; + } + + offset = rb->in & rb->mask; + + remain = rb->mask + 1 - offset; + remain = remain > size ? size : remain; + + memcpy(((uint8_t *)(rb->pool)) + offset, data, remain); + memcpy(rb->pool, (uint8_t *)data + remain, size - remain); + + rb->in += size; + + return size; +} + +/***************************************************************************** +* @brief peek data from ringbuffer +* should be add lock in multithread, +* in single read thread not need lock +* +* @param[in] rb ringbuffer instance +* @param[in] data data pointer +* @param[in] size size in byte +* +* @retval uint32_t actual peek size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_peek(usb_ringbuffer_t *rb, void *data, uint32_t size) +{ + uint32_t used; + uint32_t offset; + uint32_t remain; + + used = rb->in - rb->out; + if (size > used) { + size = used; + } + + offset = rb->out & rb->mask; + + remain = rb->mask + 1 - offset; + remain = remain > size ? size : remain; + + memcpy(data, ((uint8_t *)(rb->pool)) + offset, remain); + memcpy((uint8_t *)data + remain, rb->pool, size - remain); + + return size; +} + +/***************************************************************************** +* @brief read data from ringbuffer +* should be add lock in multithread, +* in single read thread not need lock +* +* @param[in] rb ringbuffer instance +* @param[in] data data pointer +* @param[in] size size in byte +* +* @retval uint32_t actual read size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_read(usb_ringbuffer_t *rb, void *data, uint32_t size) +{ + size = usb_ringbuffer_peek(rb, data, size); + rb->out += size; + return size; +} + +/***************************************************************************** +* @brief drop data from ringbuffer +* should be add lock in multithread, +* in single read thread not need lock +* +* @param[in] rb ringbuffer instance +* @param[in] size size in byte +* +* @retval uint32_t actual drop size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_drop(usb_ringbuffer_t *rb, uint32_t size) +{ + uint32_t used; + + used = rb->in - rb->out; + if (size > used) { + size = used; + } + + rb->out += size; + return size; +} + +/***************************************************************************** +* @brief linear write setup, get write pointer and max linear size. +* +* @param[in] rb ringbuffer instance +* @param[in] size pointer to store max linear size in byte +* +* @retval void* write memory pointer +*****************************************************************************/ +static inline void *usb_ringbuffer_linear_write_setup(usb_ringbuffer_t *rb, uint32_t *size) +{ + uint32_t unused; + uint32_t offset; + uint32_t remain; + + unused = (rb->mask + 1) - (rb->in - rb->out); + + offset = rb->in & rb->mask; + + remain = rb->mask + 1 - offset; + remain = remain > unused ? unused : remain; + + if (remain) { + *size = remain; + return ((uint8_t *)(rb->pool)) + offset; + } else { + *size = unused - remain; + return rb->pool; + } +} + +/***************************************************************************** +* @brief linear read setup, get read pointer and max linear size. +* +* @param[in] rb ringbuffer instance +* @param[in] size pointer to store max linear size in byte +* +* @retval void* +*****************************************************************************/ +static inline void *usb_ringbuffer_linear_read_setup(usb_ringbuffer_t *rb, uint32_t *size) +{ + uint32_t used; + uint32_t offset; + uint32_t remain; + + used = rb->in - rb->out; + + offset = rb->out & rb->mask; + + remain = rb->mask + 1 - offset; + remain = remain > used ? used : remain; + + if (remain) { + *size = remain; + return ((uint8_t *)(rb->pool)) + offset; + } else { + *size = used - remain; + return rb->pool; + } +} + +/***************************************************************************** +* @brief linear write done, add write pointer only +* +* @param[in] rb ringbuffer instance +* @param[in] size write size in byte +* +* @retval uint32_t actual write size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_linear_write_done(usb_ringbuffer_t *rb, uint32_t size) +{ + uint32_t unused; + + unused = (rb->mask + 1) - (rb->in - rb->out); + if (size > unused) { + size = unused; + } + rb->in += size; + + return size; +} + +/***************************************************************************** +* @brief linear read done, add read pointer only +* +* @param[in] rb ringbuffer instance +* @param[in] size read size in byte +* +* @retval uint32_t actual read size in byte +*****************************************************************************/ +static inline uint32_t usb_ringbuffer_linear_read_done(usb_ringbuffer_t *rb, uint32_t size) +{ + return usb_ringbuffer_drop(rb, size); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/drivers/usb/cherryusb/common/usb_version.h b/components/drivers/usb/cherryusb/common/usb_version.h index 3e4c2aa395a..5c59978f732 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 0x010600 -#define CHERRYUSB_VERSION_STR "v1.6.0" +#define CHERRYUSB_VERSION 0x010601 +#define CHERRYUSB_VERSION_STR "v1.6.1" #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 bdbcfd07f79..a9ad67c4575 100644 --- a/components/drivers/usb/cherryusb/core/usbd_core.c +++ b/components/drivers/usb/cherryusb/core/usbd_core.c @@ -1364,9 +1364,9 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin #endif g_usbd_core[busid].event_handler = event_handler; - ret = usb_dc_init(busid); usbd_class_event_notify_handler(busid, USBD_EVENT_INIT, NULL); g_usbd_core[busid].event_handler(busid, USBD_EVENT_INIT); + ret = usb_dc_init(busid); return ret; } @@ -1374,8 +1374,6 @@ int usbd_deinitialize(uint8_t busid) { USB_ASSERT_MSG(busid < CONFIG_USBDEV_MAX_BUS, "bus overflow\r\n"); - g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT); - usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL); usb_dc_deinit(busid); #ifdef CONFIG_USBDEV_EP0_THREAD if (g_usbd_core[busid].usbd_ep0_thread) { @@ -1385,6 +1383,7 @@ int usbd_deinitialize(uint8_t busid) usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq); } #endif - + g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT); + usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL); return 0; } diff --git a/components/drivers/usb/cherryusb/core/usbd_core.h b/components/drivers/usb/cherryusb/core/usbd_core.h index 314ccbec713..ac9c58f19ec 100644 --- a/components/drivers/usb/cherryusb/core/usbd_core.h +++ b/components/drivers/usb/cherryusb/core/usbd_core.h @@ -24,6 +24,8 @@ extern "C" { #include "usb_dc.h" #include "usb_osal.h" #include "usb_memcpy.h" +#include "usb_ringbuffer.h" +#include "usb_mempool.h" #include "usb_dcache.h" #include "usb_version.h" diff --git a/components/drivers/usb/cherryusb/core/usbh_core.c b/components/drivers/usb/cherryusb/core/usbh_core.c index 43bba3e888b..cce9a46eae8 100644 --- a/components/drivers/usb/cherryusb/core/usbh_core.c +++ b/components/drivers/usb/cherryusb/core/usbh_core.c @@ -274,8 +274,8 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config break; } /* skip to next descriptor */ - p += p[DESC_bLength]; desc_len += p[DESC_bLength]; + p += p[DESC_bLength]; } } return 0; @@ -603,9 +603,8 @@ void usbh_hubport_release(struct usbh_hubport *hport) hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, i, USBH_EVENT_INTERFACE_STOP); } hport->config.config_desc.bNumInterfaces = 0; - if (hport->mutex) { - usb_osal_mutex_delete(hport->mutex); - } + usb_osal_mutex_take(hport->mutex); + usb_osal_mutex_delete(hport->mutex); USB_LOG_INFO("Device on Bus %u, Hub %u, Port %u disconnected\r\n", hport->bus->busid, hport->parent->index, hport->port); hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_DISCONNECTED); } @@ -666,8 +665,6 @@ int usbh_deinitialize(uint8_t busid) bus = &g_usbhost_bus[busid]; - bus->event_handler(bus->busid, USB_HUB_INDEX_ANY, USB_HUB_PORT_ANY, USB_INTERFACE_ANY, USBH_EVENT_DEINIT); - usbh_hub_deinitialize(bus); usb_slist_remove(&g_bus_head, &bus->list); @@ -685,6 +682,10 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s return -USB_ERR_INVAL; } + if (!hport->connected) { + return -USB_ERR_NODEV; + } + urb = &hport->ep0_urb; usb_osal_mutex_take(hport->mutex); @@ -1214,4 +1215,4 @@ __WEAK uint8_t usbh_get_hport_active_config_index(struct usbh_hubport *hport) ARG_UNUSED(hport); return 0; // Default to configuration index 0 -} \ No newline at end of file +} diff --git a/components/drivers/usb/cherryusb/core/usbh_core.h b/components/drivers/usb/cherryusb/core/usbh_core.h index 903ce14fdb2..abd193df9fa 100644 --- a/components/drivers/usb/cherryusb/core/usbh_core.h +++ b/components/drivers/usb/cherryusb/core/usbh_core.h @@ -21,6 +21,8 @@ #include "usb_osal.h" #include "usbh_hub.h" #include "usb_memcpy.h" +#include "usb_ringbuffer.h" +#include "usb_mempool.h" #include "usb_dcache.h" #include "usb_version.h" @@ -201,7 +203,7 @@ struct usbh_bus { struct usbh_devaddr_map devgen; usb_osal_thread_t hub_thread; usb_osal_mq_t hub_mq; - usb_osal_mutex_t mutex; + usb_osal_sem_t hub_sem; usbh_event_handler_t event_handler; }; diff --git a/components/drivers/usb/cherryusb/core/usbotg_core.c b/components/drivers/usb/cherryusb/core/usbotg_core.c index 99b0cc8a6bb..54237e693b3 100644 --- a/components/drivers/usb/cherryusb/core/usbotg_core.c +++ b/components/drivers/usb/cherryusb/core/usbotg_core.c @@ -38,7 +38,7 @@ static void usbotg_host_initialize(uint8_t busid) USB_LOG_INFO("Switch to HOST mode\r\n"); g_usbotg_core[busid].usbh_initialized = true; - usbh_initialize(busid, g_usbotg_core[busid].reg_base); + usbh_initialize(busid, g_usbotg_core[busid].reg_base, NULL); } static void usbotg_device_initialize(uint8_t busid) diff --git a/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c b/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c index 9f77e73d04e..acce1e35e10 100644 --- a/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c +++ b/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c @@ -157,7 +157,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c index aad917abbfb..c4b68c55345 100644 --- a/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c +++ b/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c @@ -122,7 +122,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c index 872a6cde706..d7fb3a41f96 100644 --- a/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c +++ b/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c @@ -195,7 +195,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c index c9044550496..4fd156f7e4f 100644 --- a/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c +++ b/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c @@ -126,7 +126,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c index 38c1dbbe017..a929a39bcf8 100644 --- a/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c +++ b/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c @@ -201,7 +201,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c b/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c index 54206192754..bec8445e7e7 100644 --- a/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c +++ b/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c @@ -145,7 +145,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c b/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c index 2584d3ae768..73dfe577403 100644 --- a/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c +++ b/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c @@ -72,7 +72,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; 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 016e9808e35..93f3fb3b298 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 @@ -94,7 +94,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; @@ -112,49 +112,41 @@ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xA1, 0x01, // COLLECTION (Application) - 0x09, 0x01, // USAGE (Pointer) - - 0xA1, 0x00, // COLLECTION (Physical) - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x03, // USAGE_MAXIMUM (Button 3) - - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) - 0x75, 0x01, // REPORT_SIZE (1) - - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) - 0x81, 0x01, // INPUT (Cnst,Var,Abs) - - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x30, // USAGE (X) - 0x09, 0x31, // USAGE (Y) - 0x09, 0x38, - - 0x15, 0x81, // LOGICAL_MINIMUM (-127) - 0x25, 0x7F, // LOGICAL_MAXIMUM (127) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x03, // REPORT_COUNT (2) - - 0x81, 0x06, // INPUT (Data,Var,Rel) - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 // END_COLLECTION + 0x09, 0x01, // USAGE (Pointer) + 0xA1, 0x00, // COLLECTION (Physical) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x01, // INPUT (Cnst,Var,Abs) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, // Usage (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (2) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xC0, // END_COLLECTION + 0x09, 0x3c, // USAGE (Motion Wakeup) + 0x05, 0xff, // USAGE_PAGE (Vendor Defined 0xFF) + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x02, // REPORT_COUNT (2) + 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf) + 0x75, 0x06, // REPORT_SIZE (6) + 0x95, 0x01, // REPORT_COUNT (1) + 0xb1, 0x01, // FEATURE (Cnst,Ary,Abs) + 0xc0 // END_COLLECTION }; /*!< mouse report struct */ diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c index c941b35074c..c680b7e8295 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c @@ -76,7 +76,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c index 4c805835eeb..e8dc06ca05e 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c @@ -85,7 +85,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c index 753e81729bd..7753439a478 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c @@ -89,7 +89,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c index 2fed1cfc504..d251f458020 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c @@ -74,7 +74,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c index e98287c94c7..610df928dd0 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c @@ -74,7 +74,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c index 528ed9f63ec..512725ed470 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c @@ -82,7 +82,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 4) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; @@ -351,7 +351,7 @@ struct usbd_interface intf1; /* ecm only supports in linux, and you should input the following command * * sudo ifconfig enxaabbccddeeff up - * sudo dhcpclient enxaabbccddeeff + * sudo dhclient enxaabbccddeeff */ void cdc_ecm_init(uint8_t busid, uintptr_t reg_base) { diff --git a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c index 1b5874934dd..570064eb682 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c @@ -78,7 +78,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/dfu_st_cubemx_main.c b/components/drivers/usb/cherryusb/demo/dfu_st_cubemx_main.c deleted file mode 100644 index b845af3eda9..00000000000 --- a/components/drivers/usb/cherryusb/demo/dfu_st_cubemx_main.c +++ /dev/null @@ -1,372 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.c - * @brief : Main program body - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ -#include "usbd_core.h" -#include "usb_dfu.h" -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN PTD */ - -/* USER CODE END PTD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN PD */ -/* USER CODE END PD */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN PM */ - -/* USER CODE END PM */ - -/* Private variables ---------------------------------------------------------*/ -UART_HandleTypeDef huart1; - -PCD_HandleTypeDef hpcd_USB_FS; - -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -void SystemClock_Config(void); -static void MX_GPIO_Init(void); -static void MX_USART1_UART_Init(void); -static void MX_USB_PCD_Init(void); -/* USER CODE BEGIN PFP */ -typedef void (*pFunction)(void); -static void jump_app(void) -{ - pFunction JumpToApplication; - uint32_t JumpAddress; - - if (((*(__IO uint32_t *)USBD_DFU_APP_DEFAULT_ADD) & 0x2FFFB000) == 0x20000000) - { - /* Jump to user application */ - /*!< Jump to app reset_handler */ - JumpAddress = *(__IO uint32_t *)(USBD_DFU_APP_DEFAULT_ADD + 4); - JumpToApplication = (pFunction)JumpAddress; - - /* Initialize user application's Stack Pointer */ - __set_MSP(*(__IO uint32_t *)USBD_DFU_APP_DEFAULT_ADD); - JumpToApplication(); - } -} -/* USER CODE END PFP */ - -/* Private user code ---------------------------------------------------------*/ -/* USER CODE BEGIN 0 */ -int fputc(int ch, FILE *f) -{ - while ((USART1->SR & USART_SR_TXE) == 0) - ; - USART1->DR = ch; - return ch; -} - -void usb_dc_low_level_init(void) -{ - /* Peripheral clock enable */ - __HAL_RCC_USB_CLK_ENABLE(); - /* USB interrupt Init */ - HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); - -} - -uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len) -{ - uint32_t i = 0; - uint8_t *psrc = src; - - for (i = 0; i < len; i++) - { - dest[i] = *psrc++; - } - /* Return a valid address to avoid HardFault */ - return (uint8_t *)(dest); -} - -uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len) -{ - HAL_FLASH_Unlock(); - uint32_t i = 0; - - for (i = 0; i < len; i += 4) - { - /* Device voltage range supposed to be [2.7V to 3.6V], the operation will - * be done by byte */ - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)(dest + i), - *(uint32_t *)(src + i)) == HAL_OK) - { - /* Check the written value */ - if (*(uint32_t *)(src + i) != *(uint32_t *)(dest + i)) - { - /* Flash content doesn't match SRAM content */ - return (1); - } - } - else - { - /* Error occurred while writing data in Flash memory */ - return (2); - } - } - return 0; -} - -uint16_t dfu_erase_flash(uint32_t add) -{ - HAL_FLASH_Unlock(); - uint32_t PageError; - /* Variable contains Flash operation status */ - HAL_StatusTypeDef status; - FLASH_EraseInitTypeDef eraseinitstruct; - - eraseinitstruct.TypeErase = FLASH_TYPEERASE_PAGES; - eraseinitstruct.PageAddress = add; - eraseinitstruct.NbPages = 1U; - status = HAL_FLASHEx_Erase(&eraseinitstruct, &PageError); - return 0; -} - -void dfu_leave(void) -{ - NVIC_SystemReset(); -} - -/* USER CODE END 0 */ - -/** - * @brief The application entry point. - * @retval int - */ -int main(void) -{ - /* USER CODE BEGIN 1 */ - jump_app(); - /* USER CODE END 1 */ - - /* MCU Configuration--------------------------------------------------------*/ - - /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ - HAL_Init(); - - /* USER CODE BEGIN Init */ - - /* USER CODE END Init */ - - /* Configure the system clock */ - SystemClock_Config(); - - /* USER CODE BEGIN SysInit */ - - /* USER CODE END SysInit */ - - /* Initialize all configured peripherals */ - MX_GPIO_Init(); - MX_USART1_UART_Init(); - //MX_USB_PCD_Init(); - /* USER CODE BEGIN 2 */ - - -// extern void cdc_acm_msc_init(void); -// cdc_acm_msc_init(); - extern void dfu_flash_init(void); - dfu_flash_init(); - - /* USER CODE END 2 */ - - /* Infinite loop */ - /* USER CODE BEGIN WHILE */ - while (1) { - /* USER CODE END WHILE */ - - /* USER CODE BEGIN 3 */ -// extern void cdc_acm_data_send_with_dtr_test(void); -// cdc_acm_data_send_with_dtr_test(); -// HAL_Delay(100); - } - /* USER CODE END 3 */ -} - -/** - * @brief System Clock Configuration - * @retval None - */ -void SystemClock_Config(void) -{ - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; - - /** Initializes the RCC Oscillators according to the specified parameters - * in the RCC_OscInitTypeDef structure. - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - Error_Handler(); - } - /** Initializes the CPU, AHB and APB buses clocks - */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK - |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) - { - Error_Handler(); - } - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) - { - Error_Handler(); - } -} - -/** - * @brief USART1 Initialization Function - * @param None - * @retval None - */ -static void MX_USART1_UART_Init(void) -{ - - /* USER CODE BEGIN USART1_Init 0 */ - - /* USER CODE END USART1_Init 0 */ - - /* USER CODE BEGIN USART1_Init 1 */ - - /* USER CODE END USART1_Init 1 */ - huart1.Instance = USART1; - huart1.Init.BaudRate = 115200; - huart1.Init.WordLength = UART_WORDLENGTH_8B; - huart1.Init.StopBits = UART_STOPBITS_1; - huart1.Init.Parity = UART_PARITY_NONE; - huart1.Init.Mode = UART_MODE_TX_RX; - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; - huart1.Init.OverSampling = UART_OVERSAMPLING_16; - if (HAL_UART_Init(&huart1) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN USART1_Init 2 */ - - /* USER CODE END USART1_Init 2 */ - -} - -/** - * @brief USB Initialization Function - * @param None - * @retval None - */ -static void MX_USB_PCD_Init(void) -{ - - /* USER CODE BEGIN USB_Init 0 */ - - /* USER CODE END USB_Init 0 */ - - /* USER CODE BEGIN USB_Init 1 */ - - /* USER CODE END USB_Init 1 */ - hpcd_USB_FS.Instance = USB; - hpcd_USB_FS.Init.dev_endpoints = 8; - hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; - hpcd_USB_FS.Init.low_power_enable = DISABLE; - hpcd_USB_FS.Init.lpm_enable = DISABLE; - hpcd_USB_FS.Init.battery_charging_enable = DISABLE; - if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN USB_Init 2 */ - - /* USER CODE END USB_Init 2 */ - -} - -/** - * @brief GPIO Initialization Function - * @param None - * @retval None - */ -static void MX_GPIO_Init(void) -{ - - /* GPIO Ports Clock Enable */ - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - -} - -/* USER CODE BEGIN 4 */ - -/* USER CODE END 4 */ - -/** - * @brief This function is executed in case of error occurrence. - * @retval None - */ -void Error_Handler(void) -{ - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while (1) { - } - /* USER CODE END Error_Handler_Debug */ -} - -#ifdef USE_FULL_ASSERT -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t *file, uint32_t line) -{ - /* USER CODE BEGIN 6 */ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - /* USER CODE END 6 */ -} -#endif /* USE_FULL_ASSERT */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c b/components/drivers/usb/cherryusb/demo/dfu_template.c similarity index 64% rename from components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c rename to components/drivers/usb/cherryusb/demo/dfu_template.c index 0127c58ae80..faa6a0c879b 100644 --- a/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c +++ b/components/drivers/usb/cherryusb/demo/dfu_template.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, sakumisu + * Copyright (c) 2022 ~ 2026, sakumisu * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,13 +7,13 @@ #include "usbd_dfu.h" #define USBD_VID 0x0483 -#define USBD_PID 0xDF11 +#define USBD_PID 0xdf11 #define USBD_MAX_POWER 100 #define USBD_LANGID_STRING 1033 -#define FLASH_DESC_STR "@Internal Flash /0x08000000/16*001Ka,112*01Kg" +#define USB_CONFIG_SIZE (9 + DFU_DESCRIPTOR_LEN) -#define USB_CONFIG_SIZE (9 + 9 + 9) +#define FLASH_DESC_STR "@Internal Flash /0x08000000/16*128Kg" static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01) @@ -21,7 +21,7 @@ static const uint8_t device_descriptor[] = { static const uint8_t config_descriptor[] = { USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - DFU_DESCRIPTOR_INIT() + DFU_DESCRIPTOR_INIT(4) }; static const uint8_t device_quality_descriptor[] = { @@ -45,6 +45,7 @@ static const char *string_descriptors[] = { "CherryUSB", /* Manufacturer */ "CherryUSB DFU DEMO", /* Product */ "2022123456", /* Serial Number */ + FLASH_DESC_STR }; static const uint8_t *device_descriptor_callback(uint8_t speed) @@ -64,13 +65,13 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; } -const struct usb_descriptor dfu_flash_descriptor = { +const struct usb_descriptor dfu_descriptor = { .device_descriptor_callback = device_descriptor_callback, .config_descriptor_callback = config_descriptor_callback, .device_quality_descriptor_callback = device_quality_descriptor_callback, @@ -104,10 +105,52 @@ static void usbd_event_handler(uint8_t busid, uint8_t event) struct usbd_interface intf0; -void dfu_flash_init(uint8_t busid, uintptr_t reg_base) +void dfu_init(uint8_t busid, uintptr_t reg_base) { - usbd_desc_register(busid, &dfu_flash_descriptor); + usbd_desc_register(busid, &dfu_descriptor); usbd_add_interface(busid, usbd_dfu_init_intf(&intf0)); usbd_initialize(busid, reg_base, usbd_event_handler); } + +volatile uint32_t flash_start_address; + +void usbd_dfu_begin_load(void) +{ + flash_start_address = 0x08000000; +} + +void usbd_dfu_end_load(void) +{ +} + +void usbd_dfu_reset(void) +{ + //NVIC_SystemReset(); +} + +int usbd_dfu_write(uint16_t value, const uint8_t *data, uint16_t length) +{ + //usb_hexdump(data, length); + + // patch for stm32 special command +#if 1 + if (value == 0) { + if (data[0] == DFU_SPECIAL_CMD_SET_ADDRESS_POINTER) { + memcpy((uint8_t *)&flash_start_address, data, 4); + } else if (data[0] == DFU_SPECIAL_CMD_ERASE) { + memcpy((uint8_t *)&flash_start_address, data, 4); + } + } else if (value > 1) { + uint32_t addr = (value - 2) * CONFIG_USBDEV_REQUEST_BUFFER_LEN + flash_start_address; + } +#else + flash_start_address += length; +#endif + return 0; +} + +int usbd_dfu_read(uint16_t value, const uint8_t *data, uint16_t length, uint16_t *actual_length) +{ + return 0; +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/display/README.md b/components/drivers/usb/cherryusb/demo/display/README.md new file mode 100644 index 00000000000..a89f4e3c649 --- /dev/null +++ b/components/drivers/usb/cherryusb/demo/display/README.md @@ -0,0 +1,3 @@ +Thanks to https://github.com/chuanjinpang/win10_idd_xfz1986_usb_graphic_driver_display project. + +Install tools/display/xfz1986_usb_graphic_250224_rc_sign.exe in windows before use. \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/display/usbdisplay_template.c b/components/drivers/usb/cherryusb/demo/display/usbdisplay_template.c new file mode 100644 index 00000000000..be7ef3a0471 --- /dev/null +++ b/components/drivers/usb/cherryusb/demo/display/usbdisplay_template.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" +#include "usbd_display.h" + +#define DISPLAY_IN_EP 0x81 +#define DISPLAY_OUT_EP 0x02 + +#define USBD_VID 0x303A +#define USBD_PID 0x2987 +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +#define USB_CONFIG_SIZE (9 + 9 + 7 + 7) + +#ifdef CONFIG_USB_HS +#define DISPLAY_EP_MPS 512 +#else +#define DISPLAY_EP_MPS 64 +#endif + +static const uint8_t device_descriptor[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0101, 0x01) +}; + +static const uint8_t config_descriptor[] = { + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00), + USB_ENDPOINT_DESCRIPTOR_INIT(DISPLAY_IN_EP, 0x02, DISPLAY_EP_MPS, 0x00), + USB_ENDPOINT_DESCRIPTOR_INIT(DISPLAY_OUT_EP, 0x02, DISPLAY_EP_MPS, 0x00), +}; + +static const uint8_t device_quality_descriptor[] = { + /////////////////////////////////////// + /// device qualifier descriptor + /////////////////////////////////////// + 0x0a, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, +}; + +static const char *string_descriptors[] = { + (const char[]){ 0x09, 0x04 }, /* Langid */ + "CherryUSB", /* Manufacturer */ + "cherryusb_R640x480_Ergb16_Fps30_Bl128", /* Product */ + // "cherryusb_R640x480_Ejpg9_Fps30_Bl128", /* Product */ + "2022123456", /* Serial Number */ +}; + +static const uint8_t *device_descriptor_callback(uint8_t speed) +{ + return device_descriptor; +} + +static const uint8_t *config_descriptor_callback(uint8_t speed) +{ + return config_descriptor; +} + +static const uint8_t *device_quality_descriptor_callback(uint8_t speed) +{ + return device_quality_descriptor; +} + +static const char *string_descriptor_callback(uint8_t speed, uint8_t index) +{ + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { + return NULL; + } + return string_descriptors[index]; +} + +const struct usb_descriptor usbdisplay_descriptor = { + .device_descriptor_callback = device_descriptor_callback, + .config_descriptor_callback = config_descriptor_callback, + .device_quality_descriptor_callback = device_quality_descriptor_callback, + .string_descriptor_callback = string_descriptor_callback +}; + +static void usbd_event_handler(uint8_t busid, uint8_t event) +{ + switch (event) { + case USBD_EVENT_RESET: + break; + case USBD_EVENT_CONNECTED: + break; + case USBD_EVENT_DISCONNECTED: + break; + case USBD_EVENT_RESUME: + break; + case USBD_EVENT_SUSPEND: + break; + case USBD_EVENT_CONFIGURED: + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +struct usbd_interface intf0; + +struct usbd_display_frame frame_pool[2]; + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_display_buffer[2][640 * 480 * 2]; + +void usbdisplay_init(uint8_t busid, uintptr_t reg_base) +{ + frame_pool[0].frame_buf = usb_display_buffer[0]; + frame_pool[0].frame_bufsize = 640 * 480 * 2; + frame_pool[1].frame_buf = usb_display_buffer[1]; + frame_pool[1].frame_bufsize = 640 * 480 * 2; + + usbd_desc_register(busid, &usbdisplay_descriptor); + + usbd_add_interface(busid, usbd_display_init_intf(&intf0, DISPLAY_OUT_EP, DISPLAY_IN_EP, frame_pool, 2)); + usbd_initialize(busid, reg_base, usbd_event_handler); +} + +void usbdisplay_poll(void) +{ + struct usbd_display_frame *frame; + int ret; + + ret = usbd_display_dequeue(&frame, 0xffffffff); // timeout is not useful for baremental + if (ret < 0) { + return; + } + USB_LOG_INFO("frame type: %u, frame size %u\r\n", frame->frame_format, frame->frame_size); + usbd_display_enqueue(frame); +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/gamepad_template.c b/components/drivers/usb/cherryusb/demo/gamepad_template.c index 2decbc7c082..171ab517a0e 100644 --- a/components/drivers/usb/cherryusb/demo/gamepad_template.c +++ b/components/drivers/usb/cherryusb/demo/gamepad_template.c @@ -89,7 +89,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } diff --git a/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c b/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c index 8a43d0a5fb5..f493bd6c84c 100644 --- a/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c @@ -79,7 +79,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c index 843a7267292..2faa6a5af48 100644 --- a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c @@ -67,7 +67,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c index 24d32f90dfd..9e9e902b6de 100644 --- a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c @@ -70,7 +70,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; @@ -88,49 +88,41 @@ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xA1, 0x01, // COLLECTION (Application) - 0x09, 0x01, // USAGE (Pointer) - - 0xA1, 0x00, // COLLECTION (Physical) - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x03, // USAGE_MAXIMUM (Button 3) - - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) - 0x75, 0x01, // REPORT_SIZE (1) - - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) - 0x81, 0x01, // INPUT (Cnst,Var,Abs) - - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x30, // USAGE (X) - 0x09, 0x31, // USAGE (Y) - 0x09, 0x38, - - 0x15, 0x81, // LOGICAL_MINIMUM (-127) - 0x25, 0x7F, // LOGICAL_MAXIMUM (127) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x03, // REPORT_COUNT (2) - - 0x81, 0x06, // INPUT (Data,Var,Rel) - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 // END_COLLECTION + 0x09, 0x01, // USAGE (Pointer) + 0xA1, 0x00, // COLLECTION (Physical) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x01, // INPUT (Cnst,Var,Abs) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, // Usage (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (2) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xC0, // END_COLLECTION + 0x09, 0x3c, // USAGE (Motion Wakeup) + 0x05, 0xff, // USAGE_PAGE (Vendor Defined 0xFF) + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x02, // REPORT_COUNT (2) + 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf) + 0x75, 0x06, // REPORT_SIZE (6) + 0x95, 0x01, // REPORT_COUNT (1) + 0xb1, 0x01, // FEATURE (Cnst,Ary,Abs) + 0xc0 // END_COLLECTION }; /*!< mouse report struct */ @@ -256,7 +248,7 @@ 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) { + if (usb_device_is_configured(busid) == false) { return; } 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 c2c61305e6d..b1170798b7b 100644 --- a/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c @@ -70,7 +70,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; @@ -88,49 +88,41 @@ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xA1, 0x01, // COLLECTION (Application) - 0x09, 0x01, // USAGE (Pointer) - - 0xA1, 0x00, // COLLECTION (Physical) - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x03, // USAGE_MAXIMUM (Button 3) - - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) - 0x75, 0x01, // REPORT_SIZE (1) - - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) - 0x81, 0x01, // INPUT (Cnst,Var,Abs) - - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x30, // USAGE (X) - 0x09, 0x31, // USAGE (Y) - 0x09, 0x38, - - 0x15, 0x81, // LOGICAL_MINIMUM (-127) - 0x25, 0x7F, // LOGICAL_MAXIMUM (127) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x03, // REPORT_COUNT (2) - - 0x81, 0x06, // INPUT (Data,Var,Rel) - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 // END_COLLECTION + 0x09, 0x01, // USAGE (Pointer) + 0xA1, 0x00, // COLLECTION (Physical) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x01, // INPUT (Cnst,Var,Abs) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, // Usage (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (2) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xC0, // END_COLLECTION + 0x09, 0x3c, // USAGE (Motion Wakeup) + 0x05, 0xff, // USAGE_PAGE (Vendor Defined 0xFF) + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x02, // REPORT_COUNT (2) + 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf) + 0x75, 0x06, // REPORT_SIZE (6) + 0x95, 0x01, // REPORT_COUNT (1) + 0xb1, 0x01, // FEATURE (Cnst,Ary,Abs) + 0xc0 // END_COLLECTION }; /*!< mouse report struct */ diff --git a/components/drivers/usb/cherryusb/demo/midi_template.c b/components/drivers/usb/cherryusb/demo/midi_template.c index f0e66c4be98..6e522d44420 100644 --- a/components/drivers/usb/cherryusb/demo/midi_template.c +++ b/components/drivers/usb/cherryusb/demo/midi_template.c @@ -87,7 +87,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/msc_ram_template.c b/components/drivers/usb/cherryusb/demo/msc_ram_template.c index cd8f6464638..cd93b2b2f3d 100644 --- a/components/drivers/usb/cherryusb/demo/msc_ram_template.c +++ b/components/drivers/usb/cherryusb/demo/msc_ram_template.c @@ -71,7 +71,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; @@ -109,7 +109,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event) } } -#if !defined(RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV) && !defined(PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV) +#if !defined(RT_CHERRYUSB_DEVICE_MSC_BLKDEV) && !defined(PKG_CHERRYUSB_DEVICE_MSC_BLKDEV) #define BLOCK_SIZE 512 #define BLOCK_COUNT 10 @@ -138,58 +138,19 @@ int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t * memcpy(mass_block[sector].BlockSpace, buffer, length); return 0; } -#else -#include -#include - -#ifndef CONFIG_USBDEV_MSC_THREAD -#error "Please enable CONFIG_USBDEV_MSC_THREAD, move msc read & write from isr to thread" -#endif - -#ifndef CONFIG_USBDEV_MSC_BLOCK_DEV_NAME -#define CONFIG_USBDEV_MSC_BLOCK_DEV_NAME "sd0" -#endif - -static rt_device_t blk_dev = RT_NULL; -struct rt_device_blk_geometry geometry = { 0 }; - -void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size) -{ - rt_device_control(blk_dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - - *block_num = geometry.sector_count; - *block_size = geometry.bytes_per_sector; -} - -int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length) -{ - rt_device_read(blk_dev, sector, buffer, length / geometry.bytes_per_sector); - return 0; -} - -int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length) -{ - rt_device_write(blk_dev, sector, buffer, length / geometry.bytes_per_sector); - return 0; -} #endif static struct usbd_interface intf0; void msc_ram_init(uint8_t busid, uintptr_t reg_base) { -#if defined(RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV) || defined(PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV) - rt_err_t res; - - blk_dev = rt_device_find(CONFIG_USBDEV_MSC_BLOCK_DEV_NAME); - RT_ASSERT(blk_dev); - - res = rt_device_open(blk_dev, RT_DEVICE_OFLAG_RDWR); - RT_ASSERT(res == RT_EOK); -#endif usbd_desc_register(busid, &msc_ram_descriptor); - +#if defined(RT_CHERRYUSB_DEVICE_MSC_BLKDEV) || defined(PKG_CHERRYUSB_DEVICE_MSC_BLKDEV) + extern void usbd_msc_blkdev_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep); + usbd_msc_blkdev_init(busid, MSC_IN_EP, MSC_OUT_EP); +#else usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP)); +#endif usbd_initialize(busid, reg_base, usbd_event_handler); } 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 fab4044fe12..0ab81775015 100644 --- a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c +++ b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c @@ -172,7 +172,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; 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 a45566f6c4e..825e94e95c6 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_h264_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_h264_template.c @@ -105,7 +105,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; 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 0f1bcef6ef3..8f76ce7b168 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c @@ -105,7 +105,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; 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 1d51d8dbbc8..9cda27bc8ae 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c @@ -108,7 +108,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c index ffb2498b81f..d5d3443cc30 100644 --- a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c +++ b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c @@ -114,7 +114,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c index f203f2109e0..367d3da0560 100644 --- a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c +++ b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c @@ -191,7 +191,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 5) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c b/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c index 13d6eb07da6..89441b8cc65 100644 --- a/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c +++ b/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c @@ -106,7 +106,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 3) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/demo/winusb2.0_template.c b/components/drivers/usb/cherryusb/demo/winusb2.0_template.c index 0530d0d1ec7..2fde386f561 100644 --- a/components/drivers/usb/cherryusb/demo/winusb2.0_template.c +++ b/components/drivers/usb/cherryusb/demo/winusb2.0_template.c @@ -120,7 +120,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index > 5) { + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; } return string_descriptors[index]; diff --git a/components/drivers/usb/cherryusb/idf_component.yml b/components/drivers/usb/cherryusb/idf_component.yml index bcae2d659f5..976656cc013 100644 --- a/components/drivers/usb/cherryusb/idf_component.yml +++ b/components/drivers/usb/cherryusb/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.6.0" +version: "1.6.1" description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP tags: - usb diff --git a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c index 8454283f04d..cf0e683eaf0 100644 --- a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c +++ b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c @@ -62,6 +62,11 @@ usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) return sem; } +usb_osal_sem_t usb_osal_sem_create_counting(uint32_t max_count) +{ + return usb_osal_sem_create(0); +} + void usb_osal_sem_delete(usb_osal_sem_t sem) { rt_sem_delete((rt_sem_t)sem); diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c b/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c deleted file mode 100644 index 154d89f0b63..00000000000 --- a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 ~ 2025, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "rtthread.h" -#include "usb_config.h" - -#if defined(PKG_CHERRYUSB_HOST) || defined(RT_CHERRYUSB_HOST) - -#ifndef RT_USING_TIMER_SOFT -#error must enable RT_USING_TIMER_SOFT to support timer callback in thread -#endif - -#if RT_TIMER_THREAD_STACK_SIZE < 1024 -#error "RT_TIMER_THREAD_STACK_SIZE must be >= 1024" -#endif -#endif - -#if defined(ARCH_ARM_CORTEX_M7) || \ - defined(ARCH_ARM_CORTEX_A) || \ - defined(ARCH_RISCV64) || \ - defined(SOC_HPM6200) || defined(SOC_HPM6300) || defined(SOC_HPM6700) || defined(SOC_HPM6800) || \ - defined(SOC_HPM6E00) || defined(SOC_HPM6P00) || \ - defined(BSP_USING_BL61X) || defined(BSP_USING_BL808) -#ifndef RT_USING_CACHE -#error RT_USING_CACHE must be enabled in this chip -#endif -#endif - -#ifdef RT_USING_CACHE -#ifndef CONFIG_USB_DCACHE_ENABLE -#error CONFIG_USB_DCACHE_ENABLE must be enabled if you do not config nocache ram -#endif -#endif diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c b/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c deleted file mode 100644 index 8dd61164071..00000000000 --- a/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "rtthread.h" - -#if defined(PKG_CHERRYUSB_HOST) || defined(RT_CHERRYUSB_HOST) - -#include "usbh_core.h" - -int usbh_init(int argc, char **argv) -{ - uint8_t busid; - uint32_t reg_base; - - if (argc < 3) { - USB_LOG_ERR("please input correct command: usbh_init \r\n"); - return -1; - } - - busid = atoi(argv[1]); - reg_base = strtoll(argv[2], NULL, 16); - usbh_initialize(busid, reg_base, NULL); - - return 0; -} - -int usbh_deinit(int argc, char **argv) -{ - uint8_t busid; - - if (argc < 2) { - USB_LOG_ERR("please input correct command: usbh_deinit \r\n"); - return -1; - } - - busid = atoi(argv[1]); - usbh_deinitialize(busid); - - return 0; -} - -MSH_CMD_EXPORT(usbh_init, init usb host); -MSH_CMD_EXPORT(usbh_deinit, deinit usb host); -MSH_CMD_EXPORT(lsusb, ls usb devices); - -#ifdef CONFIG_USBHOST_SERIAL -#include "usbh_serial.h" -MSH_CMD_EXPORT(usbh_serial, usbh_serial test); -#endif - -#endif diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbd_adb_shell.c b/components/drivers/usb/cherryusb/platform/rtthread/usbd_adb_shell.c deleted file mode 100644 index 4ab7f59af37..00000000000 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbd_adb_shell.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2025, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include - -#include "usbd_core.h" -#include "usbd_adb.h" - -#ifndef CONFIG_USBDEV_SHELL_RX_BUFSIZE -#define CONFIG_USBDEV_SHELL_RX_BUFSIZE (2048) -#endif - -struct usbd_adb_shell { - struct rt_device parent; - usb_osal_sem_t tx_done; - struct rt_ringbuffer rx_rb; - rt_uint8_t rx_rb_buffer[CONFIG_USBDEV_SHELL_RX_BUFSIZE]; -} g_usbd_adb_shell; - -void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len) -{ - rt_ringbuffer_put(&g_usbd_adb_shell.rx_rb, data, len); - - if (g_usbd_adb_shell.parent.rx_indicate) { - g_usbd_adb_shell.parent.rx_indicate(&g_usbd_adb_shell.parent, len); - } -} - -void usbd_adb_notify_write_done(void) -{ - if (g_usbd_adb_shell.tx_done) { - usb_osal_sem_give(g_usbd_adb_shell.tx_done); - } -} - -static rt_err_t usbd_adb_shell_open(struct rt_device *dev, rt_uint16_t oflag) -{ - while (!usb_device_is_configured(0)) { - rt_thread_mdelay(10); - } - return RT_EOK; -} - -static rt_err_t usbd_adb_shell_close(struct rt_device *dev) -{ - if (g_usbd_adb_shell.tx_done) { - usb_osal_sem_give(g_usbd_adb_shell.tx_done); - } - - return RT_EOK; -} - -static rt_ssize_t usbd_adb_shell_read(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - return rt_ringbuffer_get(&g_usbd_adb_shell.rx_rb, (rt_uint8_t *)buffer, size); -} - -static rt_ssize_t usbd_adb_shell_write(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - int ret = 0; - - RT_ASSERT(dev != RT_NULL); - - if (!usb_device_is_configured(0)) { - return size; - } - - if (usbd_adb_can_write() && size) { - usb_osal_sem_reset(g_usbd_adb_shell.tx_done); - usbd_abd_write(ADB_SHELL_LOALID, buffer, size); - usb_osal_sem_take(g_usbd_adb_shell.tx_done, 0xffffffff); - } - - return size; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops usbd_adb_shell_ops = { - NULL, - usbd_adb_shell_open, - usbd_adb_shell_close, - usbd_adb_shell_read, - usbd_adb_shell_write, - NULL -}; -#endif - -void usbd_adb_shell_init(uint8_t in_ep, uint8_t out_ep) -{ - rt_err_t ret; - struct rt_device *device; - - device = &(g_usbd_adb_shell.parent); - - device->type = RT_Device_Class_Char; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &usbd_adb_shell_ops; -#else - device->init = NULL; - device->open = usbd_adb_shell_open; - device->close = usbd_adb_shell_close; - device->read = usbd_adb_shell_read; - device->write = usbd_adb_shell_write; - device->control = NULL; -#endif - device->user_data = NULL; - - /* register a character device */ - ret = rt_device_register(device, "adb-sh", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE); - -#ifdef RT_USING_POSIX_DEVIO - /* set fops */ - device->fops = NULL; -#endif - - g_usbd_adb_shell.tx_done = usb_osal_sem_create(0); - rt_ringbuffer_init(&g_usbd_adb_shell.rx_rb, g_usbd_adb_shell.rx_rb_buffer, sizeof(g_usbd_adb_shell.rx_rb_buffer)); -} - -static int adb_enter(int argc, char **argv) -{ - (void)argc; - (void)argv; - - finsh_set_device("adb-sh"); - rt_console_set_device("adb-sh"); - - return 0; -} -MSH_CMD_EXPORT(adb_enter, adb_enter); - -static int adb_exit(int argc, char **argv) -{ - (void)argc; - (void)argv; - - usbd_adb_close(ADB_SHELL_LOALID); - - finsh_set_device(RT_CONSOLE_DEVICE_NAME); - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); - - return 0; -} -MSH_CMD_EXPORT(adb_exit, adb_exit); diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbd_serial.c b/components/drivers/usb/cherryusb/platform/rtthread/usbd_serial.c deleted file mode 100644 index 2f6d484bca4..00000000000 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbd_serial.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2025, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include - -#include "usbd_core.h" -#include "usbd_cdc_acm.h" - -#define DEV_FORMAT_CDC_ACM "usb-acm%d" - -#ifndef CONFIG_USBDEV_MAX_CDC_ACM_CLASS -#define CONFIG_USBDEV_MAX_CDC_ACM_CLASS (4) -#endif - -#ifndef CONFIG_USBDEV_SERIAL_RX_BUFSIZE -#define CONFIG_USBDEV_SERIAL_RX_BUFSIZE (2048) -#endif - -struct usbd_serial { - struct rt_device parent; - uint8_t busid; - uint8_t in_ep; - uint8_t out_ep; - struct usbd_interface intf_ctrl; - struct usbd_interface intf_data; - usb_osal_sem_t tx_done; - uint8_t minor; - char name[32]; - struct rt_ringbuffer rx_rb; - rt_uint8_t rx_rb_buffer[CONFIG_USBDEV_SERIAL_RX_BUFSIZE]; -}; - -static uint32_t g_devinuse = 0; - -static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbd_serial_cdc_acm_rx_buf[CONFIG_USBDEV_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(512, CONFIG_USB_ALIGN_SIZE)]; - -static struct usbd_serial g_usbd_serial_cdc_acm[CONFIG_USBDEV_MAX_CDC_ACM_CLASS]; - -static struct usbd_serial *usbd_serial_alloc(void) -{ - uint8_t devno; - struct usbd_serial *serial; - - for (devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); - - serial = &g_usbd_serial_cdc_acm[devno]; - memset(serial, 0, sizeof(struct usbd_serial)); - serial->minor = devno; - snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->minor); - return serial; - } - } - return NULL; -} - -static void usbd_serial_free(struct usbd_serial *serial) -{ - uint8_t devno = serial->minor; - - if (devno < 32) { - g_devinuse &= ~(1U << devno); - } - memset(serial, 0, sizeof(struct usbd_serial)); -} - -static rt_err_t usbd_serial_open(struct rt_device *dev, rt_uint16_t oflag) -{ - struct usbd_serial *serial; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbd_serial *)dev; - - while(!usb_device_is_configured(serial->busid)) { - rt_thread_mdelay(10); - } - - usbd_ep_start_read(serial->busid, serial->out_ep, - g_usbd_serial_cdc_acm_rx_buf[serial->minor], - usbd_get_ep_mps(serial->busid, serial->out_ep)); - return RT_EOK; -} - -static rt_ssize_t usbd_serial_read(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct usbd_serial *serial; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbd_serial *)dev; - - if (!usb_device_is_configured(serial->busid)) { - return -RT_EPERM; - } - - return rt_ringbuffer_get(&serial->rx_rb, (rt_uint8_t *)buffer, size); -} - -static rt_ssize_t usbd_serial_write(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct usbd_serial *serial; - int ret = 0; - rt_uint8_t *align_buf; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbd_serial *)dev; - - if (!usb_device_is_configured(serial->busid)) { - return -RT_EPERM; - } - align_buf = (rt_uint8_t *)buffer; - - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - align_buf = rt_malloc_align(USB_ALIGN_UP(size, CONFIG_USB_ALIGN_SIZE), CONFIG_USB_ALIGN_SIZE); - if (!align_buf) { - USB_LOG_ERR("serial get align buf failed\n"); - return 0; - } - - usb_memcpy(align_buf, buffer, size); - } - - usb_osal_sem_reset(serial->tx_done); - usbd_ep_start_write(serial->busid, serial->in_ep, align_buf, size); - ret = usb_osal_sem_take(serial->tx_done, 3000); - if (ret < 0) { - USB_LOG_ERR("serial write timeout\n"); - ret = -RT_ETIMEOUT; - } else { - ret = size; - } - - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - rt_free_align(align_buf); - } - - return ret; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops usbd_serial_ops = { - NULL, - usbd_serial_open, - NULL, - usbd_serial_read, - usbd_serial_write, - NULL -}; -#endif - -rt_err_t usbd_serial_register(struct usbd_serial *serial, - void *data) -{ - rt_err_t ret; - struct rt_device *device; - RT_ASSERT(serial != RT_NULL); - - device = &(serial->parent); - - device->type = RT_Device_Class_Char; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &usbd_serial_ops; -#else - device->init = NULL; - device->open = usbd_serial_open; - device->close = NULL; - device->read = usbd_serial_read; - device->write = usbd_serial_write; - device->control = NULL; -#endif - device->user_data = data; - - /* register a character device */ - ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_REMOVABLE); - -#ifdef RT_USING_POSIX_DEVIO - /* set fops */ - device->fops = NULL; -#endif - rt_ringbuffer_init(&serial->rx_rb, serial->rx_rb_buffer, sizeof(serial->rx_rb_buffer)); - - return ret; -} - -void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - struct usbd_serial *serial; - - for (uint8_t devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) { - serial = &g_usbd_serial_cdc_acm[devno]; - if (serial->out_ep == ep) { - rt_ringbuffer_put(&serial->rx_rb, g_usbd_serial_cdc_acm_rx_buf[serial->minor], nbytes); - usbd_ep_start_read(serial->busid, serial->out_ep, - g_usbd_serial_cdc_acm_rx_buf[serial->minor], - usbd_get_ep_mps(serial->busid, serial->out_ep)); - - if (serial->parent.rx_indicate) { - serial->parent.rx_indicate(&serial->parent, nbytes); - } - break; - } - } -} - -void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - struct usbd_serial *serial; - - if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { - /* send zlp */ - usbd_ep_start_write(busid, ep, NULL, 0); - } else { - for (uint8_t devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) { - serial = &g_usbd_serial_cdc_acm[devno]; - if ((serial->in_ep == ep) && serial->tx_done) { - usb_osal_sem_give(serial->tx_done); - break; - } - } - } -} - -void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep) -{ - struct usbd_serial *serial; - - struct usbd_endpoint cdc_out_ep = { - .ep_addr = out_ep, - .ep_cb = usbd_cdc_acm_bulk_out - }; - - struct usbd_endpoint cdc_in_ep = { - .ep_addr = in_ep, - .ep_cb = usbd_cdc_acm_bulk_in - }; - - serial = usbd_serial_alloc(); - if (serial == NULL) { - USB_LOG_ERR("No more serial device available\n"); - return; - } - - serial->busid = busid; - serial->in_ep = in_ep; - serial->out_ep = out_ep; - serial->tx_done = usb_osal_sem_create(0); - - usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &serial->intf_ctrl)); - usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &serial->intf_data)); - usbd_add_endpoint(busid, &cdc_out_ep); - usbd_add_endpoint(busid, &cdc_in_ep); - - if (usbd_serial_register(serial, NULL) != RT_EOK) { - USB_LOG_ERR("Failed to register serial device\n"); - usbd_serial_free(serial); - return; - } - - USB_LOG_INFO("USB CDC ACM Serial Device %s initialized\n", serial->name); -} diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c b/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c deleted file mode 100644 index 77846665269..00000000000 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_msc.h" - -#include "rtthread.h" -#include - -#define DEV_FORMAT "/dev/sd%c" - -#ifndef RT_USING_DFS_ELMFAT -#error "RT_USING_DFS_ELMFAT must be enabled to use USB mass storage device" -#endif - -#ifndef CONFIG_USB_DFS_MOUNT_POINT -#define CONFIG_USB_DFS_MOUNT_POINT "/" -#endif - -static rt_err_t rt_udisk_init(rt_device_t dev) -{ - struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data; - - if (usbh_msc_scsi_init(msc_class) < 0) { - return -RT_ERROR; - } - - return RT_EOK; -} - -static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer, - rt_size_t size) -{ - struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data; - int ret; - rt_uint8_t *align_buf; - - align_buf = (rt_uint8_t *)buffer; - - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE); - if (!align_buf) { - rt_kprintf("msc get align buf failed\n"); - return 0; - } - } else { - } - - ret = usbh_msc_scsi_read10(msc_class, pos, (uint8_t *)align_buf, size); - if (ret < 0) { - rt_kprintf("usb mass_storage read failed\n"); - return 0; - } - - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - usb_memcpy(buffer, align_buf, size * msc_class->blocksize); - rt_free_align(align_buf); - } - - return size; -} - -static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer, - rt_size_t size) -{ - struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data; - int ret; - rt_uint8_t *align_buf; - - align_buf = (rt_uint8_t *)buffer; - - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE); - if (!align_buf) { - rt_kprintf("msc get align buf failed\n"); - return 0; - } - - usb_memcpy(align_buf, buffer, size * msc_class->blocksize); - } - - ret = usbh_msc_scsi_write10(msc_class, pos, (uint8_t *)align_buf, size); - if (ret < 0) { - rt_kprintf("usb mass_storage write failed\n"); - return 0; - } - - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - rt_free_align(align_buf); - } - - return size; -} - -static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args) -{ - /* check parameter */ - RT_ASSERT(dev != RT_NULL); - struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data; - - if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) { - struct rt_device_blk_geometry *geometry; - - geometry = (struct rt_device_blk_geometry *)args; - if (geometry == RT_NULL) - return -RT_ERROR; - - geometry->bytes_per_sector = msc_class->blocksize; - geometry->block_size = msc_class->blocksize; - geometry->sector_count = msc_class->blocknum; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops udisk_device_ops = { - rt_udisk_init, - RT_NULL, - RT_NULL, - rt_udisk_read, - rt_udisk_write, - rt_udisk_control -}; -#endif - -static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) -{ - struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV; - char name[CONFIG_USBHOST_DEV_NAMELEN]; - char mount_point[CONFIG_USBHOST_DEV_NAMELEN]; - int ret; - - snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar); - snprintf(mount_point, CONFIG_USBHOST_DEV_NAMELEN, CONFIG_USB_DFS_MOUNT_POINT, msc_class->sdchar); - - ret = dfs_mount(name, mount_point, "elm", 0, 0); - if (ret == 0) { - rt_kprintf("udisk: %s mount successfully\n", name); - } else { - rt_kprintf("udisk: %s mount failed, ret = %d\n", name, ret); - } - - usb_osal_thread_delete(NULL); -} - -void usbh_msc_run(struct usbh_msc *msc_class) -{ - struct rt_device *dev; - char name[CONFIG_USBHOST_DEV_NAMELEN]; - - dev = rt_malloc(sizeof(struct rt_device)); - memset(dev, 0, sizeof(struct rt_device)); - - snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar); - - dev->type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - dev->ops = &udisk_device_ops; -#else - dev->init = rt_udisk_init; - dev->read = rt_udisk_read; - dev->write = rt_udisk_write; - dev->control = rt_udisk_control; -#endif - dev->user_data = msc_class; - - rt_device_register(dev, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); - - usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class); -} - -void usbh_msc_stop(struct usbh_msc *msc_class) -{ - struct rt_device *dev; - - char name[CONFIG_USBHOST_DEV_NAMELEN]; - char mount_point[CONFIG_USBHOST_DEV_NAMELEN]; - - snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar); - snprintf(mount_point, CONFIG_USBHOST_DEV_NAMELEN, CONFIG_USB_DFS_MOUNT_POINT, msc_class->sdchar); - - dfs_unmount(mount_point); - dev = rt_device_find(name); - if (dev) { - rt_device_unregister(dev); - rt_free(dev); - } -} diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c b/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c deleted file mode 100644 index 292e5e3c880..00000000000 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "netif/etharp.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" -#include "lwip/tcpip.h" -#if LWIP_DHCP -#include "lwip/dhcp.h" -#include "lwip/prot/dhcp.h" -#endif - -#include -#include -#include - -#include "usbh_core.h" - -#include "lwip/opt.h" - -#ifndef RT_USING_LWIP212 -#error must enable RT_USING_LWIP212 -#endif - -#ifndef LWIP_NO_RX_THREAD -#warning suggest you to enable LWIP_NO_RX_THREAD, we do not use rtthread eth rx thread -#endif - -#ifndef LWIP_NO_TX_THREAD -#warning suggest you to enable LWIP_NO_TX_THREAD, we do not use rtthread eth tx thread -#endif - -#if LWIP_TCPIP_CORE_LOCKING_INPUT != 1 -#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1 for better performance, usb handles eth input with own thread -#endif - -#if LWIP_TCPIP_CORE_LOCKING != 1 -#error must set LWIP_TCPIP_CORE_LOCKING to 1 -#endif - -#if PBUF_POOL_BUFSIZE < 1600 -#error PBUF_POOL_BUFSIZE must be larger than 1600 -#endif - -#if RT_LWIP_TCPTHREAD_STACKSIZE < 2048 -#error RT_LWIP_TCPTHREAD_STACKSIZE must be >= 2048 -#endif - -#if !defined(CONFIG_USBHOST_PLATFORM_CDC_ECM) && \ - !defined(CONFIG_USBHOST_PLATFORM_CDC_RNDIS) && \ - !defined(CONFIG_USBHOST_PLATFORM_CDC_NCM) && \ - !defined(CONFIG_USBHOST_PLATFORM_ASIX) && \ - !defined(CONFIG_USBHOST_PLATFORM_RTL8152) -#error "Please enable at least one USB Ethernet platform in usb_config.h or Kconfig" -#endif - -// #define CONFIG_USBHOST_PLATFORM_CDC_ECM -// #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS -// #define CONFIG_USBHOST_PLATFORM_CDC_NCM -// #define CONFIG_USBHOST_PLATFORM_ASIX -// #define CONFIG_USBHOST_PLATFORM_RTL8152 - -void usbh_lwip_eth_output_common(struct pbuf *p, uint8_t *buf) -{ - struct pbuf *q; - uint8_t *buffer; - - buffer = buf; - for (q = p; q != NULL; q = q->next) { - usb_memcpy(buffer, q->payload, q->len); - buffer += q->len; - } -} - -void usbh_lwip_eth_input_common(struct netif *netif, uint8_t *buf, uint32_t len) -{ -#if LWIP_TCPIP_CORE_LOCKING_INPUT - pbuf_type type = PBUF_REF; -#else - pbuf_type type = PBUF_POOL; -#endif - err_t err; - struct pbuf *p; - - p = pbuf_alloc(PBUF_RAW, len, type); - if (p != NULL) { -#if LWIP_TCPIP_CORE_LOCKING_INPUT - p->payload = buf; -#else - usb_memcpy(p->payload, buf, len); -#endif - err = netif->input(p, netif); - if (err != ERR_OK) { - pbuf_free(p); - } - } else { - USB_LOG_ERR("No memory to alloc pbuf\r\n"); - } -} - -#ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM -#include "usbh_cdc_ecm.h" - -static struct eth_device g_cdc_ecm_dev; - -static rt_err_t rt_usbh_cdc_ecm_control(rt_device_t dev, int cmd, void *args) -{ - struct usbh_cdc_ecm *cdc_ecm_class = (struct usbh_cdc_ecm *)dev->user_data; - - switch (cmd) { - case NIOCTL_GADDR: - - /* get mac address */ - if (args) - rt_memcpy(args, cdc_ecm_class->mac, 6); - else - return -RT_ERROR; - - break; - - default: - break; - } - - return RT_EOK; -} - -static rt_err_t rt_usbh_cdc_ecm_eth_tx(rt_device_t dev, struct pbuf *p) -{ - int ret; - (void)dev; - - usbh_lwip_eth_output_common(p, usbh_cdc_ecm_get_eth_txbuf()); - ret = usbh_cdc_ecm_eth_output(p->tot_len); - if (ret < 0) { - return -RT_ERROR; - } else { - return RT_EOK; - } -} - -void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen) -{ - usbh_lwip_eth_input_common(g_cdc_ecm_dev.netif, buf, buflen); -} - -void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) -{ - memset(&g_cdc_ecm_dev, 0, sizeof(struct eth_device)); - - g_cdc_ecm_dev.parent.control = rt_usbh_cdc_ecm_control; - g_cdc_ecm_dev.eth_rx = NULL; - g_cdc_ecm_dev.eth_tx = rt_usbh_cdc_ecm_eth_tx; - g_cdc_ecm_dev.parent.user_data = cdc_ecm_class; - - eth_device_init(&g_cdc_ecm_dev, "u0"); - eth_device_linkchange(&g_cdc_ecm_dev, RT_TRUE); - - usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL); -} - -void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class) -{ - (void)cdc_ecm_class; - - eth_device_deinit(&g_cdc_ecm_dev); -} -#endif - -#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS -#include "usbh_rndis.h" - -static struct eth_device g_rndis_dev; - -static rt_timer_t keep_timer = RT_NULL; - -static void rndis_dev_keepalive_timeout(void *parameter) -{ - struct usbh_rndis *rndis_class = (struct usbh_rndis *)parameter; - usbh_rndis_keepalive(rndis_class); -} - -static void timer_init(struct usbh_rndis *rndis_class) -{ - keep_timer = rt_timer_create("keep", - rndis_dev_keepalive_timeout, - rndis_class, - 5000, - RT_TIMER_FLAG_PERIODIC | - RT_TIMER_FLAG_SOFT_TIMER); - - rt_timer_start(keep_timer); -} - -static rt_err_t rt_usbh_rndis_control(rt_device_t dev, int cmd, void *args) -{ - struct usbh_rndis *rndis_class = (struct usbh_rndis *)dev->user_data; - - switch (cmd) { - case NIOCTL_GADDR: - - /* get mac address */ - if (args) - rt_memcpy(args, rndis_class->mac, 6); - else - return -RT_ERROR; - - break; - - default: - break; - } - - return RT_EOK; -} - -static rt_err_t rt_usbh_rndis_eth_tx(rt_device_t dev, struct pbuf *p) -{ - int ret; - (void)dev; - - usbh_lwip_eth_output_common(p, usbh_rndis_get_eth_txbuf()); - ret = usbh_rndis_eth_output(p->tot_len); - if (ret < 0) { - return -RT_ERROR; - } else { - return RT_EOK; - } -} - -void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen) -{ - usbh_lwip_eth_input_common(g_rndis_dev.netif, buf, buflen); -} - -void usbh_rndis_run(struct usbh_rndis *rndis_class) -{ - memset(&g_rndis_dev, 0, sizeof(struct eth_device)); - - g_rndis_dev.parent.control = rt_usbh_rndis_control; - g_rndis_dev.eth_rx = NULL; - g_rndis_dev.eth_tx = rt_usbh_rndis_eth_tx; - g_rndis_dev.parent.user_data = rndis_class; - - eth_device_init(&g_rndis_dev, "u2"); - eth_device_linkchange(&g_rndis_dev, RT_TRUE); - - usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL); - //timer_init(rndis_class); -} - -void usbh_rndis_stop(struct usbh_rndis *rndis_class) -{ - (void)rndis_class; - - eth_device_deinit(&g_rndis_dev); - // rt_timer_stop(keep_timer); - // rt_timer_delete(keep_timer); -} -#endif - -#ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM -#include "usbh_cdc_ncm.h" - -static struct eth_device g_cdc_ncm_dev; - -static rt_err_t rt_usbh_cdc_ncm_control(rt_device_t dev, int cmd, void *args) -{ - struct usbh_cdc_ncm *cdc_ncm_class = (struct usbh_cdc_ncm *)dev->user_data; - - switch (cmd) { - case NIOCTL_GADDR: - - /* get mac address */ - if (args) - rt_memcpy(args, cdc_ncm_class->mac, 6); - else - return -RT_ERROR; - - break; - - default: - break; - } - - return RT_EOK; -} - -static rt_err_t rt_usbh_cdc_ncm_eth_tx(rt_device_t dev, struct pbuf *p) -{ - int ret; - (void)dev; - - usbh_lwip_eth_output_common(p, usbh_cdc_ncm_get_eth_txbuf()); - ret = usbh_cdc_ncm_eth_output(p->tot_len); - if (ret < 0) { - return -RT_ERROR; - } else { - return RT_EOK; - } -} - -void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen) -{ - usbh_lwip_eth_input_common(g_cdc_ncm_dev.netif, buf, buflen); -} - -void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class) -{ - memset(&g_cdc_ncm_dev, 0, sizeof(struct eth_device)); - - g_cdc_ncm_dev.parent.control = rt_usbh_cdc_ncm_control; - g_cdc_ncm_dev.eth_rx = NULL; - g_cdc_ncm_dev.eth_tx = rt_usbh_cdc_ncm_eth_tx; - g_cdc_ncm_dev.parent.user_data = cdc_ncm_class; - - eth_device_init(&g_cdc_ncm_dev, "u1"); - eth_device_linkchange(&g_cdc_ncm_dev, RT_TRUE); - - usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL); -} - -void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class) -{ - (void)cdc_ncm_class; - - eth_device_deinit(&g_cdc_ncm_dev); -} -#endif - -#ifdef CONFIG_USBHOST_PLATFORM_ASIX -#include "usbh_asix.h" - -static struct eth_device g_asix_dev; - -static rt_err_t rt_usbh_asix_control(rt_device_t dev, int cmd, void *args) -{ - struct usbh_asix *asix_class = (struct usbh_asix *)dev->user_data; - - switch (cmd) { - case NIOCTL_GADDR: - - /* get mac address */ - if (args) - rt_memcpy(args, asix_class->mac, 6); - else - return -RT_ERROR; - - break; - - default: - break; - } - - return RT_EOK; -} - -static rt_err_t rt_usbh_asix_eth_tx(rt_device_t dev, struct pbuf *p) -{ - int ret; - (void)dev; - - usbh_lwip_eth_output_common(p, usbh_asix_get_eth_txbuf()); - ret = usbh_asix_eth_output(p->tot_len); - if (ret < 0) { - return -RT_ERROR; - } else { - return RT_EOK; - } -} - -void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen) -{ - usbh_lwip_eth_input_common(g_asix_dev.netif, buf, buflen); -} - -void usbh_asix_run(struct usbh_asix *asix_class) -{ - memset(&g_asix_dev, 0, sizeof(struct eth_device)); - - g_asix_dev.parent.control = rt_usbh_asix_control; - g_asix_dev.eth_rx = NULL; - g_asix_dev.eth_tx = rt_usbh_asix_eth_tx; - g_asix_dev.parent.user_data = asix_class; - - eth_device_init(&g_asix_dev, "u3"); - eth_device_linkchange(&g_asix_dev, RT_TRUE); - - usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL); -} - -void usbh_asix_stop(struct usbh_asix *asix_class) -{ - (void)asix_class; - - eth_device_deinit(&g_asix_dev); -} -#endif - -#ifdef CONFIG_USBHOST_PLATFORM_RTL8152 -#include "usbh_rtl8152.h" - -static struct eth_device g_rtl8152_dev; - -static rt_err_t rt_usbh_rtl8152_control(rt_device_t dev, int cmd, void *args) -{ - struct usbh_rtl8152 *rtl8152_class = (struct usbh_rtl8152 *)dev->user_data; - - switch (cmd) { - case NIOCTL_GADDR: - - /* get mac address */ - if (args) - rt_memcpy(args, rtl8152_class->mac, 6); - else - return -RT_ERROR; - - break; - - default: - break; - } - - return RT_EOK; -} - -static rt_err_t rt_usbh_rtl8152_eth_tx(rt_device_t dev, struct pbuf *p) -{ - int ret; - (void)dev; - - usbh_lwip_eth_output_common(p, usbh_rtl8152_get_eth_txbuf()); - ret = usbh_rtl8152_eth_output(p->tot_len); - if (ret < 0) { - return -RT_ERROR; - } else { - return RT_EOK; - } -} - -void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen) -{ - usbh_lwip_eth_input_common(g_rtl8152_dev.netif, buf, buflen); -} - -void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class) -{ - memset(&g_rtl8152_dev, 0, sizeof(struct eth_device)); - - g_rtl8152_dev.parent.control = rt_usbh_rtl8152_control; - g_rtl8152_dev.eth_rx = NULL; - g_rtl8152_dev.eth_tx = rt_usbh_rtl8152_eth_tx; - g_rtl8152_dev.parent.user_data = rtl8152_class; - - eth_device_init(&g_rtl8152_dev, "u4"); - eth_device_linkchange(&g_rtl8152_dev, RT_TRUE); - - usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL); -} - -void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class) -{ - (void)rtl8152_class; - - eth_device_deinit(&g_rtl8152_dev); -} -#endif 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 ddead2b9db7..d8122ece267 100644 --- a/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c +++ b/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c @@ -722,7 +722,7 @@ void USBD_IRQHandler(uint8_t busid) if (ep_addr & 0x80) { usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len); } else { - usb_dcache_invalidate((uintptr_t)g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(transfer_len, CONFIG_USB_ALIGN_SIZE)); + usb_dcache_invalidate((uintptr_t)g_chipidea_udc[busid].out_ep[ep_idx / 2].xfer_buf, USB_ALIGN_UP(transfer_len, CONFIG_USB_ALIGN_SIZE)); usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len); } } 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 31be0d55db0..92479c8d132 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c @@ -95,13 +95,14 @@ static inline int dwc2_core_init(uint8_t busid) regval &= ~USB_OTG_GUSBCFG_PHYIF16; regval &= ~USB_OTG_GUSBCFG_DDR_SEL; - if (g_dwc2_udc[busid].user_params.phy_utmi_width == 16) { - regval |= USB_OTG_GUSBCFG_PHYIF16; - } break; case DWC2_PHY_TYPE_PARAM_UTMI: regval &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL; regval &= ~USB_OTG_GUSBCFG_PHYIF16; + + if (g_dwc2_udc[busid].user_params.phy_utmi_width == 16) { + regval |= USB_OTG_GUSBCFG_PHYIF16; + } break; default: @@ -616,7 +617,7 @@ int usb_dc_init(uint8_t busid) int usb_dc_deinit(uint8_t busid) { - USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT; + USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS; /* Clear Pending interrupt */ @@ -630,6 +631,11 @@ int usb_dc_deinit(uint8_t busid) USB_OTG_DEV->DOEPMSK = 0U; USB_OTG_DEV->DAINTMSK = 0U; + /* Disable all interrupts. */ + USB_OTG_GLB->GINTMSK = 0U; + /* Clear any pending interrupts */ + USB_OTG_GLB->GINTSTS = 0xBFFFFFFFU; + /* Flush the FIFO */ dwc2_flush_txfifo(busid, 0x10U); dwc2_flush_rxfifo(busid); diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c index 485b36c269e..5e54f572125 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c @@ -84,7 +84,7 @@ void usb_dc_low_level_init(uint8_t busid) USBHS_SS->PHY_FUNC_CTL_1 |= (7 << USBHS_SS_PHY_FUNC_CTL_1_PLL_FSEL_Pos); USBHS_SS->PHY_FUNC_CTL_2 |= (USBHS_SS_PHY_FUNC_CTL_2_RES_TUNING_SEL_Msk | USBHS_SS_PHY_FUNC_CTL_2_EFUSE_SEL_Msk); - rt_thread_mdelay(200); /* Wait for PHY stable */ + rt_thread_mdelay(200); // Wait for PHY stable cy_stc_sysint_t usb_int_cfg = { .intrSrc = usbhs_interrupt_usbhsctrl_IRQn, @@ -123,7 +123,7 @@ void usb_hc_low_level_init(struct usbh_bus *bus) USBHS_SS->PHY_FUNC_CTL_1 |= (7 << USBHS_SS_PHY_FUNC_CTL_1_PLL_FSEL_Pos); USBHS_SS->PHY_FUNC_CTL_2 |= (USBHS_SS_PHY_FUNC_CTL_2_RES_TUNING_SEL_Msk | USBHS_SS_PHY_FUNC_CTL_2_EFUSE_SEL_Msk); - rt_thread_mdelay(200); /* Wait for PHY stable */ + rt_thread_mdelay(200); // Wait for PHY stable cy_stc_sysint_t usb_int_cfg = { .intrSrc = usbhs_interrupt_usbhsctrl_IRQn, 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 92a7f3e0270..946dfd4656f 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c @@ -293,12 +293,11 @@ static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ep_mult, uint8_t speed) { + USB_OTG_HC((uint32_t)ch_num)->HCINTMSK = 0U; + /* Clear old interrupt conditions for this host channel. */ USB_OTG_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU; - /* Enable channel interrupts required for this transfer. */ - USB_OTG_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_CHHM; - /* Enable the top level host channel interrupt. */ USB_OTG_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU); @@ -310,6 +309,7 @@ static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint { __IO uint32_t tmpreg; uint8_t is_oddframe; + size_t flags; /* Initialize the HCTSIZn register */ USB_OTG_HC(ch_num)->HCTSIZ = (size & USB_OTG_HCTSIZ_XFRSIZ) | @@ -319,6 +319,11 @@ static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint /* xfer_buff MUST be 32-bits aligned */ USB_OTG_HC(ch_num)->HCDMA = (uint32_t)buf; + flags = usb_osal_enter_critical_section(); + + /* Enable channel interrupts required for this transfer. */ + USB_OTG_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_CHHM; + is_oddframe = (((uint32_t)USB_OTG_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U; USB_OTG_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM; USB_OTG_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29; @@ -328,6 +333,8 @@ static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg |= USB_OTG_HCCHAR_CHENA; USB_OTG_HC(ch_num)->HCCHAR = tmpreg; + + usb_osal_leave_critical_section(flags); } static inline void dwc2_chan_enable_csplit(struct usbh_bus *bus, uint8_t ch_num, bool enable) diff --git a/components/drivers/usb/cherryusb/port/hpmicro/usb_dc_hpm.c b/components/drivers/usb/cherryusb/port/hpmicro/usb_dc_hpm.c index a3a9fdc10d9..60af11870f9 100644 --- a/components/drivers/usb/cherryusb/port/hpmicro/usb_dc_hpm.c +++ b/components/drivers/usb/cherryusb/port/hpmicro/usb_dc_hpm.c @@ -7,6 +7,11 @@ #include "usbd_core.h" #include "hpm_usb_device.h" #include "usb_glue_hpm.h" +#include "hpm_sdk_version.h" + +#if SDK_VERSION_NUMBER < 0x10C00 +#error "Please use SDK version 1.12.0 or later because of USB api modification" +#endif #define USB_NUM_BIDIR_ENDPOINTS USB_SOC_DCD_MAX_ENDPOINT_COUNT @@ -46,6 +51,7 @@ struct hpm_udc { static USB_NOCACHE_RAM_SECTION ATTR_ALIGN(USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT) uint8_t _dcd_data[CONFIG_USBDEV_MAX_BUS][HPM_ALIGN_UP(sizeof(dcd_data_t), USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT)]; static USB_NOCACHE_RAM_SECTION usb_device_handle_t usb_device_handle[CONFIG_USBDEV_MAX_BUS]; +static uint8_t _setup_data[8]; /* Index to bit position in register */ static inline uint8_t ep_idx2bit(uint8_t ep_idx) @@ -234,12 +240,13 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui { uint8_t ep_idx = USB_EP_GET_IDX(ep); usb_device_handle_t *handle = g_hpm_udc[busid].handle; + bool ret; if (!data && data_len) { - return -1; + return -USB_ERR_NOMEM; } if (!g_hpm_udc[busid].in_ep[ep_idx].ep_enable) { - return -2; + return -USB_ERR_NOTCONN; } #ifdef CONFIG_USB_DCACHE_ENABLE @@ -251,21 +258,22 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui g_hpm_udc[busid].in_ep[ep_idx].actual_xfer_len = 0; usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE)); - usb_device_edpt_xfer(handle, ep, (uint8_t *)data, data_len); + ret = usb_device_edpt_xfer(handle, ep, (uint8_t *)data, data_len); - return 0; + return ret ? 0 : -USB_ERR_INVAL; } int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len) { uint8_t ep_idx = USB_EP_GET_IDX(ep); usb_device_handle_t *handle = g_hpm_udc[busid].handle; + bool ret; if (!data && data_len) { - return -1; + return -USB_ERR_NOMEM; } if (!g_hpm_udc[busid].out_ep[ep_idx].ep_enable) { - return -2; + return -USB_ERR_NOTCONN; } #ifdef CONFIG_USB_DCACHE_ENABLE @@ -277,9 +285,9 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t g_hpm_udc[busid].out_ep[ep_idx].actual_xfer_len = 0; usb_dcache_invalidate((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE)); - usb_device_edpt_xfer(handle, ep, data, data_len); + ret = usb_device_edpt_xfer(handle, ep, data, data_len); - return 0; + return ret ? 0 : -USB_ERR_INVAL; } void USBD_IRQHandler(uint8_t busid) @@ -310,6 +318,7 @@ void USBD_IRQHandler(uint8_t busid) memset(g_hpm_udc[busid].out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); usbd_event_reset_handler(busid); usb_device_bus_reset(handle, g_hpm_udc[busid].in_ep[0].ep_mps); + return; } if (int_status & intr_suspend) { @@ -359,6 +368,11 @@ void USBD_IRQHandler(uint8_t busid) break; } else { transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes; + if ((ep_idx & 0x01) != 0) { + g_hpm_udc[busid].in_ep[ep_idx / 2].actual_xfer_len = transfer_len; + } else { + g_hpm_udc[busid].out_ep[ep_idx / 2].actual_xfer_len = transfer_len; + } p_qtd->in_use = false; } @@ -374,7 +388,7 @@ void USBD_IRQHandler(uint8_t busid) if (ep_addr & 0x80) { usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len); } else { - usb_dcache_invalidate((uintptr_t)g_hpm_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(transfer_len, CONFIG_USB_ALIGN_SIZE)); + usb_dcache_invalidate((uintptr_t)g_hpm_udc[busid].out_ep[ep_idx / 2].xfer_buf, USB_ALIGN_UP(transfer_len, CONFIG_USB_ALIGN_SIZE)); usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len); } } @@ -383,10 +397,17 @@ void USBD_IRQHandler(uint8_t busid) } if (edpt_setup_status) { - /*------------- Set up Received -------------*/ - usb_device_clear_setup_status(handle, edpt_setup_status); + /*------------- Setup Received -------------*/ dcd_qhd_t *qhd0 = usb_device_qhd_get(handle, 0); - usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request); + + usb_device_clear_setup_status(handle, edpt_setup_status); + do { + usb_dcd_set_sutw(handle->regs, true); + memcpy(_setup_data, (uint8_t *)(&qhd0->setup_request), 8); + } while (!usb_dcd_get_sutw(handle->regs)); + usb_dcd_set_sutw(handle->regs, false); + + usbd_event_ep0_setup_complete_handler(busid, _setup_data); } } } \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/port/musb/README.md b/components/drivers/usb/cherryusb/port/musb/README.md index 8b5e1299599..7c7b4305672 100644 --- a/components/drivers/usb/cherryusb/port/musb/README.md +++ b/components/drivers/usb/cherryusb/port/musb/README.md @@ -9,6 +9,7 @@ ### TI - MSP432E4x +- TM4Cx ### Bekencorp diff --git a/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c b/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c index 26d2ce74caf..b0c75009bc1 100644 --- a/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c +++ b/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c @@ -924,13 +924,6 @@ void handle_ep0(struct usbh_bus *bus) musb_urb_waitup(urb); return; } - if (ep0_status & USB_CSRL0_STALL) { - HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALL; - pipe->ep0_state = USB_EP0_STATE_SETUP; - urb->errorcode = -USB_ERR_STALL; - musb_urb_waitup(urb); - return; - } switch (pipe->ep0_state) { case USB_EP0_STATE_SETUP: @@ -1097,8 +1090,8 @@ void USBH_IRQHandler(uint8_t busid) HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_NAKTO; urb->errorcode = -USB_ERR_NAK; musb_urb_waitup(urb); - } else if (ep_csrl_status & USB_TXCSRL1_STALL) { - HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_STALL; + } else if (ep_csrl_status & USB_TXCSRL1_STALLED) { + HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_STALLED; urb->errorcode = -USB_ERR_STALL; musb_urb_waitup(urb); } else { @@ -1146,8 +1139,8 @@ void USBH_IRQHandler(uint8_t busid) HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~USB_RXCSRL1_NAKTO; urb->errorcode = -USB_ERR_NAK; musb_urb_waitup(urb); - } else if (ep_csrl_status & USB_RXCSRL1_STALL) { - HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~USB_RXCSRL1_STALL; + } else if (ep_csrl_status & USB_RXCSRL1_STALLED) { + HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~USB_RXCSRL1_STALLED; urb->errorcode = -USB_ERR_STALL; musb_urb_waitup(urb); } else if (ep_csrl_status & USB_RXCSRL1_RXRDY) { From 5a5a8fc04aafae7001d57ebd9470e0d37af5af1d Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Wed, 6 May 2026 14:14:04 +0800 Subject: [PATCH 2/2] update(bsp): update cherryusb demo to v1.6.1 Signed-off-by: sakumisu <1203593632@qq.com> --- bsp/bouffalo_lab/bl61x/board/cherryusb_port.c | 2 +- bsp/bouffalo_lab/bl61x/board/usb_config.h | 7 +++- bsp/hpmicro/hpm6750evk/board/cherryusb_port.c | 41 ------------------- .../hpm6750evk2/board/cherryusb_port.c | 2 +- bsp/hpmicro/hpm6750evk2/board/usb_config.h | 7 +++- .../mcxn/frdm-mcxn947/board/cherryusb_port.c | 2 +- .../mcx/mcxn/frdm-mcxn947/board/usb_config.h | 7 +++- 7 files changed, 21 insertions(+), 47 deletions(-) delete mode 100644 bsp/hpmicro/hpm6750evk/board/cherryusb_port.c diff --git a/bsp/bouffalo_lab/bl61x/board/cherryusb_port.c b/bsp/bouffalo_lab/bl61x/board/cherryusb_port.c index 2a92418976b..0955bb364d8 100644 --- a/bsp/bouffalo_lab/bl61x/board/cherryusb_port.c +++ b/bsp/bouffalo_lab/bl61x/board/cherryusb_port.c @@ -30,7 +30,7 @@ INIT_COMPONENT_EXPORT(cherryusb_devinit); int cherryusb_hostinit(void) { - usbh_initialize(0, 0x20072000); + usbh_initialize(0, 0x20072000, NULL); return 0; } INIT_COMPONENT_EXPORT(cherryusb_hostinit); diff --git a/bsp/bouffalo_lab/bl61x/board/usb_config.h b/bsp/bouffalo_lab/bl61x/board/usb_config.h index bb9332794ed..2dc8a9ca895 100644 --- a/bsp/bouffalo_lab/bl61x/board/usb_config.h +++ b/bsp/bouffalo_lab/bl61x/board/usb_config.h @@ -160,11 +160,12 @@ #define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 #define CONFIG_USBHOST_MAX_ENDPOINTS 4 -#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4 +#define CONFIG_USBHOST_MAX_SERIAL_CLASS 4 #define CONFIG_USBHOST_MAX_HID_CLASS 4 #define CONFIG_USBHOST_MAX_MSC_CLASS 2 #define CONFIG_USBHOST_MAX_AUDIO_CLASS 1 #define CONFIG_USBHOST_MAX_VIDEO_CLASS 1 +//#define CONFIG_USBHOST_MAX_XBOX_CLASS 2 #define CONFIG_USBHOST_DEV_NAMELEN 16 @@ -191,6 +192,10 @@ #define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 #endif +#ifndef CONFIG_USBHOST_SERIAL_RX_SIZE +#define CONFIG_USBHOST_SERIAL_RX_SIZE 2048 +#endif + #ifndef CONFIG_USBHOST_MSC_TIMEOUT #define CONFIG_USBHOST_MSC_TIMEOUT 5000 #endif diff --git a/bsp/hpmicro/hpm6750evk/board/cherryusb_port.c b/bsp/hpmicro/hpm6750evk/board/cherryusb_port.c deleted file mode 100644 index d79bf933d0b..00000000000 --- a/bsp/hpmicro/hpm6750evk/board/cherryusb_port.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024/04/23 sakumisu first version - */ -#include -#include - -/* low level init here, this has implemented in cherryusb */ - -/* low level deinit here, this has implemented in cherryusb */ - -#ifdef RT_CHERRYUSB_DEVICE_TEMPLATE_MSC -int cherryusb_devinit(void) -{ - extern void msc_ram_init(uint8_t busid, uintptr_t reg_base); - - board_init_usb_pins(); - - msc_ram_init(0, HPM_USB0_BASE); - return 0; -} -INIT_COMPONENT_EXPORT(cherryusb_devinit); -#endif - -#ifdef RT_CHERRYUSB_HOST -#include "usbh_core.h" - -int cherryusb_hostinit(void) -{ - board_init_usb_pins(); - - usbh_initialize(0, HPM_USB0_BASE); - return 0; -} -INIT_COMPONENT_EXPORT(cherryusb_hostinit); -#endif \ No newline at end of file diff --git a/bsp/hpmicro/hpm6750evk2/board/cherryusb_port.c b/bsp/hpmicro/hpm6750evk2/board/cherryusb_port.c index d79bf933d0b..7d0c634a18b 100644 --- a/bsp/hpmicro/hpm6750evk2/board/cherryusb_port.c +++ b/bsp/hpmicro/hpm6750evk2/board/cherryusb_port.c @@ -34,7 +34,7 @@ int cherryusb_hostinit(void) { board_init_usb_pins(); - usbh_initialize(0, HPM_USB0_BASE); + usbh_initialize(0, HPM_USB0_BASE, NULL); return 0; } INIT_COMPONENT_EXPORT(cherryusb_hostinit); diff --git a/bsp/hpmicro/hpm6750evk2/board/usb_config.h b/bsp/hpmicro/hpm6750evk2/board/usb_config.h index ff5220c9a56..335181327ba 100644 --- a/bsp/hpmicro/hpm6750evk2/board/usb_config.h +++ b/bsp/hpmicro/hpm6750evk2/board/usb_config.h @@ -157,11 +157,12 @@ #define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 #define CONFIG_USBHOST_MAX_ENDPOINTS 4 -#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4 +#define CONFIG_USBHOST_MAX_SERIAL_CLASS 4 #define CONFIG_USBHOST_MAX_HID_CLASS 4 #define CONFIG_USBHOST_MAX_MSC_CLASS 2 #define CONFIG_USBHOST_MAX_AUDIO_CLASS 1 #define CONFIG_USBHOST_MAX_VIDEO_CLASS 1 +//#define CONFIG_USBHOST_MAX_XBOX_CLASS 2 #define CONFIG_USBHOST_DEV_NAMELEN 16 @@ -188,6 +189,10 @@ #define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 #endif +#ifndef CONFIG_USBHOST_SERIAL_RX_SIZE +#define CONFIG_USBHOST_SERIAL_RX_SIZE 2048 +#endif + #ifndef CONFIG_USBHOST_MSC_TIMEOUT #define CONFIG_USBHOST_MSC_TIMEOUT 5000 #endif diff --git a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/cherryusb_port.c b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/cherryusb_port.c index dc83981a4d2..d3ef4a17785 100644 --- a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/cherryusb_port.c +++ b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/cherryusb_port.c @@ -30,7 +30,7 @@ INIT_COMPONENT_EXPORT(cherryusb_devinit); int cherryusb_hostinit(void) { - usbh_initialize(0, USBHS1__USBC_BASE); + usbh_initialize(0, USBHS1__USBC_BASE, NULL); return 0; } INIT_COMPONENT_EXPORT(cherryusb_hostinit); diff --git a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/usb_config.h b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/usb_config.h index 6a772b7bebb..01622b19f79 100644 --- a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/usb_config.h +++ b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/usb_config.h @@ -155,11 +155,12 @@ #define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 #define CONFIG_USBHOST_MAX_ENDPOINTS 4 -#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4 +#define CONFIG_USBHOST_MAX_SERIAL_CLASS 4 #define CONFIG_USBHOST_MAX_HID_CLASS 4 #define CONFIG_USBHOST_MAX_MSC_CLASS 2 #define CONFIG_USBHOST_MAX_AUDIO_CLASS 1 #define CONFIG_USBHOST_MAX_VIDEO_CLASS 1 +//#define CONFIG_USBHOST_MAX_XBOX_CLASS 2 #define CONFIG_USBHOST_DEV_NAMELEN 16 @@ -186,6 +187,10 @@ #define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 #endif +#ifndef CONFIG_USBHOST_SERIAL_RX_SIZE +#define CONFIG_USBHOST_SERIAL_RX_SIZE 2048 +#endif + #ifndef CONFIG_USBHOST_MSC_TIMEOUT #define CONFIG_USBHOST_MSC_TIMEOUT 5000 #endif