From bf11bd6fa4983311aa2a3a44459bc6b16bcc4f75 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Mon, 26 Jan 2026 10:59:39 +0800 Subject: [PATCH] update(cherryusb): update to v1.6.0 Signed-off-by: sakumisu <1203593632@qq.com> --- components/drivers/usb/Kconfig | 2 +- components/drivers/usb/cherryusb/.gitignore | 1 + components/drivers/usb/cherryusb/Kconfig | 388 ++++---- components/drivers/usb/cherryusb/Kconfig.rtt | 462 --------- .../drivers/usb/cherryusb/Kconfig.rttpkg | 500 ---------- components/drivers/usb/cherryusb/README.md | 53 +- components/drivers/usb/cherryusb/README_zh.md | 11 +- components/drivers/usb/cherryusb/SConscript | 44 +- components/drivers/usb/cherryusb/VERSION | 4 +- .../drivers/usb/cherryusb/cherryusb.cmake | 37 +- .../usb/cherryusb/cherryusb_config_template.h | 10 +- .../usb/cherryusb/class/aoa/usbh_aoa.c | 4 - .../usb/cherryusb/class/audio/usb_audio.h | 104 +- .../drivers/usb/cherryusb/class/cdc/usb_cdc.h | 38 +- .../usb/cherryusb/class/cdc/usbh_cdc_acm.c | 285 ------ .../usb/cherryusb/class/cdc/usbh_cdc_acm.h | 50 - .../usb/cherryusb/class/cdc/usbh_cdc_ecm.c | 10 - .../usb/cherryusb/class/cdc/usbh_cdc_ncm.c | 10 - .../usb/cherryusb/class/dfu/usbd_dfu.c | 3 +- .../usb/cherryusb/class/gamepad/usb_gamepad.h | 224 +++++ .../cherryusb/class/gamepad/usbd_gamepad.c | 209 ++++ .../cherryusb/class/gamepad/usbd_gamepad.h | 22 + .../drivers/usb/cherryusb/class/hid/usb_hid.h | 229 ++--- .../usb/cherryusb/class/hid/usbh_hid.c | 455 ++++++++- .../usb/cherryusb/class/hid/usbh_hid.h | 81 ++ .../usb/cherryusb/class/hub/usbh_hub.c | 57 +- .../usb/cherryusb/class/midi/usb_midi.h | 15 + .../usb/cherryusb/class/serial/usbh_cdc_acm.c | 266 +++++ .../usb/cherryusb/class/serial/usbh_cdc_acm.h | 19 + .../usb/cherryusb/class/serial/usbh_ch34x.c | 409 ++++++++ .../usb/cherryusb/class/serial/usbh_ch34x.h | 56 ++ .../usb/cherryusb/class/serial/usbh_cp210x.c | 507 ++++++++++ .../usb/cherryusb/class/serial/usbh_cp210x.h | 187 ++++ .../usb/cherryusb/class/serial/usbh_ftdi.c | 407 ++++++++ .../usb/cherryusb/class/serial/usbh_ftdi.h | 341 +++++++ .../usb/cherryusb/class/serial/usbh_gsm.c | 131 +++ .../usb/cherryusb/class/serial/usbh_pl2303.c | 726 ++++++++++++++ .../usb/cherryusb/class/serial/usbh_pl2303.h | 43 + .../usb/cherryusb/class/serial/usbh_serial.c | 743 ++++++++++++++ .../usb/cherryusb/class/serial/usbh_serial.h | 182 ++++ .../cherryusb/class/vendor/net/usbh_asix.c | 10 - .../cherryusb/class/vendor/net/usbh_rtl8152.c | 20 +- .../class/vendor/serial/usbh_ch34x.c | 379 -------- .../class/vendor/serial/usbh_ch34x.h | 76 -- .../class/vendor/serial/usbh_cp210x.c | 328 ------- .../class/vendor/serial/usbh_cp210x.h | 73 -- .../cherryusb/class/vendor/serial/usbh_ftdi.c | 510 ---------- .../cherryusb/class/vendor/serial/usbh_ftdi.h | 96 -- .../class/vendor/serial/usbh_pl2303.c | 449 --------- .../class/vendor/serial/usbh_pl2303.h | 62 -- .../usb/cherryusb/class/vendor/wifi/.gitkeep | 0 .../usb/cherryusb/class/vendor/wifi/README.md | 6 - .../cherryusb/class/vendor/wifi/usbh_bl616.c | 513 ---------- .../cherryusb/class/vendor/wifi/usbh_bl616.h | 220 ----- .../usb/cherryusb/class/video/usbh_video.c | 138 +-- .../usb/cherryusb/class/video/usbh_video.h | 5 +- .../usb/cherryusb/class/wireless/usbh_rndis.c | 19 +- .../drivers/usb/cherryusb/common/usb_def.h | 206 +++- .../drivers/usb/cherryusb/common/usb_otg.h | 39 + .../drivers/usb/cherryusb/common/usb_util.h | 21 +- .../usb/cherryusb/common/usb_version.h | 4 +- .../drivers/usb/cherryusb/core/usbd_core.c | 238 +---- .../drivers/usb/cherryusb/core/usbd_core.h | 11 +- .../drivers/usb/cherryusb/core/usbh_core.c | 594 ++++++++---- .../drivers/usb/cherryusb/core/usbh_core.h | 42 +- .../drivers/usb/cherryusb/core/usbotg_core.c | 155 +++ .../drivers/usb/cherryusb/core/usbotg_core.h | 27 + .../cherryusb/demo/adb/usbd_adb_template.c | 88 +- .../demo/audio_v1_mic_multichan_template.c | 118 +-- .../audio_v1_mic_speaker_multichan_template.c | 250 ++--- .../demo/audio_v2_mic_multichan_template.c | 146 +-- .../audio_v2_mic_speaker_multichan_template.c | 211 ++-- .../audio_v2_speaker_multichan_template.c | 138 +-- .../demo/bootuf2/msc_bootuf2_template.c | 86 +- .../cherryusb/demo/cdc_acm_hid_msc_template.c | 149 +-- .../cherryusb/demo/cdc_acm_mavlink_template.c | 87 +- .../usb/cherryusb/demo/cdc_acm_msc_template.c | 87 +- .../cherryusb/demo/cdc_acm_multi_template.c | 89 +- .../demo/cdc_acm_rttchardev_template.c | 112 +-- .../usb/cherryusb/demo/cdc_acm_template.c | 86 +- .../usb/cherryusb/demo/cdc_ecm_template.c | 119 +-- .../usb/cherryusb/demo/cdc_rndis_template.c | 88 +- .../demo/dfu_with_st_tool_template.c | 134 +-- .../usb/cherryusb/demo/gamepad_template.c | 250 +++++ .../demo/hid_custom_inout_template.c | 243 +---- .../cherryusb/demo/hid_keyboard_template.c | 155 +-- .../usb/cherryusb/demo/hid_mouse_template.c | 156 +-- .../demo/hid_remote_wakeup_template.c | 156 +-- .../usb/cherryusb/demo/midi_template.c | 189 +--- .../usb/cherryusb/demo/msc_ram_template.c | 85 +- .../drivers/usb/cherryusb/demo/usb_host.c | 216 +++-- .../usb/cherryusb/demo/usbh_bl616_wifi_cli.c | 182 ++++ .../demo/video_audiov1_hid_template.c | 183 +--- .../demo/video_static_h264_template.c | 94 +- .../demo/video_static_mjpeg_template.c | 94 +- .../demo/video_static_yuyv_template.c | 95 +- .../usb/cherryusb/demo/webusb_hid_template.c | 309 +----- .../usb/cherryusb/demo/winusb1.0_template.c | 375 ++----- .../cherryusb/demo/winusb2.0_cdc_template.c | 252 +---- .../cherryusb/demo/winusb2.0_hid_template.c | 550 ----------- .../usb/cherryusb/demo/winusb2.0_template.c | 263 +++++ .../drivers/usb/cherryusb/idf_component.yml | 2 +- .../usb/cherryusb/platform/daplink/dap_main.c | 496 +++++++--- .../usb/cherryusb/platform/daplink/dap_main.h | 116 +-- .../cherryusb/platform/rtthread/usb_check.c | 9 +- .../usb/cherryusb/platform/rtthread/usb_msh.c | 8 +- .../cherryusb/platform/rtthread/usbd_serial.c | 12 +- .../cherryusb/platform/rtthread/usbh_dfs.c | 15 +- .../cherryusb/platform/rtthread/usbh_lwip.c | 12 +- .../cherryusb/platform/rtthread/usbh_serial.c | 914 ------------------ .../cherryusb/port/chipidea/usb_dc_chipidea.c | 13 +- .../drivers/usb/cherryusb/port/dwc2/README.md | 6 +- .../usb/cherryusb/port/dwc2/usb_dc_dwc2.c | 202 ++-- .../usb/cherryusb/port/dwc2/usb_dwc2_reg.h | 2 + .../usb/cherryusb/port/dwc2/usb_glue_at.c | 11 +- .../usb/cherryusb/port/dwc2/usb_glue_esp.c | 7 +- .../usb/cherryusb/port/dwc2/usb_glue_hc.c | 298 +++++- .../cherryusb/port/dwc2/usb_glue_infineon.c | 154 +++ .../cherryusb/port/dwc2/usb_glue_kendryte.c | 9 +- .../usb/cherryusb/port/dwc2/usb_glue_st.c | 33 +- .../usb/cherryusb/port/dwc2/usb_hc_dwc2.c | 133 +-- .../usb/cherryusb/port/ehci/usb_glue_aic.c | 62 +- .../usb/cherryusb/port/ehci/usb_glue_t113.c | 128 ++- .../usb/cherryusb/port/ehci/usb_hc_ehci.c | 4 + .../usb/cherryusb/port/hpmicro/usb_dc_hpm.c | 17 +- .../usb/cherryusb/port/hpmicro/usb_glue_hpm.c | 82 +- .../usb/cherryusb/port/hpmicro/usb_hc_hpm.c | 14 +- .../usb/cherryusb/port/kinetis/usb_glue_mcx.c | 4 +- .../usb/cherryusb/port/musb/usb_glue_sifli.c | 2 +- .../usb/cherryusb/port/musb/usb_glue_ti.c | 163 ++++ .../usb/cherryusb/port/musb/usb_hc_musb.c | 60 +- .../drivers/usb/cherryusb/tools/audacity/url | 1 + .../cherryusb/tools/chryusb_configurator/url | 1 + .../usb/cherryusb/tools/packet capture/url | 3 + .../usb/cherryusb/tools/stm32_dfuse/url | 1 + .../tools/test_srcipts/test_cdc_speed.py | 49 + .../tools/test_srcipts/test_hid_inout.py | 68 ++ .../usb/cherryusb/tools/uf2/uf2conv.py | 361 +++++++ 138 files changed, 9818 insertions(+), 11055 deletions(-) delete mode 100644 components/drivers/usb/cherryusb/Kconfig.rtt delete mode 100644 components/drivers/usb/cherryusb/Kconfig.rttpkg delete mode 100644 components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c delete mode 100644 components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.h create mode 100644 components/drivers/usb/cherryusb/class/gamepad/usb_gamepad.h create mode 100644 components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c create mode 100644 components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.h create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.c create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.h create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_ch34x.h create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_cp210x.c create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_cp210x.h create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_ftdi.h create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_gsm.c create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_pl2303.c create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_pl2303.h create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_serial.c create mode 100644 components/drivers/usb/cherryusb/class/serial/usbh_serial.h delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.h delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.h delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.h delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c delete mode 100644 components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.h create mode 100644 components/drivers/usb/cherryusb/class/vendor/wifi/.gitkeep delete mode 100644 components/drivers/usb/cherryusb/class/vendor/wifi/README.md delete mode 100644 components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c delete mode 100644 components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h create mode 100644 components/drivers/usb/cherryusb/common/usb_otg.h create mode 100644 components/drivers/usb/cherryusb/core/usbotg_core.c create mode 100644 components/drivers/usb/cherryusb/core/usbotg_core.h create mode 100644 components/drivers/usb/cherryusb/demo/gamepad_template.c create mode 100644 components/drivers/usb/cherryusb/demo/usbh_bl616_wifi_cli.c delete mode 100644 components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c create mode 100644 components/drivers/usb/cherryusb/demo/winusb2.0_template.c delete mode 100644 components/drivers/usb/cherryusb/platform/rtthread/usbh_serial.c create mode 100644 components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c create mode 100644 components/drivers/usb/cherryusb/port/musb/usb_glue_ti.c create mode 100644 components/drivers/usb/cherryusb/tools/audacity/url create mode 100644 components/drivers/usb/cherryusb/tools/chryusb_configurator/url create mode 100644 components/drivers/usb/cherryusb/tools/packet capture/url create mode 100644 components/drivers/usb/cherryusb/tools/stm32_dfuse/url create mode 100644 components/drivers/usb/cherryusb/tools/test_srcipts/test_cdc_speed.py create mode 100644 components/drivers/usb/cherryusb/tools/test_srcipts/test_hid_inout.py create mode 100644 components/drivers/usb/cherryusb/tools/uf2/uf2conv.py diff --git a/components/drivers/usb/Kconfig b/components/drivers/usb/Kconfig index 3af62ab03e2..cd8e4ebf869 100644 --- a/components/drivers/usb/Kconfig +++ b/components/drivers/usb/Kconfig @@ -1 +1 @@ -rsource "cherryusb/Kconfig.rtt" +rsource "cherryusb/Kconfig" diff --git a/components/drivers/usb/cherryusb/.gitignore b/components/drivers/usb/cherryusb/.gitignore index 22b1a7fa274..9ebda7a0117 100644 --- a/components/drivers/usb/cherryusb/.gitignore +++ b/components/drivers/usb/cherryusb/.gitignore @@ -1,4 +1,5 @@ .vscode +build **/Drivers/** **/MDK-ARM/DebugConfig/** **/MDK-ARM/RTE/** diff --git a/components/drivers/usb/cherryusb/Kconfig b/components/drivers/usb/cherryusb/Kconfig index 4c3c655ceb1..35a8e15f285 100644 --- a/components/drivers/usb/cherryusb/Kconfig +++ b/components/drivers/usb/cherryusb/Kconfig @@ -1,146 +1,155 @@ -# Kconfig file for CherryUSB -menuconfig CHERRYUSB - bool "CherryUSB Configuration" +# Kconfig file for package CherryUSB +menuconfig RT_USING_CHERRYUSB + bool "Using USB with CherryUSB" default n -if CHERRYUSB +if RT_USING_CHERRYUSB - menuconfig CHERRYUSB_DEVICE + menuconfig RT_CHERRYUSB_DEVICE bool "Enable usb device mode" default n - if CHERRYUSB_DEVICE + if RT_CHERRYUSB_DEVICE choice CHERRYUSB_DEVICE_SPEED prompt "Select usb device speed" - default CHERRYUSB_DEVICE_SPEED_FS - config CHERRYUSB_DEVICE_SPEED_FS + default RT_CHERRYUSB_DEVICE_SPEED_FS + config RT_CHERRYUSB_DEVICE_SPEED_FS bool "FS" - config CHERRYUSB_DEVICE_SPEED_HS + config RT_CHERRYUSB_DEVICE_SPEED_HS bool "HS" - config CHERRYUSB_DEVICE_SPEED_AUTO + config RT_CHERRYUSB_DEVICE_SPEED_AUTO bool "AUTO" endchoice choice CHERRYUSB_DEVICE_IP prompt "Select usb device ip, and some ip need config in usb_config.h, please check" - default CHERRYUSB_DEVICE_CUSTOM - config CHERRYUSB_DEVICE_CUSTOM + default RT_CHERRYUSB_DEVICE_CUSTOM + config RT_CHERRYUSB_DEVICE_CUSTOM bool "CUSTOM (Implement it yourself)" - config CHERRYUSB_DEVICE_FSDEV_ST + config RT_CHERRYUSB_DEVICE_FSDEV_ST bool "fsdev_st" - config CHERRYUSB_DEVICE_FSDEV_CUSTOM + config RT_CHERRYUSB_DEVICE_FSDEV_CUSTOM bool "fsdev_custom" - config CHERRYUSB_DEVICE_DWC2_ST + config RT_CHERRYUSB_DEVICE_DWC2_ST bool "dwc2_st" - config CHERRYUSB_DEVICE_DWC2_ESP + config RT_CHERRYUSB_DEVICE_DWC2_ESP bool "dwc2_esp" - config CHERRYUSB_DEVICE_DWC2_KENDRYTE + config RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE bool "dwc2_kendryte" - config CHERRYUSB_DEVICE_DWC2_AT + config RT_CHERRYUSB_DEVICE_DWC2_INFINEON + bool "dwc2_infineon" + config RT_CHERRYUSB_DEVICE_DWC2_AT bool "dwc2_at" - config CHERRYUSB_DEVICE_DWC2_HC + config RT_CHERRYUSB_DEVICE_DWC2_HC bool "dwc2_hc" - config CHERRYUSB_DEVICE_DWC2_NATION + config RT_CHERRYUSB_DEVICE_DWC2_NATION bool "dwc2_nation" - config CHERRYUSB_DEVICE_DWC2_GD + config RT_CHERRYUSB_DEVICE_DWC2_GD bool "dwc2_gd" - config CHERRYUSB_DEVICE_DWC2_CUSTOM + config RT_CHERRYUSB_DEVICE_DWC2_CUSTOM bool "dwc2_custom" - config CHERRYUSB_DEVICE_MUSB_ES + config RT_CHERRYUSB_DEVICE_MUSB_ES bool "musb_es" - config CHERRYUSB_DEVICE_MUSB_SUNXI + config RT_CHERRYUSB_DEVICE_MUSB_SUNXI bool "musb_sunxi" - config CHERRYUSB_DEVICE_MUSB_BK + config RT_CHERRYUSB_DEVICE_MUSB_BK bool "musb_bk" - config CHERRYUSB_DEVICE_MUSB_SIFLI + config RT_CHERRYUSB_DEVICE_MUSB_SIFLI bool "musb_sifli" - config CHERRYUSB_DEVICE_MUSB_CUSTOM + config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM bool "musb_custom" - config CHERRYUSB_DEVICE_CHIPIDEA_MCX + config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX bool "chipidea_mcx" - config CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM + config RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM bool "chipidea_custom" - config CHERRYUSB_DEVICE_KINETIS_MCX + config RT_CHERRYUSB_DEVICE_KINETIS_MCX bool "kinetis_mcx" - config CHERRYUSB_DEVICE_KINETIS_MM32 + config RT_CHERRYUSB_DEVICE_KINETIS_MM32 bool "kinetis_mm32" - config CHERRYUSB_DEVICE_KINETIS_CUSTOM + config RT_CHERRYUSB_DEVICE_KINETIS_CUSTOM bool "kinetis_custom" - config CHERRYUSB_DEVICE_BL + config RT_CHERRYUSB_DEVICE_BL bool "bouffalo" - config CHERRYUSB_DEVICE_HPM + config RT_CHERRYUSB_DEVICE_HPM bool "hpm" - config CHERRYUSB_DEVICE_AIC + config RT_CHERRYUSB_DEVICE_AIC bool "aic" - config CHERRYUSB_DEVICE_RP2040 + config RT_CHERRYUSB_DEVICE_RP2040 bool "rp2040" - config CHERRYUSB_DEVICE_CH32 + config RT_CHERRYUSB_DEVICE_CH32 bool "ch32" - config CHERRYUSB_DEVICE_PUSB2 + config RT_CHERRYUSB_DEVICE_PUSB2 bool "pusb2" + config RT_CHERRYUSB_DEVICE_NRF5X + bool "nrf5x" endchoice - config CHERRYUSB_DEVICE_CDC_ACM + config RT_CHERRYUSB_DEVICE_CDC_ACM bool prompt "Enable usb cdc acm device" default n - config CHERRYUSB_DEVICE_HID + config RT_CHERRYUSB_DEVICE_HID bool prompt "Enable usb hid device" default n - config CHERRYUSB_DEVICE_MSC + config RT_CHERRYUSB_DEVICE_MSC bool prompt "Enable usb msc device" default n - config CHERRYUSB_DEVICE_AUDIO + config RT_CHERRYUSB_DEVICE_AUDIO bool prompt "Enable usb audio device" default n - config CHERRYUSB_DEVICE_VIDEO + config RT_CHERRYUSB_DEVICE_VIDEO bool prompt "Enable usb video device" default n - config CHERRYUSB_DEVICE_CDC_RNDIS + config RT_CHERRYUSB_DEVICE_CDC_RNDIS bool prompt "Enable usb cdc rndis device" default n - config CHERRYUSB_DEVICE_CDC_ECM + config RT_CHERRYUSB_DEVICE_CDC_ECM bool prompt "Enable usb cdc ecm device" default n - config CHERRYUSB_DEVICE_CDC_NCM + config RT_CHERRYUSB_DEVICE_CDC_NCM bool prompt "Enable usb cdc ncm device" default n - config CHERRYUSB_DEVICE_MTP + config RT_CHERRYUSB_DEVICE_MTP bool prompt "Enable usb mtp device, it is commercial charge" default n - config CHERRYUSB_DEVICE_ADB + config RT_CHERRYUSB_DEVICE_ADB bool prompt "Enable usb adb device" default n - config CHERRYUSB_DEVICE_DFU + config RT_CHERRYUSB_DEVICE_DFU bool prompt "Enable usb dfu device" default n - config USBDEV_REQUEST_BUFFER_LEN + config RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV + bool + prompt "Enable chardev for cdc acm device" + default n + + config CONFIG_USBDEV_REQUEST_BUFFER_LEN int prompt "Set device control transfer max buffer size" default 512 - config USBDEV_MSC_MAX_BUFSIZE + config CONFIG_USBDEV_MSC_MAX_BUFSIZE int prompt "Set usb msc device max buffer size" default 512 @@ -148,286 +157,339 @@ if CHERRYUSB Set the maximum buffer size for usb msc device, it is used to transfer data. you can change it to a larger value if you need larger speed but must be a power of blocksize. - config USBDEV_RNDIS_USING_LWIP + config CONFIG_USBDEV_RNDIS_USING_LWIP bool prompt "Enable usb rndis device with lwip for lan" default n - config USBDEV_CDC_ECM_USING_LWIP + config CONFIG_USBDEV_CDC_ECM_USING_LWIP bool prompt "Enable usb cdc ecm device with lwip for lan" default n choice CHERRYUSB_DEVICE_TEMPLATE prompt "Select usb device template, please select class driver first" - default CHERRYUSB_DEVICE_TEMPLATE_NONE - config CHERRYUSB_DEVICE_TEMPLATE_NONE + default RT_CHERRYUSB_DEVICE_TEMPLATE_NONE + config RT_CHERRYUSB_DEVICE_TEMPLATE_NONE bool prompt "none (Implement it yourself)" - config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM + config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM bool prompt "cdc_acm" - depends on CHERRYUSB_DEVICE_CDC_ACM - config CHERRYUSB_DEVICE_TEMPLATE_MSC + depends on RT_CHERRYUSB_DEVICE_CDC_ACM + config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC bool prompt "msc_ram" - depends on CHERRYUSB_DEVICE_MSC - config CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD + depends on RT_CHERRYUSB_DEVICE_MSC + config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV + bool + prompt "msc_blkdev" + depends on RT_CHERRYUSB_DEVICE_MSC + config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD bool prompt "hid_keyboard" - depends on CHERRYUSB_DEVICE_HID - config CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE + depends on RT_CHERRYUSB_DEVICE_HID + config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE bool prompt "hid_mouse" - depends on CHERRYUSB_DEVICE_HID - config CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM + depends on RT_CHERRYUSB_DEVICE_HID + config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM bool prompt "hid_custom" - depends on CHERRYUSB_DEVICE_HID - config CHERRYUSB_DEVICE_TEMPLATE_VIDEO + depends on RT_CHERRYUSB_DEVICE_HID + config RT_CHERRYUSB_DEVICE_TEMPLATE_VIDEO bool prompt "video" - depends on CHERRYUSB_DEVICE_VIDEO - config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER + depends on RT_CHERRYUSB_DEVICE_VIDEO + config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER bool prompt "audio_v1_mic_speaker_multichan" - depends on CHERRYUSB_DEVICE_AUDIO - config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER + depends on RT_CHERRYUSB_DEVICE_AUDIO + config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER bool prompt "audio_v2_mic_speaker_multichan" - depends on CHERRYUSB_DEVICE_AUDIO - config CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS + depends on RT_CHERRYUSB_DEVICE_AUDIO + config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS bool prompt "cdc_rndis" - depends on CHERRYUSB_DEVICE_CDC_RNDIS - config CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM + depends on RT_CHERRYUSB_DEVICE_CDC_RNDIS + config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM bool prompt "cdc_ecm" - depends on CHERRYUSB_DEVICE_CDC_ECM - config CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM + depends on RT_CHERRYUSB_DEVICE_CDC_ECM + config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM bool prompt "cdc_ncm" - depends on CHERRYUSB_DEVICE_CDC_NCM - config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC + depends on RT_CHERRYUSB_DEVICE_CDC_NCM + config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC bool prompt "cdc_acm_msc" - depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC - config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID + depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC + config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID bool prompt "cdc_acm_msc_hid" - depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC && CHERRYUSB_DEVICE_HID - config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1 + depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC && RT_CHERRYUSB_DEVICE_HID + config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1 bool prompt "winusbv1" - config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC + config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2 + bool + prompt "winusbv2" + config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC bool prompt "winusbv2_cdc" - depends on CHERRYUSB_DEVICE_CDC_ACM - config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID + depends on RT_CHERRYUSB_DEVICE_CDC_ACM + config RT_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID + bool + prompt "webusb_hid" + depends on RT_CHERRYUSB_DEVICE_HID + config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB + bool + prompt "adb" + depends on RT_CHERRYUSB_DEVICE_ADB + config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV bool - prompt "winusbv2_hid" - depends on CHERRYUSB_DEVICE_HID + prompt "cdc_acm_chardev" + 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 CHERRYUSB_HOST + menuconfig RT_CHERRYUSB_HOST bool "Enable usb host mode" default n - if CHERRYUSB_HOST + if RT_CHERRYUSB_HOST choice CHERRYUSB_HOST_IP prompt "Select usb host ip, and some ip need config in usb_config.h, please check" - default CHERRYUSB_HOST_CUSTOM - config CHERRYUSB_HOST_CUSTOM + default RT_CHERRYUSB_HOST_CUSTOM + config RT_CHERRYUSB_HOST_CUSTOM bool "CUSTOM (Implement it yourself)" - config CHERRYUSB_HOST_EHCI_BL + config RT_CHERRYUSB_HOST_EHCI_BL bool "ehci_bouffalo" - config CHERRYUSB_HOST_EHCI_HPM + config RT_CHERRYUSB_HOST_EHCI_HPM bool "ehci_hpm" - config CHERRYUSB_HOST_EHCI_AIC + config RT_CHERRYUSB_HOST_EHCI_AIC bool "ehci_aic" - config CHERRYUSB_HOST_EHCI_MCX + config RT_CHERRYUSB_HOST_EHCI_MCX bool "ehci_mcx" - config CHERRYUSB_HOST_EHCI_NUC980 + config RT_CHERRYUSB_HOST_EHCI_NUC980 bool "ehci_nuc980" - config CHERRYUSB_HOST_EHCI_MA35D0 + config RT_CHERRYUSB_HOST_EHCI_MA35D0 bool "ehci_ma35d0" - config CHERRYUSB_HOST_EHCI_CUSTOM + config RT_CHERRYUSB_HOST_EHCI_CUSTOM bool "ehci_custom" - config CHERRYUSB_HOST_DWC2_ST + config RT_CHERRYUSB_HOST_DWC2_ST bool "dwc2_st" - config CHERRYUSB_HOST_DWC2_ESP + config RT_CHERRYUSB_HOST_DWC2_ESP bool "dwc2_esp" - config CHERRYUSB_HOST_DWC2_KENDRYTE + config RT_CHERRYUSB_HOST_DWC2_KENDRYTE bool "dwc2_kendryte" - config CHERRYUSB_HOST_DWC2_HC + config RT_CHERRYUSB_HOST_DWC2_INFINEON + bool "dwc2_infineon" + config RT_CHERRYUSB_HOST_DWC2_AT + bool "dwc2_at, f405 only" + config RT_CHERRYUSB_HOST_DWC2_HC bool "dwc2_hc" - config CHERRYUSB_HOST_DWC2_NATION + config RT_CHERRYUSB_HOST_DWC2_NATION bool "dwc2_nation" - config CHERRYUSB_HOST_DWC2_CUSTOM + config RT_CHERRYUSB_HOST_DWC2_CUSTOM bool "dwc2_custom" - config CHERRYUSB_HOST_MUSB_ES + config RT_CHERRYUSB_HOST_MUSB_ES bool "musb_es" - config CHERRYUSB_HOST_MUSB_SUNXI + config RT_CHERRYUSB_HOST_MUSB_SUNXI bool "musb_sunxi" - config CHERRYUSB_HOST_MUSB_BK + config RT_CHERRYUSB_HOST_MUSB_BK bool "musb_bk" - config CHERRYUSB_HOST_MUSB_SIFLI + config RT_CHERRYUSB_HOST_MUSB_SIFLI bool "musb_sifli" - config CHERRYUSB_HOST_MUSB_CUSTOM + config RT_CHERRYUSB_HOST_MUSB_CUSTOM bool "musb_custom" - config CHERRYUSB_HOST_PUSB2 + config RT_CHERRYUSB_HOST_PUSB2 bool "pusb2" - config CHERRYUSB_HOST_XHCI_PHYTIUM - bool "xhci_phytium" - config CHERRYUSB_HOST_XHCI_CUSTOM + config RT_CHERRYUSB_HOST_XHCI bool "xhci" - config CHERRYUSB_HOST_KINETIS_MCX - bool "kinetis_mcx" - config CHERRYUSB_HOST_KINETIS_MM32 - bool "kinetis_mm32" - config CHERRYUSB_HOST_KINETIS_CUSTOM - bool "kinetis_custom" - config CHERRYUSB_HOST_RP2040 + config RT_CHERRYUSB_HOST_RP2040 bool "rp2040" endchoice - config CHERRYUSB_HOST_CDC_ACM + config RT_CHERRYUSB_HOST_CDC_ACM bool prompt "Enable usb cdc acm driver" + select CONFIG_USBHOST_SERIAL default n - config CHERRYUSB_HOST_HID + config RT_CHERRYUSB_HOST_HID bool prompt "Enable usb hid driver" default n - config CHERRYUSB_HOST_MSC + config RT_CHERRYUSB_HOST_MSC bool prompt "Enable usb msc driver" default n + select RT_USING_DFS + select RT_USING_DFS_ELMFAT - config CHERRYUSB_HOST_CDC_ECM + config RT_CHERRYUSB_HOST_CDC_ECM bool prompt "Enable usb cdc ecm driver" - select USBHOST_PLATFORM_CDC_ECM + select RT_USING_LWIP + select CONFIG_USBHOST_PLATFORM_CDC_ECM default n - config CHERRYUSB_HOST_CDC_RNDIS + config RT_CHERRYUSB_HOST_CDC_RNDIS bool prompt "Enable usb rndis driver" - select USBHOST_PLATFORM_CDC_RNDIS + select RT_USING_LWIP + select CONFIG_USBHOST_PLATFORM_CDC_RNDIS default n - config CHERRYUSB_HOST_CDC_NCM + config RT_CHERRYUSB_HOST_CDC_NCM bool prompt "Enable usb cdc ncm driver" - select USBHOST_PLATFORM_CDC_NCM + select RT_USING_LWIP + select CONFIG_USBHOST_PLATFORM_CDC_NCM default n - config CHERRYUSB_HOST_VIDEO + config RT_CHERRYUSB_HOST_VIDEO bool prompt "Enable usb video driver, it is commercial charge" default n - config CHERRYUSB_HOST_AUDIO + config RT_CHERRYUSB_HOST_AUDIO bool prompt "Enable usb audio driver, it is commercial charge" default n - config CHERRYUSB_HOST_BLUETOOTH + config RT_CHERRYUSB_HOST_BLUETOOTH bool prompt "Enable usb bluetooth driver" default n - config CHERRYUSB_HOST_ASIX + config RT_CHERRYUSB_HOST_ASIX bool prompt "Enable usb asix driver" - select USBHOST_PLATFORM_ASIX + select RT_USING_LWIP + select CONFIG_USBHOST_PLATFORM_ASIX default n - config CHERRYUSB_HOST_RTL8152 + config RT_CHERRYUSB_HOST_RTL8152 bool prompt "Enable usb rtl8152 driver" - select USBHOST_PLATFORM_RTL8152 + select RT_USING_LWIP + select CONFIG_USBHOST_PLATFORM_RTL8152 default n - config CHERRYUSB_HOST_FTDI + config RT_CHERRYUSB_HOST_FTDI bool prompt "Enable usb ftdi driver" + select CONFIG_USBHOST_SERIAL default n - config CHERRYUSB_HOST_CH34X + config RT_CHERRYUSB_HOST_CH34X bool prompt "Enable usb ch34x driver" + select CONFIG_USBHOST_SERIAL default n - config CHERRYUSB_HOST_CP210X + config RT_CHERRYUSB_HOST_CP210X bool prompt "Enable usb cp210x driver" + select CONFIG_USBHOST_SERIAL default n - config CHERRYUSB_HOST_PL2303 + config RT_CHERRYUSB_HOST_PL2303 bool prompt "Enable usb pl2303 driver" + select CONFIG_USBHOST_SERIAL default n - config CHERRYUSB_HOST_AOA + config RT_CHERRYUSB_HOST_GSM bool - prompt "Enable usb aoa driver" + prompt "Enable usb gsm driver for 4g module" + select CONFIG_USBHOST_SERIAL default n - config USBHOST_PLATFORM_CDC_ECM + config CONFIG_USBHOST_SERIAL bool - config USBHOST_PLATFORM_CDC_RNDIS + config CONFIG_USBHOST_PLATFORM_CDC_ECM bool - config USBHOST_PLATFORM_CDC_NCM + config CONFIG_USBHOST_PLATFORM_CDC_RNDIS bool - config USBHOST_PLATFORM_ASIX + config CONFIG_USBHOST_PLATFORM_CDC_NCM bool - config USBHOST_PLATFORM_RTL8152 + config CONFIG_USBHOST_PLATFORM_ASIX bool - config USBHOST_PSC_PRIO + config CONFIG_USBHOST_PLATFORM_RTL8152 + bool + + config CONFIG_USBHOST_PSC_PRIO int prompt "Set hubport change thread priority, 0 is the max priority" default 0 - config USBHOST_PSC_STACKSIZE + config CONFIG_USBHOST_PSC_STACKSIZE int prompt "Set hubport change thread stacksize" default 4096 - config USBHOST_REQUEST_BUFFER_LEN + config CONFIG_USBHOST_REQUEST_BUFFER_LEN int prompt "Set host control transfer max buffer size" default 512 - config USBHOST_CONTROL_TRANSFER_TIMEOUT + config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT int prompt "Set host control transfer timeout, unit is ms" default 500 + config CONFIG_USBHOST_SERIAL_RX_SIZE + int + prompt "Set host serial rx max buffer size" + default 2048 + + config RT_LWIP_PBUF_POOL_BUFSIZE + int "The size of each pbuf in the pbuf pool" + range 1500 2000 + default 1600 + + config CONFIG_USB_DFS_MOUNT_POINT + string "usb host dfs mount point" + depends on RT_CHERRYUSB_HOST_MSC + default "/" + menu "Select USB host template, please select class driver first" - config TEST_USBH_CDC_ACM - int - prompt "demo for test cdc acm" - default 0 - depends on CHERRYUSB_HOST_CDC_ACM - config TEST_USBH_HID + config CONFIG_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 int prompt "demo for test hid" default 0 - depends on CHERRYUSB_HOST_HID - config TEST_USBH_MSC - int - prompt "demo for test msc" - default 0 - depends on CHERRYUSB_HOST_MSC + depends on RT_CHERRYUSB_HOST_HID + config CONFIG_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 + bool + prompt "demo for test net, cannot enable this demo, you can use lwip api to test" + default n + depends on RT_CHERRYUSB_HOST_CDC_ECM || RT_CHERRYUSB_HOST_CDC_RNDIS || RT_CHERRYUSB_HOST_CDC_NCM || RT_CHERRYUSB_HOST_ASIX || RT_CHERRYUSB_HOST_RTL8152 endmenu endif endif diff --git a/components/drivers/usb/cherryusb/Kconfig.rtt b/components/drivers/usb/cherryusb/Kconfig.rtt deleted file mode 100644 index 9e1d7a500cc..00000000000 --- a/components/drivers/usb/cherryusb/Kconfig.rtt +++ /dev/null @@ -1,462 +0,0 @@ -# Kconfig file for package CherryUSB -menuconfig RT_USING_CHERRYUSB - bool "Using USB with CherryUSB" - default n - -if RT_USING_CHERRYUSB - - menuconfig RT_CHERRYUSB_DEVICE - bool "Enable usb device mode" - default n - - if RT_CHERRYUSB_DEVICE - choice - prompt "Select usb device speed" - default RT_CHERRYUSB_DEVICE_SPEED_FS - config RT_CHERRYUSB_DEVICE_SPEED_FS - bool "FS" - config RT_CHERRYUSB_DEVICE_SPEED_HS - bool "HS" - config RT_CHERRYUSB_DEVICE_SPEED_AUTO - bool "AUTO" - endchoice - - choice - prompt "Select usb device ip, and some ip need config in usb_config.h, please check" - default RT_CHERRYUSB_DEVICE_CUSTOM - config RT_CHERRYUSB_DEVICE_CUSTOM - bool "CUSTOM (Implement it yourself)" - config RT_CHERRYUSB_DEVICE_FSDEV_ST - bool "fsdev_st" - config RT_CHERRYUSB_DEVICE_FSDEV_CUSTOM - bool "fsdev_custom" - config RT_CHERRYUSB_DEVICE_DWC2_ST - bool "dwc2_st" - config RT_CHERRYUSB_DEVICE_DWC2_ESP - bool "dwc2_esp" - config RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE - bool "dwc2_kendryte" - config RT_CHERRYUSB_DEVICE_DWC2_AT - bool "dwc2_at" - config RT_CHERRYUSB_DEVICE_DWC2_HC - bool "dwc2_hc" - config RT_CHERRYUSB_DEVICE_DWC2_NATION - bool "dwc2_nation" - config RT_CHERRYUSB_DEVICE_DWC2_GD - bool "dwc2_gd" - config RT_CHERRYUSB_DEVICE_DWC2_CUSTOM - bool "dwc2_custom" - config RT_CHERRYUSB_DEVICE_MUSB_ES - bool "musb_es" - config RT_CHERRYUSB_DEVICE_MUSB_SUNXI - bool "musb_sunxi" - config RT_CHERRYUSB_DEVICE_MUSB_BK - bool "musb_bk" - config RT_CHERRYUSB_DEVICE_MUSB_SIFLI - bool "musb_sifli" - config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM - bool "musb_custom" - config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX - bool "chipidea_mcx" - config RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM - bool "chipidea_custom" - config RT_CHERRYUSB_DEVICE_KINETIS_MCX - bool "kinetis_mcx" - config RT_CHERRYUSB_DEVICE_KINETIS_MM32 - bool "kinetis_mm32" - config RT_CHERRYUSB_DEVICE_KINETIS_CUSTOM - bool "kinetis_custom" - config RT_CHERRYUSB_DEVICE_BL - bool "bouffalo" - config RT_CHERRYUSB_DEVICE_HPM - bool "hpm" - config RT_CHERRYUSB_DEVICE_AIC - bool "aic" - config RT_CHERRYUSB_DEVICE_RP2040 - bool "rp2040" - config RT_CHERRYUSB_DEVICE_CH32 - bool "ch32" - config RT_CHERRYUSB_DEVICE_PUSB2 - bool "pusb2" - config RT_CHERRYUSB_DEVICE_NRF5X - bool "nrf5x" - endchoice - - config RT_CHERRYUSB_DEVICE_CDC_ACM - bool - prompt "Enable usb cdc acm device" - default n - - config RT_CHERRYUSB_DEVICE_HID - bool - prompt "Enable usb hid device" - default n - - config RT_CHERRYUSB_DEVICE_MSC - bool - prompt "Enable usb msc device" - default n - - config RT_CHERRYUSB_DEVICE_AUDIO - bool - prompt "Enable usb audio device" - default n - - config RT_CHERRYUSB_DEVICE_VIDEO - bool - prompt "Enable usb video device" - default n - - config RT_CHERRYUSB_DEVICE_CDC_RNDIS - bool - prompt "Enable usb cdc rndis device" - default n - - config RT_CHERRYUSB_DEVICE_CDC_ECM - bool - prompt "Enable usb cdc ecm device" - default n - - config RT_CHERRYUSB_DEVICE_CDC_NCM - bool - prompt "Enable usb cdc ncm device" - default n - - config RT_CHERRYUSB_DEVICE_MTP - bool - prompt "Enable usb mtp device, it is commercial charge" - default n - - config RT_CHERRYUSB_DEVICE_ADB - bool - prompt "Enable usb adb device" - default n - - config RT_CHERRYUSB_DEVICE_DFU - bool - prompt "Enable usb dfu device" - default n - - config RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV - bool - prompt "Enable chardev for cdc acm device" - default n - - config CONFIG_USBDEV_REQUEST_BUFFER_LEN - int - prompt "Set device control transfer max buffer size" - default 512 - - config CONFIG_USBDEV_MSC_MAX_BUFSIZE - int - prompt "Set usb msc device max buffer size" - default 512 - help - Set the maximum buffer size for usb msc device, it is used to transfer data. - you can change it to a larger value if you need larger speed but must be a power of blocksize. - - config CONFIG_USBDEV_RNDIS_USING_LWIP - bool - prompt "Enable usb rndis device with lwip for lan" - default n - - config CONFIG_USBDEV_CDC_ECM_USING_LWIP - bool - prompt "Enable usb cdc ecm device with lwip for lan" - default n - - choice - prompt "Select usb device template, please select class driver first" - default RT_CHERRYUSB_DEVICE_TEMPLATE_NONE - config RT_CHERRYUSB_DEVICE_TEMPLATE_NONE - bool - prompt "none (Implement it yourself)" - config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM - bool - prompt "cdc_acm" - depends on RT_CHERRYUSB_DEVICE_CDC_ACM - config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC - bool - prompt "msc_ram" - depends on RT_CHERRYUSB_DEVICE_MSC - config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV - bool - prompt "msc_blkdev" - depends on RT_CHERRYUSB_DEVICE_MSC - config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD - bool - prompt "hid_keyboard" - depends on RT_CHERRYUSB_DEVICE_HID - config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE - bool - prompt "hid_mouse" - depends on RT_CHERRYUSB_DEVICE_HID - config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM - bool - prompt "hid_custom" - depends on RT_CHERRYUSB_DEVICE_HID - config RT_CHERRYUSB_DEVICE_TEMPLATE_VIDEO - bool - prompt "video" - depends on RT_CHERRYUSB_DEVICE_VIDEO - config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER - bool - prompt "audio_v1_mic_speaker_multichan" - depends on RT_CHERRYUSB_DEVICE_AUDIO - config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER - bool - prompt "audio_v2_mic_speaker_multichan" - depends on RT_CHERRYUSB_DEVICE_AUDIO - config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS - bool - prompt "cdc_rndis" - depends on RT_CHERRYUSB_DEVICE_CDC_RNDIS - config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM - bool - prompt "cdc_ecm" - depends on RT_CHERRYUSB_DEVICE_CDC_ECM - config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM - bool - prompt "cdc_ncm" - depends on RT_CHERRYUSB_DEVICE_CDC_NCM - config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC - bool - prompt "cdc_acm_msc" - depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC - config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID - bool - prompt "cdc_acm_msc_hid" - depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC && RT_CHERRYUSB_DEVICE_HID - config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1 - bool - prompt "winusbv1" - config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC - bool - prompt "winusbv2_cdc" - depends on RT_CHERRYUSB_DEVICE_CDC_ACM - config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID - bool - prompt "winusbv2_hid" - depends on RT_CHERRYUSB_DEVICE_HID - config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB - bool - prompt "adb" - depends on RT_CHERRYUSB_DEVICE_ADB - config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV - bool - prompt "cdc_acm_chardev" - 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 - bool "Enable usb host mode" - default n - - if RT_CHERRYUSB_HOST - choice - prompt "Select usb host ip, and some ip need config in usb_config.h, please check" - default RT_CHERRYUSB_HOST_CUSTOM - config RT_CHERRYUSB_HOST_CUSTOM - bool "CUSTOM (Implement it yourself)" - config RT_CHERRYUSB_HOST_EHCI_BL - bool "ehci_bouffalo" - config RT_CHERRYUSB_HOST_EHCI_HPM - bool "ehci_hpm" - config RT_CHERRYUSB_HOST_EHCI_AIC - bool "ehci_aic" - config RT_CHERRYUSB_HOST_EHCI_MCX - bool "ehci_mcx" - config RT_CHERRYUSB_HOST_EHCI_NUC980 - bool "ehci_nuc980" - config RT_CHERRYUSB_HOST_EHCI_MA35D0 - bool "ehci_ma35d0" - config RT_CHERRYUSB_HOST_EHCI_CUSTOM - bool "ehci_custom" - config RT_CHERRYUSB_HOST_DWC2_ST - bool "dwc2_st" - config RT_CHERRYUSB_HOST_DWC2_ESP - bool "dwc2_esp" - config RT_CHERRYUSB_HOST_DWC2_KENDRYTE - bool "dwc2_kendryte" - config RT_CHERRYUSB_HOST_DWC2_HC - bool "dwc2_hc" - config RT_CHERRYUSB_HOST_DWC2_NATION - bool "dwc2_nation" - config RT_CHERRYUSB_HOST_DWC2_CUSTOM - bool "dwc2_custom" - config RT_CHERRYUSB_HOST_MUSB_ES - bool "musb_es" - config RT_CHERRYUSB_HOST_MUSB_SUNXI - bool "musb_sunxi" - config RT_CHERRYUSB_HOST_MUSB_BK - bool "musb_bk" - config RT_CHERRYUSB_HOST_MUSB_SIFLI - bool "musb_sifli" - config RT_CHERRYUSB_HOST_MUSB_CUSTOM - bool "musb_custom" - config RT_CHERRYUSB_HOST_PUSB2 - bool "pusb2" - config RT_CHERRYUSB_HOST_XHCI - bool "xhci" - config RT_CHERRYUSB_HOST_RP2040 - bool "rp2040" - endchoice - - config RT_CHERRYUSB_HOST_CDC_ACM - bool - prompt "Enable usb cdc acm driver" - default n - - config RT_CHERRYUSB_HOST_HID - bool - prompt "Enable usb hid driver" - default n - - config RT_CHERRYUSB_HOST_MSC - bool - prompt "Enable usb msc driver" - default n - select RT_USING_DFS - select RT_USING_DFS_ELMFAT - - config RT_CHERRYUSB_HOST_CDC_ECM - bool - prompt "Enable usb cdc ecm driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_CDC_ECM - default n - - config RT_CHERRYUSB_HOST_CDC_RNDIS - bool - prompt "Enable usb rndis driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_CDC_RNDIS - default n - - config RT_CHERRYUSB_HOST_CDC_NCM - bool - prompt "Enable usb cdc ncm driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_CDC_NCM - default n - - config RT_CHERRYUSB_HOST_VIDEO - bool - prompt "Enable usb video driver, it is commercial charge" - default n - - config RT_CHERRYUSB_HOST_AUDIO - bool - prompt "Enable usb audio driver, it is commercial charge" - default n - - config RT_CHERRYUSB_HOST_BLUETOOTH - bool - prompt "Enable usb bluetooth driver" - default n - - config RT_CHERRYUSB_HOST_ASIX - bool - prompt "Enable usb asix driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_ASIX - default n - - config RT_CHERRYUSB_HOST_RTL8152 - bool - prompt "Enable usb rtl8152 driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_RTL8152 - default n - - config RT_CHERRYUSB_HOST_FTDI - bool - prompt "Enable usb ftdi driver" - default n - - config RT_CHERRYUSB_HOST_CH34X - bool - prompt "Enable usb ch34x driver" - default n - - config RT_CHERRYUSB_HOST_CP210X - bool - prompt "Enable usb cp210x driver" - default n - - config RT_CHERRYUSB_HOST_PL2303 - bool - prompt "Enable usb pl2303 driver" - default n - - config CONFIG_USBHOST_PLATFORM_CDC_ECM - bool - - config CONFIG_USBHOST_PLATFORM_CDC_RNDIS - bool - - config CONFIG_USBHOST_PLATFORM_CDC_NCM - bool - - config CONFIG_USBHOST_PLATFORM_ASIX - bool - - config CONFIG_USBHOST_PLATFORM_RTL8152 - bool - - config CONFIG_USBHOST_PSC_PRIO - int - prompt "Set hubport change thread priority, 0 is the max priority" - default 0 - - config CONFIG_USBHOST_PSC_STACKSIZE - int - prompt "Set hubport change thread stacksize" - default 4096 - - config CONFIG_USBHOST_REQUEST_BUFFER_LEN - int - prompt "Set host control transfer max buffer size" - default 512 - - config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT - int - prompt "Set host control transfer timeout, unit is ms" - default 500 - - config RT_LWIP_PBUF_POOL_BUFSIZE - int "The size of each pbuf in the pbuf pool" - range 1500 2000 - default 1600 - - config CONFIG_USB_DFS_MOUNT_POINT - string "usb host dfs mount point" - depends on RT_CHERRYUSB_HOST_MSC - default "/" - - menu "Select USB host template, please select class driver first" - config CONFIG_TEST_USBH_CDC_ACM - int - prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead" - default 0 - depends on RT_CHERRYUSB_HOST_CDC_ACM - config CONFIG_TEST_USBH_HID - int - prompt "demo for test hid" - default 0 - depends on RT_CHERRYUSB_HOST_HID - config CONFIG_TEST_USBH_MSC - int - prompt "demo for test msc, cannot enable this demo, we have used dfs instead" - default 0 - depends on RT_CHERRYUSB_HOST_MSC - endmenu - endif -endif diff --git a/components/drivers/usb/cherryusb/Kconfig.rttpkg b/components/drivers/usb/cherryusb/Kconfig.rttpkg deleted file mode 100644 index e5a0e430a54..00000000000 --- a/components/drivers/usb/cherryusb/Kconfig.rttpkg +++ /dev/null @@ -1,500 +0,0 @@ -# Kconfig file for package CherryUSB -menuconfig PKG_USING_CHERRYUSB - depends on RT_VER_NUM < 0x50200 - bool "CherryUSB: tiny and portable USB host/device stack for embedded system with USB IP" - default n - -if PKG_USING_CHERRYUSB - - menuconfig PKG_CHERRYUSB_DEVICE - bool "Enable usb device mode" - default n - - if PKG_CHERRYUSB_DEVICE - choice - prompt "Select usb device speed" - default PKG_CHERRYUSB_DEVICE_SPEED_FS - config PKG_CHERRYUSB_DEVICE_SPEED_FS - bool "FS" - config PKG_CHERRYUSB_DEVICE_SPEED_HS - bool "HS" - config PKG_CHERRYUSB_DEVICE_SPEED_AUTO - bool "AUTO" - endchoice - - choice - prompt "Select usb device ip, and some ip need config in usb_config.h, please check" - default PKG_CHERRYUSB_DEVICE_CUSTOM - config PKG_CHERRYUSB_DEVICE_CUSTOM - bool "CUSTOM (Implement it yourself)" - config PKG_CHERRYUSB_DEVICE_FSDEV_ST - bool "fsdev_st" - config PKG_CHERRYUSB_DEVICE_FSDEV_CUSTOM - bool "fsdev_custom" - config PKG_CHERRYUSB_DEVICE_DWC2_ST - bool "dwc2_st" - config PKG_CHERRYUSB_DEVICE_DWC2_ESP - bool "dwc2_esp" - config PKG_CHERRYUSB_DEVICE_DWC2_KENDRYTE - bool "dwc2_kendryte" - config PKG_CHERRYUSB_DEVICE_DWC2_AT - bool "dwc2_at" - config PKG_CHERRYUSB_DEVICE_DWC2_HC - bool "dwc2_hc" - config PKG_CHERRYUSB_DEVICE_DWC2_NATION - bool "dwc2_nation" - config PKG_CHERRYUSB_DEVICE_DWC2_GD - bool "dwc2_gd" - config PKG_CHERRYUSB_DEVICE_DWC2_CUSTOM - bool "dwc2_custom" - config PKG_CHERRYUSB_DEVICE_MUSB_ES - bool "musb_es" - config PKG_CHERRYUSB_DEVICE_MUSB_SUNXI - bool "musb_sunxi" - config PKG_CHERRYUSB_DEVICE_MUSB_BK - bool "musb_bk" - config PKG_CHERRYUSB_DEVICE_MUSB_SIFLI - bool "musb_sifli" - config PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM - bool "musb_custom" - config PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX - bool "chipidea_mcx" - config PKG_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM - bool "chipidea_custom" - config PKG_CHERRYUSB_DEVICE_KINETIS_MCX - bool "kinetis_mcx" - config PKG_CHERRYUSB_DEVICE_KINETIS_MM32 - bool "kinetis_mm32" - config PKG_CHERRYUSB_DEVICE_KINETIS_CUSTOM - bool "kinetis_custom" - config PKG_CHERRYUSB_DEVICE_BL - bool "bouffalo" - config PKG_CHERRYUSB_DEVICE_HPM - bool "hpm" - config PKG_CHERRYUSB_DEVICE_AIC - bool "aic" - config PKG_CHERRYUSB_DEVICE_RP2040 - bool "rp2040" - config PKG_CHERRYUSB_DEVICE_CH32 - bool "ch32" - config PKG_CHERRYUSB_DEVICE_PUSB2 - bool "pusb2" - endchoice - - config PKG_CHERRYUSB_DEVICE_CDC_ACM - bool - prompt "Enable usb cdc acm device" - default n - - config PKG_CHERRYUSB_DEVICE_HID - bool - prompt "Enable usb hid device" - default n - - config PKG_CHERRYUSB_DEVICE_MSC - bool - prompt "Enable usb msc device" - default n - - config PKG_CHERRYUSB_DEVICE_AUDIO - bool - prompt "Enable usb audio device" - default n - - config PKG_CHERRYUSB_DEVICE_VIDEO - bool - prompt "Enable usb video device" - default n - - config PKG_CHERRYUSB_DEVICE_CDC_RNDIS - bool - prompt "Enable usb cdc rndis device" - default n - - config PKG_CHERRYUSB_DEVICE_CDC_ECM - bool - prompt "Enable usb cdc ecm device" - default n - - config PKG_CHERRYUSB_DEVICE_CDC_NCM - bool - prompt "Enable usb cdc ncm device" - default n - - config PKG_CHERRYUSB_DEVICE_MTP - bool - prompt "Enable usb mtp device, it is commercial charge" - default n - - config PKG_CHERRYUSB_DEVICE_ADB - bool - prompt "Enable usb adb device" - default n - - config PKG_CHERRYUSB_DEVICE_DFU - bool - prompt "Enable usb dfu device" - default n - - config PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV - bool - prompt "Enable chardev for cdc acm device" - default n - - config CONFIG_USBDEV_REQUEST_BUFFER_LEN - int - prompt "Set device control transfer max buffer size" - default 512 - - config CONFIG_USBDEV_MSC_MAX_BUFSIZE - int - prompt "Set usb msc device max buffer size" - default 512 - help - Set the maximum buffer size for usb msc device, it is used to transfer data. - you can change it to a larger value if you need larger speed but must be a power of blocksize. - - config CONFIG_USBDEV_RNDIS_USING_LWIP - bool - prompt "Enable usb rndis device with lwip for lan" - default n - - config CONFIG_USBDEV_CDC_ECM_USING_LWIP - bool - prompt "Enable usb cdc ecm device with lwip for lan" - default n - - choice - prompt "Select usb device template, please select class driver first" - default PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE - config PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE - bool - prompt "none (Implement it yourself)" - config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM - bool - prompt "cdc_acm" - depends on PKG_CHERRYUSB_DEVICE_CDC_ACM - config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC - bool - prompt "msc_ram" - depends on PKG_CHERRYUSB_DEVICE_MSC - config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV - bool - prompt "msc_blkdev" - depends on PKG_CHERRYUSB_DEVICE_MSC - config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD - bool - prompt "hid_keyboard" - depends on PKG_CHERRYUSB_DEVICE_HID - config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE - bool - prompt "hid_mouse" - depends on PKG_CHERRYUSB_DEVICE_HID - config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM - bool - prompt "hid_custom" - depends on PKG_CHERRYUSB_DEVICE_HID - config PKG_CHERRYUSB_DEVICE_TEMPLATE_VIDEO - bool - prompt "video" - depends on PKG_CHERRYUSB_DEVICE_VIDEO - config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER - bool - prompt "audio_v1_mic_speaker_multichan" - depends on PKG_CHERRYUSB_DEVICE_AUDIO - config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER - bool - prompt "audio_v2_mic_speaker_multichan" - depends on PKG_CHERRYUSB_DEVICE_AUDIO - config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS - bool - prompt "cdc_rndis" - depends on PKG_CHERRYUSB_DEVICE_CDC_RNDIS - config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM - bool - prompt "cdc_ecm" - depends on PKG_CHERRYUSB_DEVICE_CDC_ECM - config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM - bool - prompt "cdc_ncm" - depends on PKG_CHERRYUSB_DEVICE_CDC_NCM - config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC - bool - prompt "cdc_acm_msc" - depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC - config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID - bool - prompt "cdc_acm_msc_hid" - depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC && PKG_CHERRYUSB_DEVICE_HID - config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1 - bool - prompt "winusbv1" - config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC - bool - prompt "winusbv2_cdc" - depends on PKG_CHERRYUSB_DEVICE_CDC_ACM - config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID - bool - prompt "winusbv2_hid" - depends on PKG_CHERRYUSB_DEVICE_HID - config PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB - bool - prompt "adb" - depends on PKG_CHERRYUSB_DEVICE_ADB - config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV - bool - prompt "cdc_acm_chardev" - depends on PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV - endchoice - - config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME - string "usb device msc block device name" - depends on PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV - default "sd0" - - endif - - menuconfig PKG_CHERRYUSB_HOST - bool "Enable usb host mode" - default n - - if PKG_CHERRYUSB_HOST - choice - prompt "Select usb host ip, and some ip need config in usb_config.h, please check" - default PKG_CHERRYUSB_HOST_CUSTOM - config PKG_CHERRYUSB_HOST_CUSTOM - bool "CUSTOM (Implement it yourself)" - config PKG_CHERRYUSB_HOST_EHCI_BL - bool "ehci_bouffalo" - config PKG_CHERRYUSB_HOST_EHCI_HPM - bool "ehci_hpm" - config PKG_CHERRYUSB_HOST_EHCI_AIC - bool "ehci_aic" - config PKG_CHERRYUSB_HOST_EHCI_MCX - bool "ehci_mcx" - config PKG_CHERRYUSB_HOST_EHCI_NUC980 - bool "ehci_nuc980" - config PKG_CHERRYUSB_HOST_EHCI_MA35D0 - bool "ehci_ma35d0" - config PKG_CHERRYUSB_HOST_EHCI_CUSTOM - bool "ehci_custom" - config PKG_CHERRYUSB_HOST_DWC2_ST - bool "dwc2_st" - config PKG_CHERRYUSB_HOST_DWC2_ESP - bool "dwc2_esp" - config PKG_CHERRYUSB_HOST_DWC2_KENDRYTE - bool "dwc2_kendryte" - config PKG_CHERRYUSB_HOST_DWC2_HC - bool "dwc2_hc" - config PKG_CHERRYUSB_HOST_DWC2_NATION - bool "dwc2_nation" - config PKG_CHERRYUSB_HOST_DWC2_CUSTOM - bool "dwc2_custom" - config PKG_CHERRYUSB_HOST_MUSB_ES - bool "musb_es" - config PKG_CHERRYUSB_HOST_MUSB_SUNXI - bool "musb_sunxi" - config PKG_CHERRYUSB_HOST_MUSB_BK - bool "musb_bk" - config PKG_CHERRYUSB_HOST_MUSB_SIFLI - bool "musb_sifli" - config PKG_CHERRYUSB_HOST_MUSB_CUSTOM - bool "musb_custom" - config PKG_CHERRYUSB_HOST_PUSB2 - bool "pusb2" - config PKG_CHERRYUSB_HOST_XHCI - bool "xhci" - config PKG_CHERRYUSB_HOST_RP2040 - bool "rp2040" - endchoice - - config PKG_CHERRYUSB_HOST_CDC_ACM - bool - prompt "Enable usb cdc acm driver" - default n - - config PKG_CHERRYUSB_HOST_HID - bool - prompt "Enable usb hid driver" - default n - - config PKG_CHERRYUSB_HOST_MSC - bool - prompt "Enable usb msc driver" - default n - select RT_USING_DFS - select RT_USING_DFS_ELMFAT - - config PKG_CHERRYUSB_HOST_CDC_ECM - bool - prompt "Enable usb cdc ecm driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_CDC_ECM - default n - - config PKG_CHERRYUSB_HOST_CDC_RNDIS - bool - prompt "Enable usb rndis driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_CDC_RNDIS - default n - - config PKG_CHERRYUSB_HOST_CDC_NCM - bool - prompt "Enable usb cdc ncm driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_CDC_NCM - default n - - config PKG_CHERRYUSB_HOST_VIDEO - bool - prompt "Enable usb video driver, it is commercial charge" - default n - - config PKG_CHERRYUSB_HOST_AUDIO - bool - prompt "Enable usb audio driver, it is commercial charge" - default n - - config PKG_CHERRYUSB_HOST_BLUETOOTH - bool - prompt "Enable usb bluetooth driver" - default n - - config PKG_CHERRYUSB_HOST_ASIX - bool - prompt "Enable usb asix driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_ASIX - default n - - config PKG_CHERRYUSB_HOST_RTL8152 - bool - prompt "Enable usb rtl8152 driver" - select RT_USING_LWIP - select CONFIG_USBHOST_PLATFORM_RTL8152 - default n - - config PKG_CHERRYUSB_HOST_FTDI - bool - prompt "Enable usb ftdi driver" - default n - - config PKG_CHERRYUSB_HOST_CH34X - bool - prompt "Enable usb ch34x driver" - default n - - config PKG_CHERRYUSB_HOST_CP210X - bool - prompt "Enable usb cp210x driver" - default n - - config PKG_CHERRYUSB_HOST_PL2303 - bool - prompt "Enable usb pl2303 driver" - default n - - config CONFIG_USBHOST_PLATFORM_CDC_ECM - bool - - config CONFIG_USBHOST_PLATFORM_CDC_RNDIS - bool - - config CONFIG_USBHOST_PLATFORM_CDC_NCM - bool - - config CONFIG_USBHOST_PLATFORM_ASIX - bool - - config CONFIG_USBHOST_PLATFORM_RTL8152 - bool - - config CONFIG_USBHOST_PSC_PRIO - int - prompt "Set hubport change thread priority, 0 is the max priority" - default 0 - - config CONFIG_USBHOST_PSC_STACKSIZE - int - prompt "Set hubport change thread stacksize" - default 4096 - - config CONFIG_USBHOST_REQUEST_BUFFER_LEN - int - prompt "Set host control transfer max buffer size" - default 512 - - config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT - int - prompt "Set host control transfer timeout, unit is ms" - default 500 - - config RT_LWIP_PBUF_POOL_BUFSIZE - int "The size of each pbuf in the pbuf pool" - range 1500 2000 - default 1600 - - config CONFIG_USB_DFS_MOUNT_POINT - string "usb host dfs mount point" - depends on RT_CHERRYUSB_HOST_MSC - default "/" - - menu "Select USB host template, please select class driver first" - config CONFIG_TEST_USBH_CDC_ACM - int - prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead" - default 0 - depends on PKG_CHERRYUSB_HOST_CDC_ACM - config CONFIG_TEST_USBH_HID - int - prompt "demo for test hid" - default 0 - depends on PKG_CHERRYUSB_HOST_HID - config CONFIG_TEST_USBH_MSC - int - prompt "demo for test msc, cannot enable this demo, we have used dfs instead" - default 0 - depends on PKG_CHERRYUSB_HOST_MSC - endmenu - endif - - config PKG_CHERRYUSB_PATH - string - default "/packages/system/CherryUSB" - - choice - prompt "Version" - default PKG_USING_CHERRYUSB_V010502 - help - Select the package version - - config PKG_USING_CHERRYUSB_LATEST_VERSION - bool "latest" - config PKG_USING_CHERRYUSB_V010502 - bool "v1.5.2" - config PKG_USING_CHERRYUSB_V010501 - bool "v1.5.1" - config PKG_USING_CHERRYUSB_V010500 - bool "v1.5.0" - config PKG_USING_CHERRYUSB_V010403 - bool "v1.4.3" - config PKG_USING_CHERRYUSB_V010301 - bool "v1.3.1" - config PKG_USING_CHERRYUSB_V010200 - bool "v1.2.0" - config PKG_USING_CHERRYUSB_V001002 - bool "v0.10.2" - endchoice - - config PKG_CHERRYUSB_VER - string - default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION - default "v1.5.2" if PKG_USING_CHERRYUSB_V010502 - default "v1.5.1" if PKG_USING_CHERRYUSB_V010501 - default "v1.5.0" if PKG_USING_CHERRYUSB_V010500 - default "v1.4.3" if PKG_USING_CHERRYUSB_V010403 - default "v1.3.1" if PKG_USING_CHERRYUSB_V010301 - default "v1.2.0" if PKG_USING_CHERRYUSB_V010200 - default "v0.10.2" if PKG_USING_CHERRYUSB_V001002 -endif diff --git a/components/drivers/usb/cherryusb/README.md b/components/drivers/usb/cherryusb/README.md index fcb6f13c96f..d514f1fb08d 100644 --- a/components/drivers/usb/cherryusb/README.md +++ b/components/drivers/usb/cherryusb/README.md @@ -40,6 +40,8 @@ Taking into account USB performance issues and trying to achieve the theoretical - Unlimited length make it easier to interface with hardware DMA and take advantage of DMA - Packetization is handled in interrupt +Performance show:https://cherryusb.cherry-embedded.org/show/ + ## Directory Structure | Directory | Description | @@ -103,14 +105,15 @@ CherryUSB Host Stack has the following functions: - Support blocking transfers and asynchronous transfers - Support Composite Device - Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2/ehci/xhci/rp2040) -- Support Communication Device Class (CDC_ACM, CDC_ECM) +- Support Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM) - Support Human Interface Device (HID) - Support Mass Storage Class (MSC) - Support USB Video CLASS (UVC1.0, UVC1.5) - Support USB Audio CLASS (UAC1.0) - Support Remote NDIS (RNDIS) - Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm) -- Support Vendor class (serial, net, wifi) +- Support Vendor Serial Class(CH34X、CP210X、PL2303、FTDI、GSM) +- Support Vendor network Class(RTL8152、AX88772) - Support USB modeswitch - Support Android Open Accessory - Support multi host with the same USB IP @@ -141,14 +144,14 @@ Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affe #define CONFIG_USBHOST_MAX_EXTHUBS 1 #define CONFIG_USBHOST_MAX_EHPORTS 4 #define CONFIG_USBHOST_MAX_INTERFACES 8 -#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 +#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2 #define CONFIG_USBHOST_MAX_ENDPOINTS 4 ``` x is affected by the following macros: ``` -#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 @@ -179,32 +182,33 @@ Quickly start, USB basic concepts, API manual, Class basic concepts and examples ## Video Tutorial -CherryUSB Cheese (based V1.4.3): https://www.bilibili.com/cheese/play/ss707687201 . +CherryUSB Cheese (>= V1.4.3): https://www.bilibili.com/cheese/play/ss707687201 . ## Descriptor Generator Tool -TODO +Cherry Descriptor: https://desc.cherry-embedded.org/en ## Demo Repo -| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status | +| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note | |:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:| -|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term | -|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term | -|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term | -|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term | -|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term | -|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term | -|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term | -|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term | -|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term | -|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term | -|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term | -|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb | -|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb | -|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD | -|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD | +|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official | +|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community | +|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official | +|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | +|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | +|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | +|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[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 | ## Package Support @@ -226,5 +230,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8. Thanks to the following companies for their support (in no particular order): - - + diff --git a/components/drivers/usb/cherryusb/README_zh.md b/components/drivers/usb/cherryusb/README_zh.md index 64287a558b7..cf76f3ea281 100644 --- a/components/drivers/usb/cherryusb/README_zh.md +++ b/components/drivers/usb/cherryusb/README_zh.md @@ -112,7 +112,8 @@ CherryUSB Host 协议栈当前实现以下功能: - Support USB Audio CLASS (UAC1.0) - 支持 Remote NDIS (RNDIS) - 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能) -- 支持 Vendor 类 class (serial, net, wifi) +- 支持 Vendor Serial 类(CH34X、CP210X、PL2303、FTDI、GSM) +- 支持 Vendor network 类(RTL8152、AX88772) - 支持 USB modeswitch - 支持 Android Open Accessory - 支持相同 USB IP 的多主机 @@ -150,7 +151,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2,关闭 log) x 受以下宏影响: ``` -#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 @@ -181,11 +182,11 @@ CherryUSB 快速入门、USB 基本概念、API 手册、Class 基本概念和 ## 视频教程 -CherryUSB 课程(基于 V1.4.3):https://www.bilibili.com/cheese/play/ss707687201 。 +CherryUSB 课程(>= V1.4.3):https://www.bilibili.com/cheese/play/ss707687201 。 ## 描述符生成工具 -TODO +Cherry Descriptor: https://desc.cherry-embedded.org/zh ## 示例仓库 @@ -197,7 +198,7 @@ TODO |Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | |Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | |Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing | +|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 | diff --git a/components/drivers/usb/cherryusb/SConscript b/components/drivers/usb/cherryusb/SConscript index a2a80fdc375..b134dec2ad7 100644 --- a/components/drivers/usb/cherryusb/SConscript +++ b/components/drivers/usb/cherryusb/SConscript @@ -14,9 +14,8 @@ path += [cwd + '/class/wireless'] path += [cwd + '/class/midi'] path += [cwd + '/class/adb'] path += [cwd + '/class/dfu'] -path += [cwd + '/class/midi'] +path += [cwd + '/class/serial'] path += [cwd + '/class/vendor/net'] -path += [cwd + '/class/vendor/serial'] path += [cwd + '/class/vendor/wifi'] src = [] @@ -47,6 +46,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE']): src += Glob('port/dwc2/usb_dc_dwc2.c') src += Glob('port/dwc2/usb_glue_kendryte.c') + if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_INFINEON']): + src += Glob('port/dwc2/usb_dc_dwc2.c') + src += Glob('port/dwc2/usb_glue_infineon.c') if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_AT']): src += Glob('port/dwc2/usb_dc_dwc2.c') src += Glob('port/dwc2/usb_glue_at.c') @@ -112,6 +114,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): LIBS = ['libpusb2_dc_a32_softfp_neon.a'] if GetDepend(['RT_CHERRYUSB_DEVICE_NRF5X']): src += Glob('port/nrf5x/usb_dc_nrf5x.c') + if GetDepend(['RT_CHERRYUSB_DEVICE_RP2040']): + path += [cwd + '/port/rp2040'] + src += Glob('port/rp2040/usb_dc_rp2040.c') if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_ACM']): src += Glob('class/cdc/usbd_cdc_acm.c') @@ -166,10 +171,12 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): src += Glob('demo/cdc_acm_hid_msc_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1']): src += Glob('demo/winusb1.0_template.c') + if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2']): + src += Glob('demo/winusb2.0_template.c') if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC']): src += Glob('demo/winusb2.0_cdc_template.c') - if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID']): - src += Glob('demo/winusb2.0_hid_template.c') + if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_WEBUSB_HID']): + src += Glob('demo/webusb_hid_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']): @@ -216,6 +223,12 @@ if GetDepend(['RT_CHERRYUSB_HOST']): if GetDepend(['RT_CHERRYUSB_HOST_DWC2_KENDRYTE']): src += Glob('port/dwc2/usb_hc_dwc2.c') src += Glob('port/dwc2/usb_glue_kendryte.c') + if GetDepend(['RT_CHERRYUSB_HOST_DWC2_INFINEON']): + src += Glob('port/dwc2/usb_hc_dwc2.c') + src += Glob('port/dwc2/usb_glue_infineon.c') + if GetDepend(['RT_CHERRYUSB_HOST_DWC2_AT']): + src += Glob('port/dwc2/usb_hc_dwc2.c') + src += Glob('port/dwc2/usb_glue_at.c') if GetDepend(['RT_CHERRYUSB_HOST_DWC2_HC']): src += Glob('port/dwc2/usb_hc_dwc2.c') src += Glob('port/dwc2/usb_glue_hc.c') @@ -266,8 +279,12 @@ if GetDepend(['RT_CHERRYUSB_HOST']): LIBPATH = [cwd + '/port/xhci/phytium'] LIBS = ['libxhci_a32_softfp_neon.a'] + if GetDepend(['RT_CHERRYUSB_HOST_RP2040']): + path += [cwd + '/port/rp2040'] + src += Glob('port/rp2040/usb_hc_rp2040.c') + if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM']): - src += Glob('class/cdc/usbh_cdc_acm.c') + src += Glob('class/serial/usbh_cdc_acm.c') if GetDepend(['RT_CHERRYUSB_HOST_HID']): src += Glob('class/hid/usbh_hid.c') if GetDepend(['RT_CHERRYUSB_HOST_MSC']): @@ -289,23 +306,26 @@ if GetDepend(['RT_CHERRYUSB_HOST']): if GetDepend(['RT_CHERRYUSB_HOST_RTL8152']): src += Glob('class/vendor/net/usbh_rtl8152.c') if GetDepend(['RT_CHERRYUSB_HOST_FTDI']): - src += Glob('class/vendor/serial/usbh_ftdi.c') + src += Glob('class/serial/usbh_ftdi.c') if GetDepend(['RT_CHERRYUSB_HOST_CH34X']): - src += Glob('class/vendor/serial/usbh_ch34x.c') + src += Glob('class/serial/usbh_ch34x.c') if GetDepend(['RT_CHERRYUSB_HOST_CP210X']): - src += Glob('class/vendor/serial/usbh_cp210x.c') + src += Glob('class/serial/usbh_cp210x.c') if GetDepend(['RT_CHERRYUSB_HOST_PL2303']): - src += Glob('class/vendor/serial/usbh_pl2303.c') + src += Glob('class/serial/usbh_pl2303.c') - if GetDepend(['CONFIG_TEST_USBH_HID']): + if GetDepend(['RT_TEST_USBH_HID']): + CPPDEFINES+=['CONFIG_TEST_USBH_HID'] src += Glob('demo/usb_host.c') if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM']) \ or GetDepend(['RT_CHERRYUSB_HOST_FTDI']) \ or GetDepend(['RT_CHERRYUSB_HOST_CH34X']) \ or GetDepend(['RT_CHERRYUSB_HOST_CP210X']) \ - or GetDepend(['RT_CHERRYUSB_HOST_PL2303']): - src += Glob('platform/rtthread/usbh_serial.c') + 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') if GetDepend('RT_USING_DFS') and GetDepend(['RT_CHERRYUSB_HOST_MSC']): src += Glob('platform/rtthread/usbh_dfs.c') diff --git a/components/drivers/usb/cherryusb/VERSION b/components/drivers/usb/cherryusb/VERSION index 7aa5f8b8df2..bf6627b8a1b 100644 --- a/components/drivers/usb/cherryusb/VERSION +++ b/components/drivers/usb/cherryusb/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 1 -VERSION_MINOR = 5 -PATCHLEVEL = 2 +VERSION_MINOR = 6 +PATCHLEVEL = 0 VERSION_TWEAK = 0 EXTRAVERSION = 0 diff --git a/components/drivers/usb/cherryusb/cherryusb.cmake b/components/drivers/usb/cherryusb/cherryusb.cmake index 3d7c28b3d97..69573249366 100644 --- a/components/drivers/usb/cherryusb/cherryusb.cmake +++ b/components/drivers/usb/cherryusb/cherryusb.cmake @@ -47,10 +47,11 @@ list( ${CMAKE_CURRENT_LIST_DIR}/class/midi ${CMAKE_CURRENT_LIST_DIR}/class/adb ${CMAKE_CURRENT_LIST_DIR}/class/dfu + ${CMAKE_CURRENT_LIST_DIR}/class/serial ${CMAKE_CURRENT_LIST_DIR}/class/vendor/net - ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi ${CMAKE_CURRENT_LIST_DIR}/class/aoa + ${CMAKE_CURRENT_LIST_DIR}/class/gamepad ) if(CONFIG_CHERRYUSB_DEVICE) @@ -85,6 +86,9 @@ if(CONFIG_CHERRYUSB_DEVICE) if(CONFIG_CHERRYUSB_DEVICE_ADB) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/adb/usbd_adb.c) endif() + if(CONFIG_CHERRYUSB_DEVICE_GAMEPAD) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/gamepad/usbd_gamepad.c) + endif() if(CONFIG_CHERRYUSB_DEVICE_FSDEV_ST) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/fsdev/usb_dc_fsdev.c) @@ -156,7 +160,7 @@ if(CONFIG_CHERRYUSB_HOST) ) if(CONFIG_CHERRYUSB_HOST_CDC_ACM) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_acm.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_cdc_acm.c) endif() if(CONFIG_CHERRYUSB_HOST_CDC_ECM) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ecm.c) @@ -235,30 +239,39 @@ if(CONFIG_CHERRYUSB_HOST) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/net/usbh_rtl8152.c) endif() if(CONFIG_CHERRYUSB_HOST_CH34X) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_ch34x.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_ch34x.c) endif() if(CONFIG_CHERRYUSB_HOST_CP210X) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_cp210x.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_cp210x.c) endif() if(CONFIG_CHERRYUSB_HOST_FTDI) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_ftdi.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_ftdi.c) endif() if(CONFIG_CHERRYUSB_HOST_PL2303) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_pl2303.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_pl2303.c) endif() - if(CONFIG_CHERRYUSB_HOST_BL616) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi/usbh_bl616.c) + if(CONFIG_CHERRYUSB_HOST_GSM) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_gsm.c) endif() if(CONFIG_CHERRYUSB_HOST_AOA) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/aoa/usbh_aoa.c) endif() + if(CONFIG_CHERRYUSB_HOST_CDC_ACM + OR CONFIG_CHERRYUSB_HOST_CH34X + OR CONFIG_CHERRYUSB_HOST_CP210X + OR CONFIG_CHERRYUSB_HOST_FTDI + OR CONFIG_CHERRYUSB_HOST_PL2303 + OR CONFIG_CHERRYUSB_HOST_GSM + ) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/serial/usbh_serial.c) + endif() + if(CONFIG_CHERRYUSB_HOST_CDC_ECM OR CONFIG_CHERRYUSB_HOST_CDC_RNDIS OR CONFIG_CHERRYUSB_HOST_CDC_NCM OR CONFIG_CHERRYUSB_HOST_ASIX OR CONFIG_CHERRYUSB_HOST_RTL8152 - OR CONFIG_CHERRYUSB_HOST_BL616 ) if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf") list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_net.c) @@ -335,11 +348,15 @@ if(CONFIG_CHERRYUSB_HOST) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c) endif() - if(CONFIG_TEST_USBH_CDC_ACM OR CONFIG_TEST_USBH_HID OR CONFIG_TEST_USBH_MSC) + if(CONFIG_TEST_USBH_SERIAL OR CONFIG_TEST_USBH_HID OR CONFIG_TEST_USBH_MSC) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/demo/usb_host.c) endif() endif() +if(CONFIG_CHERRYUSB_DEVICE AND CONFIG_CHERRYUSB_HOST) +list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/core/usbotg_core.c) +endif() + if(DEFINED CONFIG_CHERRYUSB_OSAL) if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos") list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_freertos.c) diff --git a/components/drivers/usb/cherryusb/cherryusb_config_template.h b/components/drivers/usb/cherryusb/cherryusb_config_template.h index 1e8aab740c3..9f069005288 100644 --- a/components/drivers/usb/cherryusb/cherryusb_config_template.h +++ b/components/drivers/usb/cherryusb/cherryusb_config_template.h @@ -157,7 +157,7 @@ #define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2 #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 @@ -188,6 +188,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 @@ -301,6 +305,7 @@ /* ---------------- MUSB Configuration ---------------- */ #define CONFIG_USB_MUSB_PIPE_NUM 8 // #define CONFIG_USB_MUSB_SUNXI +// #define CONFIG_USB_MUSB_WITHOUT_MULTIPOINT /* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, * the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. @@ -317,4 +322,7 @@ #define usb_ramaddr2phyaddr(addr) (addr) #endif +/* Enable OTG support, only support hpmicro now */ +// #define CONFIG_USB_OTG_ENABLE + #endif diff --git a/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c b/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c index ddae9571482..02d9fab553f 100644 --- a/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c +++ b/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c @@ -176,9 +176,6 @@ int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *repo int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len) { struct usb_setup_packet *setup; - int ret; - uint8_t len; - uint32_t offset; if (!aoa_class || !aoa_class->hport) { return -USB_ERR_INVAL; @@ -198,7 +195,6 @@ int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *ev static int usbh_aoa_connect(struct usbh_hubport *hport, uint8_t intf) { struct usb_endpoint_descriptor *ep_desc; - int ret = 0; struct usbh_aoa *aoa_class = &g_aoa_class; diff --git a/components/drivers/usb/cherryusb/class/audio/usb_audio.h b/components/drivers/usb/cherryusb/class/audio/usb_audio.h index eb518b7bcb5..6c25c3de21d 100644 --- a/components/drivers/usb/cherryusb/class/audio/usb_audio.h +++ b/components/drivers/usb/cherryusb/class/audio/usb_audio.h @@ -88,18 +88,6 @@ #define AUDIO_ENDPOINT_UNDEFINED 0x00U #define AUDIO_ENDPOINT_GENERAL 0x01U -/* Feature Unit Control Bits */ -#define AUDIO_CONTROL_MUTE 0x0001 -#define AUDIO_CONTROL_VOLUME 0x0002 -#define AUDIO_CONTROL_BASS 0x0004 -#define AUDIO_CONTROL_MID 0x0008 -#define AUDIO_CONTROL_TREBLE 0x0010 -#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020 -#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040 -#define AUDIO_CONTROL_DEALY 0x0080 -#define AUDIO_CONTROL_BASS_BOOST 0x0100 -#define AUDIO_CONTROL_LOUDNESS 0x0200 - /* Encoder Type Codes */ #define AUDIO_ENCODER_UNDEF 0x00 #define AUDIO_ENCODER_OTHER 0x01 @@ -245,22 +233,34 @@ #define AUDIO_FU_CONTROL_OVERFLOW 0x0f #define AUDIO_FU_CONTROL_LATENCY 0x10 -#define AUDIO_V2_FU_CONTROL_UNDEF 0x00 -#define AUDIO_V2_FU_CONTROL_MUTE (0x03 << 0) -#define AUDIO_V2_FU_CONTROL_VOLUME (0x03 << 2) -#define AUDIO_V2_FU_CONTROL_BASS (0x03 << 4) -#define AUDIO_V2_FU_CONTROL_MID (0x03 << 6) -#define AUDIO_V2_FU_CONTROL_TREBLE (0x03 << 8) -#define AUDIO_V2_FU_CONTROL_EQUALIZER (0x03 << 10) -#define AUDIO_V2_FU_CONTROL_AGC (0x03 << 12) -#define AUDIO_V2_FU_CONTROL_DELAY (0x03 << 14) -#define AUDIO_V2_FU_CONTROL_BASS_BOOST (0x03 << 16) -#define AUDIO_V2_FU_CONTROL_LOUDNESS (0x03 << 18) -#define AUDIO_V2_FU_CONTROL_INP_GAIN (0x03 << 20) -#define AUDIO_V2_FU_CONTROL_INP_GAIN_PAD (0x03 << 22) -#define AUDIO_V2_FU_CONTROL_PHASE_INVERT (0x03 << 24) -#define AUDIO_V2_FU_CONTROL_UNDERFLOW (0x03 << 26) -#define AUDIO_V2_FU_CONTROL_OVERFLOW (0x03 << 28) +/* Feature Unit Control Bits */ +#define AUDIO_CONTROL_MUTE 0x0001 +#define AUDIO_CONTROL_VOLUME 0x0002 +#define AUDIO_CONTROL_BASS 0x0004 +#define AUDIO_CONTROL_MID 0x0008 +#define AUDIO_CONTROL_TREBLE 0x0010 +#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020 +#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040 +#define AUDIO_CONTROL_DEALY 0x0080 +#define AUDIO_CONTROL_BASS_BOOST 0x0100 +#define AUDIO_CONTROL_LOUDNESS 0x0200 + +#define AUDIO_V2_CONTROL_UNDEF 0x00 +#define AUDIO_V2_CONTROL_MUTE (0x03 << 0) +#define AUDIO_V2_CONTROL_VOLUME (0x03 << 2) +#define AUDIO_V2_CONTROL_BASS (0x03 << 4) +#define AUDIO_V2_CONTROL_MID (0x03 << 6) +#define AUDIO_V2_CONTROL_TREBLE (0x03 << 8) +#define AUDIO_V2_CONTROL_EQUALIZER (0x03 << 10) +#define AUDIO_V2_CONTROL_AGC (0x03 << 12) +#define AUDIO_V2_CONTROL_DELAY (0x03 << 14) +#define AUDIO_V2_CONTROL_BASS_BOOST (0x03 << 16) +#define AUDIO_V2_CONTROL_LOUDNESS (0x03 << 18) +#define AUDIO_V2_CONTROL_INP_GAIN (0x03 << 20) +#define AUDIO_V2_CONTROL_INP_GAIN_PAD (0x03 << 22) +#define AUDIO_V2_CONTROL_PHASE_INVERT (0x03 << 24) +#define AUDIO_V2_CONTROL_UNDERFLOW (0x03 << 26) +#define AUDIO_V2_CONTROL_OVERFLOW (0x03 << 28) /* Parametric Equalizer Section Effect Unit Control Selectors */ #define AUDIO_PE_CONTROL_UNDEF 0x00 @@ -605,7 +605,7 @@ struct audio_cs_if_ac_header_descriptor { uint8_t baInterfaceNr[]; } __PACKED; -#define AUDIO_SIZEOF_AC_HEADER_DESC(n) (8 + n) +#define AUDIO_SIZEOF_AC_HEADER_DESC(bInCollection) (8 + (bInCollection)) struct audio_cs_if_ac_input_terminal_descriptor { uint8_t bLength; @@ -646,7 +646,7 @@ struct audio_cs_if_ac_feature_unit_descriptor { uint8_t iFeature; } __PACKED; -#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + (ch + 1) * n) +#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(bNrChannels, bControlSize) (7 + ((bNrChannels) + 1) * (bControlSize)) struct audio_cs_if_ac_selector_unit_descriptor { uint8_t bLength; @@ -658,7 +658,7 @@ struct audio_cs_if_ac_selector_unit_descriptor { uint8_t iSelector; } __PACKED; -#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(n) (6 + n) +#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(bNrInPins) (6 + (bNrInPins)) struct audio_cs_if_as_general_descriptor { uint8_t bLength; @@ -683,7 +683,7 @@ struct audio_cs_if_as_format_type_descriptor { uint8_t tSamFreq[3]; } __PACKED; -#define AUDIO_SIZEOF_FORMAT_TYPE_DESC(n) (8 + 3 * n) +#define AUDIO_SIZEOF_FORMAT_TYPE_DESC(bSamFreqType) (8 + 3 * (bSamFreqType)) struct audio_ep_descriptor { uint8_t bLength; @@ -738,7 +738,7 @@ struct audio_cs_ep_ep_general_descriptor { PP_NARG(__VA_ARGS__), /* bInCollection */ \ __VA_ARGS__ /* baInterfaceNr */ -#define AUDIO_AC_DESCRIPTOR_INIT_LEN(n) (0x08 + 0x09 + 0x08 + n) +#define AUDIO_AC_DESCRIPTOR_LEN(bInCollection) (0x08 + 0x09 + 0x08 + bInCollection) #define AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(bTerminalID, wTerminalType, bNrChannels, wChannelConfig) \ 0x0C, /* bLength */ \ @@ -880,8 +880,8 @@ struct audio_cs_ep_ep_general_descriptor { 0x03, /* bRefresh, 8ms */ \ 0x00 /* bSynchAddress */ -#define AUDIO_AS_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07) -#define AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07 + 0x09) +#define AUDIO_AS_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07) +#define AUDIO_AS_FEEDBACK_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07 + 0x09) #define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \ 0x09, /* bLength */ \ @@ -924,9 +924,9 @@ struct audio_cs_ep_ep_general_descriptor { 0x00, /* wLockDelay */ \ 0x00 -#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07) +#define AUDIO_AS_ALTSETTING_DESCRIPTOR_LEN(bSamFreqType) (0x09 + 0x07 + 0x08 + 3 * (bSamFreqType) + 0x09 + 0x07) -#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ +#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ bInterfaceNumber, /* bInterfaceNumber */ \ @@ -937,19 +937,6 @@ struct audio_cs_ep_ep_general_descriptor { AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \ 0x00 /* iInterface */ -#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bInterfaceNumber, /* bInterfaceNumber */ \ - 0x00, /* bAlternateSetting */ \ - bNumEndpoints, /* bNumEndpoints */ \ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ - AUDIO_SUBCLASS_MIDISTREAMING, /* bInterfaceSubClass */ \ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \ - 0x00 /* iInterface */ - -#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT_LEN 0x09 - struct audio_v2_channel_cluster_descriptor { uint8_t bNrChannels; uint32_t bmChannelConfig; @@ -993,7 +980,7 @@ struct audio_v2_cs_if_ac_clock_selector_descriptor { uint8_t iClockSelector; } __PACKED; -#define AUDIO_SIZEOF_AC_CLOCK_SELECTOR_DESC(n) (7 + n) +#define AUDIO_SIZEOF_AC_CLOCK_SELECTOR_DESC(bNrInPins) (7 + (bNrInPins)) struct audio_v2_cs_if_ac_clock_multiplier_descriptor { uint8_t bLength; @@ -1005,7 +992,7 @@ struct audio_v2_cs_if_ac_clock_multiplier_descriptor { uint8_t iClockMultiplier; } __PACKED; -#define AUDIO_SIZEOF_AC_CLOCK_MULTIPLIER_DESC() (7) +#define AUDIO_SIZEOF_AC_CLOCK_MULTIPLIER_DESC (7) struct audio_v2_cs_if_ac_input_terminal_descriptor { uint8_t bLength; @@ -1049,7 +1036,7 @@ struct audio_v2_cs_if_ac_feature_unit_descriptor { uint8_t iFeature; } __PACKED; -#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(ch) (6 + (ch + 1) * 4) +#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(bNrChannels) (6 + ((bNrChannels) + 1) * 4) struct audio_v2_cs_if_as_general_descriptor { uint8_t bLength; @@ -1124,7 +1111,7 @@ struct audio_v2_control_range3_param_block { WBVAL(wTotalLength), /* wTotalLength */ \ bmControls /* bmControls */ \ -#define AUDIO_V2_AC_DESCRIPTOR_INIT_LEN (0x08 + 0x09 + 0x09) +#define AUDIO_V2_AC_DESCRIPTOR_LEN (0x08 + 0x09 + 0x09) #define AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(bClockID, bmAttributes, bmControls) \ 0x08, /* bLength */ \ @@ -1262,7 +1249,7 @@ struct audio_v2_control_range3_param_block { 0x00, /* wLockDelay */ \ 0x00 -#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ +#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ bInterfaceNumber, /* bInterfaceNumber */ \ @@ -1331,9 +1318,10 @@ struct audio_v2_control_range3_param_block { // clang-format on -#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) -#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08) -#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) +#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_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/cdc/usb_cdc.h b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h index d1546eec575..6a8e807d3c7 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h +++ b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h @@ -217,12 +217,12 @@ #define CDC_SERIAL_STATE_BREAK (1 << 2) /* state of break detection */ #define CDC_SERIAL_STATE_BREAK_Pos (2) #define CDC_SERIAL_STATE_BREAK_Msk (1 << CDC_SERIAL_STATE_BREAK_Pos) -#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) /* state of transmission carrier */ -#define CDC_SERIAL_STATE_TX_CARRIER_Pos (1) -#define CDC_SERIAL_STATE_TX_CARRIER_Msk (1 << CDC_SERIAL_STATE_TX_CARRIER_Pos) -#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) /* state of receiver carrier */ -#define CDC_SERIAL_STATE_RX_CARRIER_Pos (0) -#define CDC_SERIAL_STATE_RX_CARRIER_Msk (1 << CDC_SERIAL_STATE_RX_CARRIER_Pos) +#define CDC_SERIAL_STATE_DSR (1 << 1) /* state of transmission carrier */ +#define CDC_SERIAL_STATE_DSR_Pos (1) +#define CDC_SERIAL_STATE_DSR_Msk (1 << CDC_SERIAL_STATE_DSR_Pos) +#define CDC_SERIAL_STATE_DCD (1 << 0) /* state of receiver carrier */ +#define CDC_SERIAL_STATE_DCD_Pos (0) +#define CDC_SERIAL_STATE_DCD_Msk (1 << CDC_SERIAL_STATE_DCD_Pos) #define CDC_ECM_XMIT_OK (1 << 0) #define CDC_ECM_RVC_OK (1 << 1) @@ -551,10 +551,9 @@ 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) +#define CDC_ECM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 7 + 9 + 7 + 7) // clang-format off -#define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, \ -eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) \ +#define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \ /* Interface Associate */ \ 0x08, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ @@ -587,10 +586,10 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */\ CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype */\ str_idx, /* Device's MAC string index */\ - DBVAL_BE(eth_statistics), /* Ethernet statistics (bitmap) */\ - WBVAL(wMaxSegmentSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\ - WBVAL(wNumberMCFilters), /* wNumberMCFilters: the number of multicast filters */\ - bNumberPowerFilters, /* bNumberPowerFilters: the number of wakeup power filters */\ + DBVAL_BE(0x00000000), /* Ethernet statistics (bitmap) */\ + WBVAL(1514), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\ + WBVAL(0), /* wNumberMCFilters: the number of multicast filters */ \ + 0, /* bNumberPowerFilters: the number of wakeup power filters */ \ 0x07, /* bLength */ \ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ int_ep, /* bEndpointAddress */ \ @@ -621,10 +620,9 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) // clang-format on /*Length of template descriptor: 77 bytes*/ -#define CDC_NCM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 7 + 7) +#define CDC_NCM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 6 + 7 + 9 + 7 + 7) // clang-format off -#define CDC_NCM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, \ -eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) \ +#define CDC_NCM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \ /* Interface Associate */ \ 0x08, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ @@ -657,10 +655,10 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */\ CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype */\ str_idx, /* Device's MAC string index */\ - DBVAL_BE(eth_statistics), /* Ethernet statistics (bitmap) */\ - WBVAL(wMaxPacketSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\ - WBVAL(wNumberMCFilters), /* wNumberMCFilters: the number of multicast filters */\ - bNumberPowerFilters, /* bNumberPowerFilters: the number of wakeup power filters */\ + DBVAL_BE(0x00000000), /* Ethernet statistics (bitmap) */\ + WBVAL(1514), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\ + WBVAL(0), /* wNumberMCFilters: the number of multicast filters */ \ + 0, /* bNumberPowerFilters: the number of wakeup power filters */ \ 0x06, \ CDC_CS_INTERFACE, \ CDC_FUNC_DESC_NCM, \ diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c deleted file mode 100644 index 2fc54eed6bb..00000000000 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2022, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_cdc_acm.h" - -#undef USB_DBG_TAG -#define USB_DBG_TAG "usbh_cdc_acm" -#include "usb_log.h" - -#define DEV_FORMAT "/dev/ttyACM%d" - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; - -static struct usbh_cdc_acm g_cdc_acm_class[CONFIG_USBHOST_MAX_CDC_ACM_CLASS]; -static uint32_t g_devinuse = 0; - -static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void) -{ - uint8_t devno; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); - memset(&g_cdc_acm_class[devno], 0, sizeof(struct usbh_cdc_acm)); - g_cdc_acm_class[devno].minor = devno; - return &g_cdc_acm_class[devno]; - } - } - return NULL; -} - -static void usbh_cdc_acm_class_free(struct usbh_cdc_acm *cdc_acm_class) -{ - uint8_t devno = cdc_acm_class->minor; - - if (devno < 32) { - g_devinuse &= ~(1U << devno); - } - memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm)); -} - -int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding) -{ - struct usb_setup_packet *setup; - - if (!cdc_acm_class || !cdc_acm_class->hport) { - return -USB_ERR_INVAL; - } - setup = cdc_acm_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CDC_REQUEST_SET_LINE_CODING; - setup->wValue = 0; - setup->wIndex = cdc_acm_class->intf; - setup->wLength = 7; - - memcpy(g_cdc_acm_buf[cdc_acm_class->minor], line_coding, sizeof(struct cdc_line_coding)); - - return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]); -} - -int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding) -{ - struct usb_setup_packet *setup; - int ret; - - if (!cdc_acm_class || !cdc_acm_class->hport) { - return -USB_ERR_INVAL; - } - setup = cdc_acm_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CDC_REQUEST_GET_LINE_CODING; - setup->wValue = 0; - setup->wIndex = cdc_acm_class->intf; - setup->wLength = 7; - - ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]); - if (ret < 0) { - return ret; - } - memcpy(line_coding, g_cdc_acm_buf[cdc_acm_class->minor], sizeof(struct cdc_line_coding)); - return ret; -} - -int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts) -{ - struct usb_setup_packet *setup; - - if (!cdc_acm_class || !cdc_acm_class->hport) { - return -USB_ERR_INVAL; - } - setup = cdc_acm_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE; - setup->wValue = (dtr << 0) | (rts << 1); - setup->wIndex = cdc_acm_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(cdc_acm_class->hport, setup, NULL); -} - -static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - - struct usbh_cdc_acm *cdc_acm_class = usbh_cdc_acm_class_alloc(); - if (cdc_acm_class == NULL) { - USB_LOG_ERR("Fail to alloc cdc_acm_class\r\n"); - return -USB_ERR_NOMEM; - } - - cdc_acm_class->hport = hport; - cdc_acm_class->intf = intf; - - hport->config.intf[intf].priv = cdc_acm_class; - hport->config.intf[intf + 1].priv = NULL; - -#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY - ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; - USBH_EP_INIT(cdc_acm_class->intin, ep_desc); -#endif - for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc; - - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(cdc_acm_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(cdc_acm_class->bulkout, ep_desc); - } - } - - snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, cdc_acm_class->minor); - - USB_LOG_INFO("Register CDC ACM Class:%s\r\n", hport->config.intf[intf].devname); - -#if 0 - USB_LOG_INFO("Test cdc acm rx and tx and rx for 5 times, baudrate is 115200\r\n"); - - struct cdc_line_coding linecoding; - uint8_t count = 5; - - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_cdc_acm_set_line_coding(cdc_acm_class, &linecoding); - usbh_cdc_acm_set_line_state(cdc_acm_class, true, false); - - memset(g_cdc_acm_buf, 'a', sizeof(g_cdc_acm_buf)); - ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, g_cdc_acm_buf, sizeof(g_cdc_acm_buf), 0xfffffff); - USB_LOG_RAW("out ret:%d\r\n", ret); - while (count--) { - ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, g_cdc_acm_buf, sizeof(g_cdc_acm_buf), 0xfffffff); - USB_LOG_RAW("in ret:%d\r\n", ret); - if (ret > 0) { - for (uint32_t i = 0; i < ret; i++) { - USB_LOG_RAW("%02x ", g_cdc_acm_buf[i]); - } - } - USB_LOG_RAW("\r\n"); - } -#endif - - usbh_cdc_acm_run(cdc_acm_class); - return ret; -} - -static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv; - - if (cdc_acm_class) { - if (cdc_acm_class->bulkin) { - usbh_kill_urb(&cdc_acm_class->bulkin_urb); - } - - if (cdc_acm_class->bulkout) { - usbh_kill_urb(&cdc_acm_class->bulkout_urb); - } - -#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY - if (cdc_acm_class->intin) { - usbh_kill_urb(&cdc_acm_class->intin_urb); - } -#endif - - if (hport->config.intf[intf].devname[0] != '\0') { - usb_osal_thread_schedule_other(); - USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname); - usbh_cdc_acm_stop(cdc_acm_class); - } - - usbh_cdc_acm_class_free(cdc_acm_class); - } - - return ret; -} - -int usbh_cdc_acm_bulk_in_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &cdc_acm_class->bulkin_urb; - - usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &cdc_acm_class->bulkout_urb; - - usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf) -{ - (void)hport; - (void)intf; - return 0; -} - -static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - (void)hport; - (void)intf; - return 0; -} - -__WEAK void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class) -{ - (void)cdc_acm_class; -} - -__WEAK void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class) -{ - (void)cdc_acm_class; -} - -const struct usbh_class_driver cdc_acm_class_driver = { - .driver_name = "cdc_acm", - .connect = usbh_cdc_acm_connect, - .disconnect = usbh_cdc_acm_disconnect -}; - -const struct usbh_class_driver cdc_data_class_driver = { - .driver_name = "cdc_data", - .connect = usbh_cdc_data_connect, - .disconnect = usbh_cdc_data_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = { - .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, - .bInterfaceClass = USB_DEVICE_CLASS_CDC, - .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL, - .bInterfaceProtocol = 0x00, - .id_table = NULL, - .class_driver = &cdc_acm_class_driver -}; - -CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = { - .match_flags = USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = USB_DEVICE_CLASS_CDC_DATA, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .id_table = NULL, - .class_driver = &cdc_data_class_driver -}; diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.h b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.h deleted file mode 100644 index 80800bf9f22..00000000000 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2022, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_CDC_ACM_H -#define USBH_CDC_ACM_H - -#include "usb_cdc.h" - -struct usbh_cdc_acm { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ -#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY - struct usb_endpoint_descriptor *intin; /* INTR IN endpoint (optional) */ -#endif - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; -#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY - struct usbh_urb intin_urb; -#endif - - struct cdc_line_coding linecoding; - - uint8_t intf; - uint8_t minor; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding); -int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding); -int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts); - -int usbh_cdc_acm_bulk_in_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); -int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); - -void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class); -void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_CDC_ACM_H */ diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c index 73eaa430e90..0c64ff11bd4 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c @@ -306,16 +306,6 @@ int usbh_cdc_ecm_eth_output(uint32_t buflen) return usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb); } -__WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) -{ - (void)cdc_ecm_class; -} - -__WEAK void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class) -{ - (void)cdc_ecm_class; -} - const struct usbh_class_driver cdc_ecm_class_driver = { .driver_name = "cdc_ecm", .connect = usbh_cdc_ecm_connect, diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c index 2ee6e4cece9..fa2ccc0cc86 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c @@ -386,16 +386,6 @@ int usbh_cdc_ncm_eth_output(uint32_t buflen) return usbh_submit_urb(&g_cdc_ncm_class.bulkout_urb); } -__WEAK void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class) -{ - (void)cdc_ncm_class; -} - -__WEAK void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class) -{ - (void)cdc_ncm_class; -} - const struct usbh_class_driver cdc_ncm_class_driver = { .driver_name = "cdc_ncm", .connect = usbh_cdc_ncm_connect, diff --git a/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c b/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c index a870aee3a94..2da382884b8 100644 --- a/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c +++ b/components/drivers/usb/cherryusb/class/dfu/usbd_dfu.c @@ -106,7 +106,6 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u { struct usb_setup_packet *req = setup; uint32_t addr; - uint8_t *phaddr; /* 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)) { @@ -143,7 +142,7 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u addr = ((g_usbd_dfu.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + g_usbd_dfu.data_ptr; /* Return the physical address where data are stored */ - phaddr = dfu_read_flash((uint8_t *)addr, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength); + 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); diff --git a/components/drivers/usb/cherryusb/class/gamepad/usb_gamepad.h b/components/drivers/usb/cherryusb/class/gamepad/usb_gamepad.h new file mode 100644 index 00000000000..28e2e6465d6 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/gamepad/usb_gamepad.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USB_GAMEPAD_H +#define USB_GAMEPAD_H + +#include "usb_hid.h" + +/* + * GAMEPAD BUTTON LAYOUT + * + * ____________________________ __ + * / [__L2__] [__R2__] \ | + * / [__ L1 __] [__ R1 __] \ | Triggers + * __/________________________________\__ __| + * / _ \ | + * / /\ __ (B4) \ | + * / || __ |A1| __ _ _ \ | Main Pad + * | <===DP===> |S1| |S2| (B3) -|- (B2)| | + * \ || ¯¯ ¯¯ _ / | + * /\ \/ / \ / \ (B1) /\ __| + * / \________ | LS | ____ | RS | _______/ \ | + * | / \ \___/ / \ \___/ / \ | | Sticks + * | / \_____/ \_____/ \ | __| + * | / L3 R3 \ | + * \_____/ \_____/ + * + * |________|______| |______|___________| + * D-Pad Left Right Face + * Stick Stick Buttons + * + * Extended: A2=Touchpad/Capture A3=Mute L4/R4=Paddles + */ + +// W3C Gamepad API standard button order +// Bit position = W3C button index (trivial conversion: 1 << index) +// +// Gamepad XInput Switch PS3/4/5 DInput +// ------ ------ ------ ------- ------ + +// Face buttons (right cluster) +#define USB_GAMEPAD_BUTTON_B1 (1 << 0) // A B Cross 2 +#define USB_GAMEPAD_BUTTON_B2 (1 << 1) // B A Circle 3 +#define USB_GAMEPAD_BUTTON_B3 (1 << 2) // X Y Square 1 +#define USB_GAMEPAD_BUTTON_B4 (1 << 3) // Y X Triangle 4 + +// Shoulder buttons +#define USB_GAMEPAD_BUTTON_L1 (1 << 4) // LB L L1 5 +#define USB_GAMEPAD_BUTTON_R1 (1 << 5) // RB R R1 6 +#define USB_GAMEPAD_BUTTON_L2 (1 << 6) // LT ZL L2 7 +#define USB_GAMEPAD_BUTTON_R2 (1 << 7) // RT ZR R2 8 + +// Center cluster +#define USB_GAMEPAD_BUTTON_S1 (1 << 8) // Back - Select 9 +#define USB_GAMEPAD_BUTTON_S2 (1 << 9) // Start + Start 10 + +// Stick clicks +#define USB_GAMEPAD_BUTTON_L3 (1 << 10) // LS LS L3 11 +#define USB_GAMEPAD_BUTTON_R3 (1 << 11) // RS RS R3 12 + +// D-pad +#define USB_GAMEPAD_BUTTON_DU (1 << 12) // D-Up D-Up D-Up Hat +#define USB_GAMEPAD_BUTTON_DD (1 << 13) // D-Down D-Down D-Down Hat +#define USB_GAMEPAD_BUTTON_DL (1 << 14) // D-Left D-Left D-Left Hat +#define USB_GAMEPAD_BUTTON_DR (1 << 15) // D-Right D-Right D-Right Hat + +// Auxiliary +#define USB_GAMEPAD_BUTTON_A1 (1 << 16) // Guide Home PS 13 +#define USB_GAMEPAD_BUTTON_A2 (1 << 17) // - Capture Touchpad 14 +#define USB_GAMEPAD_BUTTON_A3 (1 << 18) // - - Mute - +#define USB_GAMEPAD_BUTTON_A4 (1 << 19) // - - - - + +// Paddles (extended) +#define USB_GAMEPAD_BUTTON_L4 (1 << 20) // P1 - - - +#define USB_GAMEPAD_BUTTON_R4 (1 << 21) // P2 - - - + +#define XINPUT_VID 0x045E // Microsoft +#define XINPUT_PID 0x028E // Xbox 360 Controller +#define XINPUT_BCD_DEVICE 0x0114 // v1.14 + +/* XInput (Xbox 360) USB */ + +// XInput Interface Class/Subclass/Protocol +#define XINPUT_INTERFACE_CLASS 0xFF +#define XINPUT_INTERFACE_SUBCLASS 0x5D +#define XINPUT_INTERFACE_PROTOCOL 0x01 + +#define XINPUT_BUTTON_MASK_UP (1U << 0) +#define XINPUT_BUTTON_MASK_DOWN (1U << 1) +#define XINPUT_BUTTON_MASK_LEFT (1U << 2) +#define XINPUT_BUTTON_MASK_RIGHT (1U << 3) +#define XINPUT_BUTTON_MASK_START (1U << 4) +#define XINPUT_BUTTON_MASK_BACK (1U << 5) +#define XINPUT_BUTTON_MASK_L3 (1U << 6) +#define XINPUT_BUTTON_MASK_R3 (1U << 7) +#define XINPUT_BUTTON_MASK_LB (1U << 8) +#define XINPUT_BUTTON_MASK_RB (1U << 9) +#define XINPUT_BUTTON_MASK_GUIDE (1U << 10) +//#define XINPUT_BUTTON_MASK_UNUSED (1U << 11) +#define XINPUT_BUTTON_MASK_A (1U << 12) +#define XINPUT_BUTTON_MASK_B (1U << 13) +#define XINPUT_BUTTON_MASK_X (1U << 14) +#define XINPUT_BUTTON_MASK_Y (1U << 15) + +// LED patterns for report_id 0x01 +#define XINPUT_LED_OFF 0x00 +#define XINPUT_LED_BLINK 0x01 +#define XINPUT_LED_FLASH_1 0x02 +#define XINPUT_LED_FLASH_2 0x03 +#define XINPUT_LED_FLASH_3 0x04 +#define XINPUT_LED_FLASH_4 0x05 +#define XINPUT_LED_ON_1 0x06 +#define XINPUT_LED_ON_2 0x07 +#define XINPUT_LED_ON_3 0x08 +#define XINPUT_LED_ON_4 0x09 +#define XINPUT_LED_ROTATE 0x0A +#define XINPUT_LED_BLINK_SLOW 0x0B +#define XINPUT_LED_BLINK_SLOW_1 0x0C +#define XINPUT_LED_BLINK_SLOW_2 0x0D + +struct xinput_in_report { + uint8_t report_id; /* Always 0x00 */ + uint8_t report_size; /* Always 0x14 (20) */ + uint16_t buttons; /* DPAD, Start, Back, L3, R3, LB, RB, Guide, A, B, X, Y */ + uint8_t lt; /* Left trigger (0-255) */ + uint8_t rt; /* Right trigger (0-255) */ + int16_t lx; /* Left stick X (-32768 to 32767) */ + int16_t ly; /* Left stick Y (-32768 to 32767) */ + int16_t rx; /* Right stick X (-32768 to 32767) */ + int16_t ry; /* Right stick Y (-32768 to 32767) */ + uint8_t reserved[6]; /* Reserved/padding */ +} __PACKED; + +struct xinput_out_report { + uint8_t report_id; // 0x00 = rumble, 0x01 = LED + uint8_t report_size; // 0x08 + uint8_t led; // LED pattern (0x00 for rumble) + uint8_t rumble_l; // Left motor (large, 0-255) + uint8_t rumble_r; // Right motor (small, 0-255) + uint8_t reserved[3]; // Padding +} __PACKED; + +// clang-format off +#define XINPUT_DESCRIPTOR_LEN (9 + 16 + 7 + 7) + +#define XINPUT_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep) \ + USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, 0x02, 0xff, 0x5d, 0x01, 0x00), /* XInput proprietary descriptor (0x21) */ \ + 16, 0x21, 0x00, 0x01, 0x01, 0x24, in_ep, 0x14, 0x03, 0x00, 0x03, 0x13, out_ep, 0x00, 0x03, 0x00, \ + USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x03, 32, 0x01), \ + USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x03, 32, 0x08) +// clang-format on + +#define SWITCH_VID 0x0F0D // 0x057E Nintendo Pro Controller +#define SWITCH_PID 0x0092 // 0x2009 +#define SWITCH_BCD_DEVICE 0x0100 // v1.00 + +// Button masks (16-bit) +#define SWITCH_MASK_Y (1U << 0) +#define SWITCH_MASK_B (1U << 1) +#define SWITCH_MASK_A (1U << 2) +#define SWITCH_MASK_X (1U << 3) +#define SWITCH_MASK_L (1U << 4) +#define SWITCH_MASK_R (1U << 5) +#define SWITCH_MASK_ZL (1U << 6) +#define SWITCH_MASK_ZR (1U << 7) +#define SWITCH_MASK_MINUS (1U << 8) +#define SWITCH_MASK_PLUS (1U << 9) +#define SWITCH_MASK_L3 (1U << 10) +#define SWITCH_MASK_R3 (1U << 11) +#define SWITCH_MASK_HOME (1U << 12) +#define SWITCH_MASK_CAPTURE (1U << 13) + +// D-pad / Hat switch values +#define SWITCH_HAT_UP 0x00 +#define SWITCH_HAT_UP_RIGHT 0x01 +#define SWITCH_HAT_RIGHT 0x02 +#define SWITCH_HAT_DOWN_RIGHT 0x03 +#define SWITCH_HAT_DOWN 0x04 +#define SWITCH_HAT_DOWN_LEFT 0x05 +#define SWITCH_HAT_LEFT 0x06 +#define SWITCH_HAT_UP_LEFT 0x07 +#define SWITCH_HAT_CENTER 0x08 + +// Analog stick range +#define SWITCH_JOYSTICK_MIN 0x00 +#define SWITCH_JOYSTICK_MID 0x80 +#define SWITCH_JOYSTICK_MAX 0xFF + +struct switch_in_report { + uint16_t buttons; // 16 button bits + uint8_t hat; // D-pad (hat switch, 0-8) + uint8_t lx; // Left stick X (0-255, 128 = center) + uint8_t ly; // Left stick Y (0-255, 128 = center) + uint8_t rx; // Right stick X (0-255, 128 = center) + uint8_t ry; // Right stick Y (0-255, 128 = center) + uint8_t vendor; // Vendor-specific byte +} __PACKED; + +struct switch_out_report { + uint8_t data[8]; // Vendor-specific rumble data +} __PACKED; + +#define HID_SWITCH_REPORT_DESC_SIZE 86 + +// clang-format off +#define SWITCH_DESCRIPTOR_LEN HID_CUSTOM_INOUT_DESCRIPTOR_LEN + +#define SWITCH_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep) \ + HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, HID_SWITCH_REPORT_DESC_SIZE, out_ep, in_ep, 64, 0x01) +// clang-format on + +struct usb_gamepad_report { + uint32_t buttons; + uint8_t lt; + uint8_t rt; + uint8_t lx; + uint8_t ly; + uint8_t rx; + uint8_t ry; +}; + +#endif /* USB_GAMEPAD_H */ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c b/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c new file mode 100644 index 00000000000..8ffbfda8a3a --- /dev/null +++ b/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" +#include "usbd_hid.h" +#include "usbd_gamepad.h" + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t gamepad_report_buffer[64]; + +static int xinput_vendor_class_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) +{ + struct xinput_in_report xinput_report; + + memset(&xinput_report, 0, sizeof(xinput_report)); + xinput_report.report_size = 20; + + memcpy(*data, &xinput_report, sizeof(xinput_report)); + *len = sizeof(xinput_report); + return 0; +} + +int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *report) +{ + struct xinput_in_report *xinput_report; + + xinput_report = (struct xinput_in_report *)gamepad_report_buffer; + memset(xinput_report, 0, sizeof(xinput_report)); + xinput_report->report_size = 20; + + if (report->buttons & USB_GAMEPAD_BUTTON_DU) + xinput_report->buttons |= XINPUT_BUTTON_MASK_UP; + if (report->buttons & USB_GAMEPAD_BUTTON_DD) + xinput_report->buttons |= XINPUT_BUTTON_MASK_DOWN; + if (report->buttons & USB_GAMEPAD_BUTTON_DL) + xinput_report->buttons |= XINPUT_BUTTON_MASK_LEFT; + if (report->buttons & USB_GAMEPAD_BUTTON_DR) + xinput_report->buttons |= XINPUT_BUTTON_MASK_RIGHT; + if (report->buttons & USB_GAMEPAD_BUTTON_S2) + xinput_report->buttons |= XINPUT_BUTTON_MASK_START; + if (report->buttons & USB_GAMEPAD_BUTTON_S1) + xinput_report->buttons |= XINPUT_BUTTON_MASK_BACK; + if (report->buttons & USB_GAMEPAD_BUTTON_L3) + xinput_report->buttons |= XINPUT_BUTTON_MASK_L3; + if (report->buttons & USB_GAMEPAD_BUTTON_R3) + xinput_report->buttons |= XINPUT_BUTTON_MASK_R3; + if (report->buttons & USB_GAMEPAD_BUTTON_L1) + xinput_report->buttons |= XINPUT_BUTTON_MASK_LB; + if (report->buttons & USB_GAMEPAD_BUTTON_R1) + xinput_report->buttons |= XINPUT_BUTTON_MASK_RB; + if (report->buttons & USB_GAMEPAD_BUTTON_A1) + xinput_report->buttons |= XINPUT_BUTTON_MASK_GUIDE; + if (report->buttons & USB_GAMEPAD_BUTTON_B1) + xinput_report->buttons |= XINPUT_BUTTON_MASK_A; + if (report->buttons & USB_GAMEPAD_BUTTON_B2) + xinput_report->buttons |= XINPUT_BUTTON_MASK_B; + if (report->buttons & USB_GAMEPAD_BUTTON_B3) + xinput_report->buttons |= XINPUT_BUTTON_MASK_X; + if (report->buttons & USB_GAMEPAD_BUTTON_B4) + xinput_report->buttons |= XINPUT_BUTTON_MASK_Y; + + // Analog triggers (0-255), fall back to digital if analog is 0 but button pressed + xinput_report->lt = report->lt; + xinput_report->rt = report->rt; + if (xinput_report->lt == 0 && (report->buttons & USB_GAMEPAD_BUTTON_L2)) + xinput_report->lt = 0xFF; + if (xinput_report->rt == 0 && (report->buttons & USB_GAMEPAD_BUTTON_R2)) + xinput_report->rt = 0xFF; + + return usbd_ep_start_write(0, ep, gamepad_report_buffer, sizeof(struct xinput_in_report)); +} + +// Convert gamepad dpad mask to switch hat value +static uint8_t convert_dpad_to_switch_hat(uint32_t buttons) +{ + // Joypad uses active-high (1 = pressed) + uint8_t up = (buttons & USB_GAMEPAD_BUTTON_DU) ? 1 : 0; + uint8_t down = (buttons & USB_GAMEPAD_BUTTON_DD) ? 1 : 0; + uint8_t left = (buttons & USB_GAMEPAD_BUTTON_DL) ? 1 : 0; + uint8_t right = (buttons & USB_GAMEPAD_BUTTON_DR) ? 1 : 0; + + if (up && right) + return SWITCH_HAT_UP_RIGHT; + if (up && left) + return SWITCH_HAT_UP_LEFT; + if (down && right) + return SWITCH_HAT_DOWN_RIGHT; + if (down && left) + return SWITCH_HAT_DOWN_LEFT; + if (up) + return SWITCH_HAT_UP; + if (down) + return SWITCH_HAT_DOWN; + if (left) + return SWITCH_HAT_LEFT; + if (right) + return SWITCH_HAT_RIGHT; + + return SWITCH_HAT_CENTER; +} + +int usbd_gamepad_switch_send_report(uint8_t ep, struct usb_gamepad_report *report) +{ + struct switch_in_report *switch_report; + + switch_report = (struct switch_in_report *)gamepad_report_buffer; + memset(switch_report, 0, sizeof(switch_report)); + + if (report->buttons & USB_GAMEPAD_BUTTON_S1) + switch_report->buttons |= SWITCH_MASK_MINUS; + if (report->buttons & USB_GAMEPAD_BUTTON_S2) + switch_report->buttons |= SWITCH_MASK_PLUS; + if (report->buttons & USB_GAMEPAD_BUTTON_L1) + switch_report->buttons |= SWITCH_MASK_L; + if (report->buttons & USB_GAMEPAD_BUTTON_R1) + switch_report->buttons |= SWITCH_MASK_R; + if (report->buttons & USB_GAMEPAD_BUTTON_L2) + switch_report->buttons |= SWITCH_MASK_ZL; + if (report->buttons & USB_GAMEPAD_BUTTON_R2) + switch_report->buttons |= SWITCH_MASK_ZR; + if (report->buttons & USB_GAMEPAD_BUTTON_L3) + switch_report->buttons |= SWITCH_MASK_L3; + if (report->buttons & USB_GAMEPAD_BUTTON_R3) + switch_report->buttons |= SWITCH_MASK_R3; + if (report->buttons & USB_GAMEPAD_BUTTON_A1) + switch_report->buttons |= SWITCH_MASK_HOME; + if (report->buttons & USB_GAMEPAD_BUTTON_A2) + switch_report->buttons |= SWITCH_MASK_CAPTURE; + if (report->buttons & USB_GAMEPAD_BUTTON_B1) + switch_report->buttons |= SWITCH_MASK_B; + if (report->buttons & USB_GAMEPAD_BUTTON_B2) + switch_report->buttons |= SWITCH_MASK_A; + if (report->buttons & USB_GAMEPAD_BUTTON_B3) + switch_report->buttons |= SWITCH_MASK_Y; + if (report->buttons & USB_GAMEPAD_BUTTON_B4) + switch_report->buttons |= SWITCH_MASK_X; + + switch_report->hat = convert_dpad_to_switch_hat(report->buttons); + + // Analog sticks (HID convention: 0=up, 255=down - no inversion needed) + switch_report->lx = report->lx; + switch_report->ly = report->ly; + switch_report->rx = report->rx; + switch_report->ry = report->ry; + + switch_report->vendor = 0; + + return usbd_ep_start_write(0, ep, gamepad_report_buffer, sizeof(struct switch_in_report)); +} + +struct usbd_interface *usbd_gamepad_xinput_init_intf(struct usbd_interface *intf) +{ + intf->class_interface_handler = NULL; + intf->class_endpoint_handler = NULL; + intf->vendor_handler = xinput_vendor_class_request_handler; + intf->notify_handler = NULL; + + return intf; +} + +static const uint8_t hid_switch_report_desc[HID_SWITCH_REPORT_DESC_SIZE] = { + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x05, // Usage (Game Pad) + 0xA1, 0x01, // Collection (Application) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x35, 0x00, // Physical Minimum (0) + 0x45, 0x01, // Physical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x10, // Report Count (16) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button 1) + 0x29, 0x10, // Usage Maximum (Button 16) + 0x81, 0x02, // Input (Data,Var,Abs) + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x25, 0x07, // Logical Maximum (7) + 0x46, 0x3B, 0x01, // Physical Maximum (315) + 0x75, 0x04, // Report Size (4) + 0x95, 0x01, // Report Count (1) + 0x65, 0x14, // Unit (Eng Rot:Angular Pos) + 0x09, 0x39, // Usage (Hat switch) + 0x81, 0x42, // Input (Data,Var,Abs,Null) + 0x65, 0x00, // Unit (None) + 0x95, 0x01, // Report Count (1) + 0x81, 0x01, // Input (Const) - 4-bit padding + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x46, 0xFF, 0x00, // Physical Maximum (255) + 0x09, 0x30, // Usage (X) - Left Stick X + 0x09, 0x31, // Usage (Y) - Left Stick Y + 0x09, 0x32, // Usage (Z) - Right Stick X + 0x09, 0x35, // Usage (Rz) - Right Stick Y + 0x75, 0x08, // Report Size (8) + 0x95, 0x04, // Report Count (4) + 0x81, 0x02, // Input (Data,Var,Abs) + 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined) + 0x09, 0x20, // Usage (0x20) + 0x95, 0x01, // Report Count (1) + 0x81, 0x02, // Input (Data,Var,Abs) - Vendor byte + 0x0A, 0x21, 0x26, // Usage (0x2621) + 0x95, 0x08, // Report Count (8) + 0x91, 0x02, // Output (Data,Var,Abs) - Rumble + 0xC0, // End Collection +}; + +struct usbd_interface *usbd_gamepad_switch_init_intf(struct usbd_interface *intf) +{ + return usbd_hid_init_intf(0, intf, hid_switch_report_desc, HID_SWITCH_REPORT_DESC_SIZE); +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.h b/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.h new file mode 100644 index 00000000000..8f4f20a8330 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/gamepad/usbd_gamepad.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBD_GAMEPAD_H +#define USBD_GAMEPAD_H + +#include "usb_gamepad.h" + +#define USBD_GAMEPAD_MODE_XINPUT 0 +#define USBD_GAMEPAD_MODE_SWITCH 1 +#define USBD_GAMEPAD_MODE_XBOXONE 2 +#define USBD_GAMEPAD_MODE_PS4 3 + +struct usbd_interface *usbd_gamepad_xinput_init_intf(struct usbd_interface *intf); +struct usbd_interface *usbd_gamepad_switch_init_intf(struct usbd_interface *intf); + +int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *report); +int usbd_gamepad_switch_send_report(uint8_t ep, struct usb_gamepad_report *report); + +#endif /* USBD_GAMEPAD_H */ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/hid/usb_hid.h b/components/drivers/usb/cherryusb/class/hid/usb_hid.h index ea6c0f2556e..b2bd5713300 100644 --- a/components/drivers/usb/cherryusb/class/hid/usb_hid.h +++ b/components/drivers/usb/cherryusb/class/hid/usb_hid.h @@ -35,7 +35,7 @@ #define HID_REPORT_OUTPUT 0x02 #define HID_REPORT_FEATURE 0x03 -/* HID Descriptor ***********************************************************/ +/* HID Descriptor */ #define HID_COUNTRY_NONE 0x00 /* Not Supported */ #define HID_COUNTRY_ARABIC 0x01 /* Arabic */ @@ -74,99 +74,114 @@ #define HID_COUNTRY_YUGOSLAVIA 0x34 /* Yugoslavia */ #define HID_COUNTRY_TURKISHF 0x35 /* Turkish-F */ -/* HID report items */ -#define HID_REPORT_ITEM_SIZE_MASK 0x03 -#define HID_REPORT_ITEM_SIZE_0 0x00 /* No data follows */ -#define HID_REPORT_ITEM_SIZE_1 0x01 /* 1 byte of data follows */ -#define HID_REPORT_ITEM_SIZE_2 0x02 /* 2 bytes of data follow */ -#define HID_REPORT_ITEM_SIZE_4 0x03 /* 4 bytes of data follow */ -#define HID_REPORT_ITEM_TYPE_MASK 0x0c -#define HID_REPORT_ITEM_TYPE_MAIN 0x00 -#define HID_REPORT_ITEM_TYPE_GLOBAL 0x04 -#define HID_REPORT_ITEM_TYPE_LOCAL 0x08 -#define HID_REPORT_ITEM_TAG_MASK 0xf0 +/* HID report See specification at + * https://www.usb.org/sites/default/files/hid1_11.pdf + * https://www.usb.org/sites/default/files/hut1_22.pdf + */ + +#define HID_SIZE_MASK (0x3 << 0) +#define HID_TYPE_MASK (0x3 << 2) +#define HID_TAG_MASK (0xF << 4) + +#define HID_ITEMTYPE_MAIN (0x0 << 2) +#define HID_ITEMTYPE_GLOBAL (0x1 << 2) +#define HID_ITEMTYPE_LOCAL (0x2 << 2) +#define HID_ITEMTYPE_LONG (0x3 << 2) /* Main Items (HID 6.2.2.4) */ -#define HID_MAIN_ITEM_CONSTANT (1 << 0) /* Constant(1) vs Data(0) */ -#define HID_MAIN_ITEM_VARIABLE (1 << 1) /* Variable(1) vs Array(0) */ -#define HID_MAIN_ITEM_RELATIVE (1 << 2) /* Relative(1) vs Absolute(0) */ -#define HID_MAIN_ITEM_WRAP (1 << 3) /* Wrap(1) vs No Wrap(0) */ -#define HID_MAIN_ITEM_NONLINEAR (1 << 4) /* Non Linear(1) vs Linear(0) */ -#define HID_MAIN_ITEM_NOPREFERRED (1 << 5) /* No Preferred (1) vs Preferred State(0) */ -#define HID_MAIN_ITEM_NULLSTATE (1 << 6) /* Null state(1) vs No Null position(0) */ -#define HID_MAIN_ITEM_VOLATILE (1 << 7) /* Volatile(1) vs Non volatile(0) */ -#define HID_MAIN_ITEM_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */ - -#define HID_MAIN_ITEM_SIZE(pfx) ((pfx)&HID_REPORT_ITEM_SIZE_MASK) -#define HID_MAIN_ITEM_INPUT_PREFIX 0x80 -#define HID_MAIN_ITEM_INPUT_CONSTANT HID_MAIN_ITEM_CONSTANT -#define HID_MAIN_ITEM_INPUT_VARIABLE HID_MAIN_ITEM_VARIABLE -#define HID_MAIN_ITEM_INPUT_RELATIVE HID_MAIN_ITEM_RELATIVE -#define HID_MAIN_ITEM_INPUT_WRAP HID_MAIN_ITEM_WRAP -#define HID_MAIN_ITEM_INPUT_NONLINEAR HID_MAIN_ITEM_NONLINEAR -#define HID_MAIN_ITEM_INPUT_NOPREFERRED HID_MAIN_ITEM_NOPREFERRED -#define HID_MAIN_ITEM_INPUT_NULLSTATE HID_MAIN_ITEM_NULLSTATE -#define HID_MAIN_ITEM_INPUT_BUFFEREDBYTES HID_MAIN_ITEM_BUFFEREDBYTES - -#define HID_MAIN_ITEM_OUTPUT_PREFIX 0x90 -#define HID_MAIN_ITEM_OUTPUT_CONSTANT HID_MAIN_ITEM_CONSTANT -#define HID_MAIN_ITEM_OUTPUT_VARIABLE HID_MAIN_ITEM_VARIABLE -#define HID_MAIN_ITEM_OUTPUT_RELATIVE HID_MAIN_ITEM_RELATIVE -#define HID_MAIN_ITEM_OUTPUT_WRAP HID_MAIN_ITEM_WRAP -#define HID_MAIN_ITEM_OUTPUT_NONLINEAR HID_MAIN_ITEM_NONLINEAR -#define HID_MAIN_ITEM_OUTPUT_NOPREFERRED HID_MAIN_ITEM_NOPREFERRED -#define HID_MAIN_ITEM_OUTPUT_NULLSTATE HID_MAIN_ITEM_NULLSTATE -#define HID_MAIN_ITEM_OUTPUT_VOLATILE HID_MAIN_ITEM_VOLATILE -#define HID_MAIN_ITEM_OUTPUT_BUFFEREDBYTES HID_MAIN_ITEM_BUFFEREDBYTES - -#define HID_MAIN_ITEM_FEATURE_PREFIX 0xb0 -#define HID_MAIN_ITEM_FEATURE_CONSTANT HID_MAIN_ITEM_CONSTANT -#define HID_MAIN_ITEM_FEATURE_VARIABLE HID_MAIN_ITEM_VARIABLE -#define HID_MAIN_ITEM_FEATURE_RELATIVE HID_MAIN_ITEM_RELATIVE -#define HID_MAIN_ITEM_FEATURE_WRAP HID_MAIN_ITEM_WRAP -#define HID_MAIN_ITEM_FEATURE_NONLINEAR HID_MAIN_ITEM_NONLINEAR -#define HID_MAIN_ITEM_FEATURE_NOPREFERRED HID_MAIN_ITEM_NOPREFERRED -#define HID_MAIN_ITEM_FEATURE_NULLSTATE HID_MAIN_ITEM_NULLSTATE -#define HID_MAIN_ITEM_FEATURE_VOLATILE HID_MAIN_ITEM_VOLATILE -#define HID_MAIN_ITEM_FEATURE_BUFFEREDBYTES HID_MAIN_ITEM_BUFFEREDBYTES - -#define HID_MAIN_ITEM_COLLECTION_PREFIX 0xa0 -#define HID_MAIN_ITEM_COLLECTION_PHYSICAL 0x00 /* Physical (group of axes) */ -#define HID_MAIN_ITEM_COLLECTION_APPL 0x01 /* Application (mouse, keyboard) */ -#define HID_MAIN_ITEM_COLLECTION_LOGICAL 0x02 /* Logical (interrelated data) */ -#define HID_MAIN_ITEM_COLLECTION_REPORT 0x03 /* Report */ -#define HID_MAIN_ITEM_COLLECTION_ARRAY 0x04 /* Named Array */ -#define HID_MAIN_ITEM_COLLECTION_SWITCH 0x05 /* Usage Switch */ -#define HID_MAIN_ITEM_COLLECTION_MODIFIER 0x06 /* Usage Modifier */ -#define HID_MAIN_ITEM_ENDCOLLECTION_PREFIX 0xc0 +#define HID_MAINITEM_TAG_INPUT (0x08 << 4) +#define HID_MAINITEM_TAG_OUTPUT (0x09 << 4) +#define HID_MAINITEM_TAG_COLLECTION (0x0a << 4) +#define HID_MAINITEM_TAG_FEATURE (0x0b << 4) +#define HID_MAINITEM_TAG_ENDCOLLECTION (0x0c << 4) + +#define HID_MAINITEM_CONSTANT (1 << 0) /* Constant(1) vs Data(0) */ +#define HID_MAINITEM_VARIABLE (1 << 1) /* Variable(1) vs Array(0) */ +#define HID_MAINITEM_RELATIVE (1 << 2) /* Relative(1) vs Absolute(0) */ +#define HID_MAINITEM_WRAP (1 << 3) /* Wrap(1) vs No Wrap(0) */ +#define HID_MAINITEM_NONLINEAR (1 << 4) /* Non Linear(1) vs Linear(0) */ +#define HID_MAINITEM_NOPREFERRED (1 << 5) /* No Preferred (1) vs Preferred State(0) */ +#define HID_MAINITEM_NULLSTATE (1 << 6) /* Null state(1) vs No Null position(0) */ +#define HID_MAINITEM_VOLATILE (1 << 7) /* Volatile(1) vs Non volatile(0) */ +#define HID_MAINITEM_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */ + +#define HID_MAINITEM_COLLECTION_PHYSICAL 0x00 /* Physical (group of axes) */ +#define HID_MAINITEM_COLLECTION_APPL 0x01 /* Application (mouse, keyboard) */ +#define HID_MAINITEM_COLLECTION_LOGICAL 0x02 /* Logical (interrelated data) */ +#define HID_MAINITEM_COLLECTION_REPORT 0x03 /* Report */ +#define HID_MAINITEM_COLLECTION_ARRAY 0x04 /* Named Array */ +#define HID_MAINITEM_COLLECTION_SWITCH 0x05 /* Usage Switch */ +#define HID_MAINITEM_COLLECTION_MODIFIER 0x06 /* Usage Modifier */ /* Global Items (HID 6.2.2.7) */ -#define HID_GLOBAL_ITEM_SIZE(pfx) ((pfx)&HID_REPORT_ITEM_SIZE_MASK) -#define HID_GLOBAL_ITEM_USAGEPAGE_PREFIX 0x04 /* Usage Page */ -#define HID_GLOBAL_ITEM_LOGICALMIN_PREFIX 0x14 /* Logical Minimum */ -#define HID_GLOBAL_ITEM_LOGICALMAX_PREFIX 0x24 /* Logical Maximum */ -#define HID_GLOBAL_ITEM_PHYSICALMIN_PREFIX 0x34 /* Physical Minimum */ -#define HID_GLOBAL_ITEM_PHYSMICALAX_PREFIX 0x44 /* Physical Maximum */ -#define HID_GLOBAL_ITEM_UNITEXP_PREFIX 0x54 /* Unit Exponent */ -#define HID_GLOBAL_ITEM_UNIT_PREFIX 0x64 /* Unit */ -#define HID_GLOBAL_ITEM_REPORTSIZE_PREFIX 0x74 /* Report Size */ -#define HID_GLOBAL_ITEM_REPORTID_PREFIX 0x84 /* Report ID */ -#define HID_GLOBAL_ITEM_REPORTCOUNT_PREFIX 0x94 /* Report Count */ -#define HID_GLOBAL_ITEM_PUSH_PREFIX 0xa4 /* Push */ -#define HID_GLOBAL_ITEM_POP_PREFIX 0xb4 /* Pop */ +#define HID_GLOBALITEM_TAG_USAGE_PAGE (0x00 << 4) +#define HID_GLOBALITEM_TAG_LOGICAL_MIN (0x01 << 4) +#define HID_GLOBALITEM_TAG_LOGICAL_MAX (0x02 << 4) +#define HID_GLOBALITEM_TAG_PHYSICAL_MIN (0x03 << 4) +#define HID_GLOBALITEM_TAG_PHYSICAL_MAX (0x04 << 4) +#define HID_GLOBALITEM_TAG_UNIT_EXP (0x05 << 4) +#define HID_GLOBALITEM_TAG_UNIT (0x06 << 4) +#define HID_GLOBALITEM_TAG_REPORT_SIZE (0x07 << 4) +#define HID_GLOBALITEM_TAG_REPORT_ID (0x08 << 4) +#define HID_GLOBALITEM_TAG_REPORT_COUNT (0x09 << 4) +#define HID_GLOBALITEM_TAG_PUSH (0x0a << 4) +#define HID_GLOBALITEM_TAG_POP (0x0b << 4) /* Local Items (HID 6.2.2.8) */ -#define HID_LOCAL_ITEM_SIZE(pfx) ((pfx)&HID_REPORT_ITEM_SIZE_MASK) -#define HID_LOCAL_ITEM_USAGE_PREFIX 0x08 /* Usage */ -#define HID_LOCAL_ITEM_USAGEMIN_PREFIX 0x18 /* Usage Minimum */ -#define HID_LOCAL_ITEM_USAGEMAX_PREFIX 0x28 /* Usage Maximum */ -#define HID_LOCAL_ITEM_DESIGNATORIDX_PREFIX 0x38 /* Designator Index */ -#define HID_LOCAL_ITEM_DESIGNATORMIN_PREFIX 0x48 /* Designator Minimum */ -#define HID_LOCAL_ITEM_DESIGNATORMAX_PREFIX 0x58 /* Designator Maximum */ -#define HID_LOCAL_ITEM_STRINGIDX_PREFIX 0x78 /* String Index */ -#define HID_LOCAL_ITEM_STRINGMIN_PREFIX 0x88 /* String Minimum */ -#define HID_LOCAL_ITEM_STRINGMAX_PREFIX 0x98 /* xx */ -#define HID_LOCAL_ITEM_DELIMITER_PREFIX 0xa8 /* Delimiter */ +#define HID_LOCALITEM_TAG_USAGE (0x00 << 4) +#define HID_LOCALITEM_TAG_USAGE_MIN (0x01 << 4) +#define HID_LOCALITEM_TAG_USAGE_MAX (0x02 << 4) +#define HID_LOCALITEM_TAG_DESIG_INDEX (0x03 << 4) +#define HID_LOCALITEM_TAG_DESIG_MIN (0x04 << 4) +#define HID_LOCALITEM_TAG_DESIG_MAX (0x05 << 4) +/* No 6 in spec */ +#define HID_LOCALITEM_TAG_STRING_INDEX (0x07 << 4) +#define HID_LOCALITEM_TAG_STRING_MIN (0x08 << 4) +#define HID_LOCALITEM_TAG_STRING_MAX (0x09 << 4) +#define HID_LOCALITEM_TAG_DELIMITER (0x0a << 4) /* Also listed as reserved in spec! */ + +/* Usage pages (HuT 3) */ +#define HID_USAGE_PAGE_UNDEFINED 0x00 /* Undefined */ +#define HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS 0x01 /* Generic Desktop Controls */ +#define HID_USAGE_PAGE_SIMULATION_CONTROLS 0x02 /* Simulation Controls */ +#define HID_USAGE_PAGE_VR_CONTROLS 0x03 /* VR Controls */ +#define HID_USAGE_PAGE_SPORT_CONTROLS 0x04 /* Sport Controls */ +#define HID_USAGE_PAGE_GAME_CONTROLS 0x05 /* Game Controls */ +#define HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS 0x06 /* Generic Device Controls */ +#define HID_USAGE_PAGE_KEYBOARD_KEYPAD 0x07 /* Keyboard/Keypad */ +#define HID_USAGE_PAGE_LED 0x08 /* LEDs */ +#define HID_USAGE_PAGE_BUTTON 0x09 /* Button */ +#define HID_USAGE_PAGE_ORDINAL 0x0a /* Ordinal */ +#define HID_USAGE_PAGE_TELEPHONY 0x0b /* Telephony */ +#define HID_USAGE_PAGE_CONSUMER 0x0c /* Consumer */ +#define HID_USAGE_PAGE_DIGITIZER 0x0d /* Digitizer */ +#define HID_USAGE_PAGE_HAPTICS /* 0x0e Reserved */ +#define HID_USAGE_PAGE_PID 0x0f /* PID Page Physical Interface Device */ +#define HID_USAGE_PAGE_UNICODE 0x10 /* Unicode */ +#define HID_USAGE_PAGE_SOC 0x11 /* Sensor Orientation Category */ +#define HID_USAGE_PAGE_EYE_AND_HEAD_TRACKER 0x12 /* Eye and Head Tracker */ + /* 0x13 Reserved */ +#define HID_USAGE_PAGE_ALPHA_DISPLAY 0x14 /* Alphanumeric Display */ + /* 0x15-3f Reserved */ +#define HID_USAGE_PAGE_MEDICAL 0x40 /* Medical Instruments */ +#define HID_USAGE_PAGE_BRAILLE_DISPLAY 0x41 /* Braille Display */ + /* 0x42-0x58 Reserved */ +#define HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION 0x59 /* Lighting and Illumination */ + /* 0x5a-0x7f Reserved */ +#define HID_USAGE_PAGE_USB_MONITOR 0x80 /* USB Monitor */ +#define HID_USAGE_PAGE_USB_ENUMERATED_VALUES 0x81 /* USB Enumerated Values */ +#define HID_USAGE_PAGE_VESA_VIRTUAL_CONTROLS 0x82 /* VESA Virtual Controls */ +#define HID_USAGE_PAGE_POWER_DEVICE 0x84 /* Power Device */ +#define HID_USAGE_PAGE_BATTERY_SYSTEM 0x85 /* Battery System */ +#define HID_USAGE_PAGE_BARCODE_SCANNER 0x8c /* Bar Code Scanner page */ +#define HID_USAGE_PAGE_SCALE 0x8d /* Scale page */ +#define HID_USAGE_PAGE_MSR 0x8e /* Magnetic Stripe Reading (MSR) Devices */ +#define HID_USAGE_PAGE_POS 0x8f /* Point of Sale devices */ +#define HID_USAGE_PAGE_CAMERA_CONTROL 0x90 /* Camera Control Page */ +#define HID_USAGE_PAGE_ARCADE 0x91 +#define HID_USAGE_PAGE_GAMING_DEVICE 0x92 +#define HID_USAGE_PAGE_FIDO_ALLIANCE 0xF1D0 +#define HID_USAGE_PAGE_VENDOR_PAGE_HBYTE 0xFF00 /* Modifier Keys (HID 8.3) */ #define HID_MODIFIER_LCTRL (1 << 0) /* Left Ctrl */ @@ -205,38 +220,6 @@ #define HID_JS_INPUT_REPORT_BUTTON3 (1 << 6) #define HID_JS_INPUT_REPORT_BUTTON4 (1 << 7) -/* Usage pages (HuT 3) */ -#define HID_USAGE_PAGE_UNDEFINED 0x00 /* Undefined */ -#define HID_USAGE_PAGE_GENERIC_DCTRL 0x01 /* Generic Desktop Controls */ -#define HID_USAGE_PAGE_SIMCTRL 0x02 /* Simulation Controls */ -#define HID_USAGE_PAGE_VRCTRL 0x03 /* VR Controls */ -#define HID_USAGE_PAGE_SPORTCTRL 0x04 /* Sport Controls */ -#define HID_USAGE_PAGE_GAMECTRL 0x05 /* Game Controls */ -#define HID_USAGE_PAGE_GENERIC_DEVCTRL 0x06 /* Generic Device Controls */ -#define HID_USAGE_PAGE_KBD 0x07 /* Keyboard/Keypad */ -#define HID_USAGE_PAGE_LEDS 0x08 /* LEDs */ -#define HID_USAGE_PAGE_BUTTON 0x09 /* Button */ -#define HID_USAGE_PAGE_ORDINAL 0x0a /* Ordinal */ -#define HID_USAGE_PAGE_TELEPHONY 0x0b /* Telephony */ -#define HID_USAGE_PAGE_CONSUMER 0x0c /* Consumer */ -#define HID_USAGE_PAGE_DIGITIZER 0x0d /* Digitizer */ - /* 0x0e Reserved */ -#define HID_USAGE_PAGE_PIDPAGE 0x0f /* PID Page Physical Interface Device */ -#define HID_USAGE_PAGE_UNICODE 0x10 /* Unicode */ - /* 0x11-13 Reserved */ -#define HID_USAGE_PAGE_ALPHA_DISPLAY 0x14 /* Alphanumeric Display */ - /* 0x15-3f Reserved */ -#define HID_USAGE_PAGE_MEDICAL 0x40 /* Medical Instruments */ - /* 0x41-7f Reserved */ - /* 0x80-83 Monitor Devices */ - /* 0x84-87 Power Devices */ - /* 0x88-8b Reserved */ -#define HID_USAGE_PAGE_BARCODE_SCANNER 0x8c /* Bar Code Scanner page */ -#define HID_USAGE_PAGE_SCALE 0x8d /* Scale page */ -#define HID_USAGE_PAGE_MSR 0x8e /* Magnetic Stripe Reading (MSR) Devices */ -#define HID_USAGE_PAGE_POS 0x8f /* Point of Sale devices */ -#define HID_USAGE_PAGE_CAMERA_CTRL 0x90 /* Camera Control Page */ - /* Generic Desktop Page Usage IDs (HuT 4) */ #define HID_DESKTOP_USAGE_UNDEFINED 0x00 /* Undefined */ #define HID_DESKTOP_USAGE_POINTER 0x01 /* Pointer */ @@ -634,7 +617,7 @@ struct usb_hid_js_report { #define HID_CUSTOM_INOUT_DESCRIPTOR_LEN (9 + 9 + 7 + 7) -#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, in_ep, out_ep,wMaxPacketSize, bInterval) \ +#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, out_ep, in_ep, wMaxPacketSize, bInterval) \ 0x09, /* bLength: Interface Descriptor size */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \ bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \ @@ -654,13 +637,13 @@ struct usb_hid_js_report { WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \ 0x07, /* bLength: Endpoint Descriptor size */ \ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \ - in_ep, /* bEndpointAddress: Endpoint Address (IN) */ \ + out_ep, /* bEndpointAddress: Endpoint Address (OUT) */ \ 0x03, /* bmAttributes: Interrupt endpoint */ \ WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \ bInterval, /* bInterval: Polling Interval */ \ 0x07, /* bLength: Endpoint Descriptor size */ \ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \ - out_ep, /* bEndpointAddress: Endpoint Address (IN) */ \ + in_ep, /* bEndpointAddress: Endpoint Address (IN) */ \ 0x03, /* bmAttributes: Interrupt endpoint */ \ WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \ bInterval /* bInterval: Polling Interval */ diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c index 5c400c7b173..4fd1a91a014 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c +++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c @@ -20,7 +20,7 @@ #define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */ #define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */ -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(32, CONFIG_USB_ALIGN_SIZE)]; static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS]; static uint32_t g_devinuse = 0; @@ -106,7 +106,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer) if (ret < 8) { return ret; } - memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, 1)); + memcpy(buffer, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1)); return ret; } @@ -148,7 +148,7 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol) if (ret < 8) { return ret; } - memcpy(protocol, g_hid_buf[hid_class->minor], MIN(ret - 8, 1)); + memcpy(protocol, g_hid_buf[hid_class->minor], MIN((uint32_t)ret - 8, 1)); return ret; } @@ -173,7 +173,6 @@ int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen) { struct usb_setup_packet *setup; - int ret; if (!hid_class || !hid_class->hport) { return -USB_ERR_INVAL; @@ -186,18 +185,12 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t setup->wIndex = 0; setup->wLength = buflen; - ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]); - if (ret < 8) { - return ret; - } - memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, buflen)); - return ret; + return usbh_control_transfer(hid_class->hport, setup, buffer); } int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) { struct usb_endpoint_descriptor *ep_desc; - int ret; uint8_t cur_iface = 0xff; uint8_t *p; bool found = false; @@ -249,23 +242,6 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) return -USB_ERR_INVAL; } found: - // /* 0x0 = boot protocol, 0x1 = report protocol */ - // ret = usbh_hid_set_protocol(hid_class, 0x1); - // if (ret < 0) { - // return ret; - // } - - ret = usbh_hid_set_idle(hid_class, 0, 0); - if (ret < 0) { - USB_LOG_WRN("Do not support set idle\r\n"); - } - - /* We read report desc but do nothing (because of too much memory usage for parsing report desc, parsed by users) */ - ret = usbh_hid_get_report_descriptor(hid_class, g_hid_buf[hid_class->minor], MIN(sizeof(g_hid_buf[hid_class->minor]), hid_class->report_size)); - if (ret < 0) { - return ret; - } - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { @@ -280,7 +256,7 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) USB_LOG_INFO("Register HID Class:%s\r\n", hport->config.intf[intf].devname); usbh_hid_run(hid_class); - return ret; + return 0; } int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf) @@ -310,6 +286,427 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf) return ret; } +static uint32_t hid_get_itemval(const uint8_t *data, unsigned int idx, unsigned int size) +{ + uint32_t value = 0; + + for (unsigned int i = 1; i <= size; i++) + value |= data[idx + i] << (8 * (i - 1)); + + return value; +} + +struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_len, uint32_t max_usages) +{ + 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)); + + while (i < report_len) { + itemtag = data[i] & HID_TAG_MASK; + itemtype = data[i] & HID_TYPE_MASK; + itemsize = 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); + + USB_LOG_DBG("itemtype 0x%02x, itemtag 0x%02x, itemsize %d, itemval 0x%08x\r\n", + itemtype, itemtag, itemsize, itemval); + + switch (itemtype) { + 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"); + 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; + + if (hid_report->output_count >= CONFIG_USBHOST_HID_MAX_OUTPUT) { + USB_LOG_ERR("hid output fields exceed max limit\r\n"); + goto err; + } + + 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); + } + + hid_report->output_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_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)); + + break; + case HID_MAINITEM_TAG_ENDCOLLECTION: + break; + default: + goto err; + } + break; + 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; + break; + case HID_GLOBALITEM_TAG_LOGICAL_MIN: + field.logical_min = (int32_t)itemval; + flags |= HID_REPORT_FLAG_LOGICAL_MIN; + break; + case HID_GLOBALITEM_TAG_LOGICAL_MAX: + field.logical_max = (int32_t)itemval; + flags |= HID_REPORT_FLAG_LOGICAL_MAX; + break; + case HID_GLOBALITEM_TAG_REPORT_SIZE: + field.report_size = itemval; + flags |= HID_REPORT_FLAG_REPORT_SIZE; + break; + case HID_GLOBALITEM_TAG_REPORT_COUNT: + field.report_count = itemval; + flags |= HID_REPORT_FLAG_REPORT_COUNT; + break; + case HID_GLOBALITEM_TAG_REPORT_ID: + hid_report->uses_report_id = true; + field.report_id = itemval; + flags |= HID_REPORT_FLAG_REPORT_ID; + break; + default: + goto err; + } + break; + 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; + } + + usages[field.usage_count++] = 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; + 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); + break; + default: + goto err; + } + break; + default: + goto err; + } + + i += (1 + itemsize); + } + usb_osal_free(usages); + return hid_report; +err: + if (hid_report) { + usb_osal_free(hid_report); + + for (uint32_t j = 0; j < hid_report->input_count; j++) + usb_osal_free(hid_report->input_fields[j].usages); + + for (uint32_t j = 0; j < hid_report->output_count; j++) + usb_osal_free(hid_report->output_fields[j].usages); + + for (uint32_t j = 0; j < hid_report->feature_count; j++) + usb_osal_free(hid_report->feature_fields[j].usages); + } + + if (usages) + usb_osal_free(usages); + return NULL; +} + +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); + + for (uint32_t j = 0; j < hid_report->output_count; j++) + usb_osal_free(hid_report->output_fields[j].usages); + + for (uint32_t j = 0; j < hid_report->feature_count; j++) + usb_osal_free(hid_report->feature_fields[j].usages); + + usb_osal_free(hid_report); + } +} + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_report_buf[2048]; + +static const char *hid_property_string(uint32_t value) +{ + 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; + +} + +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)); +} + +int lshid(int argc, char **argv) +{ + struct usbh_hid *hid_class; + struct hid_report *hid_report; + int ret; + + if (argc < 2) { + USB_LOG_ERR("please input correct command: lshid path\r\n"); + return -1; + } + + hid_class = usbh_find_class_instance(argv[1]); + if (!hid_class) { + USB_LOG_ERR("cannot find hid device\r\n"); + return -1; + } + + if (hid_class->report_size > sizeof(g_hid_report_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); + 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); + } + + usbh_hid_report_free(hid_report); + } else { + USB_LOG_ERR("HID report parsed failed\r\n"); + } + return 0; +} + __WEAK void usbh_hid_run(struct usbh_hid *hid_class) { (void)hid_class; diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h index 8b87e0c0b58..fa5c7663afe 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h +++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h @@ -8,6 +8,82 @@ #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 +#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; + int32_t logical_min; + int32_t logical_max; + uint32_t properties; + + uint32_t usage_min; + uint32_t usage_max; + + uint32_t flags; +}; + +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 { struct usbh_hubport *hport; struct usb_endpoint_descriptor *intin; /* INTR IN endpoint */ @@ -36,9 +112,14 @@ 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); + void usbh_hid_run(struct usbh_hid *hid_class); void usbh_hid_stop(struct usbh_hid *hid_class); +int lshid(int argc, char **argv); + #ifdef __cplusplus } #endif diff --git a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c index 008c600ceea..910aa0c2cd2 100644 --- a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c +++ b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c @@ -238,6 +238,7 @@ int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature) { struct usb_setup_packet roothub_setup; struct usb_setup_packet *setup; + int ret; if (hub->is_roothub) { setup = &roothub_setup; @@ -246,9 +247,22 @@ int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature) setup->wValue = feature; setup->wIndex = port; setup->wLength = 0; - return usbh_roothub_control(hub->bus, setup, NULL); + + ret = usbh_roothub_control(hub->bus, setup, NULL); + + if ((feature == HUB_PORT_FEATURE_RESET) && (ret >= 0)) { + hub->bus->event_handler(hub->bus->busid, hub->index, port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_RESET); + } + + return ret; } else { - return _usbh_hub_set_feature(hub, port, feature); + ret = _usbh_hub_set_feature(hub, port, feature); + + if ((feature == HUB_PORT_FEATURE_RESET) && (ret >= 0)) { + hub->bus->event_handler(hub->bus->busid, hub->index, port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_RESET); + } + + return ret; } } @@ -337,11 +351,11 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) } /* - * Super-Speed hubs need to know their depth to be able to - * parse the bits of the route-string that correspond to - * their downstream port number. - * - */ + * Super-Speed hubs need to know their depth to be able to + * parse the bits of the route-string that correspond to + * their downstream port number. + * + */ if ((hport->depth != 0) && (hport->speed == USB_SPEED_SUPER)) { ret = usbh_hub_set_depth(hub, hport->depth - 1); if (ret < 0) { @@ -373,6 +387,11 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5); } + if (hub->nports > CONFIG_USBHOST_MAX_EHPORTS) { + USB_LOG_ERR("Hub nports %u overflow\r\n", hub->nports); + return -USB_ERR_NOMEM; + } + for (uint8_t port = 0; port < hub->nports; port++) { hub->child[port].port = port + 1; hub->child[port].parent = hub; @@ -470,6 +489,8 @@ static void usbh_hub_events(struct usbh_hub *hub) int ret; size_t flags; + (void)speed_table; + if (!hub->connected) { return; } @@ -560,6 +581,8 @@ static void usbh_hub_events(struct usbh_hub *hub) /* Last, check connect status */ if (portstatus & HUB_PORT_STATUS_CONNECTION) { + hub->bus->event_handler(hub->bus->busid, hub->index, port + 1, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_CONNECTED); + ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_RESET); if (ret < 0) { USB_LOG_ERR("Failed to reset port %u, errorcode: %d\r\n", port + 1, ret); @@ -641,7 +664,6 @@ static void usbh_hub_events(struct usbh_hub *hub) child = &hub->child[port]; /** release child sources */ usbh_hubport_release(child); - USB_LOG_INFO("Device on Bus %u, Hub %u, Port %u disconnected\r\n", hub->bus->busid, hub->index, port + 1); } } } @@ -660,12 +682,15 @@ static void usbh_hub_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) 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); 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); usbh_hub_events(hub); + usb_osal_mutex_give(bus->mutex); } } @@ -695,6 +720,12 @@ 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"); + return -1; + } + snprintf(thread_name, 32, "usbh_hub%u", bus->busid); bus->hub_thread = usb_osal_thread_create(thread_name, CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbh_hub_thread, bus); if (bus->hub_thread == NULL) { @@ -708,8 +739,8 @@ int usbh_hub_deinitialize(struct usbh_bus *bus) { struct usbh_hubport *hport; struct usbh_hub *hub; - size_t flags; + usb_osal_mutex_take(bus->mutex); hub = &bus->hcd.roothub; for (uint8_t port = 0; port < hub->nports; port++) { hport = &hub->child[port]; @@ -717,15 +748,13 @@ int usbh_hub_deinitialize(struct usbh_bus *bus) usbh_hubport_release(hport); } - flags = usb_osal_enter_critical_section(); - usb_hc_deinit(bus); - usb_osal_leave_critical_section(flags); - - usb_osal_mq_delete(bus->hub_mq); usb_osal_thread_delete(bus->hub_thread); + usb_osal_mq_delete(bus->hub_mq); + usb_osal_mutex_give(bus->mutex); + usb_osal_mutex_delete(bus->mutex); return 0; } diff --git a/components/drivers/usb/cherryusb/class/midi/usb_midi.h b/components/drivers/usb/cherryusb/class/midi/usb_midi.h index 3e7a846f4ef..e68675a77d4 100644 --- a/components/drivers/usb/cherryusb/class/midi/usb_midi.h +++ b/components/drivers/usb/cherryusb/class/midi/usb_midi.h @@ -6,6 +6,8 @@ #ifndef USB_MIDI_H #define USB_MIDI_H +#include "usb_audio.h" + /* bDescriptorSubType */ #define MIDI_VC_HEADER_DESCRIPTOR_SUBTYPE 0x01U #define MIDI_MS_HEADER_DESCRIPTOR_SUBTYPE 0x01U @@ -201,6 +203,19 @@ struct midi_cs_ep_ms_general_descriptor { #define MIDI_SIZEOF_MS_GENERAL_DESC(n) (4 + n) // clang-format off +#define MIDI_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bInterfaceNumber, /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + bNumEndpoints, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ + AUDIO_SUBCLASS_MIDISTREAMING, /* bInterfaceSubClass */ \ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \ + 0x00 /* iInterface */ + +#define MIDI_STANDARD_DESCRIPTOR_LEN 0x09 + #define MIDI_CS_HEADER_DESCRIPTOR_INIT(wTotalLength) \ 0x07, /* bLength */ \ USB_CS_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.c b/components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.c new file mode 100644 index 00000000000..cf5363efa5d --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2022 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_serial.h" +#include "usbh_cdc_acm.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_cdc_acm" +#include "usb_log.h" + +struct usbh_cdc_acm { + struct usb_endpoint_descriptor *intin; + struct usbh_urb intin_urb; + struct usb_osal_timer *modem_timer; + uint16_t modem_status; +}; + +static int usbh_cdc_acm_attach(struct usbh_serial *serial) +{ + struct usb_endpoint_descriptor *ep_desc; + int ret; + + struct usbh_cdc_acm *cdc_acm_class = usb_osal_malloc(sizeof(struct usbh_cdc_acm)); + if (!cdc_acm_class) { + USB_LOG_ERR("No memory for cdc_acm_class\r\n"); + return -USB_ERR_NOMEM; + } + memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm)); + serial->priv = cdc_acm_class; + + for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) { + ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc; + + if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) { + if (ep_desc->bEndpointAddress & 0x80) { + USBH_EP_INIT(cdc_acm_class->intin, ep_desc); + break; + } else { + } + } + } + + if (!cdc_acm_class->intin) { + USB_LOG_ERR("Failed to find interrupt endpoint\r\n"); + ret = -USB_ERR_NODEV; + goto errout; + } + return 0; +errout: + serial->priv = NULL; + usb_osal_free(cdc_acm_class); + return ret; +} + +static void usbh_cdc_acm_detach(struct usbh_serial *serial) +{ + struct usbh_cdc_acm *cdc_acm_class; + + if (!serial || !serial->priv) { + return; + } + + cdc_acm_class = (struct usbh_cdc_acm *)serial->priv; + if (cdc_acm_class->intin) { + usbh_kill_urb(&cdc_acm_class->intin_urb); + } + serial->priv = NULL; + usb_osal_free(cdc_acm_class); +} + +static int usbh_cdc_acm_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CDC_REQUEST_SET_LINE_CODING; + setup->wValue = 0; + setup->wIndex = serial->intf; + setup->wLength = 7; + + memcpy(serial->iobuffer, line_coding, sizeof(struct cdc_line_coding)); + + return usbh_control_transfer(serial->hport, setup, serial->iobuffer); +} + +static int usbh_cdc_acm_get_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + struct usb_setup_packet *setup; + int ret; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CDC_REQUEST_GET_LINE_CODING; + setup->wValue = 0; + setup->wIndex = serial->intf; + setup->wLength = 7; + + ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer); + if (ret < 0) { + return ret; + } + memcpy(line_coding, serial->iobuffer, sizeof(struct cdc_line_coding)); + return ret; +} + +static int usbh_cdc_acm_set_line_state(struct usbh_serial *serial, bool dtr, bool rts) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE; + setup->wValue = (dtr << 0) | (rts << 1); + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_cdc_acm_get_modem_status(struct usbh_serial *serial) +{ + struct usbh_cdc_acm *cdc_acm_class; + uintptr_t flags; + uint16_t status; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + flags = usb_osal_enter_critical_section(); + + cdc_acm_class = (struct usbh_cdc_acm *)serial->priv; + + status = (cdc_acm_class->modem_status & CDC_SERIAL_STATE_DSR ? USBH_SERIAL_TIOCM_DSR : 0) | + (cdc_acm_class->modem_status & CDC_SERIAL_STATE_RING ? USBH_SERIAL_TIOCM_RI : 0) | + (cdc_acm_class->modem_status & CDC_SERIAL_STATE_DCD ? USBH_SERIAL_TIOCM_CD : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0); + + usb_osal_leave_critical_section(flags); + + return status; +} + +#ifdef CONFIG_USBH_SERIAL_GET_MODEM_STATUS +static int __usbh_cdc_acm_get_modem_status(struct usbh_serial *serial) +{ + struct usbh_cdc_acm *cdc_acm_class; + struct cdc_acm_notification *notification; + uint16_t difference; + uintptr_t flags; + int ret; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + cdc_acm_class = (struct usbh_cdc_acm *)serial->priv; + + usbh_int_urb_fill(&cdc_acm_class->intin_urb, serial->hport, cdc_acm_class->intin, &serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET], cdc_acm_class->intin->wMaxPacketSize, 0xffffffff, NULL, NULL); + ret = usbh_submit_urb(&cdc_acm_class->intin_urb); + if (ret < 0) { + return ret; + } + + if (cdc_acm_class->intin_urb.actual_length < sizeof(struct cdc_acm_notification)) { + return -USB_ERR_INVAL; + } + + notification = (struct cdc_acm_notification *)&serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET]; + if (notification->bNotificationType != CDC_NOTIFICATION_SERIAL_STATE) { + return -USB_ERR_INVAL; + } + + flags = usb_osal_enter_critical_section(); + + difference = cdc_acm_class->modem_status ^ notification->data; + cdc_acm_class->modem_status = notification->data; + + if (difference & CDC_SERIAL_STATE_DSR) + serial->iocount.dsr++; + if (difference & CDC_SERIAL_STATE_DCD) + serial->iocount.dcd++; + if (notification->data & CDC_SERIAL_STATE_BREAK) + serial->iocount.brk++; + if (notification->data & CDC_SERIAL_STATE_FRAMING) + serial->iocount.frame++; + if (notification->data & CDC_SERIAL_STATE_PARITY) + serial->iocount.parity++; + if (notification->data & CDC_SERIAL_STATE_OVERRUN) + serial->iocount.overrun++; + + usb_osal_leave_critical_section(flags); + + return ret; +} +#endif + +static const struct usbh_serial_driver cdc_acm_driver = { + .driver_name = "cdc_acm", + + .ignore_rx_header = 0, + .ignore_tx_header = 0, + + .attach = usbh_cdc_acm_attach, + .detach = usbh_cdc_acm_detach, + .set_flow_control = NULL, + .set_line_coding = usbh_cdc_acm_set_line_coding, + .get_line_coding = usbh_cdc_acm_get_line_coding, + .set_line_state = usbh_cdc_acm_set_line_state, + .get_modem_status = usbh_cdc_acm_get_modem_status, +}; + +static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) +{ + return usbh_serial_probe(hport, intf, &cdc_acm_driver) ? 0 : -USB_ERR_NOMEM; +} + +static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv; + + if (serial) { + usbh_serial_remove(serial); + } + return 0; +} + +const struct usbh_class_driver cdc_acm_class_driver = { + .driver_name = "cdc_acm", + .connect = usbh_cdc_acm_connect, + .disconnect = usbh_cdc_acm_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_none_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .bInterfaceClass = USB_DEVICE_CLASS_CDC, + .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL, + .bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE, + .id_table = NULL, + .class_driver = &cdc_acm_class_driver +}; + +CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_at_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .bInterfaceClass = USB_DEVICE_CLASS_CDC, + .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL, + .bInterfaceProtocol = CDC_COMMON_PROTOCOL_AT_COMMANDS, + .id_table = NULL, + .class_driver = &cdc_acm_class_driver +}; diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.h b/components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.h new file mode 100644 index 00000000000..2940cd9c1a8 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_cdc_acm.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBH_CDC_ACM_H +#define USBH_CDC_ACM_H + +#include "usb_cdc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* USBH_CDC_ACM_H */ diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c b/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c new file mode 100644 index 00000000000..4e31a1afa3b --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.c @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_serial.h" +#include "usbh_ch34x.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_ch43x" +#include "usb_log.h" + +struct usbh_ch34x { + struct usb_endpoint_descriptor *intin; + struct usbh_urb intin_urb; + struct usb_osal_timer *modem_timer; + uint16_t modem_status; +}; + +/* refer to https://github.com/WCHSoftGroup/ch341ser_linux/blob/main/driver/ch341.c */ + +static int usbh_ch34x_get_baudrate_div(uint32_t baudrate, uint8_t *factor, uint8_t *divisor) +{ + uint8_t a; + uint8_t b; + uint32_t c; + + switch (baudrate) { + case 921600: + a = 0xf3; + b = 7; + break; + + case 307200: + a = 0xd9; + b = 7; + break; + + default: + if (baudrate > 6000000 / 255) { + b = 3; + c = 6000000; + } else if (baudrate > 750000 / 255) { + b = 2; + c = 750000; + } else if (baudrate > 93750 / 255) { + b = 1; + c = 93750; + } else { + b = 0; + c = 11719; + } + a = (uint8_t)(c / baudrate); + if (a == 0 || a == 0xFF) { + return -USB_ERR_INVAL; + } + if ((c / a - baudrate) > (baudrate - c / (a + 1))) { + a++; + } + a = (uint8_t)(256 - a); + break; + } + + *factor = a; + *divisor = b; + + return 0; +} + +static int usbh_ch34x_control_out(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = bRequest; + setup->wValue = wValue; + setup->wIndex = wIndex; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_ch34x_control_in(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t size) +{ + struct usb_setup_packet *setup; + int ret; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = bRequest; + setup->wValue = wValue; + setup->wIndex = wIndex; + setup->wLength = size; + + ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer); + if (ret < 0) { + return ret; + } + memcpy(data, serial->iobuffer, size); + + return ret; +} + +static int usbh_ch34x_get_version(struct usbh_serial *serial) +{ + int ret; + uint8_t buf[2]; + + ret = usbh_ch34x_control_in(serial, CH34X_READ_VERSION, 0, 0, buf, 2); + if (ret < 0) { + return ret; + } + + USB_LOG_INFO("chip version: 0x%02x\r\n", buf[0]); + return ret; +} + +static int usbh_ch34x_attach(struct usbh_serial *serial) +{ + struct usb_endpoint_descriptor *ep_desc; + int ret; + + struct usbh_ch34x *ch34x_class = usb_osal_malloc(sizeof(struct usbh_ch34x)); + if (!ch34x_class) { + USB_LOG_ERR("No memory for ch34x_class\r\n"); + return -USB_ERR_NOMEM; + } + memset(ch34x_class, 0, sizeof(struct usbh_ch34x)); + serial->priv = ch34x_class; + + for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) { + ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc; + + if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) { + if (ep_desc->bEndpointAddress & 0x80) { + USBH_EP_INIT(ch34x_class->intin, ep_desc); + break; + } else { + } + } + } + + if (!ch34x_class->intin) { + USB_LOG_ERR("Failed to find interrupt endpoint\r\n"); + ret = -USB_ERR_NODEV; + goto errout; + } + + ret = usbh_ch34x_get_version(serial); + ret |= usbh_ch34x_control_out(serial, CH34X_SERIAL_INIT, 0, 0); + ret |= usbh_ch34x_control_out(serial, CH34X_WRITE_REG, 0x1312, 0xd982); + ret |= usbh_ch34x_control_out(serial, CH34X_WRITE_REG, 0x0f2c, 0x0007); + if (ret < 0) { + goto errout; + } + + return 0; +errout: + serial->priv = NULL; + usb_osal_free(ch34x_class); + return ret; +} + +static void usbh_ch34x_detach(struct usbh_serial *serial) +{ + struct usbh_ch34x *ch34x_class; + + if (!serial || !serial->priv) { + return; + } + + ch34x_class = (struct usbh_ch34x *)serial->priv; + if (ch34x_class->intin) { + usbh_kill_urb(&ch34x_class->intin_urb); + } + serial->priv = NULL; + usb_osal_free(ch34x_class); +} + +static int usbh_ch34x_set_flow_ctrl(struct usbh_serial *serial, bool hardctrl) +{ + return usbh_ch34x_control_out(serial, CH34X_WRITE_REG, 0x2727, hardctrl ? 0x0101 : 0x0000); +} + +static int usbh_ch34x_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + uint16_t reg_value = 0; + uint16_t value = 0; + uint16_t index = 0; + uint8_t factor = 0; + uint8_t divisor = 0; + + switch (line_coding->bParityType) { + case 0: + break; + case 1: + reg_value |= CH341_L_PO; + break; + case 2: + reg_value |= CH341_L_PE; + break; + case 3: + reg_value |= CH341_L_PM; + break; + case 4: + reg_value |= CH341_L_PS; + break; + default: + return -USB_ERR_INVAL; + } + + switch (line_coding->bDataBits) { + case 5: + reg_value |= CH341_L_D5; + break; + case 6: + reg_value |= CH341_L_D6; + break; + case 7: + reg_value |= CH341_L_D7; + break; + case 8: + reg_value |= CH341_L_D8; + break; + default: + return -USB_ERR_INVAL; + } + + if (line_coding->bCharFormat == 2) { + reg_value |= CH341_L_SB; + } + + usbh_ch34x_get_baudrate_div(line_coding->dwDTERate, &factor, &divisor); + + reg_value |= 0xC0; + value |= 0x9c; + value |= reg_value << 8; + index |= 0x80 | divisor; + index |= (uint16_t)factor << 8; + + return usbh_ch34x_control_out(serial, CH34X_SERIAL_INIT, value, index); +} + +static int usbh_ch34x_set_line_state(struct usbh_serial *serial, bool dtr, bool rts) +{ + uint16_t value = 0; + uint8_t control = 0; + + control = (dtr << 5) | (rts << 6); + value = (uint8_t)~control; + + return usbh_ch34x_control_out(serial, CH34X_MODEM_CTRL, value, 0x0000); +} + +static int usbh_ch34x_get_modem_status(struct usbh_serial *serial) +{ + struct usbh_ch34x *ch34x_class; + uintptr_t flags; + uint16_t status; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + flags = usb_osal_enter_critical_section(); + + ch34x_class = (struct usbh_ch34x *)serial->priv; + + status = (ch34x_class->modem_status & CH341_CTI_DS ? USBH_SERIAL_TIOCM_DSR : 0) | + (ch34x_class->modem_status & CH341_CTI_C ? USBH_SERIAL_TIOCM_CTS : 0) | + (ch34x_class->modem_status & CH341_CTRL_RI ? USBH_SERIAL_TIOCM_RI : 0) | + (ch34x_class->modem_status & CH341_CTI_DC ? USBH_SERIAL_TIOCM_CD : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0); + + usb_osal_leave_critical_section(flags); + + return status; +} + +#ifdef CONFIG_USBH_SERIAL_GET_MODEM_STATUS +static int __usbh_ch34x_get_modem_status(struct usbh_serial *serial, uint16_t *status) +{ + struct usbh_ch34x *ch34x_class; + uint8_t type = 0; + uint8_t data = 0; + uint16_t difference; + uintptr_t flags; + int ret; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + ch34x_class = (struct usbh_ch34x *)serial->priv; + + usbh_int_urb_fill(&ch34x_class->intin_urb, serial->hport, ch34x_class->intin, &serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET], ch34x_class->intin->wMaxPacketSize, 0xffffffff, NULL, NULL); + ret = usbh_submit_urb(&ch34x_class->intin_urb); + if (ret < 0) { + return ret; + } + + if (ret < 4) { + return -USB_ERR_INVAL; + } + + flags = usb_osal_enter_critical_section(); + + type = serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET]; + if (type & CH341_CTT_M) { + data = ~serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET + 2] & CH341_CTI_ST; + difference = data ^ (ch34x_class->modem_status & CH341_CTI_ST); + ch34x_class->modem_status = data; + + if (difference) { + if (difference & CH341_CTI_C) { + serial->iocount.cts++; + } + if (difference & CH341_CTI_DS) { + serial->iocount.dsr++; + } + if (difference & CH341_CTRL_RI) { + serial->iocount.rng++; + } + if (difference & CH341_CTI_DC) { + serial->iocount.dcd++; + } + } + } + + if (type & CH341_CTT_O) { + serial->iocount.overrun++; + } + if ((type & CH341_CTT_F) == CH341_CTT_F) { + serial->iocount.frame++; + } + if (type & CH341_CTT_P) { + serial->iocount.parity++; + } + + usb_osal_leave_critical_section(flags); + + return ret; +} +#endif + +static const struct usbh_serial_driver ch34x_driver = { + .driver_name = "ch34x", + + .ignore_rx_header = 0, + .ignore_tx_header = 0, + + .attach = usbh_ch34x_attach, + .detach = usbh_ch34x_detach, + .set_flow_control = usbh_ch34x_set_flow_ctrl, + .set_line_coding = usbh_ch34x_set_line_coding, + .get_line_coding = NULL, + .set_line_state = usbh_ch34x_set_line_state, + .get_modem_status = usbh_ch34x_get_modem_status, +}; + +static int usbh_ch34x_connect(struct usbh_hubport *hport, uint8_t intf) +{ + return usbh_serial_probe(hport, intf, &ch34x_driver) ? 0 : -USB_ERR_NOMEM; +} + +static int usbh_ch34x_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv; + + if (serial) { + usbh_serial_remove(serial); + } + + return 0; +} + +static const uint16_t ch34x_id_table[][2] = { + { 0x1A86, 0x7523 }, /* ch340 chip */ + { 0x1A86, 0x7522 }, /* ch340k chip */ + { 0x1A86, 0x5523 }, /* ch341 chip */ + { 0x1A86, 0xe523 }, /* ch330 chip */ + { 0x4348, 0x5523 }, /* ch340 custom chip */ + { 0, 0 }, +}; + +const struct usbh_class_driver ch34x_class_driver = { + .driver_name = "ch34x", + .connect = usbh_ch34x_connect, + .disconnect = usbh_ch34x_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = { + .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .id_table = ch34x_id_table, + .class_driver = &ch34x_class_driver +}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.h b/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.h new file mode 100644 index 00000000000..21e481012c1 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_ch34x.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBH_CH34X_H +#define USBH_CH34X_H + +#include "usb_cdc.h" + +/* Requests */ +#define CH34X_READ_VERSION 0x5F +#define CH34X_WRITE_REG 0x9A +#define CH34X_READ_REG 0x95 +#define CH34X_SERIAL_INIT 0xA1 +#define CH34X_MODEM_CTRL 0xA4 + +// modem control bits +#define CH34X_BIT_RTS (1 << 6) +#define CH34X_BIT_DTR (1 << 5) + +#define CH341_CTO_O 0x10 +#define CH341_CTO_D 0x20 +#define CH341_CTO_R 0x40 +#define CH341_CTI_C 0x01 +#define CH341_CTI_DS 0x02 +#define CH341_CTRL_RI 0x04 +#define CH341_CTI_DC 0x08 +#define CH341_CTI_ST 0x0f + +#define CH341_CTT_M BIT(3) +#define CH341_CTT_F (BIT(2) | BIT(6)) +#define CH341_CTT_P BIT(2) +#define CH341_CTT_O BIT(1) + +#define CH341_L_ER 0x80 +#define CH341_L_ET 0x40 +#define CH341_L_PS 0x38 +#define CH341_L_PM 0x28 +#define CH341_L_PE 0x18 +#define CH341_L_PO 0x08 +#define CH341_L_SB 0x04 +#define CH341_L_D8 0x03 +#define CH341_L_D7 0x02 +#define CH341_L_D6 0x01 +#define CH341_L_D5 0x00 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* USBH_CH34X_H */ diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_cp210x.c b/components/drivers/usb/cherryusb/class/serial/usbh_cp210x.c new file mode 100644 index 00000000000..7b240e2c330 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_cp210x.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_serial.h" +#include "usbh_cp210x.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_cp210x" +#include "usb_log.h" + +struct usbh_cp210x { + uint8_t partnum; + uint32_t fw_version; + uint32_t min_speed; + uint32_t max_speed; + bool use_actual_rate; + bool no_flow_control; + bool no_event_mode; +}; + +struct cp210x_rate { + uint32_t rate; + uint32_t high; +}; + +static const struct cp210x_rate cp210x_an205_table1[] = { + { 300, 300 }, + { 600, 600 }, + { 1200, 1200 }, + { 1800, 1800 }, + { 2400, 2400 }, + { 4000, 4000 }, + { 4800, 4803 }, + { 7200, 7207 }, + { 9600, 9612 }, + { 14400, 14428 }, + { 16000, 16062 }, + { 19200, 19250 }, + { 28800, 28912 }, + { 38400, 38601 }, + { 51200, 51558 }, + { 56000, 56280 }, + { 57600, 58053 }, + { 64000, 64111 }, + { 76800, 77608 }, + { 115200, 117028 }, + { 128000, 129347 }, + { 153600, 156868 }, + { 230400, 237832 }, + { 250000, 254234 }, + { 256000, 273066 }, + { 460800, 491520 }, + { 500000, 567138 }, + { 576000, 670254 }, + { 921600, 0xffffffff } +}; + +/* + * Quantises the baud rate as per AN205 Table 1 + */ +static uint32_t cp210x_get_an205_rate(uint32_t baud) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cp210x_an205_table1); ++i) { + if (baud <= cp210x_an205_table1[i].high) + break; + } + + return cp210x_an205_table1[i].rate; +} + +static uint32_t cp210x_get_actual_rate(uint32_t baud) +{ + unsigned int prescale = 1; + unsigned int div; + + if (baud <= 365) + prescale = 4; + + div = DIV_ROUND_CLOSEST(48000000, 2 * prescale * baud); + baud = 48000000 / (2 * prescale * div); + + return baud; +} + +static void usbh_cp210x_init_max_speed(struct usbh_serial *serial) +{ + struct usbh_cp210x *cp210x_class; + + if (!serial || !serial->hport || !serial->priv) { + return; + } + + cp210x_class = (struct usbh_cp210x *)serial->priv; + + bool use_actual_rate = false; + uint32_t min = 300; + uint32_t max; + + switch (cp210x_class->partnum) { + case CP210X_PARTNUM_CP2101: + max = 921600; + break; + case CP210X_PARTNUM_CP2102: + case CP210X_PARTNUM_CP2103: + max = 1000000; + break; + case CP210X_PARTNUM_CP2104: + use_actual_rate = true; + max = 2000000; + break; + case CP210X_PARTNUM_CP2108: + max = 2000000; + break; + case CP210X_PARTNUM_CP2105: + if (serial->intf == 0) { + use_actual_rate = true; + max = 2000000; /* ECI */ + } else { + min = 2400; + max = 921600; /* SCI */ + } + break; + case CP210X_PARTNUM_CP2102N_QFN28: + case CP210X_PARTNUM_CP2102N_QFN24: + case CP210X_PARTNUM_CP2102N_QFN20: + use_actual_rate = true; + max = 3000000; + break; + default: + max = 2000000; + break; + } + + cp210x_class->min_speed = min; + cp210x_class->max_speed = max; + cp210x_class->use_actual_rate = use_actual_rate; +} + +static int usbh_cp210x_control_out(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t size) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = bRequest; + setup->wValue = wValue; + setup->wIndex = wIndex; + setup->wLength = size; + + if (data && size) { + memcpy(serial->iobuffer, data, size); + return usbh_control_transfer(serial->hport, setup, serial->iobuffer); + } else { + return usbh_control_transfer(serial->hport, setup, NULL); + } +} + +static int usbh_cp210x_control_in(struct usbh_serial *serial, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t size) +{ + struct usb_setup_packet *setup; + int ret; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = bRequest; + setup->wValue = wValue; + setup->wIndex = wIndex; + setup->wLength = size; + + ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer); + if (ret < 0) { + return ret; + } + memcpy(data, serial->iobuffer, size); + + return ret; +} + +static int usbh_cp210x_get_partnum(struct usbh_serial *serial) +{ + uint8_t version[3]; + struct usbh_cp210x *cp210x_class; + int ret; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + cp210x_class = (struct usbh_cp210x *)serial->priv; + + ret = usbh_cp210x_control_in(serial, CP210X_VENDOR_SPECIFIC, CP210X_GET_PARTNUM, serial->intf, (uint8_t *)&cp210x_class->partnum, 1); + if (ret < 0) { + return ret; + } + + USB_LOG_INFO("chip partnum: 0x%02x\r\n", cp210x_class->partnum); + + switch (cp210x_class->partnum) { + case CP210X_PARTNUM_CP2102: + break; + case CP210X_PARTNUM_CP2105: + case CP210X_PARTNUM_CP2108: + ret = usbh_cp210x_control_in(serial, CP210X_VENDOR_SPECIFIC, CP210X_GET_FW_VER_2N, serial->intf, version, 3); + if (ret < 0) { + return ret; + } + cp210x_class->fw_version = version[0] << 16 | version[1] << 8 | version[2]; + break; + case CP210X_PARTNUM_CP2102N_QFN28: + case CP210X_PARTNUM_CP2102N_QFN24: + case CP210X_PARTNUM_CP2102N_QFN20: + ret = usbh_cp210x_control_in(serial, CP210X_VENDOR_SPECIFIC, CP210X_GET_FW_VER_2N, serial->intf, version, 3); + if (ret < 0) { + return ret; + } + cp210x_class->fw_version = version[0] << 16 | version[1] << 8 | version[2]; + if (cp210x_class->fw_version <= 0x10004) + cp210x_class->no_flow_control = true; + break; + default: + break; + } + return ret; +} + +static int usbh_cp210x_enable(struct usbh_serial *serial) +{ + return usbh_cp210x_control_out(serial, CP210X_IFC_ENABLE, 1, serial->intf, NULL, 0); +} + +static int usbh_cp210x_set_chars(struct usbh_serial *serial) +{ + struct cp210x_special_chars chars = { 0 }; + + return usbh_cp210x_control_out(serial, CP210X_SET_CHARS, 0, serial->intf, (uint8_t *)&chars, sizeof(struct cp210x_special_chars)); +} + +// static int usbh_cp210x_get_common_status(struct usbh_serial *serial, struct cp210x_comm_status *status) +// { +// return usbh_cp210x_control_in(serial, CP210X_GET_COMM_STATUS, 0, serial->intf, (uint8_t *)status, sizeof(struct cp210x_comm_status)); +// } + +static int usbh_cp210x_set_baudrate(struct usbh_serial *serial, uint32_t baudrate) +{ + struct usb_setup_packet *setup; + struct usbh_cp210x *cp210x_class; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + cp210x_class = (struct usbh_cp210x *)serial->priv; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CP210X_SET_BAUDRATE; + setup->wValue = 0; + setup->wIndex = serial->intf; + setup->wLength = 4; + + if (cp210x_class->use_actual_rate) + baudrate = cp210x_get_actual_rate(baudrate); + else if (baudrate < 1000000) + baudrate = cp210x_get_an205_rate(baudrate); + + memcpy(serial->iobuffer, (uint8_t *)&baudrate, 4); + return usbh_control_transfer(serial->hport, setup, serial->iobuffer); +} + +static int usbh_cp210x_set_data_format(struct usbh_serial *serial, uint8_t databits, uint8_t parity, uint8_t stopbits) +{ + struct usb_setup_packet *setup; + uint16_t value; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + value = ((databits & 0x0F) << 8) | ((parity & 0x0f) << 4) | ((stopbits & 0x03) << 0); + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CP210X_SET_LINE_CTL; + setup->wValue = value; + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_cp210x_attach(struct usbh_serial *serial) +{ + int ret; + + struct usbh_cp210x *cp210x_class = usb_osal_malloc(sizeof(struct usbh_cp210x)); + if (!cp210x_class) { + return -USB_ERR_NOMEM; + } + memset(cp210x_class, 0, sizeof(struct usbh_cp210x)); + serial->priv = cp210x_class; + + ret = usbh_cp210x_get_partnum(serial); + usbh_cp210x_init_max_speed(serial); + ret |= usbh_cp210x_enable(serial); + ret |= usbh_cp210x_set_chars(serial); + if (ret < 0) { + goto errout; + } + return 0; +errout: + serial->priv = NULL; + usb_osal_free(cp210x_class); + return ret; +} + +static void usbh_cp210x_detach(struct usbh_serial *serial) +{ + if (serial && serial->priv) { + serial->priv = NULL; + usb_osal_free(serial->priv); + } +} + +int usbh_cp210x_set_flow_ctrl(struct usbh_serial *serial, bool enable) +{ + struct cp210x_flow_ctl flow_ctl = { 0 }; + uint32_t flow_repl; + uint32_t ctl_hs; + int ret; + + ret = usbh_cp210x_control_in(serial, CP210X_GET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl)); + if (ret < 0) { + return ret; + } + + ctl_hs = flow_ctl.lControlHandshake; + flow_repl = flow_ctl.lFlowReplace; + + ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE; + ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE; + ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY; + ctl_hs &= ~CP210X_SERIAL_DTR_MASK; + ctl_hs |= CP210X_SERIAL_DTR_INACTIVE; + + flow_repl &= ~CP210X_SERIAL_RTS_MASK; + flow_repl &= ~CP210X_SERIAL_AUTO_RECEIVE; + flow_repl &= ~CP210X_SERIAL_AUTO_TRANSMIT; + flow_repl |= CP210X_SERIAL_RTS_INACTIVE; + + flow_repl &= ~CP210X_SERIAL_RTS_MASK; + if (enable) { + ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE; + } else { + ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE; + } + flow_ctl.lControlHandshake = ctl_hs; + flow_ctl.lFlowReplace = flow_repl; + + return usbh_cp210x_control_out(serial, CP210X_SET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl)); +} + +int usbh_cp210x_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + int ret; + + ret = usbh_cp210x_set_baudrate(serial, line_coding->dwDTERate); + if (ret < 0) { + return ret; + } + return usbh_cp210x_set_data_format(serial, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat); +} + +int usbh_cp210x_set_line_state(struct usbh_serial *serial, bool dtr, bool rts) +{ + struct cp210x_flow_ctl flow_ctl = { 0 }; + uint32_t flow_repl; + uint32_t ctl_hs; + uint16_t control = 0; + int ret; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + if (serial->rtscts) { + ret = usbh_cp210x_control_in(serial, CP210X_GET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl)); + if (ret < 0) { + return ret; + } + ctl_hs = flow_ctl.lControlHandshake; + flow_repl = flow_ctl.lFlowReplace; + + ctl_hs &= ~CP210X_SERIAL_DTR_MASK; + if (dtr) + ctl_hs |= CP210X_SERIAL_DTR_ACTIVE; + else + ctl_hs |= CP210X_SERIAL_DTR_INACTIVE; + + flow_repl &= ~CP210X_SERIAL_RTS_MASK; + if (rts) + flow_repl |= CP210X_SERIAL_RTS_FLOW_CTL; + else + flow_repl |= CP210X_SERIAL_RTS_INACTIVE; + + flow_ctl.lControlHandshake = ctl_hs; + flow_ctl.lFlowReplace = flow_repl; + + return usbh_cp210x_control_out(serial, CP210X_SET_FLOW, 0, serial->intf, (uint8_t *)&flow_ctl, sizeof(struct cp210x_flow_ctl)); + } else { + if (dtr) { + control |= CP210X_CONTROL_DTR; + } + if (rts) { + control |= CP210X_CONTROL_RTS; + } + control |= CP210X_CONTROL_WRITE_DTR; + control |= CP210X_CONTROL_WRITE_RTS; + return usbh_cp210x_control_out(serial, CP210X_SET_MHS, control, serial->intf, NULL, 0); + } +} + +static int usbh_cp210x_get_modem_status(struct usbh_serial *serial) +{ + int ret; + uint8_t control; + uint16_t status; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + + ret = usbh_cp210x_control_in(serial, CP210X_GET_MDMSTS, 0, serial->intf, (uint8_t *)&control, 1); + if (ret < 0) { + return ret; + } + + status = ((control & CP210X_CONTROL_DTR) ? USBH_SERIAL_TIOCM_DTR : 0) | + ((control & CP210X_CONTROL_RTS) ? USBH_SERIAL_TIOCM_RTS : 0) | + ((control & CP210X_CONTROL_CTS) ? USBH_SERIAL_TIOCM_CTS : 0) | + ((control & CP210X_CONTROL_DSR) ? USBH_SERIAL_TIOCM_DSR : 0) | + ((control & CP210X_CONTROL_RING) ? USBH_SERIAL_TIOCM_RI : 0) | + ((control & CP210X_CONTROL_DCD) ? USBH_SERIAL_TIOCM_CD : 0); + + return status; +} + +static const struct usbh_serial_driver cp210x_driver = { + .driver_name = "cp210x", + + .ignore_rx_header = 0, + .ignore_tx_header = 0, + + .attach = usbh_cp210x_attach, + .detach = usbh_cp210x_detach, + .set_flow_control = usbh_cp210x_set_flow_ctrl, + .set_line_coding = usbh_cp210x_set_line_coding, + .get_line_coding = NULL, + .set_line_state = usbh_cp210x_set_line_state, + .get_modem_status = usbh_cp210x_get_modem_status, +}; + +static int usbh_cp210x_connect(struct usbh_hubport *hport, uint8_t intf) +{ + return usbh_serial_probe(hport, intf, &cp210x_driver) ? 0 : -USB_ERR_NOMEM; +} + +static int usbh_cp210x_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv; + + if (serial) { + usbh_serial_remove(serial); + } + return 0; +} + +static const uint16_t cp210x_id_table[][2] = { + { 0x10C4, 0xEA60 }, + { 0, 0 }, +}; + +const struct usbh_class_driver cp210x_class_driver = { + .driver_name = "cp210x", + .connect = usbh_cp210x_connect, + .disconnect = usbh_cp210x_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = { + .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .id_table = cp210x_id_table, + .class_driver = &cp210x_class_driver +}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_cp210x.h b/components/drivers/usb/cherryusb/class/serial/usbh_cp210x.h new file mode 100644 index 00000000000..6bd02067729 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_cp210x.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBH_CP210X_H +#define USBH_CP210X_H + +#include "usb_cdc.h" + +/* Requests */ +#define CP210X_IFC_ENABLE 0x00 +#define CP210X_SET_BAUDDIV 0x01 +#define CP210X_GET_BAUDDIV 0x02 +#define CP210X_SET_LINE_CTL 0x03 // Set parity, data bits, stop bits +#define CP210X_GET_LINE_CTL 0x04 +#define CP210X_SET_BREAK 0x05 +#define CP210X_IMM_CHAR 0x06 +#define CP210X_SET_MHS 0x07 // Set DTR, RTS +#define CP210X_GET_MDMSTS 0x08 +#define CP210X_SET_XON 0x09 +#define CP210X_SET_XOFF 0x0A +#define CP210X_SET_EVENTMASK 0x0B +#define CP210X_GET_EVENTMASK 0x0C +#define CP210X_SET_CHAR 0x0D +#define CP210X_GET_CHARS 0x0E +#define CP210X_GET_PROPS 0x0F +#define CP210X_GET_COMM_STATUS 0x10 +#define CP210X_RESET 0x11 +#define CP210X_PURGE 0x12 +#define CP210X_SET_FLOW 0x13 +#define CP210X_GET_FLOW 0x14 +#define CP210X_EMBED_EVENTS 0x15 +#define CP210X_GET_EVENTSTATE 0x16 +#define CP210X_SET_CHARS 0x19 +#define CP210X_GET_BAUDRATE 0x1D +#define CP210X_SET_BAUDRATE 0x1E // Set baudrate +#define CP210X_VENDOR_SPECIFIC 0xFF + +/* CP210X_VENDOR_SPECIFIC values */ +#define CP210X_GET_FW_VER 0x000E +#define CP210X_READ_2NCONFIG 0x000E +#define CP210X_GET_FW_VER_2N 0x0010 +#define CP210X_READ_LATCH 0x00C2 +#define CP210X_GET_PARTNUM 0x370B +#define CP210X_GET_PORTCONFIG 0x370C +#define CP210X_GET_DEVICEMODE 0x3711 +#define CP210X_WRITE_LATCH 0x37E1 + +/* CP210X_IFC_ENABLE */ +#define CP210X_UART_ENABLE 0x0001 +#define CP210X_UART_DISABLE 0x0000 + +/* CP210X_(SET|GET)_BAUDDIV */ +#define CP210X_BAUD_RATE_GEN_FREQ 0x384000 + +/* CP210X_(SET|GET)_LINE_CTL */ +#define CP210X_BITS_DATA_MASK 0X0f00 +#define CP210X_BITS_DATA_5 0X0500 +#define CP210X_BITS_DATA_6 0X0600 +#define CP210X_BITS_DATA_7 0X0700 +#define CP210X_BITS_DATA_8 0X0800 +#define CP210X_BITS_DATA_9 0X0900 + +#define CP210X_BITS_PARITY_MASK 0x00f0 +#define CP210X_BITS_PARITY_NONE 0x0000 +#define CP210X_BITS_PARITY_ODD 0x0010 +#define CP210X_BITS_PARITY_EVEN 0x0020 +#define CP210X_BITS_PARITY_MARK 0x0030 +#define CP210X_BITS_PARITY_SPACE 0x0040 + +#define CP210X_BITS_STOP_MASK 0x000f +#define CP210X_BITS_STOP_1 0x0000 +#define CP210X_BITS_STOP_1_5 0x0001 +#define CP210X_BITS_STOP_2 0x0002 + +/* CP210X_SET_BREAK */ +#define CP210X_BREAK_ON 0x0001 +#define CP210X_BREAK_OFF 0x0000 + +/* CP210X_(SET_MHS|GET_MDMSTS) */ +#define CP210X_CONTROL_DTR 0x0001 +#define CP210X_CONTROL_RTS 0x0002 +#define CP210X_CONTROL_CTS 0x0010 +#define CP210X_CONTROL_DSR 0x0020 +#define CP210X_CONTROL_RING 0x0040 +#define CP210X_CONTROL_DCD 0x0080 +#define CP210X_CONTROL_WRITE_DTR 0x0100 +#define CP210X_CONTROL_WRITE_RTS 0x0200 + +/* CP210X_(GET|SET)_CHARS */ +struct cp210x_special_chars { + uint8_t bEofChar; + uint8_t bErrorChar; + uint8_t bBreakChar; + uint8_t bEventChar; + uint8_t bXonChar; + uint8_t bXoffChar; +}; + +/* CP210X_GET_COMM_STATUS returns these 0x13 bytes */ +struct cp210x_comm_status { + uint32_t ulErrors; + uint32_t ulHoldReasons; + uint32_t ulAmountInInQueue; + uint32_t ulAmountInOutQueue; + uint8_t bEofReceived; + uint8_t bWaitForImmediate; + uint8_t bReserved; +} __PACKED; + +/* + * CP210X_PURGE - 16 bits passed in wValue of USB request. + * SiLabs app note AN571 gives a strange description of the 4 bits: + * bit 0 or bit 2 clears the transmit queue and 1 or 3 receive. + * writing 1 to all, however, purges cp2108 well enough to avoid the hang. + */ +#define PURGE_ALL 0x000f + +/* CP210X_EMBED_EVENTS */ +#define CP210X_ESCCHAR 0xec + +#define CP210X_LSR_OVERRUN BIT(1) +#define CP210X_LSR_PARITY BIT(2) +#define CP210X_LSR_FRAME BIT(3) +#define CP210X_LSR_BREAK BIT(4) + +/* CP210X_GET_FLOW/CP210X_SET_FLOW read/write these 0x10 bytes */ +struct cp210x_flow_ctl { + uint32_t lControlHandshake; + uint32_t lFlowReplace; + uint32_t lXonLimit; + uint32_t lXoffLimit; +}; + +/* cp210x_flow_ctl::ulControlHandshake */ +#define CP210X_SERIAL_DTR_MASK (0x03 << 0) +#define CP210X_SERIAL_DTR_INACTIVE (0 << 0) +#define CP210X_SERIAL_DTR_ACTIVE (1 << 0) +#define CP210X_SERIAL_DTR_FLOW_CTL (2 << 0) +#define CP210X_SERIAL_CTS_HANDSHAKE BIT(3) +#define CP210X_SERIAL_DSR_HANDSHAKE BIT(4) +#define CP210X_SERIAL_DCD_HANDSHAKE BIT(5) +#define CP210X_SERIAL_DSR_SENSITIVITY BIT(6) + +/* cp210x_flow_ctl::ulFlowReplace */ +#define CP210X_SERIAL_AUTO_TRANSMIT BIT(0) +#define CP210X_SERIAL_AUTO_RECEIVE BIT(1) +#define CP210X_SERIAL_ERROR_CHAR BIT(2) +#define CP210X_SERIAL_NULL_STRIPPING BIT(3) +#define CP210X_SERIAL_BREAK_CHAR BIT(4) +#define CP210X_SERIAL_RTS_MASK (0x03 << 6) +#define CP210X_SERIAL_RTS_INACTIVE (0 << 6) +#define CP210X_SERIAL_RTS_ACTIVE (1 << 6) +#define CP210X_SERIAL_RTS_FLOW_CTL (2 << 6) +#define CP210X_SERIAL_XOFF_CONTINUE BIT(31) + +/* CP210X_VENDOR_SPECIFIC, CP210X_GET_DEVICEMODE call reads these 0x2 bytes. */ +struct cp210x_pin_mode { + uint8_t eci; + uint8_t sci; +}; + +#define CP210X_PIN_MODE_MODEM 0 +#define CP210X_PIN_MODE_GPIO BIT(0) + +/* Part number definitions */ +#define CP210X_PARTNUM_CP2101 0x01 +#define CP210X_PARTNUM_CP2102 0x02 +#define CP210X_PARTNUM_CP2103 0x03 +#define CP210X_PARTNUM_CP2104 0x04 +#define CP210X_PARTNUM_CP2105 0x05 +#define CP210X_PARTNUM_CP2108 0x08 +#define CP210X_PARTNUM_CP2102N_QFN28 0x20 +#define CP210X_PARTNUM_CP2102N_QFN24 0x21 +#define CP210X_PARTNUM_CP2102N_QFN20 0x22 +#define CP210X_PARTNUM_UNKNOWN 0xFF + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* USBH_CP210X_H */ diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c b/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c new file mode 100644 index 00000000000..16debf37f1d --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.c @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_serial.h" +#include "usbh_ftdi.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_ftdi" +#include "usb_log.h" + +enum ftdi_chip_type { + SIO, + FT232A, + FT232B, + FT2232C, + FT232R, + FT232H, + FT2232H, + FT4232H, + FT4232HA, + FT232HP, + FT233HP, + FT2232HP, + FT2233HP, + FT4232HP, + FT4233HP, + FTX, +}; + +static const char *ftdi_chip_name[] = { + [SIO] = "SIO", /* the serial part of FT8U100AX */ + [FT232A] = "FT232A", + [FT232B] = "FT232B", + [FT2232C] = "FT2232C/D", + [FT232R] = "FT232R", + [FT232H] = "FT232H", + [FT2232H] = "FT2232H", + [FT4232H] = "FT4232H", + [FT4232HA] = "FT4232HA", + [FT232HP] = "FT232HP", + [FT233HP] = "FT233HP", + [FT2232HP] = "FT2232HP", + [FT2233HP] = "FT2233HP", + [FT4232HP] = "FT4232HP", + [FT4233HP] = "FT4233HP", + [FTX] = "FT-X", +}; + +struct usbh_ftdi { + enum ftdi_chip_type chip_type; +}; + +static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, int base) +{ + static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; + uint32_t divisor; + /* divisor shifted 3 bits to the left */ + int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); + divisor = divisor3 >> 3; + divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14; + /* Deal with special cases for highest baud rates. */ + if (divisor == 1) /* 1.0 */ + divisor = 0; + else if (divisor == 0x4001) /* 1.5 */ + divisor = 1; + return divisor; +} + +static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) +{ + return ftdi_232bm_baud_base_to_divisor(baud, 48000000); +} + +static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, int base) +{ + static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; + uint32_t divisor; + int divisor3; + + /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ + divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud); + + divisor = divisor3 >> 3; + divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14; + /* Deal with special cases for highest baud rates. */ + if (divisor == 1) /* 1.0 */ + divisor = 0; + else if (divisor == 0x4001) /* 1.5 */ + divisor = 1; + /* + * Set this bit to turn off a divide by 2.5 on baud rate generator + * This enables baud rates up to 12Mbaud but cannot reach below 1200 + * baud with this bit set + */ + divisor |= 0x00020000; + return divisor; +} + +static uint32_t ftdi_2232h_baud_to_divisor(uint32_t baud) +{ + return ftdi_2232h_baud_base_to_divisor(baud, 120000000); +} + +int usbh_ftdi_reset(struct usbh_serial *serial) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = FTDI_SIO_RESET; + setup->wValue = 0; + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_ftdi_set_baudrate(struct usbh_serial *serial, uint32_t baudrate) +{ + struct usb_setup_packet *setup; + struct usbh_ftdi *ftdi_class; + uint32_t div_value; + uint16_t value; + uint8_t baudrate_high; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + ftdi_class = (struct usbh_ftdi *)serial->priv; + + switch (ftdi_class->chip_type) { + case FT232B: + case FT2232C: + case FT232R: + if (baudrate > 3000000) { + return -USB_ERR_INVAL; + } + div_value = ftdi_232bm_baud_to_divisor(baudrate); + break; + default: + if ((baudrate <= 12000000) && (baudrate >= 1200)) { + div_value = ftdi_2232h_baud_to_divisor(baudrate); + } else if (baudrate < 1200) { + div_value = ftdi_232bm_baud_to_divisor(baudrate); + } else { + return -USB_ERR_INVAL; + } + break; + } + + value = div_value & 0xFFFF; + baudrate_high = (div_value >> 16) & 0xff; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = FTDI_SIO_SET_BAUDRATE; + setup->wValue = value; + setup->wIndex = (baudrate_high << 8) | serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_ftdi_set_data_format(struct usbh_serial *serial, uint8_t databits, uint8_t parity, uint8_t stopbits, uint8_t isbreak) +{ + /** + * D0-D7 databits BITS_7=7, BITS_8=8 + * D8-D10 parity NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4 + * D11-D12 STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2 + * D14 BREAK_OFF=0, BREAK_ON=1 + **/ + struct usb_setup_packet *setup; + uint16_t value; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + value = ((isbreak & 0x01) << 14) | ((stopbits & 0x03) << 11) | ((parity & 0x0f) << 8) | (databits & 0x0f); + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = FTDI_SIO_SET_DATA; + setup->wValue = value; + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_ftdi_set_latency_timer(struct usbh_serial *serial, uint16_t value) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = FTDI_SIO_SET_LATENCY_TIMER; + setup->wValue = value; + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_ftdi_attach(struct usbh_serial *serial) +{ + uint16_t version; + uint8_t chip_type; + int ret; + + version = serial->hport->device_desc.bcdDevice; + + switch (version) { + case 0x400: + chip_type = FT232B; + break; + case 0x500: + chip_type = FT2232C; + break; + case 0x600: + chip_type = FT232R; + break; + case 0x700: + chip_type = FT2232H; + break; + case 0x900: + chip_type = FT232H; + break; + + default: + USB_LOG_ERR("Unsupported FTDI chip version: 0x%04x\r\n", version); + return -USB_ERR_NOTSUPP; + } + + USB_LOG_INFO("chip name: %s\r\n", ftdi_chip_name[chip_type]); + + struct usbh_ftdi *ftdi_class = usb_osal_malloc(sizeof(struct usbh_ftdi)); + if (!ftdi_class) { + USB_LOG_ERR("No memory for ftdi_class\r\n"); + return -USB_ERR_NOMEM; + } + memset(ftdi_class, 0, sizeof(struct usbh_ftdi)); + serial->priv = ftdi_class; + + ftdi_class->chip_type = chip_type; + ret = usbh_ftdi_set_latency_timer(serial, 0x10); + if (ret < 0) { + goto errout; + } + return 0; +errout: + serial->priv = NULL; + usb_osal_free(ftdi_class); + return ret; +} + +static void usbh_ftdi_detach(struct usbh_serial *serial) +{ + if (serial && serial->priv) { + serial->priv = NULL; + usb_osal_free(serial->priv); + } +} + +static int usbh_ftdi_set_flow_ctrl(struct usbh_serial *serial, bool hardctrl) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = FTDI_SIO_SET_FLOW_CTRL; + setup->wValue = hardctrl ? FTDI_SIO_RTS_CTS_HS : FTDI_SIO_DISABLE_FLOW_CTRL; + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_ftdi_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + int ret = usbh_ftdi_set_baudrate(serial, line_coding->dwDTERate); + if (ret < 0) { + return ret; + } + return usbh_ftdi_set_data_format(serial, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat, 0); +} + +static int usbh_ftdi_set_line_state(struct usbh_serial *serial, bool dtr, bool rts) +{ + struct usb_setup_packet *setup; + uint16_t value = 0; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + value = ((dtr ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW) | (rts ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW)); + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = FTDI_SIO_SET_MODEM_CTRL; + setup->wValue = value; + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_ftdi_get_modem_status(struct usbh_serial *serial) +{ + struct usb_setup_packet *setup; + uint16_t status = 0; + int ret; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = FTDI_SIO_GET_MODEM_STATUS; + setup->wValue = 0x0000; + setup->wIndex = serial->intf; + setup->wLength = 2; + + ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer); + if (ret < 0) { + return 0; + } + + status = (serial->iobuffer[0] & FTDI_SIO_DSR_MASK ? USBH_SERIAL_TIOCM_DSR : 0) | + (serial->iobuffer[0] & FTDI_SIO_CTS_MASK ? USBH_SERIAL_TIOCM_CTS : 0) | + (serial->iobuffer[0] & FTDI_SIO_RI_MASK ? USBH_SERIAL_TIOCM_RI : 0) | + (serial->iobuffer[0] & FTDI_SIO_RLSD_MASK ? USBH_SERIAL_TIOCM_CD : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0); + + return status; +} + +static const struct usbh_serial_driver ftdi_driver = { + .driver_name = "ftdi", + + .ignore_rx_header = 2, + .ignore_tx_header = 0, + + .attach = usbh_ftdi_attach, + .detach = usbh_ftdi_detach, + .set_flow_control = usbh_ftdi_set_flow_ctrl, + .set_line_coding = usbh_ftdi_set_line_coding, + .get_line_coding = NULL, + .set_line_state = usbh_ftdi_set_line_state, + .get_modem_status = usbh_ftdi_get_modem_status, +}; + +static int usbh_ftdi_connect(struct usbh_hubport *hport, uint8_t intf) +{ + return usbh_serial_probe(hport, intf, &ftdi_driver) ? 0 : -USB_ERR_NOMEM; +} + +static int usbh_ftdi_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv; + + if (serial) { + usbh_serial_remove(serial); + } + return 0; +} + +static const uint16_t ftdi_id_table[][2] = { + { 0x0403, 0x6001 }, + { 0x0403, 0x6010 }, + { 0x0403, 0x6014 }, + { 0, 0 }, +}; + +const struct usbh_class_driver ftdi_class_driver = { + .driver_name = "ftdi", + .connect = usbh_ftdi_connect, + .disconnect = usbh_ftdi_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = { + .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .id_table = ftdi_id_table, + .class_driver = &ftdi_class_driver +}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.h b/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.h new file mode 100644 index 00000000000..0d176299ee5 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_ftdi.h @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBH_FTDI_H +#define USBH_FTDI_H + +#include "usb_cdc.h" + +#define FTDI_VID 0x0403 /* Vendor Id */ + +/* FTDI device PIDs */ +#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ +#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ +#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ +#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ +#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */ +#define FTDI_FTX_PID 0x6015 /* FT-X series (FT201X, FT230X, FT231X, etc) */ +#define FTDI_FT2233HP_PID 0x6040 /* Dual channel hi-speed device with PD */ +#define FTDI_FT4233HP_PID 0x6041 /* Quad channel hi-speed device with PD */ +#define FTDI_FT2232HP_PID 0x6042 /* Dual channel hi-speed device with PD */ +#define FTDI_FT4232HP_PID 0x6043 /* Quad channel hi-speed device with PD */ +#define FTDI_FT233HP_PID 0x6044 /* Dual channel hi-speed device with PD */ +#define FTDI_FT232HP_PID 0x6045 /* Dual channel hi-speed device with PD */ +#define FTDI_FT4232HA_PID 0x6048 /* Quad channel automotive grade hi-speed device */ +#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ +#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ + +/* Requests */ +#define FTDI_SIO_RESET 0x00 /* Reset the port */ +#define FTDI_SIO_SET_MODEM_CTRL 0x01 /* Set the modem control register */ +#define FTDI_SIO_SET_FLOW_CTRL 0x02 /* Set flow control register */ +#define FTDI_SIO_SET_BAUDRATE 0x03 /* Set baud rate */ +#define FTDI_SIO_SET_DATA 0x04 /* Set the data characteristics of the port */ +#define FTDI_SIO_GET_MODEM_STATUS 0x05 +#define FTDI_SIO_SET_EVENT_CHAR 0x06 +#define FTDI_SIO_SET_ERROR_CHAR 0x07 +#define FTDI_SIO_SET_LATENCY_TIMER 0x09 +#define FTDI_SIO_GET_LATENCY_TIMER 0x0A +#define FTDI_SIO_SET_BITMODE 0x0B +#define FTDI_SIO_READ_PINS 0x0C +#define FTDI_SIO_READ_EEPROM 0x90 +#define FTDI_SIO_WRITE_EEPROM 0x91 +#define FTDI_SIO_ERASE_EEPROM 0x92 + +/* Channel indices for FT2232, FT2232H and FT4232H devices */ +#define FTDI_SIO_CHANNEL_A 1 +#define FTDI_SIO_CHANNEL_B 2 +#define FTDI_SIO_CHANNEL_C 3 +#define FTDI_SIO_CHANNEL_D 4 + +/* + * BmRequestType: 0100 0000B + * bRequest: FTDI_SIO_RESET + * wValue: Control Value + * 0 = Reset SIO + * 1 = Purge RX buffer + * 2 = Purge TX buffer + * wIndex: Port + * wLength: 0 + * Data: None + * + * The Reset SIO command has this effect: + * + * Sets flow control set to 'none' + * Event char = $0D + * Event trigger = disabled + * Purge RX buffer + * Purge TX buffer + * Clear DTR + * Clear RTS + * baud and data format not reset + * + * The Purge RX and TX buffer commands affect nothing except the buffers + * + */ + +#define FTDI_SIO_RESET_SIO 0 +#define FTDI_SIO_RESET_PURGE_RX 1 +#define FTDI_SIO_RESET_PURGE_TX 2 + +/* + * BmRequestType: 0100 0000B + * bRequest: FTDI_SIO_SET_BAUDRATE + * wValue: BaudDivisor value - see below + * wIndex: Port + * wLength: 0 + * Data: None + * The BaudDivisor values are calculated as follows: + * - BaseClock is either 12000000 or 48000000 depending on the device. + * FIXME: I wish I knew how to detect old chips to select proper base clock! + * - BaudDivisor is a fixed point number encoded in a funny way. + * (--WRONG WAY OF THINKING--) + * BaudDivisor is a fixed point number encoded with following bit weighs: + * (-2)(-1)(13..0). It is a radical with a denominator of 4, so values + * end with 0.0 (00...), 0.25 (10...), 0.5 (01...), and 0.75 (11...). + * (--THE REALITY--) + * The both-bits-set has quite different meaning from 0.75 - the chip + * designers have decided it to mean 0.125 instead of 0.75. + * This info looked up in FTDI application note "FT8U232 DEVICES \ Data Rates + * and Flow Control Consideration for USB to RS232". + * - BaudDivisor = (BaseClock / 16) / BaudRate, where the (=) operation should + * automagically re-encode the resulting value to take fractions into + * consideration. + * As all values are integers, some bit twiddling is in order: + * BaudDivisor = (BaseClock / 16 / BaudRate) | + * (((BaseClock / 2 / BaudRate) & 4) ? 0x4000 // 0.5 + * : ((BaseClock / 2 / BaudRate) & 2) ? 0x8000 // 0.25 + * : ((BaseClock / 2 / BaudRate) & 1) ? 0xc000 // 0.125 + * : 0) + * + * For the FT232BM, a 17th divisor bit was introduced to encode the multiples + * of 0.125 missing from the FT8U232AM. Bits 16 to 14 are coded as follows + * (the first four codes are the same as for the FT8U232AM, where bit 16 is + * always 0): + * 000 - add .000 to divisor + * 001 - add .500 to divisor + * 010 - add .250 to divisor + * 011 - add .125 to divisor + * 100 - add .375 to divisor + * 101 - add .625 to divisor + * 110 - add .750 to divisor + * 111 - add .875 to divisor + * Bits 15 to 0 of the 17-bit divisor are placed in the urb value. Bit 16 is + * placed in bit 0 of the urb index. + * + * Note that there are a couple of special cases to support the highest baud + * rates. If the calculated divisor value is 1, this needs to be replaced with + * 0. Additionally for the FT232BM, if the calculated divisor value is 0x4001 + * (1.5), this needs to be replaced with 0x0001 (1) (but this divisor value is + * not supported by the FT8U232AM). + */ + +enum ftdi_sio_baudrate { + ftdi_sio_b300 = 0, + ftdi_sio_b600 = 1, + ftdi_sio_b1200 = 2, + ftdi_sio_b2400 = 3, + ftdi_sio_b4800 = 4, + ftdi_sio_b9600 = 5, + ftdi_sio_b19200 = 6, + ftdi_sio_b38400 = 7, + ftdi_sio_b57600 = 8, + ftdi_sio_b115200 = 9 +}; + +/* + * BmRequestType: 0100 0000B + * bRequest: FTDI_SIO_SET_DATA + * wValue: Data characteristics (see below) + * wIndex: Port + * wLength: 0 + * Data: No + * + * Data characteristics + * + * B0..7 Number of data bits + * B8..10 Parity + * 0 = None + * 1 = Odd + * 2 = Even + * 3 = Mark + * 4 = Space + * B11..13 Stop Bits + * 0 = 1 + * 1 = 1.5 + * 2 = 2 + * B14 + * 1 = TX ON (break) + * 0 = TX OFF (normal state) + * B15 Reserved + * + */ + +#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8) +#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8) +#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8) +#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8) +#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8) +#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11) +#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11) +#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11) +#define FTDI_SIO_SET_BREAK (0x1 << 14) + +/* + * BmRequestType: 0100 0000B + * bRequest: FTDI_SIO_MODEM_CTRL + * wValue: ControlValue (see below) + * wIndex: Port + * wLength: 0 + * Data: None + * + * NOTE: If the device is in RTS/CTS flow control, the RTS set by this + * command will be IGNORED without an error being returned + * Also - you can not set DTR and RTS with one control message + * + * ControlValue + * B0 DTR state + * 0 = reset + * 1 = set + * B1 RTS state + * 0 = reset + * 1 = set + * B2..7 Reserved + * B8 DTR state enable + * 0 = ignore + * 1 = use DTR state + * B9 RTS state enable + * 0 = ignore + * 1 = use RTS state + * B10..15 Reserved + * + */ + +#define FTDI_SIO_SET_DTR_MASK 0x1 +#define FTDI_SIO_SET_DTR_HIGH ((FTDI_SIO_SET_DTR_MASK << 8) | 1) +#define FTDI_SIO_SET_DTR_LOW ((FTDI_SIO_SET_DTR_MASK << 8) | 0) +#define FTDI_SIO_SET_RTS_MASK 0x2 +#define FTDI_SIO_SET_RTS_HIGH ((FTDI_SIO_SET_RTS_MASK << 8) | 2) +#define FTDI_SIO_SET_RTS_LOW ((FTDI_SIO_SET_RTS_MASK << 8) | 0) + +/* + * BmRequestType: 0100 0000b + * bRequest: FTDI_SIO_SET_FLOW_CTRL + * wValue: Xoff/Xon + * wIndex: Protocol/Port - hIndex is protocol / lIndex is port + * wLength: 0 + * Data: None + * + * hIndex protocol is: + * B0 Output handshaking using RTS/CTS + * 0 = disabled + * 1 = enabled + * B1 Output handshaking using DTR/DSR + * 0 = disabled + * 1 = enabled + * B2 Xon/Xoff handshaking + * 0 = disabled + * 1 = enabled + * + * A value of zero in the hIndex field disables handshaking + * + * If Xon/Xoff handshaking is specified, the hValue field should contain the + * XOFF character and the lValue field contains the XON character. + */ + +#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0 +#define FTDI_SIO_RTS_CTS_HS (0x1 << 8) +#define FTDI_SIO_DTR_DSR_HS (0x2 << 8) +#define FTDI_SIO_XON_XOFF_HS (0x4 << 8) + +/* + * BmRequestType: 1100 0000b + * bRequest: FTDI_SIO_GET_MODEM_STATUS + * wValue: zero + * wIndex: Port + * wLength: 1 + * Data: Status + * + * One byte of data is returned + * B0..3 0 + * B4 CTS + * 0 = inactive + * 1 = active + * B5 DSR + * 0 = inactive + * 1 = active + * B6 Ring Indicator (RI) + * 0 = inactive + * 1 = active + * B7 Receive Line Signal Detect (RLSD) + * 0 = inactive + * 1 = active + */ + +#define FTDI_SIO_CTS_MASK 0x10 +#define FTDI_SIO_DSR_MASK 0x20 +#define FTDI_SIO_RI_MASK 0x40 +#define FTDI_SIO_RLSD_MASK 0x80 + +/* Possible bitmodes for FTDI_SIO_SET_BITMODE_REQUEST */ +#define FTDI_SIO_BITMODE_RESET 0x00 +#define FTDI_SIO_BITMODE_CBUS 0x20 + +/* + * IN Endpoint + * + * The device reserves the first two bytes of data on this endpoint to contain + * the current values of the modem and line status registers. In the absence of + * data, the device generates a message consisting of these two status bytes + * every 40 ms + * + * Byte 0: Modem Status + * + * Offset Description + * B0 Reserved - must be 1 + * B1 Reserved - must be 0 + * B2 Reserved - must be 0 + * B3 Reserved - must be 0 + * B4 Clear to Send (CTS) + * B5 Data Set Ready (DSR) + * B6 Ring Indicator (RI) + * B7 Receive Line Signal Detect (RLSD) + * + * Byte 1: Line Status + * + * Offset Description + * B0 Data Ready (DR) + * B1 Overrun Error (OE) + * B2 Parity Error (PE) + * B3 Framing Error (FE) + * B4 Break Interrupt (BI) + * B5 Transmitter Holding Register (THRE) + * B6 Transmitter Empty (TEMT) + * B7 Error in RCVR FIFO + * + */ +#define FTDI_RS0_CTS (1 << 4) +#define FTDI_RS0_DSR (1 << 5) +#define FTDI_RS0_RI (1 << 6) +#define FTDI_RS0_RLSD (1 << 7) + +#define FTDI_RS_DR 1 +#define FTDI_RS_OE (1 << 1) +#define FTDI_RS_PE (1 << 2) +#define FTDI_RS_FE (1 << 3) +#define FTDI_RS_BI (1 << 4) +#define FTDI_RS_THRE (1 << 5) +#define FTDI_RS_TEMT (1 << 6) +#define FTDI_RS_FIFO (1 << 7) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* USBH_FTDI_H */ diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_gsm.c b/components/drivers/usb/cherryusb/class/serial/usbh_gsm.c new file mode 100644 index 00000000000..63418736602 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_gsm.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_serial.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_gsm" +#include "usb_log.h" + +struct usbh_gsm { + struct usb_endpoint_descriptor *intin; + struct usbh_urb intin_urb; + struct usb_osal_timer *modem_timer; + uint16_t modem_status; +}; + +static int usbh_gsm_attach(struct usbh_serial *serial) +{ + struct usb_endpoint_descriptor *ep_desc; + + struct usbh_gsm *gsm_class = usb_osal_malloc(sizeof(struct usbh_gsm)); + if (!gsm_class) { + USB_LOG_ERR("No memory for gsm_class\r\n"); + return -USB_ERR_NOMEM; + } + memset(gsm_class, 0, sizeof(struct usbh_gsm)); + serial->priv = gsm_class; + + for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) { + ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc; + + if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) { + if (ep_desc->bEndpointAddress & 0x80) { + USBH_EP_INIT(gsm_class->intin, ep_desc); + break; + } else { + } + } + } + + if (!gsm_class->intin) { + USB_LOG_WRN("Do not find interrupt endpoint, so disable modem status monitor\r\n"); + } + return 0; +} + +static void usbh_gsm_detach(struct usbh_serial *serial) +{ + struct usbh_gsm *gsm_class; + + if (!serial || !serial->priv) { + return; + } + + gsm_class = (struct usbh_gsm *)serial->priv; + if (gsm_class->intin) { + usbh_kill_urb(&gsm_class->intin_urb); + } + serial->priv = NULL; + usb_osal_free(gsm_class); +} + +static int usbh_gsm_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + return 0; +} + +static int usbh_gsm_set_line_state(struct usbh_serial *serial, bool dtr, bool rts) +{ + return 0; +} + +static const struct usbh_serial_driver gsm_driver = { + .driver_name = "gsm", + + .ignore_rx_header = 0, + .ignore_tx_header = 0, + + .attach = usbh_gsm_attach, + .detach = usbh_gsm_detach, + .set_flow_control = NULL, + .set_line_coding = usbh_gsm_set_line_coding, + .get_line_coding = NULL, + .set_line_state = usbh_gsm_set_line_state, + .get_modem_status = NULL, +}; + +static int usbh_gsm_connect(struct usbh_hubport *hport, uint8_t intf) +{ + return usbh_serial_probe(hport, intf, &gsm_driver) ? 0 : -USB_ERR_NOMEM; +} + +static int usbh_gsm_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv; + + if (serial) { + usbh_serial_remove(serial); + } + return 0; +} + +const struct usbh_class_driver gsm_class_driver = { + .driver_name = "gsm", + .connect = usbh_gsm_connect, + .disconnect = usbh_gsm_disconnect +}; + +static const uint16_t gsm_id_table[][2] = { + { 0x2C7C, 0x0120 }, /* Quectel EC20 */ + { 0x2C7C, 0x0121 }, /* Quectel EC21 */ + { 0x2C7C, 0x0125 }, /* Quectel EC25 */ + { 0x2C7C, 0x0191 }, /* Quectel EG91 */ + { 0x2C7C, 0x0195 }, /* Quectel EG95 */ + { 0x2C7C, 0x6002 }, /* Quectel EC200/EC600/EC800/EG91x */ + { 0x1E0E, 0x9001 }, /* SIMCOM SIM7600 */ + { 0x2ECC, 0x3012 }, /* Chinamobile ML307R */ + { 0, 0 }, +}; + +CLASS_INFO_DEFINE const struct usbh_class_info gsm_class_info = { + .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .id_table = gsm_id_table, + .class_driver = &gsm_class_driver +}; diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_pl2303.c b/components/drivers/usb/cherryusb/class/serial/usbh_pl2303.c new file mode 100644 index 00000000000..062f8128fdb --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_pl2303.c @@ -0,0 +1,726 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * Copyright (c) 2024, Derek Konigsberg + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_serial.h" +#include "usbh_pl2303.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_pl2303" +#include "usb_log.h" + +#define UART_STATE_INDEX 8 +#define UART_STATE_MSR_MASK 0x8b +#define UART_STATE_TRANSIENT_MASK 0x74 +#define UART_DCD 0x01 +#define UART_DSR 0x02 +#define UART_BREAK_ERROR 0x04 +#define UART_RING 0x08 +#define UART_FRAME_ERROR 0x10 +#define UART_PARITY_ERROR 0x20 +#define UART_OVERRUN_ERROR 0x40 +#define UART_CTS 0x80 + +struct pl2303_type_data { + const char *name; + uint32_t max_baud_rate; + unsigned long quirks; + unsigned int no_autoxonxoff : 1; + unsigned int no_divisors : 1; + unsigned int alt_divisors : 1; +}; + +enum pl2303_type { + TYPE_H, + TYPE_HX, + TYPE_TA, + TYPE_TB, + TYPE_HXD, + TYPE_HXN, + TYPE_COUNT +}; + +struct usbh_pl2303 { + enum pl2303_type chip_type; + uint32_t quirks; + struct usb_endpoint_descriptor *intin; + struct usbh_urb intin_urb; + struct usb_osal_timer *modem_timer; + uint16_t modem_status; +}; + +static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = { + [TYPE_H] = { + .name = "PL2303H", + .max_baud_rate = 1228800, + .quirks = PL2303_QUIRK_LEGACY, + .no_autoxonxoff = true, + }, + [TYPE_HX] = { + .name = "PL2303HX", + .max_baud_rate = 6000000, + }, + [TYPE_TA] = { + .name = "PL2303TA", + .max_baud_rate = 6000000, + .alt_divisors = true, + }, + [TYPE_TB] = { + .name = "PL2303TB", + .max_baud_rate = 12000000, + .alt_divisors = true, + }, + [TYPE_HXD] = { + .name = "PL2303HXD", + .max_baud_rate = 12000000, + }, + [TYPE_HXN] = { + .name = "PL2303G", + .max_baud_rate = 12000000, + .no_divisors = true, + }, +}; + +/* + * Returns the nearest supported baud rate that can be set directly without + * using divisors. + */ +static uint32_t pl2303_get_supported_baud_rate(uint32_t baud) +{ + static const uint32_t baud_sup[] = { + 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, + 14400, 19200, 28800, 38400, 57600, 115200, 230400, 460800, + 614400, 921600, 1228800, 2457600, 3000000, 6000000 + }; + + unsigned i; + + for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) { + if (baud_sup[i] > baud) + break; + } + + if (i == ARRAY_SIZE(baud_sup)) + baud = baud_sup[i - 1]; + else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1])) + baud = baud_sup[i - 1]; + else + baud = baud_sup[i]; + + return baud; +} + +/* + * NOTE: If unsupported baud rates are set directly, the PL2303 seems to + * use 9600 baud. + */ +static uint32_t pl2303_encode_baud_rate_direct(unsigned char buf[4], + uint32_t baud) +{ + memcpy(buf, &baud, 4); + + return baud; +} + +static uint32_t pl2303_encode_baud_rate_divisor_alt(unsigned char buf[4], + uint32_t baud) +{ + unsigned int baseline, mantissa, exponent; + + /* + * Apparently, for the TA version the formula is: + * baudrate = 12M * 32 / (mantissa * 2^exponent) + * where + * mantissa = buf[10:0] + * exponent = buf[15:13 16] + */ + baseline = 12000000 * 32; + mantissa = baseline / baud; + if (mantissa == 0) + mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */ + exponent = 0; + while (mantissa >= 2048) { + if (exponent < 15) { + mantissa >>= 1; /* divide by 2 */ + exponent++; + } else { + /* Exponent is maxed. Trim mantissa and leave. */ + mantissa = 2047; + break; + } + } + + buf[3] = 0x80; + buf[2] = exponent & 0x01; + buf[1] = (exponent & ~0x01) << 4 | mantissa >> 8; + buf[0] = mantissa & 0xff; + + /* Calculate and return the exact baud rate. */ + baud = (baseline / mantissa) >> exponent; + + return baud; +} + +static uint32_t pl2303_encode_baud_rate_divisor(unsigned char buf[4], + uint32_t baud) +{ + unsigned int baseline, mantissa, exponent; + + /* + * Apparently the formula is: + * baudrate = 12M * 32 / (mantissa * 4^exponent) + * where + * mantissa = buf[8:0] + * exponent = buf[11:9] + */ + baseline = 12000000 * 32; + mantissa = baseline / baud; + if (mantissa == 0) + mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */ + exponent = 0; + while (mantissa >= 512) { + if (exponent < 7) { + mantissa >>= 2; /* divide by 4 */ + exponent++; + } else { + /* Exponent is maxed. Trim mantissa and leave. */ + mantissa = 511; + break; + } + } + + buf[3] = 0x80; + buf[2] = 0; + buf[1] = exponent << 1 | mantissa >> 8; + buf[0] = mantissa & 0xff; + + /* Calculate and return the exact baud rate. */ + baud = (baseline / mantissa) >> (exponent << 1); + + return baud; +} + +static int pl2303_vendor_write(struct usbh_serial *serial, uint16_t wValue, uint16_t wIndex) +{ + struct usb_setup_packet *setup; + struct usbh_pl2303 *pl2303_class; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + pl2303_class = (struct usbh_pl2303 *)serial->priv; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = pl2303_class->chip_type == TYPE_HXN ? PL2303_VENDOR_WRITE_NREQUEST : PL2303_VENDOR_WRITE_REQUEST; + setup->wValue = wValue; + setup->wIndex = wIndex; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int pl2303_vendor_read(struct usbh_serial *serial, uint16_t wValue, uint8_t *data) +{ + struct usb_setup_packet *setup; + struct usbh_pl2303 *pl2303_class; + int ret; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + pl2303_class = (struct usbh_pl2303 *)serial->priv; + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = pl2303_class->chip_type == TYPE_HXN ? PL2303_VENDOR_READ_NREQUEST : PL2303_VENDOR_READ_REQUEST; + setup->wValue = wValue; + setup->wIndex = 0; + setup->wLength = 1; + + ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer); + if (ret < 0) { + return ret; + } + memcpy(data, serial->iobuffer, 1); + + return ret; +} + +static bool pl2303_supports_hx_status(struct usbh_serial *serial) +{ + int ret; + uint8_t buf; + + ret = pl2303_vendor_read(serial, PL2303_READ_TYPE_HX_STATUS, &buf); + if (ret < 0) { + return false; + } + + return true; +} + +static bool pl2303_is_hxd_clone(struct usbh_serial *serial) +{ + struct usb_setup_packet *setup; + int ret; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = CDC_REQUEST_GET_LINE_CODING; + setup->wValue = 0; + setup->wIndex = 0; + setup->wLength = 7; + + ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer); + if (ret < 0) { + return false; + } + return true; +} + +static int pl2303_update_reg(struct usbh_serial *serial, uint8_t reg, uint8_t mask, uint8_t val) +{ + int ret; + uint8_t buf[1]; + struct usbh_pl2303 *pl2303_class; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + pl2303_class = (struct usbh_pl2303 *)serial->priv; + + if (pl2303_class->chip_type == TYPE_HXN) + ret = pl2303_vendor_read(serial, reg, buf); + else + ret = pl2303_vendor_read(serial, reg | 0x80, buf); + + if (ret < 0) { + return ret; + } + + *buf &= ~mask; + *buf |= val & mask; + + return pl2303_vendor_write(serial, reg, *buf); +} + +static int usbh_pl2303_get_chiptype(struct usbh_serial *serial) +{ + if (serial->hport->device_desc.bDeviceClass == 0x02) { + return TYPE_H; /* variant 0 */ + } + + if (serial->hport->device_desc.bMaxPacketSize0 != 0x40) { + if (serial->hport->device_desc.bDeviceClass == 0x00 || serial->hport->device_desc.bDeviceClass == 0xff) + return TYPE_H; /* variant 1 */ + + return TYPE_H; /* variant 0 */ + } + + switch (serial->hport->device_desc.bcdUSB) { + case 0x101: + /* USB 1.0.1? Let's assume they meant 1.1... */ + case 0x110: + switch (serial->hport->device_desc.bcdDevice) { + case 0x300: + return TYPE_HX; + case 0x400: + return TYPE_HXD; + default: + return TYPE_HX; + } + break; + case 0x200: + switch (serial->hport->device_desc.bcdDevice) { + case 0x100: /* GC */ + case 0x105: + return TYPE_HXN; + case 0x300: /* GT / TA */ + if (pl2303_supports_hx_status(serial)) + return TYPE_TA; + __attribute__((fallthrough)); + case 0x305: + case 0x400: /* GL */ + case 0x405: + return TYPE_HXN; + case 0x500: /* GE / TB */ + if (pl2303_supports_hx_status(serial)) + return TYPE_TB; + __attribute__((fallthrough)); + case 0x505: + case 0x600: /* GS */ + case 0x605: + case 0x700: /* GR */ + case 0x705: + case 0x905: /* GT-2AB */ + case 0x1005: /* GC-Q20 */ + return TYPE_HXN; + } + break; + } + + USB_LOG_ERR("Unsupported PL2303 Device\r\n"); + return -USB_ERR_NOTSUPP; +} + +static int usbh_pl2303_attach(struct usbh_serial *serial) +{ + struct usbh_pl2303 *pl2303_class; + struct usb_endpoint_descriptor *ep_desc; + uint8_t type; + int ret; + + ret = usbh_pl2303_get_chiptype(serial); + if (ret < 0) { + return ret; + } + + pl2303_class = usb_osal_malloc(sizeof(struct usbh_pl2303)); + if (pl2303_class == NULL) { + USB_LOG_ERR("Fail to alloc pl2303_class\r\n"); + return -USB_ERR_NOMEM; + } + memset(pl2303_class, 0, sizeof(struct usbh_pl2303)); + serial->priv = pl2303_class; + + for (uint8_t i = 0; i < serial->hport->config.intf[serial->intf].altsetting[0].intf_desc.bNumEndpoints; i++) { + ep_desc = &serial->hport->config.intf[serial->intf].altsetting[0].ep[i].ep_desc; + + if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) { + if (ep_desc->bEndpointAddress & 0x80) { + USBH_EP_INIT(pl2303_class->intin, ep_desc); + break; + } else { + } + } + } + + if (!pl2303_class->intin) { + USB_LOG_ERR("Failed to find interrupt endpoint\r\n"); + ret = -USB_ERR_NODEV; + goto errout; + } + + type = (uint8_t)ret; + pl2303_class->chip_type = type; + pl2303_class->quirks = pl2303_type_data[pl2303_class->chip_type].quirks; + + USB_LOG_INFO("chip type: %s\r\n", pl2303_type_data[pl2303_class->chip_type].name); + + if (type == TYPE_HXD && pl2303_is_hxd_clone(serial)) { + pl2303_class->quirks |= PL2303_QUIRK_NO_BREAK_GETLINE; + } + + if (type != TYPE_HXN) { + uint8_t buf[1]; + ret = pl2303_vendor_read(serial, 0x8484, buf); + ret |= pl2303_vendor_write(serial, 0x0404, 0); + ret |= pl2303_vendor_read(serial, 0x8484, buf); + ret |= pl2303_vendor_read(serial, 0x8383, buf); + ret |= pl2303_vendor_read(serial, 0x8484, buf); + ret |= pl2303_vendor_write(serial, 0x0404, 1); + ret |= pl2303_vendor_read(serial, 0x8484, buf); + ret |= pl2303_vendor_read(serial, 0x8383, buf); + ret |= pl2303_vendor_write(serial, 0, 1); + ret |= pl2303_vendor_write(serial, 1, 0); + if (pl2303_class->quirks & PL2303_QUIRK_LEGACY) + ret |= pl2303_vendor_write(serial, 2, 0x24); + else + ret |= pl2303_vendor_write(serial, 2, 0x44); + } else { + ret = 0; + } + + if (ret < 0) { + USB_LOG_ERR("pl2303 init failed\r\n"); + goto errout; + } + + return 0; +errout: + serial->priv = NULL; + usb_osal_free(pl2303_class); + return ret; +} + +static void usbh_pl2303_detach(struct usbh_serial *serial) +{ + struct usbh_pl2303 *pl2303_class; + + if (!serial || !serial->priv) { + return; + } + + pl2303_class = (struct usbh_pl2303 *)serial->priv; + if (pl2303_class->intin) { + usbh_kill_urb(&pl2303_class->intin_urb); + } + serial->priv = NULL; + usb_osal_free(pl2303_class); +} + +static int usbh_pl2303_set_flow_ctrl(struct usbh_serial *serial, bool hardctrl) +{ + struct usbh_pl2303 *pl2303_class; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + pl2303_class = (struct usbh_pl2303 *)serial->priv; + + if (hardctrl) { + if (pl2303_class->quirks & PL2303_QUIRK_LEGACY) { + return pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x40); + } else if (pl2303_class->chip_type == TYPE_HXN) { + return pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG, + PL2303_HXN_FLOWCTRL_MASK, + PL2303_HXN_FLOWCTRL_RTS_CTS); + } else { + return pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x60); + } + } else { + if (pl2303_class->chip_type == TYPE_HXN) { + return pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG, + PL2303_HXN_FLOWCTRL_MASK, + PL2303_HXN_FLOWCTRL_NONE); + } else { + return pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0); + } + } +} + +static int usbh_pl2303_set_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + struct usb_setup_packet *setup; + struct usbh_pl2303 *pl2303_class; + uint32_t baud; + uint32_t baud_sup; + uint8_t buf[7]; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + setup = serial->hport->setup; + pl2303_class = (struct usbh_pl2303 *)serial->priv; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CDC_REQUEST_SET_LINE_CODING; + setup->wValue = 0; + setup->wIndex = serial->intf; + setup->wLength = 7; + + baud = line_coding->dwDTERate; + if (pl2303_type_data[pl2303_class->chip_type].max_baud_rate) { + baud = MIN(baud, pl2303_type_data[pl2303_class->chip_type].max_baud_rate); + } + /* + * Use direct method for supported baud rates, otherwise use divisors. + * Newer chip types do not support divisor encoding. + */ + if (pl2303_type_data[pl2303_class->chip_type].no_divisors) + baud_sup = baud; + else + baud_sup = pl2303_get_supported_baud_rate(baud); + + if (baud == baud_sup) + baud = pl2303_encode_baud_rate_direct(buf, baud); + else if (pl2303_type_data[pl2303_class->chip_type].alt_divisors) + baud = pl2303_encode_baud_rate_divisor_alt(buf, baud); + else + baud = pl2303_encode_baud_rate_divisor(buf, baud); + + buf[4] = line_coding->bCharFormat; + buf[5] = line_coding->bParityType; + buf[6] = line_coding->bDataBits; + + memcpy(serial->iobuffer, buf, sizeof(struct cdc_line_coding)); + + return usbh_control_transfer(serial->hport, setup, serial->iobuffer); +} + +static int usbh_pl2303_get_line_coding(struct usbh_serial *serial, struct cdc_line_coding *line_coding) +{ + struct usb_setup_packet *setup; + int ret; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CDC_REQUEST_GET_LINE_CODING; + setup->wValue = 0; + setup->wIndex = serial->intf; + setup->wLength = 7; + + ret = usbh_control_transfer(serial->hport, setup, serial->iobuffer); + if (ret < 0) { + return ret; + } + memcpy(line_coding, serial->iobuffer, sizeof(struct cdc_line_coding)); + return ret; +} + +static int usbh_pl2303_set_line_state(struct usbh_serial *serial, bool dtr, bool rts) +{ + struct usb_setup_packet *setup; + + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + setup = serial->hport->setup; + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE; + setup->wValue = (dtr << 0) | (rts << 1); + setup->wIndex = serial->intf; + setup->wLength = 0; + + return usbh_control_transfer(serial->hport, setup, NULL); +} + +static int usbh_pl2303_get_modem_status(struct usbh_serial *serial) +{ + struct usbh_pl2303 *pl2303_class; + uintptr_t flags; + uint16_t status; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + + flags = usb_osal_enter_critical_section(); + pl2303_class = (struct usbh_pl2303 *)serial->priv; + + status = (pl2303_class->modem_status & UART_DSR ? USBH_SERIAL_TIOCM_DSR : 0) | + (pl2303_class->modem_status & UART_CTS ? USBH_SERIAL_TIOCM_CTS : 0) | + (pl2303_class->modem_status & UART_RING ? USBH_SERIAL_TIOCM_RI : 0) | + (pl2303_class->modem_status & UART_DCD ? USBH_SERIAL_TIOCM_CD : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_DTR ? USBH_SERIAL_TIOCM_DTR : 0) | + (serial->line_state & USBH_SERIAL_TIOCM_RTS ? USBH_SERIAL_TIOCM_RTS : 0); + + usb_osal_leave_critical_section(flags); + + return status; +} + +#ifdef CONFIG_USBH_SERIAL_GET_MODEM_STATUS +static int __usbh_pl2303_get_modem_status(struct usbh_serial *serial) +{ + struct usbh_pl2303 *pl2303_class; + uint8_t status = 0; + uint16_t difference; + uintptr_t flags; + int ret; + + if (!serial || !serial->hport || !serial->priv) { + return -USB_ERR_INVAL; + } + pl2303_class = (struct usbh_pl2303 *)serial->priv; + + usbh_int_urb_fill(&pl2303_class->intin_urb, serial->hport, pl2303_class->intin, &serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET], pl2303_class->intin->wMaxPacketSize, 0xffffffff, NULL, NULL); + ret = usbh_submit_urb(&pl2303_class->intin_urb); + if (ret < 0) { + return ret; + } + + if (ret < 1) { + return -USB_ERR_INVAL; + } + + flags = usb_osal_enter_critical_section(); + + status = serial->iobuffer[USBH_SERIAL_INT_NOCACHE_OFFSET]; + difference = pl2303_class->modem_status ^ status; + pl2303_class->modem_status = status; + + if (status & UART_BREAK_ERROR) + serial->iocount.brk++; + + if (difference & UART_STATE_MSR_MASK) { + if (difference & UART_CTS) + serial->iocount.cts++; + if (difference & UART_DSR) + serial->iocount.dsr++; + if (difference & UART_RING) + serial->iocount.rng++; + if (difference & UART_DCD) { + serial->iocount.dcd++; + } + } + + usb_osal_leave_critical_section(flags); + + return ret; +} +#endif + +static const struct usbh_serial_driver pl2303_driver = { + .driver_name = "pl2303", + + .ignore_rx_header = 0, + .ignore_tx_header = 0, + + .attach = usbh_pl2303_attach, + .detach = usbh_pl2303_detach, + .set_flow_control = usbh_pl2303_set_flow_ctrl, + .set_line_coding = usbh_pl2303_set_line_coding, + .get_line_coding = usbh_pl2303_get_line_coding, + .set_line_state = usbh_pl2303_set_line_state, + .get_modem_status = usbh_pl2303_get_modem_status, +}; + +static int usbh_pl2303_connect(struct usbh_hubport *hport, uint8_t intf) +{ + return usbh_serial_probe(hport, intf, &pl2303_driver) ? 0 : -USB_ERR_NOMEM; +} + +static int usbh_pl2303_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + struct usbh_serial *serial = (struct usbh_serial *)hport->config.intf[intf].priv; + + if (serial) { + usbh_serial_remove(serial); + } + + return 0; +} + +static const uint16_t pl2303_id_table[][2] = { + { 0x067B, 0x2303 }, // PL2303 Serial (ATEN/IOGEAR UC232A) + { 0x067B, 0x2304 }, // PL2303HXN Serial, type TB + { 0x067B, 0x23A3 }, // PL2303HXN Serial, type GC + { 0x067B, 0x23B3 }, // PL2303HXN Serial, type GB + { 0x067B, 0x23C3 }, // PL2303HXN Serial, type GT + { 0x067B, 0x23D3 }, // PL2303HXN Serial, type GL + { 0x067B, 0x23E3 }, // PL2303HXN Serial, type GE + { 0x067B, 0x23F3 }, // PL2303HXN Serial, type GS + { 0, 0 }, +}; + +const struct usbh_class_driver pl2303_class_driver = { + .driver_name = "pl2303", + .connect = usbh_pl2303_connect, + .disconnect = usbh_pl2303_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info pl2303_class_info = { + .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .id_table = pl2303_id_table, + .class_driver = &pl2303_class_driver +}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_pl2303.h b/components/drivers/usb/cherryusb/class/serial/usbh_pl2303.h new file mode 100644 index 00000000000..83391c16495 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_pl2303.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 ~ 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBH_PL2303_H +#define USBH_PL2303_H + +#include "usb_cdc.h" + +#define PL2303_VENDOR_WRITE_REQUEST 0x01 +#define PL2303_VENDOR_WRITE_NREQUEST 0x80 +#define PL2303_VENDOR_READ_REQUEST 0x01 +#define PL2303_VENDOR_READ_NREQUEST 0x81 + +#define PL2303_FLOWCTRL_MASK 0xf0 + +#define PL2303_READ_TYPE_HX_STATUS 0x8080 + +#define PL2303_HXN_RESET_REG 0x07 +#define PL2303_HXN_RESET_UPSTREAM_PIPE 0x02 +#define PL2303_HXN_RESET_DOWNSTREAM_PIPE 0x01 + +#define PL2303_HXN_FLOWCTRL_REG 0x0a +#define PL2303_HXN_FLOWCTRL_MASK 0x1c +#define PL2303_HXN_FLOWCTRL_NONE 0x1c +#define PL2303_HXN_FLOWCTRL_RTS_CTS 0x18 +#define PL2303_HXN_FLOWCTRL_XON_XOFF 0x0c + +#define PL2303_QUIRK_UART_STATE_IDX0 BIT(0) +#define PL2303_QUIRK_LEGACY BIT(1) +#define PL2303_QUIRK_ENDPOINT_HACK BIT(2) +#define PL2303_QUIRK_NO_BREAK_GETLINE BIT(3) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* USBH_PL2303_H */ diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_serial.c b/components/drivers/usb/cherryusb/class/serial/usbh_serial.c new file mode 100644 index 00000000000..d6361b211a3 --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_serial.c @@ -0,0 +1,743 @@ +/* + * Copyright (c) 2025, sakumisu + * Copyright (c) 2025, MDLZCOOL + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbh_core.h" +#include "usbh_serial.h" + +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbh_serial" +#include "usb_log.h" + +#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; +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; + uint8_t devno2; + + for (devno = 0; devno < CONFIG_USBHOST_MAX_SERIAL_CLASS; devno++) { + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); + memset(&g_serial_class[devno], 0, sizeof(struct usbh_serial)); + g_serial_class[devno].minor = devno; + g_serial_class[devno].cdc_minor = -1; + g_serial_class[devno].iobuffer = g_serial_iobuffer[devno]; + g_serial_class[devno].rx_complete_sem = usb_osal_sem_create(0); + + if (is_cdcacm) { + for (devno2 = 0; devno2 < CONFIG_USBHOST_MAX_SERIAL_CLASS; devno2++) { + if ((g_cdcacm_devinuse & (1U << devno2)) == 0) { + g_cdcacm_devinuse |= (1U << devno2); + g_serial_class[devno].cdc_minor = devno2; + return &g_serial_class[devno]; + } + } + + g_devinuse &= ~(1U << devno); + return NULL; + } else { + return &g_serial_class[devno]; + } + } + } + return NULL; +} + +static void usbh_serial_free(struct usbh_serial *serial) +{ + uint8_t devno = serial->minor; + if (devno < 32) { + g_devinuse &= ~(1U << devno); + } + + if (serial->cdc_minor >= 0) { + g_cdcacm_devinuse &= ~(1U << serial->cdc_minor); + } + + if (g_serial_class[devno].rx_complete_sem) { + usb_osal_sem_delete(g_serial_class[devno].rx_complete_sem); + } +} + +static void usbh_serial_callback(void *arg, int nbytes) +{ + struct usbh_serial *serial = (struct usbh_serial *)arg; + int ret; + + if (nbytes < 0) { + if (nbytes != -USB_ERR_SHUTDOWN) { + USB_LOG_ERR("serial transfer error: %d\n", nbytes); + } + serial->rx_errorcode = nbytes; + usb_osal_sem_give(serial->rx_complete_sem); + return; + } + + if (nbytes < serial->driver->ignore_rx_header) { + USB_LOG_ERR("serial rx short packet: %d\n", nbytes); + serial->rx_errorcode = -USB_ERR_IO; + usb_osal_sem_give(serial->rx_complete_sem); + return; + } + + if (nbytes >= serial->driver->ignore_rx_header) { + /* resubmit the read urb */ + usbh_bulk_urb_fill(&serial->bulkin_urb, serial->hport, serial->bulkin, &serial->iobuffer[serial->rx_buf_index ? USBH_SERIAL_RX_NOCACHE_OFFSET : USBH_SERIAL_RX2_NOCACHE_OFFSET], serial->bulkin->wMaxPacketSize, + 0, usbh_serial_callback, serial); + ret = usbh_submit_urb(&serial->bulkin_urb); + if (ret < 0) { + USB_LOG_ERR("serial submit failed: %d\n", ret); + serial->rx_errorcode = ret; + usb_osal_sem_give(serial->rx_complete_sem); + 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)); + + if (serial->rx_complete_callback) { + serial->rx_complete_callback(serial, nbytes - serial->driver->ignore_rx_header); + } + serial->rx_buf_index ^= 1; + serial->rx_errorcode = 0; + usb_osal_sem_give(serial->rx_complete_sem); + } +} + +struct usbh_serial *usbh_serial_probe(struct usbh_hubport *hport, uint8_t intf, + const struct usbh_serial_driver *driver) +{ + struct usb_endpoint_descriptor *ep_desc; + struct usbh_serial *serial; + bool is_cdcacm = false; + int ret; + + if (strcmp(driver->driver_name, "cdc_acm") == 0) { + is_cdcacm = true; + } + + serial = usbh_serial_alloc(is_cdcacm); + if (serial == NULL) { + USB_LOG_ERR("Fail to alloc serial class\r\n"); + return NULL; + } + + serial->hport = hport; + serial->intf = intf; + serial->driver = driver; + + if (driver->attach) { + ret = driver->attach(serial); + if (ret < 0) { + USB_LOG_ERR("Serial attach failed: %d\r\n", ret); + usbh_serial_free(serial); + return NULL; + } + } + + if (is_cdcacm) { + intf = intf + 1; /* data interface */ + } + + for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { + ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; + + if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_BULK) { + if (ep_desc->bEndpointAddress & 0x80) { + USBH_EP_INIT(serial->bulkin, ep_desc); + } else { + USBH_EP_INIT(serial->bulkout, ep_desc); + } + } + } + + if (is_cdcacm) { + intf = intf - 1; /* data interface */ + } + + if (!serial->bulkin || !serial->bulkout) { + USB_LOG_ERR("Serial bulk in/out endpoint not found\r\n"); + usbh_serial_free(serial); + return NULL; + } + + if (is_cdcacm) { + snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->cdc_minor); + } else { + snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_VENDOR, serial->minor); + } + + hport->config.intf[intf].priv = serial; + USB_LOG_INFO("Register Serial Class: %s (%s)\r\n", hport->config.intf[intf].devname, driver->driver_name); + + usbh_serial_run(serial); + + return serial; +} + +void usbh_serial_remove(struct usbh_serial *serial) +{ + if (!serial || !serial->hport) + return; + + usbh_serial_close(serial); + + if (serial->driver && serial->driver->detach) { + serial->driver->detach(serial); + } + + if (serial->hport->config.intf[serial->intf].priv) { + usb_osal_thread_schedule_other(); + USB_LOG_INFO("Unregister Serial Class: %s (%s)\r\n", serial->hport->config.intf[serial->intf].devname, serial->driver->driver_name); + usbh_serial_stop(serial); + } + + usbh_serial_free(serial); +} + +struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags) +{ + struct usbh_serial *serial; + int ret; + + serial = usbh_find_class_instance(devname); + if (!serial) { + return NULL; + } + + if (serial->ref_count != 0) { + USB_LOG_ERR("Device busy: %s\r\n", devname); + return NULL; + } + + if (serial && serial->driver && serial->driver->open) { + ret = serial->driver->open(serial); + if (ret < 0) { + return NULL; + } + } + + usbh_serial_ringbuffer_init(&serial->rx_rb, serial->rx_rb_pool, CONFIG_USBHOST_SERIAL_RX_SIZE); + + serial->ref_count++; + serial->open_flags = open_flags; + + return serial; +} + +int usbh_serial_close(struct usbh_serial *serial) +{ + if (!serial || !serial->hport) { + return -USB_ERR_INVAL; + } + + if (serial->ref_count == 0) { + return 0; + } + + if (serial->bulkin) { + usbh_kill_urb(&serial->bulkin_urb); + } + if (serial->bulkout) { + usbh_kill_urb(&serial->bulkout_urb); + } + + if (serial && serial->driver && serial->driver->set_flow_control && serial->rtscts) { + serial->driver->set_flow_control(serial, false); + } + + if (serial && serial->driver && serial->driver->close) { + serial->driver->close(serial); + } + + serial->ref_count--; + serial->rtscts = false; + + return 0; +} + +static int usbh_serial_tiocmset(struct usbh_serial *serial, uint32_t set, uint32_t clear) +{ + int ret; + uint16_t line_state; + bool dtr; + bool rts; + + if (!serial || !serial->hport || !serial->hport->connected) { + return -USB_ERR_INVAL; + } + + if (serial->ref_count == 0) { + return -USB_ERR_NODEV; + } + + line_state = serial->line_state; + clear &= ~set; /* 'set' takes precedence over 'clear' */ + + if (set & USBH_SERIAL_TIOCM_DTR) { + line_state |= USBH_SERIAL_TIOCM_DTR; + } + if (set & USBH_SERIAL_TIOCM_RTS) { + line_state |= USBH_SERIAL_TIOCM_RTS; + } + if (clear & USBH_SERIAL_TIOCM_DTR) { + line_state &= ~USBH_SERIAL_TIOCM_DTR; + } + if (clear & USBH_SERIAL_TIOCM_RTS) { + line_state &= ~USBH_SERIAL_TIOCM_RTS; + } + + dtr = (line_state & USBH_SERIAL_TIOCM_DTR) ? true : false; + rts = (line_state & USBH_SERIAL_TIOCM_RTS) ? true : false; + + if (serial && serial->driver && serial->driver->set_line_state) { + ret = serial->driver->set_line_state(serial, dtr, rts); + } else { + return -USB_ERR_NOTSUPP; + } + serial->line_state = line_state; + + return ret; +} + +int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg) +{ + int ret; + + if (!serial || !serial->hport || !serial->hport->connected) { + return -USB_ERR_INVAL; + } + + if (serial->ref_count == 0) { + return -USB_ERR_NODEV; + } + + switch (cmd) { + case USBH_SERIAL_CMD_SET_ATTR: { + struct usbh_serial_termios *termios = (struct usbh_serial_termios *)arg; + struct cdc_line_coding line_coding; + + line_coding.dwDTERate = termios->baudrate; + line_coding.bCharFormat = termios->stopbits; + line_coding.bParityType = termios->parity; + line_coding.bDataBits = termios->databits; + + if (serial->bulkin) { + usbh_kill_urb(&serial->bulkin_urb); + } + if (serial->bulkout) { + usbh_kill_urb(&serial->bulkout_urb); + } + + if (serial && serial->driver && serial->driver->set_line_coding) { + ret = serial->driver->set_line_coding(serial, &line_coding); + if (ret < 0) { + return ret; + } + } else { + return -USB_ERR_NOTSUPP; + } + + memcpy(&serial->line_coding, &line_coding, sizeof(struct cdc_line_coding)); + + if (serial && serial->driver && serial->driver->set_flow_control) { + ret = serial->driver->set_flow_control(serial, termios->rtscts); + } + + serial->rtscts = termios->rtscts; + serial->rx_timeout_ms = termios->rx_timeout; + + ret = usbh_serial_tiocmset(serial, USBH_SERIAL_TIOCM_DTR | USBH_SERIAL_TIOCM_RTS, 0); + if (ret < 0) { + return ret; + } + + usbh_serial_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, + 0, usbh_serial_callback, serial); + ret = usbh_submit_urb(&serial->bulkin_urb); + + return ret; + } break; + case USBH_SERIAL_CMD_GET_ATTR: { + struct usbh_serial_termios *termios = (struct usbh_serial_termios *)arg; + struct cdc_line_coding line_coding; + + if (serial && serial->driver && serial->driver->get_line_coding) { + return serial->driver->get_line_coding(serial, &line_coding); + } else { + memcpy(&line_coding, &serial->line_coding, sizeof(struct cdc_line_coding)); + } + + termios->baudrate = line_coding.dwDTERate; + termios->stopbits = line_coding.bCharFormat; + termios->parity = line_coding.bParityType; + termios->databits = line_coding.bDataBits; + termios->rtscts = serial->rtscts; + termios->rx_timeout = serial->rx_timeout_ms; + return 0; + } break; + case USBH_SERIAL_CMD_IOCMBIS: { + uint32_t flags = *(uint32_t *)arg; + + return usbh_serial_tiocmset(serial, flags, 0); + } break; + case USBH_SERIAL_CMD_IOCMBIC: { + uint32_t flags = *(uint32_t *)arg; + + return usbh_serial_tiocmset(serial, 0, flags); + } break; + case USBH_SERIAL_CMD_TIOCMSET: { + uint32_t flags = *(uint32_t *)arg; + + uint32_t set = 0; + uint32_t clear = 0; + + set |= (flags & USBH_SERIAL_TIOCM_DTR) ? USBH_SERIAL_TIOCM_DTR : 0; + set |= (flags & USBH_SERIAL_TIOCM_RTS) ? USBH_SERIAL_TIOCM_RTS : 0; + clear |= !(flags & USBH_SERIAL_TIOCM_DTR) ? USBH_SERIAL_TIOCM_DTR : 0; + clear |= !(flags & USBH_SERIAL_TIOCM_RTS) ? USBH_SERIAL_TIOCM_RTS : 0; + + return usbh_serial_tiocmset(serial, set, clear); + } break; + case USBH_SERIAL_CMD_TIOCMGET: { + uint32_t *flags = (uint32_t *)arg; + int status; + + if (serial && serial->driver && serial->driver->get_modem_status) { + status = serial->driver->get_modem_status(serial); + if (status < 0) { + return status; + } + } else { + return -USB_ERR_NOTSUPP; + } + *flags = status; + } break; + default: + break; + } + + return -USB_ERR_NOTSUPP; +} + +int usbh_serial_write(struct usbh_serial *serial, const void *buffer, uint32_t buflen) +{ + int ret; + struct usbh_urb *urb; + + if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkout) { + return -USB_ERR_INVAL; + } + + if (serial->ref_count == 0) { + return -USB_ERR_NODEV; + } + + urb = &serial->bulkout_urb; + + usbh_bulk_urb_fill(urb, serial->hport, serial->bulkout, (uint8_t *)buffer, buflen, 0xffffffff, NULL, NULL); + ret = usbh_submit_urb(urb); + if (ret == 0) { + ret = urb->actual_length; + } + return ret; +} + +int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen) +{ + int ret; + + if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkin || !serial->line_coding.dwDTERate) { + return -USB_ERR_INVAL; + } + + if (serial->ref_count == 0) { + return -USB_ERR_NODEV; + } + + if (serial->open_flags & USBH_SERIAL_O_NONBLOCK) { + return usbh_serial_ringbuffer_read(&serial->rx_rb, buffer, buflen); + } else { + if (usbh_serial_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; + } + if (serial->rx_errorcode < 0) { + return serial->rx_errorcode; + } + } + return usbh_serial_ringbuffer_read(&serial->rx_rb, buffer, buflen); + } +} + +int usbh_serial_cdc_write_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg) +{ + struct usbh_urb *urb; + + if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkout || !complete || serial->line_coding.dwDTERate) { + return -USB_ERR_INVAL; + } + + if (serial->ref_count == 0) { + return -USB_ERR_NODEV; + } + + urb = &serial->bulkout_urb; + + usbh_bulk_urb_fill(urb, serial->hport, serial->bulkout, buffer, buflen, + 0, complete, serial); + return usbh_submit_urb(urb); +} + +int usbh_serial_cdc_read_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg) +{ + struct usbh_urb *urb; + + if (!serial || !serial->hport || !serial->hport->connected || !serial->bulkin || !complete || serial->line_coding.dwDTERate) { + return -USB_ERR_INVAL; + } + + if (serial->ref_count == 0) { + return -USB_ERR_NODEV; + } + + if (buflen % serial->bulkin->wMaxPacketSize) { + return -USB_ERR_INVAL; + } + + urb = &serial->bulkin_urb; + + usbh_bulk_urb_fill(urb, serial->hport, serial->bulkin, buffer, MIN(buflen, serial->bulkin->wMaxPacketSize), + 0, complete, serial); + return usbh_submit_urb(urb); +} + +void usbh_serial_help(void) +{ + USB_LOG_RAW("USB host serial test\r\n" + "Usage: usbh_serial [options]...\r\n" + "\r\n" + "-b set serial baudrate\r\n" + "-t set rts and dtr\r\n" + "-w string write string\r\n" + "-r read data and dump\r\n" + "-x close serial device\r\n" + "\r\n"); +} + +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_serial_testbuffer[512]; + +int usbh_serial(int argc, char **argv) +{ + static struct usbh_serial *serial; + int ret; + + if (argc < 3) { + usbh_serial_help(); + return 0; + } + + if (serial) { + if (!serial->hport || !serial->hport->connected) { + serial = NULL; + } + } + + if (!serial) { + serial = usbh_serial_open(argv[1], USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK); + if (!serial) { + USB_LOG_ERR("Fail to open serial device: %s\r\n", argv[1]); + return -USB_ERR_INVAL; + } + } + + if (strncmp(argv[2], "-b", 2) == 0 && argc >= 4) { + struct usbh_serial_termios termios; + + memset(&termios, 0, sizeof(termios)); + termios.baudrate = atoi(argv[3]); + termios.stopbits = 0; + termios.parity = 0; + termios.databits = 8; + termios.rtscts = false; + termios.rx_timeout = 0; + usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios); + } else if (strncmp(argv[2], "-t", 2) == 0 && argc >= 5) { + uint32_t flags; + + flags = atoi(argv[3]) ? USBH_SERIAL_TIOCM_DTR : 0; + flags |= atoi(argv[4]) ? USBH_SERIAL_TIOCM_RTS : 0; + + usbh_serial_control(serial, USBH_SERIAL_CMD_TIOCMSET, &flags); + USB_LOG_INFO("Set DTR: %d, RTS: %d\r\n", atoi(argv[3]), atoi(argv[4])); + } else if (strncmp(argv[2], "-w", 2) == 0 && argc >= 4) { + memcpy(g_serial_testbuffer, argv[3], MIN(strlen(argv[3]), sizeof(g_serial_testbuffer))); + uint32_t len = snprintf((char *)g_serial_testbuffer, sizeof(g_serial_testbuffer), "%s\r\n", argv[3]); + ret = usbh_serial_write(serial, g_serial_testbuffer, len); + if (ret >= 0) { + USB_LOG_INFO("Write %d bytes\r\n", ret); + } else { + USB_LOG_ERR("Write failed: %d\r\n", ret); + } + } else if (strncmp(argv[2], "-r", 2) == 0) { + ret = usbh_serial_read(serial, g_serial_testbuffer, sizeof(g_serial_testbuffer)); + if (ret >= 0) { + usb_hexdump(g_serial_testbuffer, ret); + USB_LOG_INFO("Read %d bytes\r\n", ret); + } else { + USB_LOG_ERR("Read failed: %d\r\n", ret); + } + } else if (strncmp(argv[2], "-x", 2) == 0) { + usbh_serial_close(serial); + serial = NULL; + } else { + usbh_serial_help(); + } + + return 0; +} + +__WEAK void usbh_serial_run(struct usbh_serial *serial) +{ + (void)serial; +} + +__WEAK void usbh_serial_stop(struct usbh_serial *serial) +{ + (void)serial; +} + +static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf) +{ + (void)hport; + (void)intf; + return 0; +} + +static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf) +{ + (void)hport; + (void)intf; + return 0; +} + +const struct usbh_class_driver cdc_data_class_driver = { + .driver_name = "cdc_data", + .connect = usbh_cdc_data_connect, + .disconnect = usbh_cdc_data_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS, + .bInterfaceClass = USB_DEVICE_CLASS_CDC_DATA, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .id_table = NULL, + .class_driver = &cdc_data_class_driver +}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/serial/usbh_serial.h b/components/drivers/usb/cherryusb/class/serial/usbh_serial.h new file mode 100644 index 00000000000..033ab705ede --- /dev/null +++ b/components/drivers/usb/cherryusb/class/serial/usbh_serial.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2025, sakumisu + * Copyright (c) 2025, MDLZCOOL + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBH_SERIAL_H +#define USBH_SERIAL_H + +#include "usb_cdc.h" + +#define USBH_SERIAL_CTRL_NOCACHE_OFFSET 0 +#define USBH_SERIAL_CTRL_NOCACHE_SIZE 32 +#define USBH_SERIAL_INT_NOCACHE_OFFSET USB_ALIGN_UP(USBH_SERIAL_CTRL_NOCACHE_SIZE, CONFIG_USB_ALIGN_SIZE) +#define USBH_SERIAL_INT_NOCACHE_SIZE 32 +#define USBH_SERIAL_RX_NOCACHE_OFFSET USB_ALIGN_UP((USBH_SERIAL_INT_NOCACHE_OFFSET + USBH_SERIAL_INT_NOCACHE_SIZE), CONFIG_USB_ALIGN_SIZE) +#define USBH_SERIAL_RX_NOCACHE_SIZE 512 +#define USBH_SERIAL_RX2_NOCACHE_OFFSET USB_ALIGN_UP((USBH_SERIAL_RX_NOCACHE_OFFSET + USBH_SERIAL_RX_NOCACHE_SIZE), CONFIG_USB_ALIGN_SIZE) +#define USBH_SERIAL_RX2_NOCACHE_SIZE 512 + +#define USBH_SERIAL_DATABITS_5 5 +#define USBH_SERIAL_DATABITS_6 6 +#define USBH_SERIAL_DATABITS_7 7 +#define USBH_SERIAL_DATABITS_8 8 + +#define USBH_SERIAL_PARITY_NONE 0 +#define USBH_SERIAL_PARITY_ODD 1 +#define USBH_SERIAL_PARITY_EVEN 2 +#define USBH_SERIAL_PARITY_MARK 3 +#define USBH_SERIAL_PARITY_SPACE 4 + +#define USBH_SERIAL_STOPBITS_1 0 +#define USBH_SERIAL_STOPBITS_1_5 1 +#define USBH_SERIAL_STOPBITS_2 2 + +/* modem lines */ +#define USBH_SERIAL_TIOCM_LE 0x001 /* line enable */ +#define USBH_SERIAL_TIOCM_DTR 0x002 /* data terminal ready */ +#define USBH_SERIAL_TIOCM_RTS 0x004 /* request to send */ +#define USBH_SERIAL_TIOCM_ST 0x010 /* secondary transmit */ +#define USBH_SERIAL_TIOCM_SR 0x020 /* secondary receive */ +#define USBH_SERIAL_TIOCM_CTS 0x040 /* clear to send */ +#define USBH_SERIAL_TIOCM_CAR 0x100 /* carrier detect */ +#define USBH_SERIAL_TIOCM_CD USBH_SERIAL_TIOCM_CAR +#define USBH_SERIAL_TIOCM_RNG 0x200 /* ring */ +#define USBH_SERIAL_TIOCM_RI USBH_SERIAL_TIOCM_RNG +#define USBH_SERIAL_TIOCM_DSR 0x400 /* data set ready */ +#define USBH_SERIAL_TIOCM_OUT1 0x2000 +#define USBH_SERIAL_TIOCM_OUT2 0x4000 +#define USBH_SERIAL_TIOCM_LOOP 0x8000 + +#define USBH_SERIAL_O_RDONLY 0x0000 /* open for reading only */ +#define USBH_SERIAL_O_WRONLY 0x0001 /* open for writing only */ +#define USBH_SERIAL_O_RDWR 0x0002 /* open for reading and writing */ + +#define USBH_SERIAL_O_ACCMODE 0x0003 /* mask for above modes, from 4.4BSD https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/include/sys/fcntl.h */ +#define USBH_SERIAL_O_NONBLOCK 0x0004 /* non-blocking I/O, from BSD apple https://opensource.apple.com/source/xnu/xnu-1228.0.2/bsd/sys/fcntl.h */ + +#define USBH_SERIAL_CMD_SET_ATTR 0 +#define USBH_SERIAL_CMD_GET_ATTR 1 +#define USBH_SERIAL_CMD_IOCMBIS 2 +#define USBH_SERIAL_CMD_IOCMBIC 3 +#define USBH_SERIAL_CMD_TIOCMSET 4 +#define USBH_SERIAL_CMD_TIOCMGET 5 + +#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. */ +} usbh_serial_ringbuf_t; + +/* + * Counters of the input lines (CTS, DSR, RI, CD) interrupts + */ + +struct usbh_serial_async_icount { + uint32_t cts, dsr, rng, dcd, tx, rx; + uint32_t frame, parity, overrun, brk; + uint32_t buf_overrun; +}; + +struct usbh_serial_termios { + uint32_t baudrate; + uint8_t databits; + uint8_t parity; + uint8_t stopbits; + bool rtscts; /* hardware flow control */ + uint32_t rx_timeout; +}; + +struct usbh_serial; + +typedef void (*usbh_serial_rx_complete_callback_t)(struct usbh_serial *serial, int nbytes); + +/** + * @brief Serial Driver Operations + */ +struct usbh_serial_driver { + const char *driver_name; + + uint8_t ignore_tx_header; + uint8_t ignore_rx_header; + + int (*attach)(struct usbh_serial *serial); + void (*detach)(struct usbh_serial *serial); + + int (*open)(struct usbh_serial *serial); + void (*close)(struct usbh_serial *serial); + int (*set_flow_control)(struct usbh_serial *serial, bool enable); + int (*set_line_coding)(struct usbh_serial *serial, struct cdc_line_coding *line_coding); + int (*get_line_coding)(struct usbh_serial *serial, struct cdc_line_coding *line_coding); + int (*set_line_state)(struct usbh_serial *serial, bool dtr, bool rts); + int (*get_modem_status)(struct usbh_serial *serial); +}; + +/** + * @brief Serial Instance + */ +struct usbh_serial { + struct usbh_hubport *hport; + uint8_t intf; /* Interface Number */ + int minor; /* Serial Port Number (/dev/ttyUSBx or /dev/ttyACMx) */ + int cdc_minor; /* Serial Port Number (/dev/ttyACMx) */ + uint8_t *iobuffer; /* I/O buffer for serial transfers */ + uint8_t ref_count; /* Reference Count */ + uint32_t open_flags; + uint32_t rx_timeout_ms; + + struct cdc_line_coding line_coding; + uint16_t line_state; + bool rtscts; /* hardware flow control */ + struct usbh_serial_async_icount iocount; + + struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ + struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ + struct usbh_urb bulkout_urb; + struct usbh_urb bulkin_urb; + + const struct usbh_serial_driver *driver; + + usbh_serial_ringbuf_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; + int rx_errorcode; + usbh_serial_rx_complete_callback_t rx_complete_callback; + + void *priv; /* Private Data */ + void *user_data; /* User Data */ +}; + +/* internal api */ +struct usbh_serial *usbh_serial_probe(struct usbh_hubport *hport, uint8_t intf, const struct usbh_serial_driver *driver); +void usbh_serial_remove(struct usbh_serial *serial); + +/* public api */ +struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags); +int usbh_serial_close(struct usbh_serial *serial); +int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg); +int usbh_serial_write(struct usbh_serial *serial, const void *buffer, uint32_t buflen); +int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen); + +/* cdc only api */ +int usbh_serial_cdc_write_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg); +int usbh_serial_cdc_read_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg); + +/* public weak api */ +void usbh_serial_run(struct usbh_serial *serial); +void usbh_serial_stop(struct usbh_serial *serial); + +int usbh_serial(int argc, char **argv); + +#ifdef __cplusplus +} +#endif + +#endif /* USBH_SERIAL_H */ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c index 981c5067995..ffa1ed500be 100644 --- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c +++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c @@ -795,16 +795,6 @@ int usbh_asix_eth_output(uint32_t buflen) return usbh_submit_urb(&g_asix_class.bulkout_urb); } -__WEAK void usbh_asix_run(struct usbh_asix *asix_class) -{ - (void)asix_class; -} - -__WEAK void usbh_asix_stop(struct usbh_asix *asix_class) -{ - (void)asix_class; -} - static const uint16_t asix_id_table[][2] = { { 0x0B95, 0x772B }, { 0x0B95, 0x7720 }, diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c index 39b597662a9..50269f26d39 100644 --- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c +++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c @@ -1034,17 +1034,17 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t byteen, uint16_t size, void *data, uint16_t type) { - int ret; + int ret = -USB_ERR_INVAL; uint16_t byteen_start, byteen_end, byen; uint16_t limit = 512; uint8_t *buf = data; /* both size and indix must be 4 bytes align */ if ((size & 3) || !size || (index & 3) || !buf) - return -USB_ERR_INVAL; + return ret; if ((uint32_t)index + (uint32_t)size > 0xffff) - return -USB_ERR_INVAL; + return ret; byteen_start = byteen & BYTE_EN_START_MASK; byteen_end = byteen & BYTE_EN_END_MASK; @@ -1596,8 +1596,8 @@ static void r8153_teredo_off(struct usbh_rtl8152 *tp) case RTL_VER_15: default: /* The bit 0 ~ 7 are relative with teredo settings. They are - * W1C (write 1 to clear), so set all 1 to disable it. - */ + * W1C (write 1 to clear), so set all 1 to disable it. + */ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, 0xff); break; } @@ -2251,16 +2251,6 @@ int usbh_rtl8152_eth_output(uint32_t buflen) return usbh_submit_urb(&g_rtl8152_class.bulkout_urb); } -__WEAK void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class) -{ - (void)rtl8152_class; -} - -__WEAK void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class) -{ - (void)rtl8152_class; -} - static const uint16_t rtl_id_table[][2] = { { 0x0BDA, 0x8152 }, { 0, 0 }, diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c deleted file mode 100644 index 3941d47dcb6..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_ch34x.h" - -#define DEV_FORMAT "/dev/ttyUSB%d" - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_ch34x_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; - -#define CONFIG_USBHOST_MAX_CP210X_CLASS 1 - -static struct usbh_ch34x g_ch34x_class[CONFIG_USBHOST_MAX_CP210X_CLASS]; -static uint32_t g_devinuse = 0; - -static struct usbh_ch34x *usbh_ch34x_class_alloc(void) -{ - uint8_t devno; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); - memset(&g_ch34x_class[devno], 0, sizeof(struct usbh_ch34x)); - g_ch34x_class[devno].minor = devno; - return &g_ch34x_class[devno]; - } - } - return NULL; -} - -static void usbh_ch34x_class_free(struct usbh_ch34x *ch34x_class) -{ - uint8_t devno = ch34x_class->minor; - - if (devno < 32) { - g_devinuse &= ~(1U << devno); - } - memset(ch34x_class, 0, sizeof(struct usbh_ch34x)); -} - -static int usbh_ch34x_get_baudrate_div(uint32_t baudrate, uint8_t *factor, uint8_t *divisor) -{ - uint8_t a; - uint8_t b; - uint32_t c; - - switch (baudrate) { - case 921600: - a = 0xf3; - b = 7; - break; - - case 307200: - a = 0xd9; - b = 7; - break; - - default: - if (baudrate > 6000000 / 255) { - b = 3; - c = 6000000; - } else if (baudrate > 750000 / 255) { - b = 2; - c = 750000; - } else if (baudrate > 93750 / 255) { - b = 1; - c = 93750; - } else { - b = 0; - c = 11719; - } - a = (uint8_t)(c / baudrate); - if (a == 0 || a == 0xFF) { - return -USB_ERR_INVAL; - } - if ((c / a - baudrate) > (baudrate - c / (a + 1))) { - a++; - } - a = (uint8_t)(256 - a); - break; - } - - *factor = a; - *divisor = b; - - return 0; -} - -static int usbh_ch34x_get_version(struct usbh_ch34x *ch34x_class) -{ - struct usb_setup_packet *setup; - int ret; - - if (!ch34x_class || !ch34x_class->hport) { - return -USB_ERR_INVAL; - } - setup = ch34x_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = CH34X_READ_VERSION; - setup->wValue = 0; - setup->wIndex = 0; - setup->wLength = 2; - - ret = usbh_control_transfer(ch34x_class->hport, setup, g_ch34x_buf); - if (ret < 0) { - return ret; - } - - USB_LOG_INFO("Ch34x chip version %02x:%02x\r\n", g_ch34x_buf[0], g_ch34x_buf[1]); - return ret; -} - -static int usbh_ch34x_flow_ctrl(struct usbh_ch34x *ch34x_class) -{ - struct usb_setup_packet *setup; - - if (!ch34x_class || !ch34x_class->hport) { - return -USB_ERR_INVAL; - } - setup = ch34x_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = CH34X_WRITE_REG; - setup->wValue = 0x2727; - setup->wIndex = 0; - setup->wLength = 0; - - return usbh_control_transfer(ch34x_class->hport, setup, NULL); -} - -int usbh_ch34x_set_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding) -{ - struct usb_setup_packet *setup; - uint16_t reg_value = 0; - uint16_t value = 0; - uint8_t factor = 0; - uint8_t divisor = 0; - - if (!ch34x_class || !ch34x_class->hport) { - return -USB_ERR_INVAL; - } - setup = ch34x_class->hport->setup; - - memcpy((uint8_t *)&ch34x_class->line_coding, line_coding, sizeof(struct cdc_line_coding)); - - /* refer to https://github.com/WCHSoftGroup/ch341ser_linux/blob/main/driver/ch341.c */ - - switch (line_coding->bParityType) { - case 0: - break; - case 1: - reg_value |= CH341_L_PO; - break; - case 2: - reg_value |= CH341_L_PE; - break; - case 3: - reg_value |= CH341_L_PM; - break; - case 4: - reg_value |= CH341_L_PS; - break; - default: - return -USB_ERR_INVAL; - } - - switch (line_coding->bDataBits) { - case 5: - reg_value |= CH341_L_D5; - break; - case 6: - reg_value |= CH341_L_D6; - break; - case 7: - reg_value |= CH341_L_D7; - break; - case 8: - reg_value |= CH341_L_D8; - break; - default: - return -USB_ERR_INVAL; - } - - if (line_coding->bCharFormat == 2) { - reg_value |= CH341_L_SB; - } - - reg_value |= 0xC0; - - value |= 0x9c; - value |= reg_value << 8; - - usbh_ch34x_get_baudrate_div(line_coding->dwDTERate, &factor, &divisor); - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = CH34X_SERIAL_INIT; - setup->wValue = value; - setup->wIndex = (factor << 8) | 0x80 | divisor; - setup->wLength = 0; - - return usbh_control_transfer(ch34x_class->hport, setup, NULL); -} - -int usbh_ch34x_get_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding) -{ - memcpy(line_coding, (uint8_t *)&ch34x_class->line_coding, sizeof(struct cdc_line_coding)); - return 0; -} - -int usbh_ch34x_set_line_state(struct usbh_ch34x *ch34x_class, bool dtr, bool rts) -{ - struct usb_setup_packet *setup; - - if (!ch34x_class || !ch34x_class->hport) { - return -USB_ERR_INVAL; - } - setup = ch34x_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = CH34X_MODEM_CTRL; - setup->wValue = 0x0f | (dtr << 5) | (rts << 6); - setup->wIndex = 0; - setup->wLength = 0; - - return usbh_control_transfer(ch34x_class->hport, setup, NULL); -} - -static int usbh_ch34x_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - - struct usbh_ch34x *ch34x_class = usbh_ch34x_class_alloc(); - if (ch34x_class == NULL) { - USB_LOG_ERR("Fail to alloc ch34x_class\r\n"); - return -USB_ERR_NOMEM; - } - - ch34x_class->hport = hport; - ch34x_class->intf = intf; - - hport->config.intf[intf].priv = ch34x_class; - - usbh_ch34x_get_version(ch34x_class); - usbh_ch34x_flow_ctrl(ch34x_class); - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) { - continue; - } else { - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(ch34x_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(ch34x_class->bulkout, ep_desc); - } - } - } - - snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, ch34x_class->minor); - - USB_LOG_INFO("Register CH34X Class:%s\r\n", hport->config.intf[intf].devname); - -#if 0 - USB_LOG_INFO("Test ch34x rx and tx and rx for 5 times, baudrate is 115200\r\n"); - - struct cdc_line_coding linecoding; - uint8_t count = 5; - - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_ch34x_set_line_coding(ch34x_class, &linecoding); - usbh_ch34x_set_line_state(ch34x_class, true, false); - - memset(g_ch34x_buf, 'a', sizeof(g_ch34x_buf)); - ret = usbh_ch34x_bulk_out_transfer(ch34x_class, g_ch34x_buf, sizeof(g_ch34x_buf), 0xfffffff); - USB_LOG_RAW("out ret:%d\r\n", ret); - while (count--) { - ret = usbh_ch34x_bulk_in_transfer(ch34x_class, g_ch34x_buf, sizeof(g_ch34x_buf), 0xfffffff); - USB_LOG_RAW("in ret:%d\r\n", ret); - if (ret > 0) { - for (uint32_t i = 0; i < ret; i++) { - USB_LOG_RAW("%02x ", g_ch34x_buf[i]); - } - USB_LOG_RAW("\r\n"); - } - } -#endif - usbh_ch34x_run(ch34x_class); - return ret; -} - -static int usbh_ch34x_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_ch34x *ch34x_class = (struct usbh_ch34x *)hport->config.intf[intf].priv; - - if (ch34x_class) { - if (ch34x_class->bulkin) { - usbh_kill_urb(&ch34x_class->bulkin_urb); - } - - if (ch34x_class->bulkout) { - usbh_kill_urb(&ch34x_class->bulkout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - usb_osal_thread_schedule_other(); - USB_LOG_INFO("Unregister CH34X Class:%s\r\n", hport->config.intf[intf].devname); - usbh_ch34x_stop(ch34x_class); - } - - usbh_ch34x_class_free(ch34x_class); - } - - return ret; -} - -int usbh_ch34x_bulk_in_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &ch34x_class->bulkin_urb; - - usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -int usbh_ch34x_bulk_out_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &ch34x_class->bulkout_urb; - - usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -__WEAK void usbh_ch34x_run(struct usbh_ch34x *ch34x_class) -{ - (void)ch34x_class; -} - -__WEAK void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class) -{ - (void)ch34x_class; -} - -static const uint16_t ch34x_id_table[][2] = { - { 0x1A86, 0x7523 }, - { 0, 0 }, -}; - -const struct usbh_class_driver ch34x_class_driver = { - .driver_name = "ch34x", - .connect = usbh_ch34x_connect, - .disconnect = usbh_ch34x_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .id_table = ch34x_id_table, - .class_driver = &ch34x_class_driver -}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.h b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.h deleted file mode 100644 index c90bf9bda60..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_CH34X_H -#define USBH_CH34X_H - -#include "usb_cdc.h" - -/* Requests */ -#define CH34X_READ_VERSION 0x5F -#define CH34X_WRITE_REG 0x9A -#define CH34X_READ_REG 0x95 -#define CH34X_SERIAL_INIT 0xA1 -#define CH34X_MODEM_CTRL 0xA4 - -// modem control bits -#define CH34X_BIT_RTS (1 << 6) -#define CH34X_BIT_DTR (1 << 5) - -#define CH341_CTO_O 0x10 -#define CH341_CTO_D 0x20 -#define CH341_CTO_R 0x40 -#define CH341_CTI_C 0x01 -#define CH341_CTI_DS 0x02 -#define CH341_CTRL_RI 0x04 -#define CH341_CTI_DC 0x08 -#define CH341_CTI_ST 0x0f - -#define CH341_L_ER 0x80 -#define CH341_L_ET 0x40 -#define CH341_L_PS 0x38 -#define CH341_L_PM 0x28 -#define CH341_L_PE 0x18 -#define CH341_L_PO 0x08 -#define CH341_L_SB 0x04 -#define CH341_L_D8 0x03 -#define CH341_L_D7 0x02 -#define CH341_L_D6 0x01 -#define CH341_L_D5 0x00 - -struct usbh_ch34x { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - - struct cdc_line_coding line_coding; - - uint8_t intf; - uint8_t minor; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_ch34x_set_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding); -int usbh_ch34x_get_line_coding(struct usbh_ch34x *ch34x_class, struct cdc_line_coding *line_coding); -int usbh_ch34x_set_line_state(struct usbh_ch34x *ch34x_class, bool dtr, bool rts); - -int usbh_ch34x_bulk_in_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); -int usbh_ch34x_bulk_out_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); - -void usbh_ch34x_run(struct usbh_ch34x *ch34x_class); -void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_CH34X_H */ diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c deleted file mode 100644 index f58350e6f8f..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_cp210x.h" - -#define DEV_FORMAT "/dev/ttyUSB%d" - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cp210x_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; - -#define CONFIG_USBHOST_MAX_CP210X_CLASS 1 - -static struct usbh_cp210x g_cp210x_class[CONFIG_USBHOST_MAX_CP210X_CLASS]; -static uint32_t g_devinuse = 0; - -static struct usbh_cp210x *usbh_cp210x_class_alloc(void) -{ - uint8_t devno; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); - memset(&g_cp210x_class[devno], 0, sizeof(struct usbh_cp210x)); - g_cp210x_class[devno].minor = devno; - return &g_cp210x_class[devno]; - } - } - return NULL; -} - -static void usbh_cp210x_class_free(struct usbh_cp210x *cp210x_class) -{ - uint8_t devno = cp210x_class->minor; - - if (devno < 32) { - g_devinuse &= ~(1U << devno); - } - memset(cp210x_class, 0, sizeof(struct usbh_cp210x)); -} - -static int usbh_cp210x_enable(struct usbh_cp210x *cp210x_class) -{ - struct usb_setup_packet *setup; - - if (!cp210x_class || !cp210x_class->hport) { - return -USB_ERR_INVAL; - } - setup = cp210x_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CP210X_IFC_ENABLE; - setup->wValue = 1; - setup->wIndex = cp210x_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(cp210x_class->hport, setup, NULL); -} - -static int usbh_cp210x_set_flow(struct usbh_cp210x *cp210x_class) -{ - struct usb_setup_packet *setup; - - if (!cp210x_class || !cp210x_class->hport) { - return -USB_ERR_INVAL; - } - setup = cp210x_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CP210X_SET_FLOW; - setup->wValue = 0; - setup->wIndex = cp210x_class->intf; - setup->wLength = 16; - - memset(g_cp210x_buf, 0, 16); - g_cp210x_buf[13] = 0x20; - return usbh_control_transfer(cp210x_class->hport, setup, g_cp210x_buf); -} - -static int usbh_cp210x_set_chars(struct usbh_cp210x *cp210x_class) -{ - struct usb_setup_packet *setup; - - if (!cp210x_class || !cp210x_class->hport) { - return -USB_ERR_INVAL; - } - setup = cp210x_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CP210X_SET_CHARS; - setup->wValue = 0; - setup->wIndex = cp210x_class->intf; - setup->wLength = 6; - - memset(g_cp210x_buf, 0, 6); - g_cp210x_buf[0] = 0x80; - g_cp210x_buf[4] = 0x88; - g_cp210x_buf[5] = 0x28; - return usbh_control_transfer(cp210x_class->hport, setup, g_cp210x_buf); -} - -static int usbh_cp210x_set_baudrate(struct usbh_cp210x *cp210x_class, uint32_t baudrate) -{ - struct usb_setup_packet *setup; - - if (!cp210x_class || !cp210x_class->hport) { - return -USB_ERR_INVAL; - } - setup = cp210x_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CP210X_SET_BAUDRATE; - setup->wValue = 0; - setup->wIndex = cp210x_class->intf; - setup->wLength = 4; - - memcpy(g_cp210x_buf, (uint8_t *)&baudrate, 4); - return usbh_control_transfer(cp210x_class->hport, setup, g_cp210x_buf); -} - -static int usbh_cp210x_set_data_format(struct usbh_cp210x *cp210x_class, uint8_t databits, uint8_t parity, uint8_t stopbits) -{ - struct usb_setup_packet *setup; - uint16_t value; - - if (!cp210x_class || !cp210x_class->hport) { - return -USB_ERR_INVAL; - } - setup = cp210x_class->hport->setup; - - value = ((databits & 0x0F) << 8) | ((parity & 0x0f) << 4) | ((stopbits & 0x03) << 0); - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CP210X_SET_LINE_CTL; - setup->wValue = value; - setup->wIndex = cp210x_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(cp210x_class->hport, setup, NULL); -} - -static int usbh_cp210x_set_mhs(struct usbh_cp210x *cp210x_class, uint8_t dtr, uint8_t rts, uint8_t dtr_mask, uint8_t rts_mask) -{ - struct usb_setup_packet *setup; - uint16_t value; - - if (!cp210x_class || !cp210x_class->hport) { - return -USB_ERR_INVAL; - } - setup = cp210x_class->hport->setup; - - value = ((dtr & 0x01) << 0) | ((rts & 0x01) << 1) | ((dtr_mask & 0x01) << 8) | ((rts_mask & 0x01) << 9); - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CP210X_SET_MHS; - setup->wValue = value; - setup->wIndex = cp210x_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(cp210x_class->hport, setup, NULL); -} - -int usbh_cp210x_set_line_coding(struct usbh_cp210x *cp210x_class, struct cdc_line_coding *line_coding) -{ - memcpy((uint8_t *)&cp210x_class->line_coding, line_coding, sizeof(struct cdc_line_coding)); - usbh_cp210x_set_baudrate(cp210x_class, line_coding->dwDTERate); - return usbh_cp210x_set_data_format(cp210x_class, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat); -} - -int usbh_cp210x_get_line_coding(struct usbh_cp210x *cp210x_class, struct cdc_line_coding *line_coding) -{ - memcpy(line_coding, (uint8_t *)&cp210x_class->line_coding, sizeof(struct cdc_line_coding)); - return 0; -} - -int usbh_cp210x_set_line_state(struct usbh_cp210x *cp210x_class, bool dtr, bool rts) -{ - return usbh_cp210x_set_mhs(cp210x_class, dtr, rts, 1, 1); -} - -static int usbh_cp210x_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - - struct usbh_cp210x *cp210x_class = usbh_cp210x_class_alloc(); - if (cp210x_class == NULL) { - USB_LOG_ERR("Fail to alloc cp210x_class\r\n"); - return -USB_ERR_NOMEM; - } - - cp210x_class->hport = hport; - cp210x_class->intf = intf; - - hport->config.intf[intf].priv = cp210x_class; - - usbh_cp210x_enable(cp210x_class); - usbh_cp210x_set_flow(cp210x_class); - usbh_cp210x_set_chars(cp210x_class); - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(cp210x_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(cp210x_class->bulkout, ep_desc); - } - } - - snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, cp210x_class->minor); - - USB_LOG_INFO("Register CP210X Class:%s\r\n", hport->config.intf[intf].devname); - -#if 0 - USB_LOG_INFO("Test cp2102 rx and tx and rx for 5 times, baudrate is 115200\r\n"); - - struct cdc_line_coding linecoding; - uint8_t count = 5; - - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_cp210x_set_line_coding(cp210x_class, &linecoding); - usbh_cp210x_set_line_state(cp210x_class, true, false); - - memset(g_cp210x_buf, 'a', sizeof(g_cp210x_buf)); - ret = usbh_cp210x_bulk_out_transfer(cp210x_class, g_cp210x_buf, sizeof(g_cp210x_buf), 0xfffffff); - USB_LOG_RAW("out ret:%d\r\n", ret); - while (count--) { - ret = usbh_cp210x_bulk_in_transfer(cp210x_class, g_cp210x_buf, sizeof(g_cp210x_buf), 0xfffffff); - USB_LOG_RAW("in ret:%d\r\n", ret); - if (ret > 0) { - for (uint32_t i = 0; i < ret; i++) { - USB_LOG_RAW("%02x ", g_cp210x_buf[i]); - } - USB_LOG_RAW("\r\n"); - } - } -#endif - usbh_cp210x_run(cp210x_class); - return ret; -} - -static int usbh_cp210x_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_cp210x *cp210x_class = (struct usbh_cp210x *)hport->config.intf[intf].priv; - - if (cp210x_class) { - if (cp210x_class->bulkin) { - usbh_kill_urb(&cp210x_class->bulkin_urb); - } - - if (cp210x_class->bulkout) { - usbh_kill_urb(&cp210x_class->bulkout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - usb_osal_thread_schedule_other(); - USB_LOG_INFO("Unregister CP210X Class:%s\r\n", hport->config.intf[intf].devname); - usbh_cp210x_stop(cp210x_class); - } - - usbh_cp210x_class_free(cp210x_class); - } - - return ret; -} - -int usbh_cp210x_bulk_in_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &cp210x_class->bulkin_urb; - - usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -int usbh_cp210x_bulk_out_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &cp210x_class->bulkout_urb; - - usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -__WEAK void usbh_cp210x_run(struct usbh_cp210x *cp210x_class) -{ - (void)cp210x_class; -} - -__WEAK void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class) -{ - (void)cp210x_class; -} - -static const uint16_t cp210x_id_table[][2] = { - { 0x10C4, 0xEA60 }, - { 0, 0 }, -}; - -const struct usbh_class_driver cp210x_class_driver = { - .driver_name = "cp210x", - .connect = usbh_cp210x_connect, - .disconnect = usbh_cp210x_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .id_table = cp210x_id_table, - .class_driver = &cp210x_class_driver -}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.h b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.h deleted file mode 100644 index d380c36c584..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_CP210X_H -#define USBH_CP210X_H - -#include "usb_cdc.h" - -/* Requests */ -#define CP210X_IFC_ENABLE 0x00 -#define CP210X_SET_BAUDDIV 0x01 -#define CP210X_GET_BAUDDIV 0x02 -#define CP210X_SET_LINE_CTL 0x03 // Set parity, data bits, stop bits -#define CP210X_GET_LINE_CTL 0x04 -#define CP210X_SET_BREAK 0x05 -#define CP210X_IMM_CHAR 0x06 -#define CP210X_SET_MHS 0x07 // Set DTR, RTS -#define CP210X_GET_MDMSTS 0x08 -#define CP210X_SET_XON 0x09 -#define CP210X_SET_XOFF 0x0A -#define CP210X_SET_EVENTMASK 0x0B -#define CP210X_GET_EVENTMASK 0x0C -#define CP210X_SET_CHAR 0x0D -#define CP210X_GET_CHARS 0x0E -#define CP210X_GET_PROPS 0x0F -#define CP210X_GET_COMM_STATUS 0x10 -#define CP210X_RESET 0x11 -#define CP210X_PURGE 0x12 -#define CP210X_SET_FLOW 0x13 -#define CP210X_GET_FLOW 0x14 -#define CP210X_EMBED_EVENTS 0x15 -#define CP210X_GET_EVENTSTATE 0x16 -#define CP210X_SET_CHARS 0x19 -#define CP210X_GET_BAUDRATE 0x1D -#define CP210X_SET_BAUDRATE 0x1E // Set baudrate -#define CP210X_VENDOR_SPECIFIC 0xFF - -struct usbh_cp210x { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - - struct cdc_line_coding line_coding; - - uint8_t intf; - uint8_t minor; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_cp210x_set_line_coding(struct usbh_cp210x *ftdi_class, struct cdc_line_coding *line_coding); -int usbh_cp210x_get_line_coding(struct usbh_cp210x *ftdi_class, struct cdc_line_coding *line_coding); -int usbh_cp210x_set_line_state(struct usbh_cp210x *ftdi_class, bool dtr, bool rts); - -int usbh_cp210x_bulk_in_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); -int usbh_cp210x_bulk_out_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); - -void usbh_cp210x_run(struct usbh_cp210x *cp210x_class); -void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_CP210X_H */ diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c deleted file mode 100644 index 4bc7f81b016..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_ftdi.h" - -#define DEV_FORMAT "/dev/ttyUSB%d" - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_ftdi_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; - -#define CONFIG_USBHOST_MAX_FTDI_CLASS 1 - -static struct usbh_ftdi g_ftdi_class[CONFIG_USBHOST_MAX_FTDI_CLASS]; -static uint32_t g_devinuse = 0; - -static const char *ftdi_chip_name[] = { - [SIO] = "SIO", /* the serial part of FT8U100AX */ - [FT232A] = "FT232A", - [FT232B] = "FT232B", - [FT2232C] = "FT2232C/D", - [FT232R] = "FT232R", - [FT232H] = "FT232H", - [FT2232H] = "FT2232H", - [FT4232H] = "FT4232H", - [FT4232HA] = "FT4232HA", - [FT232HP] = "FT232HP", - [FT233HP] = "FT233HP", - [FT2232HP] = "FT2232HP", - [FT2233HP] = "FT2233HP", - [FT4232HP] = "FT4232HP", - [FT4233HP] = "FT4233HP", - [FTX] = "FT-X", -}; - -static struct usbh_ftdi *usbh_ftdi_class_alloc(void) -{ - uint8_t devno; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_FTDI_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); - memset(&g_ftdi_class[devno], 0, sizeof(struct usbh_ftdi)); - g_ftdi_class[devno].minor = devno; - return &g_ftdi_class[devno]; - } - } - return NULL; -} - -static void usbh_ftdi_class_free(struct usbh_ftdi *ftdi_class) -{ - uint8_t devno = ftdi_class->minor; - - if (devno < 32) { - g_devinuse &= ~(1U << devno); - } - memset(ftdi_class, 0, sizeof(struct usbh_ftdi)); -} - -/* - * Divide positive or negative dividend by positive or negative divisor - * and round to closest integer. Result is undefined for negative - * divisors if the dividend variable type is unsigned and for negative - * dividends if the divisor variable type is unsigned. - */ -#define DIV_ROUND_CLOSEST(x, divisor) ( \ - { \ - typeof(x) __x = x; \ - typeof(divisor) __d = divisor; \ - (((typeof(x))-1) > 0 || \ - ((typeof(divisor))-1) > 0 || \ - (((__x) > 0) == ((__d) > 0))) ? \ - (((__x) + ((__d) / 2)) / (__d)) : \ - (((__x) - ((__d) / 2)) / (__d)); \ - }) - -static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, int base) -{ - static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; - uint32_t divisor; - /* divisor shifted 3 bits to the left */ - int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); - divisor = divisor3 >> 3; - divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14; - /* Deal with special cases for highest baud rates. */ - if (divisor == 1) /* 1.0 */ - divisor = 0; - else if (divisor == 0x4001) /* 1.5 */ - divisor = 1; - return divisor; -} - -static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) -{ - return ftdi_232bm_baud_base_to_divisor(baud, 48000000); -} - -static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, int base) -{ - static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; - uint32_t divisor; - int divisor3; - - /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ - divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud); - - divisor = divisor3 >> 3; - divisor |= (uint32_t)divfrac[divisor3 & 0x7] << 14; - /* Deal with special cases for highest baud rates. */ - if (divisor == 1) /* 1.0 */ - divisor = 0; - else if (divisor == 0x4001) /* 1.5 */ - divisor = 1; - /* - * Set this bit to turn off a divide by 2.5 on baud rate generator - * This enables baud rates up to 12Mbaud but cannot reach below 1200 - * baud with this bit set - */ - divisor |= 0x00020000; - return divisor; -} - -static uint32_t ftdi_2232h_baud_to_divisor(uint32_t baud) -{ - return ftdi_2232h_baud_base_to_divisor(baud, 120000000); -} - -int usbh_ftdi_reset(struct usbh_ftdi *ftdi_class) -{ - struct usb_setup_packet *setup; - - if (!ftdi_class || !ftdi_class->hport) { - return -USB_ERR_INVAL; - } - setup = ftdi_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = SIO_RESET_REQUEST; - setup->wValue = 0; - setup->wIndex = ftdi_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(ftdi_class->hport, setup, NULL); -} - -static int usbh_ftdi_set_modem(struct usbh_ftdi *ftdi_class, uint16_t value) -{ - struct usb_setup_packet *setup; - - if (!ftdi_class || !ftdi_class->hport) { - return -USB_ERR_INVAL; - } - setup = ftdi_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = SIO_SET_MODEM_CTRL_REQUEST; - setup->wValue = value; - setup->wIndex = ftdi_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(ftdi_class->hport, setup, NULL); -} - -static int usbh_ftdi_set_baudrate(struct usbh_ftdi *ftdi_class, uint32_t baudrate) -{ - struct usb_setup_packet *setup; - uint32_t div_value; - uint16_t value; - uint8_t baudrate_high; - - if (!ftdi_class || !ftdi_class->hport) { - return -USB_ERR_INVAL; - } - setup = ftdi_class->hport->setup; - - switch (ftdi_class->chip_type) { - case FT232B: - case FT2232C: - case FT232R: - if (baudrate > 3000000) { - return -USB_ERR_INVAL; - } - div_value = ftdi_232bm_baud_to_divisor(baudrate); - break; - default: - if ((baudrate <= 12000000) && (baudrate >= 1200)) { - div_value = ftdi_2232h_baud_to_divisor(baudrate); - } else { - return -USB_ERR_INVAL; - } - break; - } - - value = div_value & 0xFFFF; - baudrate_high = (div_value >> 16) & 0xff; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = SIO_SET_BAUDRATE_REQUEST; - setup->wValue = value; - setup->wIndex = (baudrate_high << 8) | ftdi_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(ftdi_class->hport, setup, NULL); -} - -static int usbh_ftdi_set_data_format(struct usbh_ftdi *ftdi_class, uint8_t databits, uint8_t parity, uint8_t stopbits, uint8_t isbreak) -{ - /** - * D0-D7 databits BITS_7=7, BITS_8=8 - * D8-D10 parity NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4 - * D11-D12 STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2 - * D14 BREAK_OFF=0, BREAK_ON=1 - **/ - struct usb_setup_packet *setup; - uint16_t value; - - if (!ftdi_class || !ftdi_class->hport) { - return -USB_ERR_INVAL; - } - setup = ftdi_class->hport->setup; - - value = ((isbreak & 0x01) << 14) | ((stopbits & 0x03) << 11) | ((parity & 0x0f) << 8) | (databits & 0x0f); - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = SIO_SET_DATA_REQUEST; - setup->wValue = value; - setup->wIndex = ftdi_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(ftdi_class->hport, setup, NULL); -} - -static int usbh_ftdi_set_latency_timer(struct usbh_ftdi *ftdi_class, uint16_t value) -{ - struct usb_setup_packet *setup; - - if (!ftdi_class || !ftdi_class->hport) { - return -USB_ERR_INVAL; - } - setup = ftdi_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = SIO_SET_LATENCY_TIMER_REQUEST; - setup->wValue = value; - setup->wIndex = ftdi_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(ftdi_class->hport, setup, NULL); -} - -static int usbh_ftdi_set_flow_ctrl(struct usbh_ftdi *ftdi_class, uint16_t value) -{ - struct usb_setup_packet *setup; - - if (!ftdi_class || !ftdi_class->hport) { - return -USB_ERR_INVAL; - } - setup = ftdi_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = SIO_SET_FLOW_CTRL_REQUEST; - setup->wValue = value; - setup->wIndex = ftdi_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(ftdi_class->hport, setup, NULL); -} - -static int usbh_ftdi_read_modem_status(struct usbh_ftdi *ftdi_class) -{ - struct usb_setup_packet *setup; - int ret; - - if (!ftdi_class || !ftdi_class->hport) { - return -USB_ERR_INVAL; - } - setup = ftdi_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = SIO_POLL_MODEM_STATUS_REQUEST; - setup->wValue = 0x0000; - setup->wIndex = ftdi_class->intf; - setup->wLength = 2; - - ret = usbh_control_transfer(ftdi_class->hport, setup, g_ftdi_buf); - if (ret < 0) { - return ret; - } - memcpy(ftdi_class->modem_status, g_ftdi_buf, 2); - return ret; -} - -int usbh_ftdi_set_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding) -{ - memcpy((uint8_t *)&ftdi_class->line_coding, line_coding, sizeof(struct cdc_line_coding)); - - int ret = usbh_ftdi_set_baudrate(ftdi_class, line_coding->dwDTERate); - if (ret < 0) { - return ret; - } - return usbh_ftdi_set_data_format(ftdi_class, line_coding->bDataBits, line_coding->bParityType, line_coding->bCharFormat, 0); -} - -int usbh_ftdi_get_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding) -{ - memcpy(line_coding, (uint8_t *)&ftdi_class->line_coding, sizeof(struct cdc_line_coding)); - return 0; -} - -int usbh_ftdi_set_line_state(struct usbh_ftdi *ftdi_class, bool dtr, bool rts) -{ - int ret; - - if (dtr) { - usbh_ftdi_set_modem(ftdi_class, SIO_SET_DTR_HIGH); - } else { - usbh_ftdi_set_modem(ftdi_class, SIO_SET_DTR_LOW); - } - - if (rts) { - ret = usbh_ftdi_set_modem(ftdi_class, SIO_SET_RTS_HIGH); - } else { - ret = usbh_ftdi_set_modem(ftdi_class, SIO_SET_RTS_LOW); - } - - return ret; -} - -static int usbh_ftdi_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - uint16_t version; - - struct usbh_ftdi *ftdi_class = usbh_ftdi_class_alloc(); - if (ftdi_class == NULL) { - USB_LOG_ERR("Fail to alloc ftdi_class\r\n"); - return -USB_ERR_NOMEM; - } - - ftdi_class->hport = hport; - ftdi_class->intf = intf; - - hport->config.intf[intf].priv = ftdi_class; - - version = hport->device_desc.bcdDevice; - - switch (version) { - case 0x400: - ftdi_class->chip_type = FT232B; - break; - case 0x500: - ftdi_class->chip_type = FT2232C; - break; - case 0x600: - ftdi_class->chip_type = FT232R; - break; - case 0x700: - ftdi_class->chip_type = FT2232H; - break; - case 0x800: - ftdi_class->chip_type = FT4232H; - break; - case 0x900: - ftdi_class->chip_type = FT232H; - break; - - default: - USB_LOG_ERR("Unknown FTDI chip version:%04x\r\n", version); - return -USB_ERR_NOTSUPP; - } - - USB_LOG_INFO("FTDI chip name:%s\r\n", ftdi_chip_name[ftdi_class->chip_type]); - - usbh_ftdi_reset(ftdi_class); - usbh_ftdi_set_flow_ctrl(ftdi_class, SIO_DISABLE_FLOW_CTRL); - usbh_ftdi_set_latency_timer(ftdi_class, 0x10); - usbh_ftdi_read_modem_status(ftdi_class); - USB_LOG_INFO("modem status:%02x:%02x\r\n", ftdi_class->modem_status[0], ftdi_class->modem_status[1]); - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(ftdi_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(ftdi_class->bulkout, ep_desc); - } - } - - snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, ftdi_class->minor); - - USB_LOG_INFO("Register FTDI Class:%s\r\n", hport->config.intf[intf].devname); - -#if 0 - USB_LOG_INFO("Test ftdi rx and tx and rx for 5 times, baudrate is 115200\r\n"); - - struct cdc_line_coding linecoding; - uint8_t count = 5; - - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_ftdi_set_line_coding(ftdi_class, &linecoding); - usbh_ftdi_set_line_state(ftdi_class, true, false); - - memset(g_ftdi_buf, 'a', sizeof(g_ftdi_buf)); - ret = usbh_ftdi_bulk_out_transfer(ftdi_class, g_ftdi_buf, sizeof(g_ftdi_buf), 0xfffffff); - USB_LOG_RAW("out ret:%d\r\n", ret); - while (count--) { - ret = usbh_ftdi_bulk_in_transfer(ftdi_class, g_ftdi_buf, sizeof(g_ftdi_buf), 0xfffffff); - USB_LOG_RAW("in ret:%d\r\n", ret); - if (ret > 0) { - for (uint32_t i = 0; i < ret; i++) { - USB_LOG_RAW("%02x ", g_ftdi_buf[i]); - } - } - USB_LOG_RAW("\r\n"); - } -#endif - usbh_ftdi_run(ftdi_class); - return ret; -} - -static int usbh_ftdi_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_ftdi *ftdi_class = (struct usbh_ftdi *)hport->config.intf[intf].priv; - - if (ftdi_class) { - if (ftdi_class->bulkin) { - usbh_kill_urb(&ftdi_class->bulkin_urb); - } - - if (ftdi_class->bulkout) { - usbh_kill_urb(&ftdi_class->bulkout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - usb_osal_thread_schedule_other(); - USB_LOG_INFO("Unregister FTDI Class:%s\r\n", hport->config.intf[intf].devname); - usbh_ftdi_stop(ftdi_class); - } - - usbh_ftdi_class_free(ftdi_class); - } - - return ret; -} - -int usbh_ftdi_bulk_in_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &ftdi_class->bulkin_urb; - - usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -int usbh_ftdi_bulk_out_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &ftdi_class->bulkout_urb; - - usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -__WEAK void usbh_ftdi_run(struct usbh_ftdi *ftdi_class) -{ - (void)ftdi_class; -} - -__WEAK void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class) -{ - (void)ftdi_class; -} - -static const uint16_t ftdi_id_table[][2] = { - { 0x0403, 0x6001 }, - { 0x0403, 0x6010 }, - { 0, 0 }, -}; - -const struct usbh_class_driver ftdi_class_driver = { - .driver_name = "ftdi", - .connect = usbh_ftdi_connect, - .disconnect = usbh_ftdi_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .id_table = ftdi_id_table, - .class_driver = &ftdi_class_driver -}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.h b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.h deleted file mode 100644 index 855db8d6c61..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_FTDI_H -#define USBH_FTDI_H - -#include "usb_cdc.h" - -/* Requests */ -#define SIO_RESET_REQUEST 0x00 /* Reset the port */ -#define SIO_SET_MODEM_CTRL_REQUEST 0x01 /* Set the modem control register */ -#define SIO_SET_FLOW_CTRL_REQUEST 0x02 /* Set flow control register */ -#define SIO_SET_BAUDRATE_REQUEST 0x03 /* Set baud rate */ -#define SIO_SET_DATA_REQUEST 0x04 /* Set the data characteristics of the port */ -#define SIO_POLL_MODEM_STATUS_REQUEST 0x05 -#define SIO_SET_EVENT_CHAR_REQUEST 0x06 -#define SIO_SET_ERROR_CHAR_REQUEST 0x07 -#define SIO_SET_LATENCY_TIMER_REQUEST 0x09 -#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A -#define SIO_SET_BITMODE_REQUEST 0x0B -#define SIO_READ_PINS_REQUEST 0x0C -#define SIO_READ_EEPROM_REQUEST 0x90 -#define SIO_WRITE_EEPROM_REQUEST 0x91 -#define SIO_ERASE_EEPROM_REQUEST 0x92 - -#define SIO_DISABLE_FLOW_CTRL 0x0 -#define SIO_RTS_CTS_HS (0x1 << 8) -#define SIO_DTR_DSR_HS (0x2 << 8) -#define SIO_XON_XOFF_HS (0x4 << 8) - -#define SIO_SET_DTR_MASK 0x1 -#define SIO_SET_DTR_HIGH (1 | (SIO_SET_DTR_MASK << 8)) -#define SIO_SET_DTR_LOW (0 | (SIO_SET_DTR_MASK << 8)) -#define SIO_SET_RTS_MASK 0x2 -#define SIO_SET_RTS_HIGH (2 | (SIO_SET_RTS_MASK << 8)) -#define SIO_SET_RTS_LOW (0 | (SIO_SET_RTS_MASK << 8)) - -#define SIO_RTS_CTS_HS (0x1 << 8) - -enum ftdi_chip_type { - SIO, - FT232A, - FT232B, - FT2232C, - FT232R, - FT232H, - FT2232H, - FT4232H, - FT4232HA, - FT232HP, - FT233HP, - FT2232HP, - FT2233HP, - FT4232HP, - FT4233HP, - FTX, -}; - -struct usbh_ftdi { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - - struct cdc_line_coding line_coding; - - uint8_t intf; - uint8_t minor; - uint8_t modem_status[2]; - enum ftdi_chip_type chip_type; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_ftdi_set_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding); -int usbh_ftdi_get_line_coding(struct usbh_ftdi *ftdi_class, struct cdc_line_coding *line_coding); -int usbh_ftdi_set_line_state(struct usbh_ftdi *ftdi_class, bool dtr, bool rts); - -int usbh_ftdi_bulk_in_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); -int usbh_ftdi_bulk_out_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); - -void usbh_ftdi_run(struct usbh_ftdi *ftdi_class); -void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_FTDI_H */ diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c deleted file mode 100644 index ece32538810..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * Copyright (c) 2024, Derek Konigsberg - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_pl2303.h" - -#undef USB_DBG_TAG -#define USB_DBG_TAG "usbh_pl2303" -#include "usb_log.h" - -#define DEV_FORMAT "/dev/ttyUSB%d" - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_pl2303_buf[USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; - -#define CONFIG_USBHOST_MAX_PL2303_CLASS 1 - -#define UT_WRITE_VENDOR_DEVICE (USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE) -#define UT_READ_VENDOR_DEVICE (USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE) - -static struct usbh_pl2303 g_pl2303_class[CONFIG_USBHOST_MAX_PL2303_CLASS]; -static uint32_t g_devinuse = 0; - -static struct usbh_pl2303 *usbh_pl2303_class_alloc(void) -{ - uint8_t devno; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_PL2303_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); - memset(&g_pl2303_class[devno], 0, sizeof(struct usbh_pl2303)); - g_pl2303_class[devno].minor = devno; - return &g_pl2303_class[devno]; - } - } - return NULL; -} - -static void usbh_pl2303_class_free(struct usbh_pl2303 *pl2303_class) -{ - uint8_t devno = pl2303_class->minor; - - if (devno < 32) { - g_devinuse &= ~(1U << devno); - } - memset(pl2303_class, 0, sizeof(struct usbh_pl2303)); -} - -static int usbh_pl2303_get_chiptype(struct usbh_pl2303 *pl2303_class) -{ - int ret = 0; - - switch (pl2303_class->hport->device_desc.bcdDevice) { - case 0x0300: - pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HX; - /* or TA, that is HX with external crystal */ - break; - case 0x0400: - pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HXD; - /* or EA, that is HXD with ESD protection */ - /* or RA, that has internal voltage level converter that works only up to 1Mbaud (!) */ - break; - case 0x0500: - pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HXD; - /* in fact it's TB, that is HXD with external crystal */ - break; - default: - /* NOTE: I have no info about the bcdDevice for the base PL2303 (up to 1.2Mbaud, - only fixed rates) and for PL2303SA (8-pin chip, up to 115200 baud */ - /* Determine the chip type. This algorithm is taken from Linux. */ - if (pl2303_class->hport->device_desc.bDeviceClass == 0x02) { - pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303; - } else if (pl2303_class->hport->device_desc.bMaxPacketSize0 == 0x40) { - pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HX; - } else { - pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303; - } - break; - } - - /* - * The new chip revision PL2303HXN is only compatible with the new - * PLCOM_SET_REQUEST_PL2303HXN command. Issuing the old command - * PLCOM_SET_REQUEST to the new chip raises an error. Thus, PL2303HX - * and PL2303HXN can be distinguished by issuing an old-style request - * (on a status register) to the new chip and checking the error. - */ - if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HX) { - struct usb_setup_packet *setup = pl2303_class->hport->setup; - - setup->bmRequestType = UT_READ_VENDOR_DEVICE; - setup->bRequest = PL2303_SET_REQUEST; - setup->wValue = PL2303_STATUS_REG_PL2303HX; - setup->wIndex = 0; - setup->wLength = 1; - - ret = usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf); - if (ret == -USB_ERR_STALL) { - pl2303_class->chiptype = USBH_PL2303_TYPE_PL2303HXN; - ret = 0; - } else if (ret < 0) { - USB_LOG_WRN("Error checking chip type: %d\r\n", ret); - return ret; - } - } - - switch (pl2303_class->chiptype) { - case USBH_PL2303_TYPE_PL2303: - USB_LOG_INFO("chiptype = 2303\r\n"); - break; - case USBH_PL2303_TYPE_PL2303HX: - USB_LOG_INFO("chiptype = 2303HX/TA\r\n"); - break; - case USBH_PL2303_TYPE_PL2303HXN: - USB_LOG_INFO("chiptype = 2303HXN\r\n"); - break; - case USBH_PL2303_TYPE_PL2303HXD: - USB_LOG_INFO("chiptype = 2303HXD/TB/RA/EA\r\n"); - break; - default: - USB_LOG_INFO("chiptype = [%d]\r\n", pl2303_class->chiptype); - break; - } - - return ret; -} - -static int usbh_pl2303_do(struct usbh_pl2303 *pl2303_class, - uint8_t req_type, uint8_t request, uint16_t value, uint16_t index, - uint16_t length) -{ - struct usb_setup_packet *setup; - - if (!pl2303_class || !pl2303_class->hport) { - return -USB_ERR_INVAL; - } - setup = pl2303_class->hport->setup; - - setup->bmRequestType = req_type; - setup->bRequest = request; - setup->wValue = value; - setup->wIndex = index; - setup->wLength = length; - - return usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf); -} - -int usbh_pl2303_set_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding) -{ - struct usb_setup_packet *setup; - - if (!pl2303_class || !pl2303_class->hport) { - return -USB_ERR_INVAL; - } - setup = pl2303_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CDC_REQUEST_SET_LINE_CODING; - setup->wValue = 0; - setup->wIndex = pl2303_class->intf; - setup->wLength = 7; - - memcpy(g_pl2303_buf, line_coding, sizeof(struct cdc_line_coding)); - - return usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf); -} - -int usbh_pl2303_get_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding) -{ - struct usb_setup_packet *setup; - int ret; - - if (!pl2303_class || !pl2303_class->hport) { - return -USB_ERR_INVAL; - } - setup = pl2303_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CDC_REQUEST_GET_LINE_CODING; - setup->wValue = 0; - setup->wIndex = pl2303_class->intf; - setup->wLength = 7; - - ret = usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf); - if (ret < 0) { - return ret; - } - memcpy(line_coding, g_pl2303_buf, sizeof(struct cdc_line_coding)); - return ret; -} - -int usbh_pl2303_set_line_state(struct usbh_pl2303 *pl2303_class, bool dtr, bool rts) -{ - struct usb_setup_packet *setup; - - if (!pl2303_class || !pl2303_class->hport) { - return -USB_ERR_INVAL; - } - setup = pl2303_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE; - setup->wValue = (dtr << 0) | (rts << 1); - setup->wIndex = pl2303_class->intf; - setup->wLength = 0; - - return usbh_control_transfer(pl2303_class->hport, setup, NULL); -} - -static int usbh_pl2303_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - - struct usbh_pl2303 *pl2303_class = usbh_pl2303_class_alloc(); - if (pl2303_class == NULL) { - USB_LOG_ERR("Fail to alloc pl2303_class\r\n"); - return -USB_ERR_NOMEM; - } - - pl2303_class->hport = hport; - pl2303_class->intf = intf; - - hport->config.intf[intf].priv = pl2303_class; - - do { - ret = usbh_pl2303_get_chiptype(pl2303_class); - if (ret < 0) { - break; - } - - /* Startup reset sequence, if necessary for the chip type */ - if (pl2303_class->chiptype != USBH_PL2303_TYPE_PL2303HXN) { - struct usb_setup_packet *setup = pl2303_class->hport->setup; - - setup->bmRequestType = UT_WRITE_VENDOR_DEVICE; - setup->bRequest = PL2303_SET_REQUEST; - setup->wValue = 0; - setup->wIndex = pl2303_class->intf; - setup->wLength = 0; - - ret = usbh_control_transfer(pl2303_class->hport, setup, g_pl2303_buf); - if (ret < 0) { - USB_LOG_WRN("Initialization reset failed: %d\r\n", ret); - break; - } - } - - if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303) { - /* HX variants seem to lock up after a clear stall request. */ - /* - * The FreeBSD code sets the stall flags on the in and out pipes - * here. Have no idea exactly how to do this, or if it is necessary. - * May just leave this code unwritten until test hardware is available. - */ - } else if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HX || pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HXD) { - /* Reset upstream data pipes */ - ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 8, 0, 0); - if (ret < 0) { - USB_LOG_WRN("Could not reset upstream data pipes (8,0): %d\r\n", ret); - break; - } - ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 9, 0, 0); - if (ret < 0) { - USB_LOG_WRN("Could not reset upstream data pipes (9,0): %d\r\n", ret); - break; - } - } else if (pl2303_class->chiptype == USBH_PL2303_TYPE_PL2303HXN) { - /* Reset upstream data pipes */ - ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST_PL2303HXN, 0x07, 0x03, 0); - if (ret < 0) { - USB_LOG_WRN("Could not reset upstream data pipes (7,3): %d\r\n", ret); - break; - } - } - - /* Final device initialization, if necessary for the chip type */ - if (pl2303_class->chiptype != USBH_PL2303_TYPE_PL2303HXN) { - if (usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 || - usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x0404, 0, 0) < 0 || - usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 || - usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8383, 0, 1) < 0 || - usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 || - usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x0404, 1, 0) < 0 || - usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8484, 0, 1) < 0 || - usbh_pl2303_do(pl2303_class, UT_READ_VENDOR_DEVICE, PL2303_SET_REQUEST, 0x8383, 0, 1) < 0 || - usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 0, 1, 0) < 0 || - usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 1, 0, 0) < 0) { - USB_LOG_WRN("Could not complete init sequence\r\n"); - ret = -USB_ERR_INVAL; - break; - } - - if (pl2303_class->chiptype != USBH_PL2303_TYPE_PL2303) { - ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 2, 0x44, 0); - } else { - ret = usbh_pl2303_do(pl2303_class, UT_WRITE_VENDOR_DEVICE, PL2303_SET_REQUEST, 2, 0x24, 0); - } - if (ret < 0) { - USB_LOG_WRN("Could not complete final init request: %d\r\n", ret); - break; - } - } - } while (0); - - if (ret < 0) { - USB_LOG_ERR("Failed to initialize PL2303 device: %d\r\n", ret); - return ret; - } - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - if (USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) { - continue; - } else { - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(pl2303_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(pl2303_class->bulkout, ep_desc); - } - } - } - - snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, pl2303_class->minor); - - USB_LOG_INFO("Register PL2303 Class:%s\r\n", hport->config.intf[intf].devname); - -#if 0 - USB_LOG_INFO("Test pl2303 rx and tx and rx for 5 times, baudrate is 115200\r\n"); - - struct cdc_line_coding linecoding; - uint8_t count = 5; - - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_pl2303_set_line_coding(pl2303_class, &linecoding); - usbh_pl2303_set_line_state(pl2303_class, true, false); - - memset(g_pl2303_buf, 'a', sizeof(g_pl2303_buf)); - ret = usbh_pl2303_bulk_out_transfer(pl2303_class, g_pl2303_buf, sizeof(g_pl2303_buf), 0xfffffff); - USB_LOG_RAW("out ret:%d\r\n", ret); - while (count--) { - ret = usbh_pl2303_bulk_in_transfer(pl2303_class, g_pl2303_buf, sizeof(g_pl2303_buf), 0xfffffff); - USB_LOG_RAW("in ret:%d\r\n", ret); - if (ret > 0) { - for (uint32_t i = 0; i < ret; i++) { - USB_LOG_RAW("%02x ", g_pl2303_buf[i]); - } - } - USB_LOG_RAW("\r\n"); - } -#endif - - usbh_pl2303_run(pl2303_class); - return ret; -} - -static int usbh_pl2303_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_pl2303 *pl2303_class = (struct usbh_pl2303 *)hport->config.intf[intf].priv; - - if (pl2303_class) { - if (pl2303_class->bulkin) { - usbh_kill_urb(&pl2303_class->bulkin_urb); - } - - if (pl2303_class->bulkout) { - usbh_kill_urb(&pl2303_class->bulkout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - usb_osal_thread_schedule_other(); - USB_LOG_INFO("Unregister PL2303 Class:%s\r\n", hport->config.intf[intf].devname); - usbh_pl2303_stop(pl2303_class); - } - - usbh_pl2303_class_free(pl2303_class); - } - - return ret; -} - -int usbh_pl2303_bulk_in_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &pl2303_class->bulkin_urb; - - usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -int usbh_pl2303_bulk_out_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &pl2303_class->bulkout_urb; - - usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -__WEAK void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class) -{ - (void)pl2303_class; -} - -__WEAK void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class) -{ - (void)pl2303_class; -} - -static const uint16_t pl2303_id_table[][2] = { - { 0x067B, 0x2303 }, // PL2303 Serial (ATEN/IOGEAR UC232A) - { 0x067B, 0x23A3 }, // PL2303HXN Serial, type GC - { 0x067B, 0x23B3 }, // PL2303HXN Serial, type GB - { 0x067B, 0x23C3 }, // PL2303HXN Serial, type GT - { 0x067B, 0x23D3 }, // PL2303HXN Serial, type GL - { 0x067B, 0x23E3 }, // PL2303HXN Serial, type GE - { 0x067B, 0x23F3 }, // PL2303HXN Serial, type GS - { 0, 0 }, -}; - -const struct usbh_class_driver pl2303_class_driver = { - .driver_name = "pl2303", - .connect = usbh_pl2303_connect, - .disconnect = usbh_pl2303_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info pl2303_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .id_table = pl2303_id_table, - .class_driver = &pl2303_class_driver -}; \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.h b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.h deleted file mode 100644 index 2b3d05f9e2d..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_PL2303_H -#define USBH_PL2303_H - -#include "usb_cdc.h" - -#define PL2303_SET_REQUEST 0x01 -#define PL2303_SET_REQUEST_PL2303HXN 0x80 -#define PL2303_SET_CRTSCTS 0x41 -#define PL2303_SET_CRTSCTS_PL2303X 0x61 -#define PL2303_SET_CRTSCTS_PL2303HXN 0xFA -#define PL2303_CLEAR_CRTSCTS_PL2303HXN 0xFF -#define PL2303_CRTSCTS_REG_PL2303HXN 0x0A -#define PL2303_STATUS_REG_PL2303HX 0x8080 - -/* Different PL2303 IC types */ -#define USBH_PL2303_TYPE_UNKNOWN 0 -#define USBH_PL2303_TYPE_PL2303 1 -#define USBH_PL2303_TYPE_PL2303HX 2 -#define USBH_PL2303_TYPE_PL2303HXD 3 -#define USBH_PL2303_TYPE_PL2303HXN 4 - -struct usbh_pl2303 { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ - - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - - struct cdc_line_coding linecoding; - - uint8_t intf; - uint8_t minor; - uint8_t chiptype; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_pl2303_set_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding); -int usbh_pl2303_get_line_coding(struct usbh_pl2303 *pl2303_class, struct cdc_line_coding *line_coding); -int usbh_pl2303_set_line_state(struct usbh_pl2303 *pl2303_class, bool dtr, bool rts); - -int usbh_pl2303_bulk_in_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); -int usbh_pl2303_bulk_out_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); - -void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class); -void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_PL2303_H */ diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/.gitkeep b/components/drivers/usb/cherryusb/class/vendor/wifi/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/README.md b/components/drivers/usb/cherryusb/class/vendor/wifi/README.md deleted file mode 100644 index 18384f65d5d..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/wifi/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# BL616 USB WIFI - -Usbwifi firmware please contact bouffalolab. You can purchase a module in the following ways: - -- https://iot.mi.com/moduleBrowser.html -- https://docs.ai-thinker.com/ai_m61 \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c deleted file mode 100644 index e44df5bd776..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_bl616.h" - -#undef USB_DBG_TAG -#define USB_DBG_TAG "usbh_bl616" -#include "usb_log.h" - -#define DEV_FORMAT "/dev/wifi/bl616" - -#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X" -#define ARR_ELE_6(e) (e)[0], (e)[1], (e)[2], (e)[3], (e)[4], (e)[5] - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_tx_buffer[2048 + 512]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_rx_buffer[2048 + 512]; - -static struct usbh_bl616 g_bl616_class; - -static const char *auth_to_str(uint8_t auth) -{ - const char *table[RNM_WIFI_AUTH_MAX] = { - [RNM_WIFI_AUTH_UNKNOWN] = "UNKNOWN", - [RNM_WIFI_AUTH_OPEN] = "OPEN", - [RNM_WIFI_AUTH_WEP] = "WEP", - [RNM_WIFI_AUTH_WPA_PSK] = "WPA-PSK", - [RNM_WIFI_AUTH_WPA2_PSK] = "WPA2-PSK", - [RNM_WIFI_AUTH_WPA_WPA2_PSK] = "WPA2-PSK/WPA-PSK", - [RNM_WIFI_AUTH_WPA_ENTERPRISE] = "WPA-ENT", - [RNM_WIFI_AUTH_WPA3_SAE] = "WPA3-SAE", - [RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE] = "WPA2-PSK/WPA3-SAE", - }; - if (auth < RNM_WIFI_AUTH_MAX) - return table[auth]; - else - return table[RNM_WIFI_AUTH_UNKNOWN]; -} - -static const char *cipher_to_str(uint8_t cipher) -{ - const char *table[RNM_WIFI_CIPHER_MAX] = { - [RNM_WIFI_CIPHER_UNKNOWN] = "UNKNOWN", - [RNM_WIFI_CIPHER_NONE] = "NONE", - [RNM_WIFI_CIPHER_WEP] = "WEP", - [RNM_WIFI_CIPHER_AES] = "AES", - [RNM_WIFI_CIPHER_TKIP] = "TKIP", - [RNM_WIFI_CIPHER_TKIP_AES] = "TKIP/AES", - }; - if (cipher < RNM_WIFI_CIPHER_MAX) - return table[cipher]; - else - return table[RNM_WIFI_CIPHER_UNKNOWN]; -} - -static int parse_get_mac_rsp_msg(struct usbh_bl616 *bl616_class, void *buf, int buf_len) -{ - usb_data_t *usb_hdr = buf; - rnm_mac_addr_ind_msg_t *rsp = buf + sizeof(usb_data_t); - - if (buf_len != sizeof(usb_data_t) + sizeof(rnm_mac_addr_ind_msg_t)) { - return -1; - } - if (usb_hdr->type != USBWIFI_DATA_TYPE_CMD || usb_hdr->length != sizeof(rnm_mac_addr_ind_msg_t)) { - return -1; - } - if (rsp->hdr.cmd != BFLB_CMD_GET_MAC_ADDR || !(rsp->hdr.flags & RNM_MSG_FLAG_ACK)) { - return -1; - } - memcpy(bl616_class->sta_mac, rsp->sta_mac, 6); - memcpy(bl616_class->ap_mac, rsp->ap_mac, 6); - - return 0; -} - -static int usbh_bl616_bulk_in_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &bl616_class->bulkin_urb; - - usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -static int usbh_bl616_bulk_out_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &bl616_class->bulkout_urb; - - usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -static int usbh_bl616_get_wifi_mac(struct usbh_bl616 *bl616_class) -{ - int ret; - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *rnm_msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(rnm_msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - rnm_msg->cmd = BFLB_CMD_GET_MAC_ADDR; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - ret = usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500); - if (ret < 0) { - return ret; - } - ret = usbh_bl616_bulk_in_transfer(bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), 500); - if (ret < 0) { - return ret; - } - - ret = parse_get_mac_rsp_msg(bl616_class, g_bl616_rx_buffer, ret); - return ret; -} - -static int usbh_bl616_wifi_open(struct usbh_bl616 *bl616_class) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_HELLO; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -static int usbh_bl616_wifi_close(struct usbh_bl616 *bl616_class) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_UNLOAD_DRV; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_wifi_sta_connect(const char *ssid, - const int ssid_len, - const char *password, - const int pwd_len) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_sta_connect_msg_t *msg = (rnm_sta_connect_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_sta_connect_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_sta_connect_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->hdr.cmd = BFLB_CMD_STA_CONNECT; - msg->hdr.msg_id = 0x0001; - msg->hdr.session_id = 0x0002; - msg->ssid_len = ssid_len; - memcpy(msg->ssid, ssid, ssid_len); - if (password) { - memcpy(msg->password, password, pwd_len); - } - - msg_len = sizeof(usb_data_t) + sizeof(rnm_sta_connect_msg_t); - - return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_wifi_sta_disconnect(void) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_STA_DISCONNECT; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_get_wifi_scan_result(void) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_SCAN_RESULTS; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_wifi_scan(void) -{ - int ret; - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_SCAN; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - ret = usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); - if (ret < 0) { - return ret; - } - - usb_osal_msleep(500); - return usbh_bl616_get_wifi_scan_result(); -} - -static int usbh_bl616_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - - struct usbh_bl616 *bl616_class = &g_bl616_class; - - memset(bl616_class, 0, sizeof(struct usbh_bl616)); - - bl616_class->hport = hport; - bl616_class->intf = intf; - - hport->config.intf[intf].priv = bl616_class; - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(bl616_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(bl616_class->bulkout, ep_desc); - } - } - - usbh_bl616_get_wifi_mac(bl616_class); - usbh_bl616_wifi_close(bl616_class); - usbh_bl616_wifi_open(bl616_class); - - USB_LOG_INFO("BL616 WIFI STA MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n", - bl616_class->sta_mac[0], - bl616_class->sta_mac[1], - bl616_class->sta_mac[2], - bl616_class->sta_mac[3], - bl616_class->sta_mac[4], - bl616_class->sta_mac[5]); - - USB_LOG_INFO("BL616 WIFI AP MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n", - bl616_class->ap_mac[0], - bl616_class->ap_mac[1], - bl616_class->ap_mac[2], - bl616_class->ap_mac[3], - bl616_class->ap_mac[4], - bl616_class->ap_mac[5]); - - strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN); - - USB_LOG_INFO("Register BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname); - - usbh_bl616_run(bl616_class); - return ret; -} - -static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_bl616 *bl616_class = (struct usbh_bl616 *)hport->config.intf[intf].priv; - - if (bl616_class) { - if (bl616_class->bulkin) { - usbh_kill_urb(&bl616_class->bulkin_urb); - } - - if (bl616_class->bulkout) { - usbh_kill_urb(&bl616_class->bulkout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - usb_osal_thread_schedule_other(); - USB_LOG_INFO("Unregister BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname); - usbh_bl616_stop(bl616_class); - } - - memset(bl616_class, 0, sizeof(struct usbh_bl616)); - } - - return ret; -} - -void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) -{ - int ret; - usb_data_t *usb_hdr; - rnm_base_msg_t *msg; - rnm_sta_ip_update_ind_msg_t *ipmsg; - rnm_scan_ind_msg_t *scanmsg; - uint8_t *data; - - (void)CONFIG_USB_OSAL_THREAD_GET_ARGV; - USB_LOG_INFO("Create bl616 wifi rx thread\r\n"); - - while (1) { - ret = usbh_bl616_bulk_in_transfer(&g_bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), USB_OSAL_WAITING_FOREVER); - if (ret < 0) { - break; - } - - usb_hdr = (usb_data_t *)g_bl616_rx_buffer; - - if (usb_hdr->type == USBWIFI_DATA_TYPE_CMD) { - msg = (rnm_base_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - - switch (msg->cmd) { - case BFLB_CMD_STA_CONNECTED_IND: - USB_LOG_INFO("AP connected\n"); - g_bl616_class.connect_status = true; - usbh_bl616_sta_connect_callback(); - - break; - case BFLB_CMD_STA_DISCONNECTED_IND: - if (g_bl616_class.connect_status == true) { - g_bl616_class.connect_status = false; - USB_LOG_INFO("AP disconnected\n"); - usbh_bl616_sta_disconnect_callback(); - } - break; - case BFLB_CMD_STA_IP_UPDATE_IND: - ipmsg = (rnm_sta_ip_update_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - - USB_LOG_INFO("WIFI IP update\r\n"); - USB_LOG_INFO("WIFI IPv4 Address : %d:%d:%d:%d\r\n", - ipmsg->ip4_addr[0], - ipmsg->ip4_addr[1], - ipmsg->ip4_addr[2], - ipmsg->ip4_addr[3]); - USB_LOG_INFO("WIFI IPv4 Mask : %d:%d:%d:%d\r\n", - ipmsg->ip4_mask[0], - ipmsg->ip4_mask[1], - ipmsg->ip4_mask[2], - ipmsg->ip4_mask[3]); - USB_LOG_INFO("WIFI IPv4 Gateway : %d:%d:%d:%d\r\n\r\n", - ipmsg->ip4_gw[0], - ipmsg->ip4_gw[1], - ipmsg->ip4_gw[2], - ipmsg->ip4_gw[3]); - - g_bl616_class.mode = BL_MODE_STA; - usbh_bl616_sta_update_ip(ipmsg->ip4_addr, ipmsg->ip4_mask, ipmsg->ip4_gw); - break; - case BFLB_CMD_SCAN_RESULTS: - scanmsg = (rnm_scan_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - USB_LOG_INFO("WIFI scan result:\r\n"); - for (uint32_t i = 0; i < scanmsg->num; ++i) { - struct bf1b_wifi_scan_record *r = &scanmsg->records[i]; - USB_LOG_INFO("BSSID " MAC_FMT ", channel %u, rssi %d, auth %s, cipher %s, SSID %s\r\n", - ARR_ELE_6(r->bssid), r->channel, r->rssi, - auth_to_str(r->auth_mode), cipher_to_str(r->cipher), r->ssid); - } - break; - default: - break; - } - } else if (usb_hdr->type == USBWIFI_DATA_TYPE_PKT) { - data = (uint8_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - usbh_bl616_eth_input(data, usb_hdr->length); - } else { - } - } - - USB_LOG_INFO("Delete bl616 wifi rx thread\r\n"); - usb_osal_thread_delete(NULL); -} - -uint8_t *usbh_bl616_get_eth_txbuf(void) -{ - return (g_bl616_tx_buffer + sizeof(usb_data_t)); -} - -int usbh_bl616_eth_output(uint32_t buflen) -{ - usb_data_t *usb_hdr; - uint32_t txlen; - - if (g_bl616_class.connect_status == false) { - return -USB_ERR_NOTCONN; - } - - usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - memset(usb_hdr, 0, sizeof(usb_data_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_PKT; - usb_hdr->length = buflen; - usb_hdr->payload_offset = sizeof(usb_data_t); - - txlen = buflen + sizeof(usb_data_t); - if (!(txlen % USB_GET_MAXPACKETSIZE(g_bl616_class.bulkout->wMaxPacketSize))) { - txlen += 1; - } - USB_LOG_DBG("txlen:%d\r\n", txlen); - - usbh_bulk_urb_fill(&g_bl616_class.bulkout_urb, g_bl616_class.hport, g_bl616_class.bulkout, g_bl616_tx_buffer, txlen, USB_OSAL_WAITING_FOREVER, NULL, NULL); - return usbh_submit_urb(&g_bl616_class.bulkout_urb); -} - -int wifi_sta_connect(int argc, char **argv) -{ - if (argc < 3) { - USB_LOG_ERR("Usage: %s \r\n", argv[0]); - return -1; - } - usbh_bl616_wifi_sta_connect(argv[1], strlen(argv[1]), argv[2], strlen(argv[2])); - return 0; -} - -int wifi_scan(int argc, char **argv) -{ - (void)argc; - (void)argv; - - usbh_bl616_wifi_scan(); - return 0; -} - -__WEAK void usbh_bl616_run(struct usbh_bl616 *bl616_class) -{ - (void)bl616_class; -} - -__WEAK void usbh_bl616_stop(struct usbh_bl616 *bl616_class) -{ - (void)bl616_class; -} - -static const uint16_t bl616_id_table[][2] = { - { 0x349b, 0x616f }, - { 0, 0 }, -}; - -static const struct usbh_class_driver bl616_class_driver = { - .driver_name = "bl616_wifi", - .connect = usbh_bl616_connect, - .disconnect = usbh_bl616_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info bl616_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .id_table = bl616_id_table, - .class_driver = &bl616_class_driver -}; diff --git a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h b/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h deleted file mode 100644 index 2d247ae2eab..00000000000 --- a/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_BL616_H -#define USBH_BL616_H - -#define USBWIFI_DATA_TYPE_CMD 0xA55A -#define USBWIFI_DATA_TYPE_PKT 0x6996 - -#define USB_DATA_FLAG_AP_PKT (1u << 0) - -typedef enum { - BFLB_CMD_REBOOT = 0, - BFLB_CMD_RESET, - BFLB_CMD_HELLO, - BFLB_CMD_PING, - - BFLB_CMD_GET_MAC_ADDR, - - // Scan - BFLB_CMD_SCAN, - BFLB_CMD_SCAN_RESULTS, - - // STA - BFLB_CMD_STA_CONNECT, - BFLB_CMD_STA_DISCONNECT, - BFLB_CMD_STA_CONNECTED_IND, - BFLB_CMD_STA_DISCONNECTED_IND, - BFLB_CMD_STA_IP_UPDATE_IND, - BFLB_CMD_STA_SET_AUTO_RECONNECT, - BFLB_CMD_STA_GET_LINK_STATUS, - - // AP - BFLB_CMD_AP_START, - BFLB_CMD_AP_STOP, - BFLB_CMD_AP_STARTED_IND, - BFLB_CMD_AP_STOPPED_IND, - BFLB_CMD_AP_GET_STA_LIST, - - // Monitor - BFLB_CMD_MONITOR_START, - BFLB_CMD_MONITOR_STOP, - BFLB_CMD_MONITOR_SET_CHANNEL, - BFLB_CMD_MONITOR_GET_CHANNEL, - - BFLB_CMD_SET_LPM_MODE, - - // OTA - BFLB_CMD_GET_DEV_VERSION, - BFLB_CMD_OTA, - - BFLB_CMD_EXT, - - BFLB_CMD_USER_EXT, - BFLB_CMD_UNLOAD_DRV, - - BFLB_CMD_MAX, -} bflb_cmd_t; - -typedef enum { - STATUS_OK, - STATUS_NOMEM = 128, - STATUS_INVALID_INPUT, - STATUS_INVALID_MODE, - STATUS_ERR_UNSPECIFIED, - STATUS_NOT_IMPLEMENTED, -} cmd_status_t; - -typedef enum { - RNM_WIFI_AUTH_UNKNOWN = 0, - RNM_WIFI_AUTH_OPEN, - RNM_WIFI_AUTH_WEP, - RNM_WIFI_AUTH_WPA_PSK, - RNM_WIFI_AUTH_WPA2_PSK, - RNM_WIFI_AUTH_WPA_WPA2_PSK, - RNM_WIFI_AUTH_WPA_ENTERPRISE, - RNM_WIFI_AUTH_WPA3_SAE, - RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE, - RNM_WIFI_AUTH_MAX, -} rnm_wifi_auth_mode_t; - -typedef enum { - RNM_WIFI_CIPHER_UNKNOWN = 0, - RNM_WIFI_CIPHER_NONE, - RNM_WIFI_CIPHER_WEP, - RNM_WIFI_CIPHER_AES, - RNM_WIFI_CIPHER_TKIP, - RNM_WIFI_CIPHER_TKIP_AES, - RNM_WIFI_CIPHER_MAX, -} rnm_wifi_cipher_t; - -/* common header */ -typedef struct { - uint16_t cmd; - // flag ACK is used by server to indicate a response to client -#define RNM_MSG_FLAG_ACK (1 << 0) - // flag TRANSPARENT is never transfered to peer but used locally -#define RNM_MSG_FLAG_TRANSPARENT (1 << 1) - // flag ASYNC is used by server to notify client events such as STA_CONNECTED -#define RNM_MSG_FLAG_ASYNC (1 << 2) - uint16_t flags; - uint16_t status; - uint16_t msg_id; - uint16_t session_id; - uint16_t msg_id_replying; -} rnm_base_msg_t; - -typedef struct { - rnm_base_msg_t hdr; -} rnm_ack_msg_t; - -typedef struct { - rnm_base_msg_t hdr; - uint8_t sta_mac[6]; - uint8_t ap_mac[6]; -} rnm_mac_addr_ind_msg_t; - -typedef struct { - rnm_base_msg_t hdr; - uint16_t ssid_len; - uint8_t ssid[32]; - uint8_t password[64]; -} rnm_sta_connect_msg_t; - -typedef struct { - rnm_base_msg_t hdr; - uint8_t ip4_addr[4]; - uint8_t ip4_mask[4]; - uint8_t ip4_gw[4]; - uint8_t ip4_dns1[4]; - uint8_t ip4_dns2[4]; - uint8_t gw_mac[6]; -} rnm_sta_ip_update_ind_msg_t; - -struct bf1b_wifi_scan_record { - uint8_t bssid[6]; - // TODO use compressed SSID encoding to save room - uint8_t ssid[32 + 1]; - uint16_t channel; - int8_t rssi; - uint8_t auth_mode; - uint8_t cipher; -} __PACKED; - -typedef struct { - rnm_base_msg_t hdr; - uint16_t num; - struct bf1b_wifi_scan_record records[]; -} rnm_scan_ind_msg_t; - -typedef enum { - BL_MODE_NONE, - BL_MODE_STA, // card is STA - BL_MODE_AP, // card is AP - BL_MODE_STA_AP, // card is STA&AP - BL_MODE_SNIFFER, // card is sniffer - BL_MODE_MAX, -} bl_wifi_mode_t; - -typedef struct { - uint16_t type; - uint16_t length; - uint16_t flags; - uint16_t payload_offset; - uint32_t rsvd[8]; - uint8_t payload[]; -} __attribute__((aligned(4))) usb_data_t; - -struct usbh_bl616 { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ - - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - - uint8_t intf; - - uint8_t sta_mac[6]; - uint8_t ap_mac[6]; - uint8_t mode; - bool connect_status; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_bl616_wifi_sta_connect(const char *ssid, - const int ssid_len, - const char *password, - const int pwd_len); - -int usbh_bl616_wifi_sta_disconnect(void); -int usbh_bl616_wifi_scan(void); - -void usbh_bl616_sta_connect_callback(void); -void usbh_bl616_sta_disconnect_callback(void); -void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4]); - -uint8_t *usbh_bl616_get_eth_txbuf(void); -int usbh_bl616_eth_output(uint32_t buflen); -void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen); -void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV); - -void usbh_bl616_run(struct usbh_bl616 *bl616_class); -void usbh_bl616_stop(struct usbh_bl616 *bl616_class); - -int wifi_sta_connect(int argc, char **argv); -int wifi_scan(int argc, char **argv); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_BL616_H */ diff --git a/components/drivers/usb/cherryusb/class/video/usbh_video.c b/components/drivers/usb/cherryusb/class/video/usbh_video.c index 077b6bb915d..18acbda37ab 100644 --- a/components/drivers/usb/cherryusb/class/video/usbh_video.c +++ b/components/drivers/usb/cherryusb/class/video/usbh_video.c @@ -122,12 +122,12 @@ int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class) return usbh_video_get(video_class, VIDEO_REQUEST_GET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26); } -int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex) +int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwFrameInterval) { video_class->probe.bFormatIndex = formatindex; video_class->probe.bFrameIndex = frameindex; video_class->probe.dwMaxPayloadTransferSize = 0; - video_class->probe.dwFrameInterval = 333333; + video_class->probe.dwFrameInterval = dwFrameInterval; return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26); } @@ -136,7 +136,6 @@ int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t f memcpy(&video_class->commit, &video_class->probe, sizeof(struct video_probe_and_commit_controls)); video_class->commit.bFormatIndex = formatindex; video_class->commit.bFrameIndex = frameindex; - video_class->commit.dwFrameInterval = 333333; return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26); } @@ -154,6 +153,7 @@ int usbh_video_open(struct usbh_video *video_class, bool found = false; uint8_t formatidx = 0; uint8_t frameidx = 0; + uint32_t dwDefaultFrameInterval = 0; uint8_t step; if (!video_class || !video_class->hport) { @@ -172,6 +172,7 @@ int usbh_video_open(struct usbh_video *video_class, if ((wWidth == video_class->format[i].frame[j].wWidth) && (wHeight == video_class->format[i].frame[j].wHeight)) { frameidx = j + 1; + dwDefaultFrameInterval = video_class->format[i].frame[j].dwDefaultFrameInterval; found = true; break; } @@ -204,7 +205,7 @@ int usbh_video_open(struct usbh_video *video_class, } step = 1; - ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); + ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval); if (ret < 0) { goto errout; } @@ -228,7 +229,7 @@ int usbh_video_open(struct usbh_video *video_class, } step = 5; - ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); + ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval); if (ret < 0) { goto errout; } @@ -246,26 +247,30 @@ int usbh_video_open(struct usbh_video *video_class, } step = 8; - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = USB_REQUEST_SET_INTERFACE; - setup->wValue = altsetting; - setup->wIndex = video_class->data_intf; - setup->wLength = 0; - - ret = usbh_control_transfer(video_class->hport, setup, NULL); - if (ret < 0) { - goto errout; - } + if (!video_class->is_bulk) { + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = USB_REQUEST_SET_INTERFACE; + setup->wValue = altsetting; + setup->wIndex = video_class->data_intf; + setup->wLength = 0; + + ret = usbh_control_transfer(video_class->hport, setup, NULL); + if (ret < 0) { + goto errout; + } - ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc; - mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; - mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; - if (ep_desc->bEndpointAddress & 0x80) { - video_class->isoin_mps = mps * (mult + 1); - USBH_EP_INIT(video_class->isoin, ep_desc); + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc; + mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; + mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; + if (ep_desc->bEndpointAddress & 0x80) { + video_class->isoin_mps = mps * (mult + 1); + USBH_EP_INIT(video_class->isoin, ep_desc); + } else { + return -USB_ERR_NODEV; + } } else { - video_class->isoout_mps = mps * (mult + 1); - USBH_EP_INIT(video_class->isoout, ep_desc); + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc; + USBH_EP_INIT(video_class->bulkin, ep_desc); } USB_LOG_INFO("Open video and select formatidx:%u, frameidx:%u, altsetting:%u\r\n", formatidx, frameidx, altsetting); @@ -292,54 +297,62 @@ int usbh_video_close(struct usbh_video *video_class) video_class->is_opened = false; - if (video_class->isoin) { - video_class->isoin = NULL; - } - - if (video_class->isoout) { - video_class->isoout = NULL; + if (video_class->is_bulk) { + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_ENDPOINT; + setup->bRequest = USB_REQUEST_CLEAR_FEATURE; + setup->wValue = USB_FEATURE_ENDPOINT_HALT; + setup->wIndex = video_class->bulkin->bEndpointAddress; + setup->wLength = 0; + } else { + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = USB_REQUEST_SET_INTERFACE; + setup->wValue = 0; + setup->wIndex = video_class->data_intf; + setup->wLength = 0; } - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = USB_REQUEST_SET_INTERFACE; - setup->wValue = 0; - setup->wIndex = video_class->data_intf; - setup->wLength = 0; - ret = usbh_control_transfer(video_class->hport, setup, NULL); if (ret < 0) { return ret; } + return ret; } void usbh_video_list_info(struct usbh_video *video_class) { struct usb_endpoint_descriptor *ep_desc; - uint8_t mult; - uint16_t mps; USB_LOG_INFO("============= Video device information ===================\r\n"); USB_LOG_RAW("bcdVDC:%04x\r\n", video_class->bcdVDC); - USB_LOG_RAW("Num of altsettings:%u\r\n", video_class->num_of_intf_altsettings); - - for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) { - if (i == 0) { - USB_LOG_RAW("Ingore altsetting 0\r\n"); - continue; + USB_LOG_RAW("Num of altsettings:%u (%s mode)\r\n", video_class->num_of_intf_altsettings, video_class->num_of_intf_altsettings == 1 ? "bulk" : "iso"); + + video_class->is_bulk = video_class->num_of_intf_altsettings == 1 ? true : false; + + if (video_class->is_bulk) { + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc; + USB_LOG_RAW("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", + ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize), + ep_desc->bInterval, + USB_GET_MULT(ep_desc->wMaxPacketSize)); + } else { + for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) { + if (i == 0) { + USB_LOG_RAW("Ingore altsetting 0\r\n"); + continue; + } + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc; + + USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", + i, + ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize), + ep_desc->bInterval, + USB_GET_MULT(ep_desc->wMaxPacketSize)); } - ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc; - - mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; - mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; - - USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", - i, - ep_desc->bEndpointAddress, - ep_desc->bmAttributes, - mps, - ep_desc->bInterval, - mult); } USB_LOG_RAW("bNumFormats:%u\r\n", video_class->num_of_formats); @@ -350,9 +363,10 @@ void usbh_video_list_info(struct usbh_video *video_class) USB_LOG_RAW(" Resolution:\r\n"); for (uint8_t j = 0; j < video_class->format[i].num_of_frames; j++) { USB_LOG_RAW(" FrameIndex:%u\r\n", j + 1); - USB_LOG_RAW(" wWidth: %d, wHeight: %d\r\n", - video_class->format[i].frame[j].wWidth, - video_class->format[i].frame[j].wHeight); + USB_LOG_RAW(" wWidth: %d, wHeight: %d, fps: %d\r\n", + video_class->format[i].frame[j].wWidth, + video_class->format[i].frame[j].wHeight, + (1000 / (video_class->format[i].frame[j].dwDefaultFrameInterval / 10000))); } } @@ -438,12 +452,14 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) 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; break; case VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE: frame_index = p[DESC_bFrameIndex]; 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; break; default: break; @@ -476,12 +492,6 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) struct usbh_video *video_class = (struct usbh_video *)hport->config.intf[intf].priv; if (video_class) { - if (video_class->isoin) { - } - - if (video_class->isoout) { - } - if (hport->config.intf[intf].devname[0] != '\0') { usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister Video Class:%s\r\n", hport->config.intf[intf].devname); diff --git a/components/drivers/usb/cherryusb/class/video/usbh_video.h b/components/drivers/usb/cherryusb/class/video/usbh_video.h index dac5792c141..9edce49b93d 100644 --- a/components/drivers/usb/cherryusb/class/video/usbh_video.h +++ b/components/drivers/usb/cherryusb/class/video/usbh_video.h @@ -14,6 +14,7 @@ struct usbh_video_resolution { uint16_t wWidth; uint16_t wHeight; + uint32_t dwDefaultFrameInterval; }; struct usbh_video_format { @@ -40,7 +41,7 @@ struct usbh_videostreaming { struct usbh_video { struct usbh_hubport *hport; struct usb_endpoint_descriptor *isoin; /* ISO IN endpoint */ - struct usb_endpoint_descriptor *isoout; /* ISO OUT endpoint */ + struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ uint8_t ctrl_intf; /* interface number */ uint8_t data_intf; /* interface number */ @@ -48,9 +49,9 @@ struct usbh_video { struct video_probe_and_commit_controls probe; struct video_probe_and_commit_controls commit; uint16_t isoin_mps; - uint16_t isoout_mps; bool is_opened; uint8_t current_format; + bool is_bulk; uint16_t bcdVDC; uint8_t num_of_intf_altsettings; uint8_t num_of_formats; diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c index cb00651faab..709630cbe34 100644 --- a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c +++ b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c @@ -578,16 +578,6 @@ int usbh_rndis_eth_output(uint32_t buflen) return usbh_submit_urb(&g_rndis_class.bulkout_urb); } -__WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class) -{ - (void)rndis_class; -} - -__WEAK void usbh_rndis_stop(struct usbh_rndis *rndis_class) -{ - (void)rndis_class; -} - static const struct usbh_class_driver rndis_class_driver = { .driver_name = "rndis", .connect = usbh_rndis_connect, @@ -602,3 +592,12 @@ CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = { .id_table = NULL, .class_driver = &rndis_class_driver }; + +CLASS_INFO_DEFINE const struct usbh_class_info rndis_cdcacm_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .bInterfaceClass = USB_DEVICE_CLASS_CDC, + .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL, + .bInterfaceProtocol = 0xff, + .id_table = NULL, + .class_driver = &rndis_class_driver +}; diff --git a/components/drivers/usb/cherryusb/common/usb_def.h b/components/drivers/usb/cherryusb/common/usb_def.h index 27b4d821550..be5ab061033 100644 --- a/components/drivers/usb/cherryusb/common/usb_def.h +++ b/components/drivers/usb/cherryusb/common/usb_def.h @@ -318,24 +318,24 @@ /* Setup packet definition used to read raw data from USB line */ struct usb_setup_packet { /** Request type. Bits 0:4 determine recipient, see - * \ref usb_request_recipient. Bits 5:6 determine type, see - * \ref usb_request_type. Bit 7 determines data transfer direction, see - * \ref usb_endpoint_direction. - */ + * \ref usb_request_recipient. Bits 5:6 determine type, see + * \ref usb_request_type. Bit 7 determines data transfer direction, see + * \ref usb_endpoint_direction. + */ uint8_t bmRequestType; /** Request. If the type bits of bmRequestType are equal to - * \ref usb_request_type::LIBUSB_REQUEST_TYPE_STANDARD - * "USB_REQUEST_TYPE_STANDARD" then this field refers to - * \ref usb_standard_request. For other cases, use of this field is - * application-specific. */ + * \ref usb_request_type::LIBUSB_REQUEST_TYPE_STANDARD + * "USB_REQUEST_TYPE_STANDARD" then this field refers to + * \ref usb_standard_request. For other cases, use of this field is + * application-specific. */ uint8_t bRequest; /** Value. Varies according to request */ uint16_t wValue; /** Index. Varies according to request, typically used to pass an index - * or offset */ + * or offset */ uint16_t wIndex; /** Number of bytes to transfer */ @@ -556,7 +556,7 @@ struct usb_bos_header_descriptor { } __PACKED; /* BOS Capability platform Descriptor */ -struct usb_bos_capability_platform_descriptor { +struct usb_bos_capability_platform_common_descriptor { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDevCapabilityType; @@ -564,16 +564,26 @@ struct usb_bos_capability_platform_descriptor { uint8_t PlatformCapabilityUUID[16]; } __PACKED; -/* BOS Capability MS OS Descriptors version 2 */ -struct usb_bos_capability_msosv2_descriptor { +/* Microsoft OS 2.0 Platform Capability Descriptor +* See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/ +* microsoft-defined-usb-descriptors +* Adapted from the source: +* https://github.com/sowbug/weblight/blob/master/firmware/webusb.c +* (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c +*/ +struct usb_bos_capability_platform_winusb_descriptor { + struct usb_bos_capability_platform_common_descriptor common; uint32_t dwWindowsVersion; uint16_t wMSOSDescriptorSetTotalLength; uint8_t bVendorCode; uint8_t bAltEnumCode; } __PACKED; -/* BOS Capability webusb */ -struct usb_bos_capability_webusb_descriptor { +/* WebUSB Platform Capability Descriptor: +* https://wicg.github.io/webusb/#webusb-platform-capability-descriptor +*/ +struct usb_bos_capability_platform_webusb_descriptor { + struct usb_bos_capability_platform_common_descriptor common; uint16_t bcdVersion; uint8_t bVendorCode; uint8_t iLandingPage; @@ -587,26 +597,6 @@ struct usb_bos_capability_extension_descriptor { uint32_t bmAttributes; } __PACKED; -/* Microsoft OS 2.0 Platform Capability Descriptor -* See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/ -* microsoft-defined-usb-descriptors -* Adapted from the source: -* https://github.com/sowbug/weblight/blob/master/firmware/webusb.c -* (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c -*/ -struct usb_bos_capability_platform_msosv2_descriptor { - struct usb_bos_capability_platform_descriptor platform_msos; - struct usb_bos_capability_msosv2_descriptor data_msosv2; -} __PACKED; - -/* WebUSB Platform Capability Descriptor: -* https://wicg.github.io/webusb/#webusb-platform-capability-descriptor -*/ -struct usb_bos_capability_platform_webusb_descriptor { - struct usb_bos_capability_platform_descriptor platform_webusb; - struct usb_bos_capability_webusb_descriptor data_webusb; -} __PACKED; - struct usb_webusb_url_descriptor { uint8_t bLength; uint8_t bDescriptorType; @@ -625,18 +615,12 @@ struct usb_bos_descriptor { uint32_t string_len; }; -/* USB Device Capability Descriptor */ -struct usb_device_capability_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDevCapabilityType; -} __PACKED; - /** USB descriptor header */ struct usb_desc_header { uint8_t bLength; /**< descriptor length */ uint8_t bDescriptorType; /**< descriptor type */ }; + // clang-format off #define USB_DEVICE_DESCRIPTOR_INIT(bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct, bcdDevice, bNumConfigurations) \ 0x12, /* bLength */ \ @@ -705,7 +689,7 @@ struct usb_desc_header { WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ bInterval /* bInterval */ -#define USB_IAD_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \ +#define USB_IAD_DESCRIPTOR_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \ 0x08, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ bFirstInterface, /* bFirstInterface */ \ @@ -716,9 +700,145 @@ struct usb_desc_header { 0x00 /* iFunction */ #define USB_LANGID_INIT(id) \ - 0x04, /* bLength */ \ + 0x04, /* bLength */ \ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \ WBVAL(id) /* wLangID0 */ + +#define USB_BOS_HEADER_DESCRIPTOR_INIT(wTotalLength, bNumDeviceCaps) \ + 0x05, /* bLength */ \ + USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE, /* bDescriptorType */\ + WBVAL(wTotalLength), /* wTotalLength */ \ + bNumDeviceCaps /* bNumDeviceCaps */ + +#define USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_INIT(bVendorCode, iLandingPage) \ + 0x18, /* bLength */ \ + USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, /* bDescriptorType */ \ + USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ \ + 0x00, /* bReserved */ \ + 0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, /* PlatformCapabilityUUID */ \ + 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65, \ + WBVAL(0x0100), /* bcdVersion */ \ + bVendorCode, /* bVendorCode */ \ + iLandingPage /* iLandingPage */ + +#define USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(bVendorCode, wMSOSDescriptorSetTotalLength) \ + 0x1C, /* bLength */ \ + USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, /* bDescriptorType */ \ + USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ \ + 0x00, /* bReserved */ \ + 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, /* PlatformCapabilityUUID */ \ + 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F, \ + DBVAL(0x06030000), /* dwWindowsVersion */ \ + WBVAL(wMSOSDescriptorSetTotalLength), /* wMSOSDescriptorSetTotalLength */ \ + bVendorCode, /* bVendorCode */ \ + 0x00 /* bAltEnumCode */ + +#define USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_LEN 24 +#define USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN 28 + +#define USB_MSOSV1_STRING_DESCRIPTOR_INIT(vendor_code) \ + 0x12, /* bLength */ \ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \ + 'M', 0, /* bString[0] */ \ + 'S', 0, /* bString[1] */ \ + 'F', 0, /* bString[2] */ \ + 'T', 0, /* bString[3] */ \ + '1', 0, /* bString[4] */ \ + '0', 0, /* bString[5] */ \ + '0', 0, /* bString[6] */ \ + vendor_code, /* bMS_VendorCode */ \ + 0x00 /* bPad */ + +#define USB_MSOSV1_COMP_ID_HEADER_DESCRIPTOR_INIT(bCount) \ + DBVAL((sizeof(struct usb_msosv1_compat_id_header_descriptor) + sizeof(struct usb_msosv1_comp_id_function_descriptor) * bCount)), /* dwLength */ \ + WBVAL(0x0100), /* bcdVersion */ \ + WBVAL(0x0004), /* wIndex */ \ + bCount, /* bCount */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved[7] */ + +#define USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(bFirstInterfaceNumber) \ + bFirstInterfaceNumber, /* bFirstInterfaceNumber */\ + 0x01, /* reserved1 */ \ + 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* compatibleID[8] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved2[6] */ + +#define USB_MSOSV1_COMP_ID_FUNCTION_MTP_DESCRIPTOR_INIT(bFirstInterfaceNumber)\ + bFirstInterfaceNumber, /* bFirstInterfaceNumber */\ + 0x01, /* reserved1 */ \ + 'M', 'T', 'P', 'U', 'S', 'B', 0x00, 0x00, /* compatibleID[8] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved2[6] */ + +#define USB_MSOSV1_COMP_ID_FUNCTION_ADB_DESCRIPTOR_INIT(bFirstInterfaceNumber)\ + bFirstInterfaceNumber, * bFirstInterfaceNumber */\ + 0x01, /* reserved1 */ \ + 'A', 'D', 'B', 0x00, 0x00, 0x00, 0x00, 0x00, /* compatibleID[8] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* subCompatibleID[8] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* reserved2[6] */ + +#define USB_MSOSV1_COMP_ID_DESCRIPTOR_LEN(bCount) \ + (sizeof(struct usb_msosv1_compat_id_header_descriptor) + sizeof(struct usb_msosv1_comp_id_function_descriptor) * (bCount)) + +#define USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(wDescriptorSetTotalLength) \ + WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */ \ + WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */ \ + DBVAL(0x06030000), /* dwWindowsVersion */ \ + WBVAL(wDescriptorSetTotalLength) /* wDescriptorSetTotalLength */ + +#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_INIT() \ + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ \ + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ \ + 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ \ + 0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ \ + WBVAL(132), /* wLength */ \ + WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ \ + WBVAL(WINUSB_PROP_DATA_TYPE_REG_SZ), /* wPropertyDataType */ \ + WBVAL(42), /* wPropertyNameLength bPropertyName: "DeviceInterfaceGUID" */ \ + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, \ + 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, \ + 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, \ + WBVAL(80), /* wPropertyDataLength */ \ + '{', 0, \ + 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, \ + '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, \ + '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, \ + 'A', 0, 'A', 0, '3', 0, '6', 0, '-', \ + 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, \ + '}', 0, 0, 0, 0, 0 + +#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_LEN \ + (WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132) + +#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(bFirstInterfaceNumber) \ + WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */ \ + WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */ \ + bFirstInterfaceNumber, /* bFirstInterface*/ \ + 0, /* bReserved */ \ + WBVAL((WINUSB_FUNCTION_SUBSET_HEADER_SIZE + WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132)), /* wSubsetLength */\ + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ \ + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ \ + 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ \ + 0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ \ + WBVAL(132), /* wLength */ \ + WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ \ + WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */ \ + WBVAL(42), /* wPropertyNameLength bPropertyName: "DeviceInterfaceGUID" */ \ + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, \ + 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, \ + 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, \ + WBVAL(80), /* wPropertyDataLength */ \ + '{', 0, \ + 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, \ + '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, \ + '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, \ + 'A', 0, 'A', 0, '3', 0, '6', 0, '-', \ + 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, \ + '}', 0, 0, 0, 0, 0 + +#define USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN \ + (WINUSB_FUNCTION_SUBSET_HEADER_SIZE + WINUSB_FEATURE_COMPATIBLE_ID_SIZE + 132) + // clang-format on #endif /* USB_DEF_H */ diff --git a/components/drivers/usb/cherryusb/common/usb_otg.h b/components/drivers/usb/cherryusb/common/usb_otg.h new file mode 100644 index 00000000000..032d2e9f745 --- /dev/null +++ b/components/drivers/usb/cherryusb/common/usb_otg.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USB_OTG_H +#define USB_OTG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define USBOTG_MODE_HOST 0 +#define USBOTG_MODE_DEVICE 1 +#define USBOTG_MODE_OTG 2 + +/** + * @brief usb otg controller hardware or gpio id simulator init. + * + * @return On success will return 0, and others indicate fail. + */ +int usb_otg_init(uint8_t busid); +/** + * @brief usb otg controller hardware or gpio id simulator deinit. + * + * @return On success will return 0, and others indicate fail. + */ +int usb_otg_deinit(uint8_t busid); + +/* called by user */ +void USBOTG_IRQHandler(uint8_t busid); + +#ifdef __cplusplus +} +#endif + +#endif /* USB_OTG_H */ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/common/usb_util.h b/components/drivers/usb/cherryusb/common/usb_util.h index 96a14d374c2..521bf27f567 100644 --- a/components/drivers/usb/cherryusb/common/usb_util.h +++ b/components/drivers/usb/cherryusb/common/usb_util.h @@ -185,8 +185,8 @@ (field)[3] = (uint8_t)((value) >> 0); \ } while (0) -#define WBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF) -#define DBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF), ((x >> 16) & 0xFF), ((x >> 24) & 0xFF) +#define WBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF) +#define DBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF), (((x) >> 24) & 0xFF) #define PP_NARG(...) \ PP_NARG_(__VA_ARGS__, PP_RSEQ_N()) @@ -209,6 +209,23 @@ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +/* + * Divide positive or negative dividend by positive or negative divisor + * and round to closest integer. Result is undefined for negative + * divisors if the dividend variable type is unsigned and for negative + * dividends if the divisor variable type is unsigned. + */ +#define DIV_ROUND_CLOSEST(x, divisor) ( \ + { \ + typeof(x) __x = x; \ + typeof(divisor) __d = divisor; \ + (((typeof(x))-1) > 0 || \ + ((typeof(divisor))-1) > 0 || \ + (((__x) > 0) == ((__d) > 0))) ? \ + (((__x) + ((__d) / 2)) / (__d)) : \ + (((__x) - ((__d) / 2)) / (__d)); \ + }) + #define USB_MEM_ALIGNX __attribute__((aligned(CONFIG_USB_ALIGN_SIZE))) #define USB_ALIGN_UP(size, align) (((size) + (align)-1) & ~((align)-1)) diff --git a/components/drivers/usb/cherryusb/common/usb_version.h b/components/drivers/usb/cherryusb/common/usb_version.h index 2d70bb4c5a8..3e4c2aa395a 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 0x010502 -#define CHERRYUSB_VERSION_STR "v1.5.2" +#define CHERRYUSB_VERSION 0x010600 +#define CHERRYUSB_VERSION_STR "v1.6.0" #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 66ec4dc60ca..bdbcfd07f79 100644 --- a/components/drivers/usb/cherryusb/core/usbd_core.c +++ b/components/drivers/usb/cherryusb/core/usbd_core.c @@ -48,16 +48,10 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv { uint32_t ep0_data_buf_len; /** Zero length packet flag of control transfer */ bool zlp_flag; + /** Pointer to registered descriptors */ -#ifdef CONFIG_USBDEV_ADVANCE_DESC const struct usb_descriptor *descriptors; -#else - const uint8_t *descriptors; - struct usb_msosv1_descriptor *msosv1_desc; - struct usb_msosv2_descriptor *msosv2_desc; - struct usb_bos_descriptor *bos_desc; - struct usb_webusb_descriptor *webusb_url_desc; -#endif + /* Buffer used for storing standard, class and vendor request data */ USB_MEM_ALIGNX uint8_t req_data[USB_ALIGN_UP(CONFIG_USBDEV_REQUEST_BUFFER_LEN, CONFIG_USB_ALIGN_SIZE)]; @@ -69,9 +63,7 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv { bool remote_wakeup_support; bool remote_wakeup_enabled; bool is_suspend; -#ifdef CONFIG_USBDEV_ADVANCE_DESC uint8_t speed; -#endif #ifdef CONFIG_USBDEV_TEST_MODE bool test_req; #endif @@ -180,7 +172,6 @@ static bool usbd_reset_endpoint(uint8_t busid, const struct usb_endpoint_descrip * * @return true if the descriptor was found, false otherwise */ -#ifdef CONFIG_USBDEV_ADVANCE_DESC static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **data, uint32_t *len) { uint8_t type = 0U; @@ -326,93 +317,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da } return found; } -#else -static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **data, uint32_t *len) -{ - uint8_t type = 0U; - uint8_t index = 0U; - uint8_t *p = NULL; - uint32_t cur_index = 0U; - bool found = false; - - type = HI_BYTE(type_index); - index = LO_BYTE(type_index); - - if ((type == USB_DESCRIPTOR_TYPE_STRING) && (index == USB_OSDESC_STRING_DESC_INDEX)) { - if (!g_usbd_core[busid].msosv1_desc) { - return false; - } - - *data = (uint8_t *)g_usbd_core[busid].msosv1_desc->string; - //memcpy(*data, (uint8_t *)g_usbd_core[busid].msosv1_desc->string, g_usbd_core[busid].msosv1_desc->string[0]); - *len = g_usbd_core[busid].msosv1_desc->string[0]; - - return true; - } else if (type == USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE) { - if (!g_usbd_core[busid].bos_desc) { - return false; - } - - *data = (uint8_t *)g_usbd_core[busid].bos_desc->string; - //memcpy(*data, (uint8_t *)g_usbd_core[busid].bos_desc->string, g_usbd_core[busid].bos_desc->string_len); - *len = g_usbd_core[busid].bos_desc->string_len; - return true; - } - /* - * Invalid types of descriptors, - * see USB Spec. Revision 2.0, 9.4.3 Get Descriptor - */ - else if ((type == USB_DESCRIPTOR_TYPE_INTERFACE) || (type == USB_DESCRIPTOR_TYPE_ENDPOINT) || -#ifndef CONFIG_USB_HS - (type > USB_DESCRIPTOR_TYPE_ENDPOINT)) { -#else - (type > USB_DESCRIPTOR_TYPE_OTHER_SPEED)) { -#endif - return false; - } - - p = (uint8_t *)g_usbd_core[busid].descriptors; - - cur_index = 0U; - - while (p[DESC_bLength] != 0U) { - if (p[DESC_bDescriptorType] == type) { - if (cur_index == index) { - found = true; - break; - } - - cur_index++; - } - - /* skip to next descriptor */ - p += p[DESC_bLength]; - } - - if (found) { - if ((type == USB_DESCRIPTOR_TYPE_CONFIGURATION) || ((type == USB_DESCRIPTOR_TYPE_OTHER_SPEED))) { - /* configuration or other speed descriptor is an - * exception, length is at offset 2 and 3 - */ - *len = (p[CONF_DESC_wTotalLength]) | - (p[CONF_DESC_wTotalLength + 1] << 8); - - g_usbd_core[busid].self_powered = (p[7] & USB_CONFIG_POWERED_MASK) ? true : false; - g_usbd_core[busid].remote_wakeup_support = (p[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false; - } else { - /* normally length is at offset 0 */ - *len = p[DESC_bLength]; - } - *data = p; - //memcpy(*data, p, *len); - } else { - /* nothing found */ - USB_LOG_ERR("descriptor not found!\r\n", type, index); - } - - return found; -} -#endif /** * @brief set USB configuration @@ -436,11 +340,8 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t uint32_t desc_len = 0; uint32_t current_desc_len = 0; -#ifdef CONFIG_USBDEV_ADVANCE_DESC p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed); -#else - p = (uint8_t *)g_usbd_core[busid].descriptors; -#endif + /* configure endpoints for this configuration/altsetting */ while (p[DESC_bLength] != 0U) { switch (p[DESC_bDescriptorType]) { @@ -508,11 +409,8 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting uint32_t desc_len = 0; uint32_t current_desc_len = 0; -#ifdef CONFIG_USBDEV_ADVANCE_DESC p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed); -#else - p = (uint8_t *)g_usbd_core[busid].descriptors; -#endif + USB_LOG_DBG("iface %u alt_setting %u\r\n", iface, alt_setting); while (p[DESC_bLength] != 0U) { @@ -683,11 +581,7 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe uint32_t current_desc_len = 0; uint8_t cur_iface = 0xFF; -#ifdef CONFIG_USBDEV_ADVANCE_DESC p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed); -#else - p = (uint8_t *)g_usbd_core[busid].descriptors; -#endif /* Only when device is configured, then interface requests can be valid. */ if (!is_device_configured(busid)) { @@ -925,7 +819,7 @@ static int usbd_class_request_handler(uint8_t busid, struct usb_setup_packet *se static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { uint32_t desclen; -#ifdef CONFIG_USBDEV_ADVANCE_DESC + if (g_usbd_core[busid].descriptors->msosv1_descriptor) { if (setup->bRequest == g_usbd_core[busid].descriptors->msosv1_descriptor->vendor_code) { switch (setup->wIndex) { @@ -982,61 +876,7 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s } } } -#else - if (g_usbd_core[busid].msosv1_desc) { - if (setup->bRequest == g_usbd_core[busid].msosv1_desc->vendor_code) { - switch (setup->wIndex) { - case 0x04: - *data = (uint8_t *)g_usbd_core[busid].msosv1_desc->compat_id; - desclen = g_usbd_core[busid].msosv1_desc->compat_id[0] + - (g_usbd_core[busid].msosv1_desc->compat_id[1] << 8) + - (g_usbd_core[busid].msosv1_desc->compat_id[2] << 16) + - (g_usbd_core[busid].msosv1_desc->compat_id[3] << 24); - //memcpy(*data, g_usbd_core[busid].msosv1_desc->compat_id, desclen); - *len = desclen; - return 0; - case 0x05: - *data = (uint8_t *)g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue]; - desclen = g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][0] + - (g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][1] << 8) + - (g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][2] << 16) + - (g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue][3] << 24); - //memcpy(*data, g_usbd_core[busid].msosv1_desc->comp_id_property[setup->wValue], desclen); - *len = desclen; - return 0; - default: - return -1; - } - } - } else if (g_usbd_core[busid].msosv2_desc) { - if (setup->bRequest == g_usbd_core[busid].msosv2_desc->vendor_code) { - switch (setup->wIndex) { - case WINUSB_REQUEST_GET_DESCRIPTOR_SET: - *data = (uint8_t *)g_usbd_core[busid].msosv2_desc->compat_id; - //memcpy(*data, g_usbd_core[busid].msosv2_desc->compat_id, g_usbd_core[busid].msosv2_desc->compat_id_len); - *len = g_usbd_core[busid].msosv2_desc->compat_id_len; - return 0; - default: - return -1; - } - } - } - if (g_usbd_core[busid].webusb_url_desc) { - if (setup->bRequest == g_usbd_core[busid].webusb_url_desc->vendor_code) { - switch (setup->wIndex) { - case WEBUSB_REQUEST_GET_URL: - desclen = g_usbd_core[busid].webusb_url_desc->string_len; - *data = (uint8_t *)g_usbd_core[busid].webusb_url_desc->string; - //memcpy(*data, g_usbd_core[busid].webusb_url_desc->string, desclen); - *len = desclen; - return 0; - default: - return -1; - } - } - } -#endif for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) { struct usbd_interface *intf = g_usbd_core[busid].intf[i]; @@ -1145,18 +985,22 @@ void usbd_event_suspend_handler(uint8_t busid) void usbd_event_reset_handler(uint8_t busid) { + struct usb_endpoint_descriptor ep0; + usbd_set_address(busid, 0); g_usbd_core[busid].device_address = 0; g_usbd_core[busid].configuration = 0; g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP; -#ifdef CONFIG_USBDEV_ADVANCE_DESC g_usbd_core[busid].speed = USB_SPEED_UNKNOWN; -#endif - struct usb_endpoint_descriptor ep0; + + USB_ASSERT_MSG(g_usbd_core[busid].descriptors->device_descriptor_callback != NULL, + "device_descriptor_callback is NULL\r\n"); + + struct usb_device_descriptor *device_desc = (struct usb_device_descriptor *)g_usbd_core[busid].descriptors->device_descriptor_callback(g_usbd_core[busid].speed); + ep0.wMaxPacketSize = device_desc->bMaxPacketSize0; ep0.bLength = 7; ep0.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT; - ep0.wMaxPacketSize = USB_CTRL_EP_MPS; ep0.bmAttributes = USB_ENDPOINT_TYPE_CONTROL; ep0.bEndpointAddress = USB_CONTROL_IN_EP0; ep0.bInterval = 0; @@ -1369,7 +1213,6 @@ void usbd_event_ep_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt } } -#ifdef CONFIG_USBDEV_ADVANCE_DESC void usbd_desc_register(uint8_t busid, const struct usb_descriptor *desc) { memset(&g_usbd_core[busid], 0, sizeof(struct usbd_core_priv)); @@ -1382,42 +1225,6 @@ void usbd_desc_register(uint8_t busid, const struct usb_descriptor *desc) g_usbd_core[busid].rx_msg[0].ep = 0x00; g_usbd_core[busid].rx_msg[0].cb = usbd_event_ep0_out_complete_handler; } -#else -void usbd_desc_register(uint8_t busid, const uint8_t *desc) -{ - memset(&g_usbd_core[busid], 0, sizeof(struct usbd_core_priv)); - - g_usbd_core[busid].descriptors = desc; - g_usbd_core[busid].intf_offset = 0; - - g_usbd_core[busid].tx_msg[0].ep = 0x80; - g_usbd_core[busid].tx_msg[0].cb = usbd_event_ep0_in_complete_handler; - g_usbd_core[busid].rx_msg[0].ep = 0x00; - g_usbd_core[busid].rx_msg[0].cb = usbd_event_ep0_out_complete_handler; -} - -/* Register MS OS Descriptors version 1 */ -void usbd_msosv1_desc_register(uint8_t busid, struct usb_msosv1_descriptor *desc) -{ - g_usbd_core[busid].msosv1_desc = desc; -} - -/* Register MS OS Descriptors version 2 */ -void usbd_msosv2_desc_register(uint8_t busid, struct usb_msosv2_descriptor *desc) -{ - g_usbd_core[busid].msosv2_desc = desc; -} - -void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc) -{ - g_usbd_core[busid].bos_desc = desc; -} - -void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc) -{ - g_usbd_core[busid].webusb_url_desc = desc; -} -#endif void usbd_add_interface(uint8_t busid, struct usbd_interface *intf) { @@ -1536,11 +1343,7 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin int ret; struct usbd_bus *bus; - if (busid >= CONFIG_USBDEV_MAX_BUS) { - USB_LOG_ERR("bus overflow\r\n"); - while (1) { - } - } + USB_ASSERT_MSG(busid < CONFIG_USBDEV_MAX_BUS, "bus overflow\r\n"); bus = &g_usbdev_bus[busid]; bus->reg_base = reg_base; @@ -1569,23 +1372,18 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin int usbd_deinitialize(uint8_t busid) { - if (busid >= CONFIG_USBDEV_MAX_BUS) { - USB_LOG_ERR("bus overflow\r\n"); - while (1) { - } - } + 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); - g_usbd_core[busid].intf_offset = 0; #ifdef CONFIG_USBDEV_EP0_THREAD - if (g_usbd_core[busid].usbd_ep0_mq) { - usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq); - } if (g_usbd_core[busid].usbd_ep0_thread) { usb_osal_thread_delete(g_usbd_core[busid].usbd_ep0_thread); } + if (g_usbd_core[busid].usbd_ep0_mq) { + usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq); + } #endif return 0; diff --git a/components/drivers/usb/cherryusb/core/usbd_core.h b/components/drivers/usb/cherryusb/core/usbd_core.h index 585668267c1..314ccbec713 100644 --- a/components/drivers/usb/cherryusb/core/usbd_core.h +++ b/components/drivers/usb/cherryusb/core/usbd_core.h @@ -56,6 +56,7 @@ enum usbd_event_type { typedef int (*usbd_request_handler)(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len); typedef void (*usbd_endpoint_callback)(uint8_t busid, uint8_t ep, uint32_t nbytes); typedef void (*usbd_notify_handler)(uint8_t busid, uint8_t event, void *arg); +typedef void (*usbd_event_handler_t)(uint8_t busid, uint8_t event); struct usbd_endpoint { uint8_t ep_addr; @@ -95,15 +96,7 @@ extern struct usbd_bus g_usbdev_bus[]; #error USBD_IRQHandler is obsolete, please call USBD_IRQHandler(xxx) in your irq #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC void usbd_desc_register(uint8_t busid, const struct usb_descriptor *desc); -#else -void usbd_desc_register(uint8_t busid, const uint8_t *desc); -void usbd_msosv1_desc_register(uint8_t busid, struct usb_msosv1_descriptor *desc); -void usbd_msosv2_desc_register(uint8_t busid, struct usb_msosv2_descriptor *desc); -void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc); -void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc); -#endif void usbd_add_interface(uint8_t busid, struct usbd_interface *intf); void usbd_add_endpoint(uint8_t busid, struct usbd_endpoint *ep); @@ -115,7 +108,7 @@ bool usb_device_is_suspend(uint8_t busid); int usbd_send_remote_wakeup(uint8_t busid); uint8_t usbd_get_ep0_next_state(uint8_t busid); -int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)); +int usbd_initialize(uint8_t busid, uintptr_t reg_base, usbd_event_handler_t event_handler); int usbd_deinitialize(uint8_t busid); #ifdef __cplusplus diff --git a/components/drivers/usb/cherryusb/core/usbh_core.c b/components/drivers/usb/cherryusb/core/usbh_core.c index dc292e1375e..43bba3e888b 100644 --- a/components/drivers/usb/cherryusb/core/usbh_core.c +++ b/components/drivers/usb/cherryusb/core/usbh_core.c @@ -31,31 +31,38 @@ struct usbh_bus g_usbhost_bus[CONFIG_USBHOST_MAX_BUS]; #define USB_DEV_ADDR_MARK_OFFSET 5 #define USB_DEV_ADDR_MARK_MASK 0x1f +static void dummy_event_handler(uint8_t busid, uint8_t hub_index, uint8_t hub_port, uint8_t intf, uint8_t event) +{ + (void)busid; + (void)hub_index; + (void)hub_port; + (void)intf; + (void)event; +} + static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen) { - uint8_t startaddr = devgen->next; - uint8_t devaddr; + uint8_t lastaddr = devgen->last; + uint8_t devaddr = lastaddr; int index; int bitno; for (;;) { - devaddr = devgen->next; - if (devgen->next >= 0x7f) { - devgen->next = 2; - } else { - devgen->next++; + devaddr++; + if (devaddr > 0x7f) { + devaddr = 2; + } + if (devaddr == lastaddr) { + return -USB_ERR_NOMEM; } index = devaddr >> 5; bitno = devaddr & 0x1f; - if ((devgen->alloctab[index] & (1 << bitno)) == 0) { - devgen->alloctab[index] |= (1 << bitno); + if ((devgen->alloctab[index] & (1ul << bitno)) == 0) { + devgen->alloctab[index] |= (1ul << bitno); + devgen->last = devaddr; return (int)devaddr; } - - if (startaddr == devaddr) { - return -USB_ERR_NOMEM; - } } } @@ -69,15 +76,11 @@ static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr) bitno = devaddr & USB_DEV_ADDR_MARK_MASK; /* Free the address */ - if ((devgen->alloctab[index] |= (1 << bitno)) != 0) { - devgen->alloctab[index] &= ~(1 << bitno); + if ((devgen->alloctab[index] & (1ul << bitno)) != 0) { + devgen->alloctab[index] &= ~(1ul << bitno); } else { return -1; } - - if (devaddr < devgen->next) { - devgen->next = devaddr; - } } return 0; @@ -91,7 +94,7 @@ static int usbh_free_devaddr(struct usbh_hubport *hport) return 0; } -static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, +static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, uint8_t intf, uint16_t vid, uint16_t pid) { struct usbh_class_info *index = NULL; @@ -106,6 +109,9 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) { continue; } + if ((index->match_flags & USB_CLASS_MATCH_INTF_NUM) && !(index->bInterfaceNumber == intf)) { + continue; + } if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) { /* scan id table */ uint32_t i; @@ -275,60 +281,6 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config return 0; } -static void usbh_print_hubport_info(struct usbh_hubport *hport) -{ - USB_LOG_RAW("Device Descriptor:\r\n"); - USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength); - USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType); - USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB); - USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass); - USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass); - USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol); - USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0); - USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor); - USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct); - USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice); - USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer); - USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct); - USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber); - USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations); - - USB_LOG_RAW("Config Descriptor:\r\n"); - USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength); - USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType); - USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength); - USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces); - USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue); - USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration); - USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes); - USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower); - - for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) { - for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) { - USB_LOG_RAW("\tInterface Descriptor:\r\n"); - USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength); - USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType); - USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber); - USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting); - USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints); - USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass); - USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass); - USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol); - USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface); - - for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) { - USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n"); - USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength); - USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType); - USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress); - USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes); - USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize); - USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval); - } - } - } -} - static void usbh_print_setup(struct usb_setup_packet *setup) { (void)setup; @@ -466,7 +418,7 @@ int usbh_enumerate(struct usbh_hubport *hport) USB_LOG_INFO("The device has %d bNumConfigurations\r\n", ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumConfigurations); - config_index = 0; + config_index = usbh_get_hport_active_config_index(hport); USB_LOG_DBG("The device selects config %d\r\n", config_index); /* Read the first 9 bytes of the config descriptor */ @@ -599,23 +551,35 @@ int usbh_enumerate(struct usbh_hubport *hport) } #endif USB_LOG_INFO("Enumeration success, start loading class driver\r\n"); + hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, USB_INTERFACE_ANY, USBH_EVENT_DEVICE_CONFIGURED); /*search supported class driver*/ for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) { intf_desc = &hport->config.intf[i].altsetting[0].intf_desc; - struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol, hport->device_desc.idVendor, hport->device_desc.idProduct); + USB_ASSERT_MSG(intf_desc->bInterfaceNumber == i, "Interface number mismatch, do not support non-standard device\r\n"); + + struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass, + intf_desc->bInterfaceSubClass, + intf_desc->bInterfaceProtocol, + intf_desc->bInterfaceNumber, + hport->device_desc.idVendor, + hport->device_desc.idProduct); if (class_driver == NULL) { - USB_LOG_ERR("do not support Class:0x%02x,Subclass:0x%02x,Protocl:0x%02x\r\n", + USB_LOG_ERR("Do not support Class:0x%02x, Subclass:0x%02x, Protocl:0x%02x on interface %u\r\n", intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, - intf_desc->bInterfaceProtocol); - + intf_desc->bInterfaceProtocol, + i); + hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, i, USBH_EVENT_INTERFACE_UNSUPPORTED); continue; } hport->config.intf[i].class_driver = class_driver; - USB_LOG_INFO("Loading %s class driver\r\n", class_driver->driver_name); + USB_LOG_INFO("Loading %s class driver on interface %u\r\n", class_driver->driver_name, i); ret = CLASS_CONNECT(hport, i); + if (ret >= 0) { + hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, i, USBH_EVENT_INTERFACE_START); + } } errout: @@ -630,17 +594,20 @@ void usbh_hubport_release(struct usbh_hubport *hport) { if (hport->connected) { hport->connected = false; + usbh_kill_urb(&hport->ep0_urb); usbh_free_devaddr(hport); for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) { if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->disconnect) { CLASS_DISCONNECT(hport, i); } + hport->bus->event_handler(hport->bus->busid, hport->parent->index, hport->port, i, USBH_EVENT_INTERFACE_STOP); } hport->config.config_desc.bNumInterfaces = 0; - usbh_kill_urb(&hport->ep0_urb); if (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); } } @@ -652,25 +619,27 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_bas bus->hcd.reg_base = reg_base; /* devaddr 1 is for roothub */ - bus->devgen.next = 2; + bus->devgen.last = 0x7f; usb_slist_add_tail(&g_bus_head, &bus->list); } -int usbh_initialize(uint8_t busid, uintptr_t reg_base) +int usbh_initialize(uint8_t busid, uintptr_t reg_base, usbh_event_handler_t event_handler) { struct usbh_bus *bus; - if (busid >= CONFIG_USBHOST_MAX_BUS) { - USB_LOG_ERR("bus overflow\r\n"); - while (1) { - } - } + USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n"); bus = &g_usbhost_bus[busid]; usbh_bus_init(bus, busid, reg_base); + if (event_handler) { + bus->event_handler = event_handler; + } else { + bus->event_handler = dummy_event_handler; + } + #ifdef __ARMCC_VERSION /* ARM C Compiler */ extern const int usbh_class_info$$Base; extern const int usbh_class_info$$Limit; @@ -693,14 +662,12 @@ int usbh_deinitialize(uint8_t busid) { struct usbh_bus *bus; - if (busid >= CONFIG_USBHOST_MAX_BUS) { - USB_LOG_ERR("bus overflow\r\n"); - while (1) { - } - } + USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n"); 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); @@ -711,6 +678,7 @@ int usbh_deinitialize(uint8_t busid) int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer) { struct usbh_urb *urb; + volatile uint8_t retry = 3; int ret; if (!hport || !setup) { @@ -723,12 +691,21 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s usbh_print_setup(setup); +resubmit: usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL); ret = usbh_submit_urb(urb); if (ret == 0) { ret = urb->actual_length; } + if (ret < 0 && (ret != -USB_ERR_TIMEOUT)) { + retry--; + if (retry > 0) { + USB_LOG_WRN("Control transfer failed, errorcode %d, retrying...\r\n", ret); + goto resubmit; + } + } + usb_osal_mutex_give(hport->mutex); return ret; } @@ -816,73 +793,6 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn return NULL; } -static void usbh_list_all_interface_driver(struct usbh_hub *hub) -{ - struct usbh_hubport *hport; - struct usbh_hub *hub_next; - const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" }; - - for (uint8_t port = 0; port < hub->nports; port++) { - hport = &hub->child[port]; - if (hport->connected) { - for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { - if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) { - for (uint8_t j = 0; j < hub->index; j++) { - USB_LOG_RAW("\t"); - } - - USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n", - hport->port, - hport->dev_addr, - itf, - hport->config.intf[itf].class_driver->driver_name, - speed_table[hport->speed]); - - if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) { - hub_next = hport->config.intf[itf].priv; - - if (hub_next && hub_next->connected) { - usbh_list_all_interface_driver(hub_next); - } - } - } - } - } - } -} - -static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *hub) -{ - struct usbh_hubport *hport; - struct usbh_hub *hub_next; - - for (uint8_t port = 0; port < hub->nports; port++) { - hport = &hub->child[port]; - if (hport->connected) { - USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n", - bus->busid, - hub->index, - hport->port, - hport->dev_addr, - hport->device_desc.idVendor, - hport->device_desc.idProduct); - usbh_print_hubport_info(hport); - - for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { - if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) { - if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) { - hub_next = hport->config.intf[itf].priv; - - if (hub_next && hub_next->connected) { - usbh_list_all_interface_desc(bus, hub_next); - } - } - } - } - } - } -} - static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port) { struct usbh_hubport *hport; @@ -960,64 +870,348 @@ struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t return hport; } +static void usbh_print_hubport_info(struct usbh_hubport *hport) +{ + USB_LOG_RAW("Device Descriptor:\r\n"); + USB_LOG_RAW(" bLength: 0x%02x \r\n", hport->device_desc.bLength); + USB_LOG_RAW(" bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType); + USB_LOG_RAW(" bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB); + USB_LOG_RAW(" bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass); + USB_LOG_RAW(" bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass); + USB_LOG_RAW(" bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol); + USB_LOG_RAW(" bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0); + USB_LOG_RAW(" idVendor: 0x%04x \r\n", hport->device_desc.idVendor); + USB_LOG_RAW(" idProduct: 0x%04x \r\n", hport->device_desc.idProduct); + USB_LOG_RAW(" bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice); + USB_LOG_RAW(" iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer); + USB_LOG_RAW(" iProduct: 0x%02x \r\n", hport->device_desc.iProduct); + USB_LOG_RAW(" iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber); + USB_LOG_RAW(" bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations); + + USB_LOG_RAW(" Config Descriptor:\r\n"); + USB_LOG_RAW(" bLength: 0x%02x \r\n", hport->config.config_desc.bLength); + USB_LOG_RAW(" bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType); + USB_LOG_RAW(" wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength); + USB_LOG_RAW(" bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces); + USB_LOG_RAW(" bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue); + USB_LOG_RAW(" iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration); + USB_LOG_RAW(" bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes); + USB_LOG_RAW(" bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower); + + for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) { + for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) { + USB_LOG_RAW(" Interface Descriptor:\r\n"); + USB_LOG_RAW(" bLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength); + USB_LOG_RAW(" bDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType); + USB_LOG_RAW(" bInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber); + USB_LOG_RAW(" bAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting); + USB_LOG_RAW(" bNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints); + USB_LOG_RAW(" bInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass); + USB_LOG_RAW(" bInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass); + USB_LOG_RAW(" bInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol); + USB_LOG_RAW(" iInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface); + + for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) { + USB_LOG_RAW(" Endpoint Descriptor:\r\n"); + USB_LOG_RAW(" bLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength); + USB_LOG_RAW(" bDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType); + USB_LOG_RAW(" bEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress); + USB_LOG_RAW(" bmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes); + USB_LOG_RAW(" wMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize); + USB_LOG_RAW(" bInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval); + } + } + } +} + +static void usbh_list_device(struct usbh_hub *hub, bool astree, bool verbose, int dev_addr, int vid, int pid) +{ + static const char *speed_table[] = { + "UNKNOWN", + "low-speed", + "full-speed", + "high-speed", + "wireless", + "super-speed", + "super-speed-plus", + }; + + static const char *root_speed_table[] = { + "UNKNOWN", + "1.1", + "1.1", + "2.0", + "2.5", + "3.0", + "3.0", + }; + + static const uint16_t speed_baud[] = { + 0, + 12, + 12, + 480, + 480, + 5000, + 10000, + }; + + struct usbh_bus *bus; + struct usbh_hubport *hport; + struct usbh_hub *hub_next; + + uint8_t imbuf[64]; + uint8_t ipbuf[64]; + + const char *pimstr; + const char *pipstr; + + bool imvalid = false; + bool ipvalid = false; + + int ret; + + bus = hub->bus; + + (void)speed_table; + + if (hub->is_roothub) { + if (astree) { + USB_LOG_RAW("/: Bus %02u.Port 1: Dev %u, Class=root_hub, Driver=hcd, %uM\r\n", + bus->busid, hub->hub_addr, speed_baud[hub->speed]); + + } else { + if ((dev_addr < 0) || (hub->hub_addr == dev_addr)) { + if (((vid < 0) || (vid == 0xffff)) && ((pid < 0) || (pid == 0xffff))) { + USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s root hub\r\n", + bus->busid, hub->hub_addr, 0xffff, 0xffff, + "Cherry-Embedded", root_speed_table[hub->speed]); + } + } + } + } + + for (uint8_t port = 0; port < hub->nports; port++) { + hport = &hub->child[port]; + if (hport->connected) { + ret = 0; + if (hport->device_desc.iManufacturer) { + memset(imbuf, 0, sizeof(imbuf)); + ret = usbh_get_string_desc(hport, hport->device_desc.iManufacturer, imbuf, sizeof(imbuf)); + if (ret == 0) { + imvalid = true; + } + } + + if (hport->device_desc.iProduct) { + memset(ipbuf, 0, sizeof(ipbuf)); + ret = usbh_get_string_desc(hport, hport->device_desc.iProduct, ipbuf, sizeof(ipbuf)); + if (ret == 0) { + ipvalid = true; + } + } + + if (imvalid) { + pimstr = (const char *)imbuf; + } else { + pimstr = "Not specified Manufacturer"; + } + + if (ipvalid) { + pipstr = (const char *)ipbuf; + } else { + pipstr = "Not specified Product"; + } + + if (!astree) { + if ((dev_addr < 0) || (hport->dev_addr == dev_addr)) { + if (((vid < 0) || (vid == hport->device_desc.idVendor)) && ((pid < 0) || (pid == hport->device_desc.idProduct))) { + USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s\r\n", + bus->busid, hport->dev_addr, hport->device_desc.idVendor, hport->device_desc.idProduct, + pimstr, pipstr); + + if (verbose) { + usbh_print_hubport_info(hport); + } + } + } + } + + for (uint8_t intf = 0; intf < hport->config.config_desc.bNumInterfaces; intf++) { + if (hport->config.intf[intf].class_driver && hport->config.intf[intf].class_driver->driver_name) { + if (astree) { + for (uint8_t j = 0; j < hub->index; j++) { + USB_LOG_RAW(" "); + } + + USB_LOG_RAW("|__ Port %u: Dev %u, If %u, ClassDriver=%s, %uM\r\n", + hport->port, hport->dev_addr, intf, hport->config.intf[intf].class_driver->driver_name, speed_baud[hport->speed]); + } + + if (!strcmp(hport->config.intf[intf].class_driver->driver_name, "hub")) { + hub_next = hport->config.intf[intf].priv; + + if (hub_next && hub_next->connected) { + usbh_list_device(hub_next, astree, verbose, dev_addr, vid, pid); + } + } + } else if (astree) { + for (uint8_t j = 0; j < hub->index; j++) { + USB_LOG_RAW(" "); + } + + USB_LOG_RAW("|__ Port %u: Dev %u, If 0 ClassDriver=none, %uM\r\n", + hport->port, hport->dev_addr, speed_baud[hport->speed]); + } + } + } + } +} + +void lsusb_help(void) +{ + USB_LOG_RAW("List USB Devices\r\n" + "Usage: lsusb [options]...\r\n" + "\r\n" + "-v, --verbose\r\n" + " - increase verbosity (show descriptors)\r\n" + "-s [[bus]:][dev_addr]\r\n" + " - show only devices with specified device and/or\r\n" + " bus numbers (in decimal)\r\n" + "-d vendor:[product]\r\n" + " - show only devices with the specified vendor and\r\n" + " product ID numbers (in hexadecimal)\r\n" + "-t, --tree\r\n" + " - dump the physical USB device hierarchy as a tree\r\n" + "-V, --version\r\n" + " - show version of the cherryusb\r\n" + "-h, --help\r\n" + " - show usage and help information\r\n"); +} + int lsusb(int argc, char **argv) { usb_slist_t *bus_list; - struct usbh_hub *hub; struct usbh_bus *bus; - size_t flags; + + int busid = -1; + int dev_addr = -1; + int vid = -1; + int pid = -1; + bool astree = false; + bool verbose = false; if (argc < 2) { - USB_LOG_RAW("Usage: lsusb [options]...\r\n"); - USB_LOG_RAW("List USB devices\r\n"); - USB_LOG_RAW(" -v, --verbose\r\n"); - USB_LOG_RAW(" Increase verbosity (show descriptors)\r\n"); - // USB_LOG_RAW(" -s [[bus]:[devnum]]\r\n"); - // USB_LOG_RAW(" Show only devices with specified device and/or bus numbers (in decimal)\r\n"); - // USB_LOG_RAW(" -d vendor:[product]\r\n"); - // USB_LOG_RAW(" Show only devices with the specified vendor and product ID numbers (in hexadecimal)\r\n"); - USB_LOG_RAW(" -t, --tree\r\n"); - USB_LOG_RAW(" Dump the physical USB device hierachy as a tree\r\n"); - USB_LOG_RAW(" -V, --version\r\n"); - USB_LOG_RAW(" Show version of program\r\n"); - USB_LOG_RAW(" -h, --help\r\n"); - USB_LOG_RAW(" Show usage and help\r\n"); - return 0; - } - if (argc > 3) { + lsusb_help(); return 0; } - flags = usb_osal_enter_critical_section(); + while (argc > 1) { + argc--; + argv++; - if (strcmp(argv[1], "-V") == 0) { - USB_LOG_RAW("CherryUSB Version %s\r\n", CHERRYUSB_VERSION_STR); - } + if (!strcmp(*argv, "-V") || !strcmp(*argv, "--version")) { + USB_LOG_RAW("CherryUSB version %s\r\n", CHERRYUSB_VERSION_STR); + return 0; + } else if (!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) { + lsusb_help(); + return 0; + } else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) { + verbose = true; + } else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--tree")) { + astree = true; + } else if (!strcmp(*argv, "-s")) { + if (argc > 1) { + argc--; + argv++; + + if (*argv[0] == '-') { + continue; + } - if (strcmp(argv[1], "-t") == 0) { - usb_slist_for_each(bus_list, &g_bus_head) - { - bus = usb_slist_entry(bus_list, struct usbh_bus, list); - hub = &bus->hcd.roothub; + char *endptr; + const char *colon = strchr(*argv, ':'); + (void)endptr; - USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n", - bus->busid, - hub->index, - hub->nports); - usbh_list_all_interface_driver(hub); + if (colon != NULL) { + const char *str; + if (colon > *argv) { + busid = strtol(*argv, &endptr, 10); + } + str = colon + 1; + if (*str != '\0') { + dev_addr = strtol(str, &endptr, 10); + if (dev_addr <= 0 || dev_addr >= 128) { + dev_addr = -1; + } + } + } else { + dev_addr = strtol(*argv, &endptr, 10); + if (dev_addr <= 0 || dev_addr >= 128) { + dev_addr = -1; + } + } + } + } else if (!strcmp(*argv, "-d")) { + if (argc > 1) { + argc--; + argv++; + + if (*argv[0] == '-') { + continue; + } + + char *endptr; + const char *colon = strchr(*argv, ':'); + (void)endptr; + + if (colon == NULL) { + continue; + } + const char *str; + + vid = strtol(*argv, &endptr, 16); + if (vid < 0 || vid > 0xffff) { + vid = -1; + continue; + } + str = colon + 1; + if (*str != '\0') { + pid = strtol(str, &endptr, 16); + if (pid < 0 || pid > 0xffff) { + pid = -1; + } + } + } } } - if (strcmp(argv[1], "-v") == 0) { - usb_slist_for_each(bus_list, &g_bus_head) - { - bus = usb_slist_entry(bus_list, struct usbh_bus, list); - hub = &bus->hcd.roothub; + if (astree) { + busid = -1; + dev_addr = -1; + vid = -1; + pid = -1; + verbose = false; + } - usbh_list_all_interface_desc(bus, hub); + usb_slist_for_each(bus_list, &g_bus_head) + { + bus = usb_slist_entry(bus_list, struct usbh_bus, list); + if (busid >= 0) { + if (bus->busid != busid) { + continue; + } } + + usbh_list_device(&bus->hcd.roothub, astree, verbose, dev_addr, vid, pid); } - usb_osal_leave_critical_section(flags); return 0; } + +__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 060c402ef61..903ce14fdb2 100644 --- a/components/drivers/usb/cherryusb/core/usbh_core.h +++ b/components/drivers/usb/cherryusb/core/usbh_core.h @@ -28,11 +28,41 @@ extern "C" { #endif +enum usbh_event_type { + /* USB HCD IRQ */ + USBH_EVENT_ERROR, + USBH_EVENT_SOF, + + /* USB DEVICE STATUS */ + USBH_EVENT_DEVICE_RESET, + USBH_EVENT_DEVICE_CONNECTED, + USBH_EVENT_DEVICE_DISCONNECTED, + USBH_EVENT_DEVICE_CONFIGURED, + USBH_EVENT_DEVICE_WAKEUP, + USBH_EVENT_DEVICE_SUSPEND, + USBH_EVENT_DEVICE_RESUME, + + /* USB DEVICE INTERFACE STATUS */ + USBH_EVENT_INTERFACE_UNSUPPORTED, + USBH_EVENT_INTERFACE_START, + USBH_EVENT_INTERFACE_STOP, + + /* USB FRAMEWORK STATUS */ + USBH_EVENT_INIT, + USBH_EVENT_DEINIT, + USBH_EVENT_UNKNOWN, +}; + +#define USB_HUB_PORT_ANY 0 +#define USB_HUB_INDEX_ANY 0 +#define USB_INTERFACE_ANY 0xff + #define USB_CLASS_MATCH_VENDOR 0x0001 #define USB_CLASS_MATCH_PRODUCT 0x0002 #define USB_CLASS_MATCH_INTF_CLASS 0x0004 #define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008 #define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010 +#define USB_CLASS_MATCH_INTF_NUM 0x0020 #define USB_CLASS_MATCH_VID_PID (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT) #define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i)) @@ -60,11 +90,14 @@ extern "C" { USB_GET_MULT(ep_desc->wMaxPacketSize)); \ } while (0) +typedef void (*usbh_event_handler_t)(uint8_t busid, uint8_t hub_index, uint8_t hub_port, uint8_t intf, uint8_t event); + struct usbh_class_info { uint8_t match_flags; /* Used for product specific matches; range is inclusive */ uint8_t bInterfaceClass; /* Base device class code */ uint8_t bInterfaceSubClass; /* Sub-class, depends on base class. Eg. */ uint8_t bInterfaceProtocol; /* Protocol, depends on base class. Eg. */ + uint8_t bInterfaceNumber; /* Interface number */ const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */ const struct usbh_class_driver *class_driver; }; @@ -131,7 +164,7 @@ struct usbh_hub { uint8_t powerdelay; uint8_t tt_think; bool ismtt; - struct usb_hub_descriptor hub_desc; /* USB 2.0 only */ + struct usb_hub_descriptor hub_desc; /* USB 2.0 only */ struct usb_hub_ss_descriptor hub_ss_desc; /* USB 3.0 only */ struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS]; struct usbh_hubport *parent; @@ -150,7 +183,7 @@ struct usbh_devaddr_map { * alloctab[3]:addr from 96~127 * */ - uint8_t next; /* Next device address */ + uint8_t last; /* Last device address */ uint32_t alloctab[4]; /* Bit allocation table */ }; @@ -168,6 +201,8 @@ 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; + usbh_event_handler_t event_handler; }; static inline void usbh_control_urb_fill(struct usbh_urb *urb, @@ -274,10 +309,11 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out */ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting); -int usbh_initialize(uint8_t busid, uintptr_t reg_base); +int usbh_initialize(uint8_t busid, uintptr_t reg_base, usbh_event_handler_t event_handler); int usbh_deinitialize(uint8_t busid); void *usbh_find_class_instance(const char *devname); struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port); +uint8_t usbh_get_hport_active_config_index(struct usbh_hubport *hport); int lsusb(int argc, char **argv); diff --git a/components/drivers/usb/cherryusb/core/usbotg_core.c b/components/drivers/usb/cherryusb/core/usbotg_core.c new file mode 100644 index 00000000000..99b0cc8a6bb --- /dev/null +++ b/components/drivers/usb/cherryusb/core/usbotg_core.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbotg_core.h" + +#ifdef CONFIG_USB_OTG_ENABLE +#undef USB_DBG_TAG +#define USB_DBG_TAG "usbotg_core" +#include "usb_log.h" + +#define CONFIG_USB_OTG_MAX_BUS CONFIG_USBHOST_MAX_BUS + +struct usbotg_core_priv { + uint8_t busid; + uint32_t reg_base; + bool usbh_initialized; + bool usbd_initialized; + usbd_event_handler_t device_event_callback; + usbh_event_handler_t host_event_callback; + uint8_t request_mode; + usb_osal_sem_t change_sem; + usb_osal_thread_t change_thread; +} g_usbotg_core[CONFIG_USB_OTG_MAX_BUS]; + +static void usbotg_host_initialize(uint8_t busid) +{ + if (g_usbotg_core[busid].usbh_initialized) { + return; + } + + if (g_usbotg_core[busid].usbd_initialized) { + usbd_deinitialize(busid); + g_usbotg_core[busid].usbd_initialized = false; + } + + 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); +} + +static void usbotg_device_initialize(uint8_t busid) +{ + if (g_usbotg_core[busid].usbd_initialized) { + return; + } + + if (g_usbotg_core[busid].usbh_initialized) { + usbh_deinitialize(busid); + g_usbotg_core[busid].usbh_initialized = false; + } + + USB_LOG_INFO("Switch to DEVICE mode\r\n"); + + g_usbotg_core[busid].usbd_initialized = true; + usbd_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base, g_usbotg_core[busid].device_event_callback); +} + +static void usbotg_rolechange_thread(void *argument) +{ + uint8_t busid = (uint8_t)(uintptr_t)argument; + + usb_otg_init(busid); + + while (1) { + if (usb_osal_sem_take(g_usbotg_core[busid].change_sem, USB_OSAL_WAITING_FOREVER) == 0) { + if (g_usbotg_core[busid].request_mode == USBOTG_MODE_HOST) { + usbotg_host_initialize(busid); + } else if (g_usbotg_core[busid].request_mode == USBOTG_MODE_DEVICE) { + usbotg_device_initialize(busid); + } + } + } +} + +int usbotg_initialize(uint8_t busid, uint32_t reg_base, usbd_event_handler_t device_event_callback, usbh_event_handler_t host_event_callback, uint8_t default_role) +{ + char thread_name[32] = { 0 }; + + USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n"); + + g_usbotg_core[busid].busid = busid; + g_usbotg_core[busid].reg_base = reg_base; + g_usbotg_core[busid].device_event_callback = device_event_callback; + g_usbotg_core[busid].host_event_callback = host_event_callback; + + g_usbotg_core[busid].change_sem = usb_osal_sem_create(0); + if (g_usbotg_core[busid].change_sem == NULL) { + USB_LOG_ERR("Failed to create change_sem\r\n"); + while (1) { + } + } + + snprintf(thread_name, 32, "usbotg%u", busid); + g_usbotg_core[busid].change_thread = usb_osal_thread_create(thread_name, 2048, 10, usbotg_rolechange_thread, (void *)(uintptr_t)busid); + if (g_usbotg_core[busid].change_thread == NULL) { + USB_LOG_ERR("Failed to create usbotg thread\r\n"); + while (1) { + } + } + + usbotg_trigger_role_change(busid, default_role); + return 0; +} + +int usbotg_deinitialize(uint8_t busid) +{ + USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n"); + + if (g_usbotg_core[busid].usbd_initialized) { + usbd_deinitialize(busid); + g_usbotg_core[busid].usbd_initialized = false; + } + + if (g_usbotg_core[busid].usbh_initialized) { + usbh_deinitialize(busid); + g_usbotg_core[busid].usbh_initialized = false; + } + + if (g_usbotg_core[busid].change_thread) { + usb_osal_thread_delete(g_usbotg_core[busid].change_thread); + } + + if (g_usbotg_core[busid].change_sem) { + usb_otg_deinit(busid); + usb_osal_sem_delete(g_usbotg_core[busid].change_sem); + } + + return 0; +} + +void usbotg_trigger_role_change(uint8_t busid, uint8_t mode) +{ + USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n"); + + g_usbotg_core[busid].request_mode = mode; + + if (g_usbotg_core[busid].change_sem) { + usb_osal_sem_give(g_usbotg_core[busid].change_sem); + } +} + +void USBOTG_IRQHandler(uint8_t busid) +{ + USB_ASSERT_MSG(busid < CONFIG_USB_OTG_MAX_BUS, "bus overflow\r\n"); + + if (g_usbotg_core[busid].usbh_initialized) { + USBH_IRQHandler(busid); + } else if (g_usbotg_core[busid].usbd_initialized) { + USBD_IRQHandler(busid); + } +} +#endif /* CONFIG_USB_OTG_ENABLE */ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/core/usbotg_core.h b/components/drivers/usb/cherryusb/core/usbotg_core.h new file mode 100644 index 00000000000..7eadb878ca3 --- /dev/null +++ b/components/drivers/usb/cherryusb/core/usbotg_core.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef USBOTG_CORE_H +#define USBOTG_CORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "usbd_core.h" +#include "usbh_core.h" +#include "usb_otg.h" + +int usbotg_initialize(uint8_t busid, uint32_t reg_base, usbd_event_handler_t device_event_callback, usbh_event_handler_t host_event_callback, uint8_t default_role); +int usbotg_deinitialize(uint8_t busid); + +/* called by user */ +void usbotg_trigger_role_change(uint8_t busid, uint8_t mode); + +#ifdef __cplusplus +} +#endif + +#endif /* USBOTG_CORE_H */ \ No newline at end of file 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 24f6d7acb5d..9f77e73d04e 100644 --- a/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c +++ b/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c @@ -108,7 +108,6 @@ struct usb_msosv1_descriptor msosv1_desc = { .comp_id_property = WINUSB_IFx_WCIDProperties, }; -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -171,80 +170,6 @@ const struct usb_descriptor adb_descriptor = { .string_descriptor_callback = string_descriptor_callback, .msosv1_descriptor = &msosv1_desc }; -#else -/*!< global descriptor */ -static const uint8_t adb_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'A', 0x00, /* wcChar6 */ - 'D', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x1C, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'A', 0x00, /* wcChar6 */ - 'D', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - '2', 0x00, /* wcChar9 */ - '0', 0x00, /* wcChar10 */ - '2', 0x00, /* wcChar11 */ - '4', 0x00, /* wcChar12 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static void usbd_event_handler(uint8_t busid, uint8_t event) { @@ -288,20 +213,15 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base) /* shell_init() must be called in-task */ if (0 != shell_init(false)) { /* shell failed to be initialized */ - printf("Failed to initialize shell\r\n"); + USB_LOG_RAW("Failed to initialize shell\r\n"); for (;;) { ; } } #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC + usbd_desc_register(busid, &adb_descriptor); -#else - usbd_desc_register(busid, adb_descriptor); -#endif -#ifndef CONFIG_USBDEV_ADVANCE_DESC - usbd_msosv1_desc_register(busid, &msosv1_desc); -#endif + usbd_add_interface(busid, usbd_adb_init_intf(busid, &intf0, WINUSB_IN_EP, WINUSB_OUT_EP)); usbd_initialize(busid, reg_base, usbd_event_handler); -} +} \ No newline at end of file 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 94ca950c967..aad917abbfb 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 @@ -21,14 +21,15 @@ #define AUDIO_IN_FU_ID 0x02 -/* AUDIO Class Config */ -#define AUDIO_FREQ 16000U +#define AUDIO_MIC_FREQ 16000U +#define AUDIO_MIC_FRAME_SIZE_BYTE 2u +#define AUDIO_MIC_RESOLUTION_BIT 16u -#define IN_CHANNEL_NUM 1 +#define IN_CHANNEL_NUM 2 #if IN_CHANNEL_NUM == 1 #define INPUT_CTRL 0x03, 0x03 -#define INPUT_CH_ENABLE 0x0000 +#define INPUT_CH_ENABLE 0x0001 #elif IN_CHANNEL_NUM == 2 #define INPUT_CTRL 0x03, 0x03, 0x03 #define INPUT_CH_ENABLE 0x0003 @@ -54,32 +55,31 @@ /* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 1) */ /* 16bit(2 Bytes) 单声道(Mono:1) */ -#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * 2 * IN_CHANNEL_NUM) / 1000)) +#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_MIC_FREQ * 2 * IN_CHANNEL_NUM) / 1000)) -#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \ - AUDIO_AC_DESCRIPTOR_INIT_LEN(1) + \ - AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \ - AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_AS_DESCRIPTOR_INIT_LEN(1)) +#define USB_CONFIG_SIZE (unsigned long)(9 + \ + AUDIO_AC_DESCRIPTOR_LEN(1) + \ + AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \ + AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_AS_DESCRIPTOR_LEN(1)) #define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(1) + \ AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \ AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01), AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE), AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL), AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID), - AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)) + AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)) }; static const uint8_t device_quality_descriptor[] = { @@ -134,89 +134,6 @@ const struct usb_descriptor audio_v1_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t audio_v1_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01), - AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID), - AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'A', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '0' + IN_CHANNEL_NUM, 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif volatile bool tx_flag = 0; volatile bool ep_tx_busy_flag = false; @@ -301,13 +218,12 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_IN_EP }, }; +// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too. + void audio_v1_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &audio_v1_descriptor); -#else - usbd_desc_register(busid, audio_v1_descriptor); -#endif + usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 1)); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 1)); usbd_add_endpoint(busid, &audio_in_ep); 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 c764ee93237..872a6cde706 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 @@ -21,13 +21,69 @@ #define FEEDBACK_ENDP_PACKET_SIZE 0x03 #endif -#define AUDIO_IN_EP 0x81 -#define AUDIO_OUT_EP 0x02 +#define AUDIO_IN_EP 0x81 +#define AUDIO_OUT_EP 0x02 #define AUDIO_OUT_FEEDBACK_EP 0x83 #define AUDIO_IN_FU_ID 0x02 #define AUDIO_OUT_FU_ID 0x05 +#define IN_CHANNEL_NUM 2 + +#if IN_CHANNEL_NUM == 1 +#define INPUT_CTRL 0x03, 0x03 +#define INPUT_CH_ENABLE 0x0001 +#elif IN_CHANNEL_NUM == 2 +#define INPUT_CTRL 0x03, 0x03, 0x03 +#define INPUT_CH_ENABLE 0x0003 +#elif IN_CHANNEL_NUM == 3 +#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03 +#define INPUT_CH_ENABLE 0x0007 +#elif IN_CHANNEL_NUM == 4 +#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03 +#define INPUT_CH_ENABLE 0x000f +#elif IN_CHANNEL_NUM == 5 +#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define INPUT_CH_ENABLE 0x001f +#elif IN_CHANNEL_NUM == 6 +#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define INPUT_CH_ENABLE 0x003F +#elif IN_CHANNEL_NUM == 7 +#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define INPUT_CH_ENABLE 0x007f +#elif IN_CHANNEL_NUM == 8 +#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define INPUT_CH_ENABLE 0x00ff +#endif + +#define OUT_CHANNEL_NUM 2 + +#if OUT_CHANNEL_NUM == 1 +#define OUTPUT_CTRL 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x0001 +#elif OUT_CHANNEL_NUM == 2 +#define OUTPUT_CTRL 0x03, 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x0003 +#elif OUT_CHANNEL_NUM == 3 +#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x0007 +#elif OUT_CHANNEL_NUM == 4 +#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x000f +#elif OUT_CHANNEL_NUM == 5 +#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x001f +#elif OUT_CHANNEL_NUM == 6 +#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x003F +#elif OUT_CHANNEL_NUM == 7 +#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x007f +#elif OUT_CHANNEL_NUM == 8 +#define OUTPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +#define OUTPUT_CH_ENABLE 0x00ff +#endif + /* AUDIO Class Config */ #define AUDIO_SPEAKER_FREQ 16000U #define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u @@ -44,60 +100,59 @@ #define AUDIO_IN_PACKET ((uint32_t)((AUDIO_MIC_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * 2) / 1000)) #if USING_FEEDBACK == 0 -#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \ - AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \ - AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ - AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ - AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \ - AUDIO_AS_DESCRIPTOR_INIT_LEN(1)) +#define USB_CONFIG_SIZE (unsigned long)(9 + \ + AUDIO_AC_DESCRIPTOR_LEN(2) + \ + AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \ + AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \ + AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_AS_DESCRIPTOR_LEN(1) + \ + AUDIO_AS_DESCRIPTOR_LEN(1)) #else -#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \ - AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \ - AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ - AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ - AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \ - AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(1)) +#define USB_CONFIG_SIZE (unsigned long)(9 + \ + AUDIO_AC_DESCRIPTOR_LEN(2) + \ + AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \ + AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \ + AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_AS_DESCRIPTOR_LEN(1) + \ + AUDIO_AS_FEEDBACK_DESCRIPTOR_LEN(1)) #endif -#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) + \ - AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ - AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ +#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) + \ + AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \ + AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM, 1) + \ AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02), - AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02), - AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05), + AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE), + AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL), + AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID), + AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE), + AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x04, 0x01, OUTPUT_CTRL), + AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID), + AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, + EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)), #if USING_FEEDBACK == 0 - AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, + AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), #else - AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET, - EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), + AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x02, 0x04, OUT_CHANNEL_NUM, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET, + EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), #endif - AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, - EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)) }; static const uint8_t device_quality_descriptor[] = { @@ -152,104 +207,6 @@ const struct usb_descriptor audio_v1_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t audio_v1_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02), - AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02), - AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05), -#if USING_FEEDBACK == 0 - AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, - EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), -#else - AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET, - EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), -#endif - AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, - EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'A', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ -#if USING_FEEDBACK == 0 - '1', 0x00, /* wcChar9 */ -#else - '2', 0x00, /* wcChar9 */ -#endif -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET]; @@ -297,11 +254,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf) AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value); /* uac1 can only use 10.14 */ usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE); #endif - printf("OPEN1\r\n"); + USB_LOG_INFO("OPEN1\r\n"); } else { tx_flag = 1; ep_tx_busy_flag = false; - printf("OPEN2\r\n"); + USB_LOG_INFO("OPEN2\r\n"); } } @@ -309,11 +266,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf) { if (intf == 1) { rx_flag = 0; - printf("CLOSE1\r\n"); + USB_LOG_INFO("CLOSE1\r\n"); } else { tx_flag = 0; ep_tx_busy_flag = false; - printf("CLOSE2\r\n"); + USB_LOG_INFO("CLOSE2\r\n"); } } @@ -393,13 +350,12 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_OUT_EP }, }; +// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too. + void audio_v1_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &audio_v1_descriptor); -#else - usbd_desc_register(busid, audio_v1_descriptor); -#endif + usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 2)); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 2)); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0100, audio_entity_table, 2)); 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 cd6e9b151a3..c9044550496 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 @@ -22,17 +22,17 @@ #define AUDIO_IN_CLOCK_ID 0x01 #define AUDIO_IN_FU_ID 0x03 -#define AUDIO_IN_MAX_FREQ 16000 -#define HALF_WORD_BYTES 2 //2 half word (one channel) -#define SAMPLE_BITS 16 //16 bit per channel +#define AUDIO_IN_MAX_FREQ 96000 +#define AUDIO_MIC_FRAME_SIZE_BYTE 2u +#define AUDIO_MIC_RESOLUTION_BIT 16u -#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME) +#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME) #define IN_CHANNEL_NUM 2 #if IN_CHANNEL_NUM == 1 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) -#define INPUT_CH_ENABLE 0x00000000 +#define INPUT_CH_ENABLE 0x00000001 #elif IN_CHANNEL_NUM == 2 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define INPUT_CH_ENABLE 0x00000003 @@ -56,15 +56,15 @@ #define INPUT_CH_ENABLE 0x000000ff #endif -#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000)) +#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * IN_CHANNEL_NUM) / 1000)) -#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \ - AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \ - AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ - AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ - AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN) +#define USB_CONFIG_SIZE (9 + \ + AUDIO_V2_AC_DESCRIPTOR_LEN + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_AS_DESCRIPTOR_LEN) #define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \ AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ @@ -72,19 +72,18 @@ AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, 0x01, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, INPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x03, 0x01, 0x0000), - AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL) + AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03), + AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000), + AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x02, INPUT_CTRL), + AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 0x0000), + AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL) }; static const uint8_t device_quality_descriptor[] = { @@ -139,96 +138,24 @@ const struct usb_descriptor audio_v2_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t audio_v2_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, 0x01, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, INPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x03, 0x01, 0x0000), - AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'A', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ - '4', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static const uint8_t mic_default_sampling_freq_table[] = { - AUDIO_SAMPLE_FREQ_NUM(1), + AUDIO_SAMPLE_FREQ_NUM(5), + AUDIO_SAMPLE_FREQ_4B(8000), + AUDIO_SAMPLE_FREQ_4B(8000), + AUDIO_SAMPLE_FREQ_4B(0x00), AUDIO_SAMPLE_FREQ_4B(16000), AUDIO_SAMPLE_FREQ_4B(16000), - AUDIO_SAMPLE_FREQ_4B(0x00) + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(32000), + AUDIO_SAMPLE_FREQ_4B(32000), + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(48000), + AUDIO_SAMPLE_FREQ_4B(48000), + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(96000), + AUDIO_SAMPLE_FREQ_4B(96000), + AUDIO_SAMPLE_FREQ_4B(0x00), }; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET]; @@ -323,13 +250,12 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_IN_EP }, }; +// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too. + void audio_v2_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &audio_v2_descriptor); -#else - usbd_desc_register(busid, audio_v2_descriptor); -#endif + usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2)); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2)); usbd_add_endpoint(busid, &audio_in_ep); 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 ce77c302688..38c1dbbe017 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 @@ -30,19 +30,21 @@ #define AUDIO_IN_CLOCK_ID 0x05 #define AUDIO_IN_FU_ID 0x07 -#define AUDIO_OUT_MAX_FREQ 96000 -#define AUDIO_IN_MAX_FREQ 16000 +#define AUDIO_OUT_MAX_FREQ 96000 +#define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u +#define AUDIO_SPEAKER_RESOLUTION_BIT 16u -#define HALF_WORD_BYTES 2 //2 half word (one channel) -#define SAMPLE_BITS 16 //16 bit per channel +#define AUDIO_IN_MAX_FREQ 96000 +#define AUDIO_MIC_FRAME_SIZE_BYTE 2u +#define AUDIO_MIC_RESOLUTION_BIT 16u -#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME) +#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME) #define IN_CHANNEL_NUM 2 #if IN_CHANNEL_NUM == 1 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) -#define INPUT_CH_ENABLE 0x00000000 +#define INPUT_CH_ENABLE 0x00000001 #elif IN_CHANNEL_NUM == 2 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define INPUT_CH_ENABLE 0x00000003 @@ -70,7 +72,7 @@ #if OUT_CHANNEL_NUM == 1 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) -#define OUTPUT_CH_ENABLE 0x00000000 +#define OUTPUT_CH_ENABLE 0x00000001 #elif OUT_CHANNEL_NUM == 2 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000003 @@ -95,35 +97,35 @@ #endif /* AudioFreq * DataSize (2 bytes) * NumChannels */ -#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000)) -#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000)) +#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * AUDIO_SPEAKER_FRAME_SIZE_BYTE * OUT_CHANNEL_NUM) / 1000)) +#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * IN_CHANNEL_NUM) / 1000)) #if USING_FEEDBACK == 0 -#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \ - AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \ - AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ - AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ - AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ - AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ - AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN + \ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN) +#define USB_CONFIG_SIZE (9 + \ + AUDIO_V2_AC_DESCRIPTOR_LEN + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_AS_DESCRIPTOR_LEN + \ + AUDIO_V2_AS_DESCRIPTOR_LEN) #else -#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \ - AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \ - AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ - AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ - AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ - AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ - AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN + \ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN) +#define USB_CONFIG_SIZE (9 + \ + AUDIO_V2_AC_DESCRIPTOR_LEN + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN + \ + AUDIO_V2_AS_DESCRIPTOR_LEN) #endif #define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \ @@ -136,28 +138,27 @@ AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000), + AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03), + AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000), + AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL), + AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 0x0000), + AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_IN_CLOCK_ID, 0x03, 0x03), + AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, AUDIO_IN_CLOCK_ID, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000), + AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x06, INPUT_CTRL), + AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID, AUDIO_IN_CLOCK_ID, 0x0000), #if USING_FEEDBACK == 0 - AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL), + AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL), #else - AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP), + AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP), #endif - AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL) + AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL) }; static const uint8_t device_quality_descriptor[] = { @@ -212,103 +213,6 @@ const struct usb_descriptor audio_v2_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -uint8_t audio_v2_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000), -#if USING_FEEDBACK == 0 - AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL), -#else - AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP), -#endif - AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'A', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ -#if USING_FEEDBACK == 0 - '3', 0x00, /* wcChar9 */ -#else - '4', 0x00, /* wcChar9 */ -#endif -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static const uint8_t speaker_default_sampling_freq_table[] = { AUDIO_SAMPLE_FREQ_NUM(5), @@ -330,9 +234,21 @@ static const uint8_t speaker_default_sampling_freq_table[] = { }; static const uint8_t mic_default_sampling_freq_table[] = { - AUDIO_SAMPLE_FREQ_NUM(1), + AUDIO_SAMPLE_FREQ_NUM(5), + AUDIO_SAMPLE_FREQ_4B(8000), + AUDIO_SAMPLE_FREQ_4B(8000), + AUDIO_SAMPLE_FREQ_4B(0x00), AUDIO_SAMPLE_FREQ_4B(16000), AUDIO_SAMPLE_FREQ_4B(16000), + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(32000), + AUDIO_SAMPLE_FREQ_4B(32000), + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(48000), + AUDIO_SAMPLE_FREQ_4B(48000), + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(96000), + AUDIO_SAMPLE_FREQ_4B(96000), AUDIO_SAMPLE_FREQ_4B(0x00) }; @@ -501,13 +417,12 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_IN_EP }, }; +// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too. + void audio_v2_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &audio_v2_descriptor); -#else - usbd_desc_register(busid, audio_v2_descriptor); -#endif + usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4)); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 4)); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0200, audio_entity_table, 4)); 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 e89c8808100..54206192754 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 @@ -31,13 +31,13 @@ #define HALF_WORD_BYTES 2 //2 half word (one channel) #define SAMPLE_BITS 16 //16 bit per channel -#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME) +#define BMCONTROL (AUDIO_V2_CONTROL_MUTE | AUDIO_V2_CONTROL_VOLUME) #define OUT_CHANNEL_NUM 2 #if OUT_CHANNEL_NUM == 1 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) -#define OUTPUT_CH_ENABLE 0x00000000 +#define OUTPUT_CH_ENABLE 0x00000001 #elif OUT_CHANNEL_NUM == 2 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000003 @@ -64,21 +64,21 @@ #define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000)) #if USING_FEEDBACK == 0 -#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \ - AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \ - AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ - AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ - AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN) +#define USB_CONFIG_SIZE (9 + \ + AUDIO_V2_AC_DESCRIPTOR_LEN + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_AS_DESCRIPTOR_LEN) #else -#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \ - AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \ - AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ - AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ - AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ - AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN) +#define USB_CONFIG_SIZE (9 + \ + AUDIO_V2_AC_DESCRIPTOR_LEN + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN) #endif #define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \ @@ -87,18 +87,17 @@ AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00), AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000), + AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, AUDIO_OUT_CLOCK_ID, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000), AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000), + AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, AUDIO_OUT_FU_ID, AUDIO_OUT_CLOCK_ID, 0x0000), #if USING_FEEDBACK == 0 AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL), #else @@ -158,98 +157,6 @@ const struct usb_descriptor audio_v2_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t audio_v2_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03), - AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL), - AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000), -#if USING_FEEDBACK == 0 - AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL), -#else - AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP), -#endif - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'A', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ -#if USING_FEEDBACK == 0 - '3', 0x00, /* wcChar9 */ -#else - '4', 0x00, /* wcChar9 */ -#endif -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static const uint8_t default_sampling_freq_table[] = { AUDIO_SAMPLE_FREQ_NUM(5), @@ -397,13 +304,12 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_OUT_EP }, }; +// In windows, audio driver cannot remove auto, so when you modify any descriptor information, please modify string descriptors too. + void audio_v2_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &audio_v2_descriptor); -#else - usbd_desc_register(busid, audio_v2_descriptor); -#endif + usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2)); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2)); usbd_add_endpoint(busid, &audio_out_ep); 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 158866057ee..2584d3ae768 100644 --- a/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c +++ b/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c @@ -23,7 +23,6 @@ #define MSC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01) }; @@ -85,85 +84,6 @@ const struct usb_descriptor msc_bootuf2_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t msc_bootuf2_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'F', 0x00, /* wcChar11 */ - '2', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static void usbd_event_handler(uint8_t busid, uint8_t event) { @@ -215,11 +135,9 @@ static struct usbd_interface intf0; void msc_bootuf2_init(uint8_t busid, uintptr_t reg_base) { boot2uf2_flash_init(); -#ifdef CONFIG_USBDEV_ADVANCE_DESC + usbd_desc_register(busid, &msc_bootuf2_descriptor); -#else - usbd_desc_register(busid, msc_bootuf2_descriptor); -#endif + usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP)); usbd_initialize(busid, reg_base, usbd_event_handler); 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 0851cf89d2c..016e9808e35 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 @@ -43,7 +43,6 @@ #define MSC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01) }; @@ -52,37 +51,7 @@ static const uint8_t config_descriptor[] = { USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02), - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x03, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ + HID_MOUSE_DESCRIPTOR_INIT(0x03, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL), }; static const uint8_t device_quality_descriptor[] = { @@ -137,117 +106,6 @@ const struct usb_descriptor cdc_acm_hid_msc_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t cdc_acm_hid_msc_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), - MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02), - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x03, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'C', 0x00, /* wcChar10 */ - 'M', 0x00, /* wcChar11 */ - 'H', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif /*!< hid mouse report descriptor */ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { @@ -399,11 +257,8 @@ struct usbd_interface intf3; void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_acm_hid_msc_descriptor); -#else - usbd_desc_register(busid, cdc_acm_hid_msc_descriptor); -#endif + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0)); usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1)); usbd_add_endpoint(busid, &cdc_out_ep); 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 0a8bc3b66cf..c941b35074c 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_mavlink_template.c @@ -27,7 +27,6 @@ #define CDC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -89,86 +88,6 @@ const struct usb_descriptor cdc_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t cdc_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'C', 0x00, /* wcChar10 */ - 'D', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif chry_ringbuffer_t usb_rx_rb; uint8_t usb_rx_buffer[2048]; @@ -243,11 +162,9 @@ static struct usbd_interface intf1; void cdc_acm_mavlink_init(uint8_t busid, uintptr_t reg_base) { chry_ringbuffer_init(&usb_rx_rb, usb_rx_buffer, sizeof(usb_rx_buffer)); -#ifdef CONFIG_USBDEV_ADVANCE_DESC + usbd_desc_register(busid, &cdc_descriptor); -#else - usbd_desc_register(busid, cdc_descriptor); -#endif + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0)); usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1)); usbd_add_endpoint(busid, &cdc_out_ep); 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 e889cbc8c8e..4c805835eeb 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c @@ -35,7 +35,6 @@ #define MSC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -98,87 +97,6 @@ const struct usb_descriptor cdc_msc_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t cdc_msc_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), - MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x00), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'C', 0x00, /* wcChar10 */ - '-', 0x00, /* wcChar11 */ - 'M', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; @@ -249,11 +167,8 @@ struct usbd_interface intf2; void cdc_acm_msc_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_msc_descriptor); -#else - usbd_desc_register(busid, cdc_msc_descriptor); -#endif + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0)); usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1)); usbd_add_endpoint(busid, &cdc_out_ep); 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 80b40b02067..753e81729bd 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c @@ -37,7 +37,6 @@ #define CDC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -102,89 +101,6 @@ const struct usb_descriptor cdc_multi_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t cdc_multi_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x08, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), - CDC_ACM_DESCRIPTOR_INIT(0x02, CDC_INT_EP2, CDC_OUT_EP2, CDC_IN_EP2, CDC_MAX_MPS, 0x02), - CDC_ACM_DESCRIPTOR_INIT(0x04, CDC_INT_EP3, CDC_OUT_EP3, CDC_IN_EP3, CDC_MAX_MPS, 0x02), - CDC_ACM_DESCRIPTOR_INIT(0x06, CDC_INT_EP4, CDC_OUT_EP4, CDC_IN_EP4, CDC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'C', 0x00, /* wcChar10 */ - 'D', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[4][2048]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[4][2048]; @@ -292,11 +208,8 @@ struct usbd_interface intf7; void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_multi_descriptor); -#else - usbd_desc_register(busid, cdc_multi_descriptor); -#endif + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0)); usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1)); usbd_add_endpoint(busid, &cdc_out_ep1); 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 f5fec3f0ea6..2fed1cfc504 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_rttchardev_template.c @@ -25,7 +25,6 @@ #define CDC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -87,86 +86,6 @@ const struct usb_descriptor cdc_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t cdc_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'C', 0x00, /* wcChar10 */ - 'D', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static void usbd_event_handler(uint8_t busid, uint8_t event) { @@ -198,11 +117,32 @@ extern void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_e void cdc_acm_chardev_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_descriptor); -#else - usbd_desc_register(busid, cdc_descriptor); -#endif + usbd_cdc_acm_serial_init(busid, CDC_IN_EP, CDC_OUT_EP); usbd_initialize(busid, reg_base, usbd_event_handler); -} \ No newline at end of file +} + +static int cdc_acm_enter(int argc, char **argv) +{ + (void)argc; + (void)argv; + + finsh_set_device("usb-acm0"); + rt_console_set_device("usb-acm0"); + + return 0; +} +MSH_CMD_EXPORT(cdc_acm_enter, cdc_acm_enter); + +static int cdc_acm_exit(int argc, char **argv) +{ + (void)argc; + (void)argv; + + finsh_set_device(RT_CONSOLE_DEVICE_NAME); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); + + return 0; +} +MSH_CMD_EXPORT(cdc_acm_exit, cdc_acm_exit); \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c index 3ff8ae2ab69..e98287c94c7 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_acm_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_acm_template.c @@ -25,7 +25,6 @@ #define CDC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -87,86 +86,6 @@ const struct usb_descriptor cdc_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t cdc_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'C', 0x00, /* wcChar10 */ - 'D', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; @@ -245,11 +164,8 @@ void cdc_acm_init(uint8_t busid, uintptr_t reg_base) memcpy(&write_buffer[0], data, 10); memset(&write_buffer[10], 'a', 2038); -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_descriptor); -#else - usbd_desc_register(busid, cdc_descriptor); -#endif + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0)); usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1)); usbd_add_endpoint(busid, &cdc_out_ep); diff --git a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c index b259e753196..528ed9f63ec 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c @@ -29,22 +29,16 @@ #define CDC_MAX_MPS 64 #endif -#define CDC_ECM_ETH_STATISTICS_BITMAP 0x00000000 - /* str idx = 4 is for mac address: aa:bb:cc:dd:ee:ff*/ #define CDC_ECM_MAC_STRING_INDEX 4 -/* Ethernet Maximum Segment size, typically 1514 bytes */ -#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U - -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; static const uint8_t config_descriptor[] = { USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_ETH_STATISTICS_BITMAP, CONFIG_CDC_ECM_ETH_MAX_SEGSZE, 0, 0, CDC_ECM_MAC_STRING_INDEX) + CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_MAC_STRING_INDEX) }; static const uint8_t device_quality_descriptor[] = { @@ -68,6 +62,7 @@ static const char *string_descriptors[] = { "CherryUSB", /* Manufacturer */ "CherryUSB CDC ECM DEMO", /* Product */ "2022123456", /* Serial Number */ + "aabbccddeeff", /* ecm mac address */ }; static const uint8_t *device_descriptor_callback(uint8_t speed) @@ -87,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 > 3) { + if (index > 4) { return NULL; } return string_descriptors[index]; @@ -99,107 +94,6 @@ const struct usb_descriptor cdc_ecm_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t cdc_ecm_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_ETH_STATISTICS_BITMAP, CONFIG_CDC_ECM_ETH_MAX_SEGSZE, 0, 0, CDC_ECM_MAC_STRING_INDEX), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x2E, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'C', 0x00, /* wcChar10 */ - 'D', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'E', 0x00, /* wcChar14 */ - 'C', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - ' ', 0x00, /* wcChar17 */ - 'D', 0x00, /* wcChar18 */ - 'E', 0x00, /* wcChar19 */ - 'M', 0x00, /* wcChar20 */ - 'O', 0x00, /* wcChar21 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ - /////////////////////////////////////// - /// string4 descriptor - /////////////////////////////////////// - 0x1A, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'a', 0x00, /* wcChar0 */ - 'a', 0x00, /* wcChar1 */ - 'b', 0x00, /* wcChar2 */ - 'b', 0x00, /* wcChar3 */ - 'c', 0x00, /* wcChar4 */ - 'c', 0x00, /* wcChar5 */ - 'd', 0x00, /* wcChar6 */ - 'd', 0x00, /* wcChar7 */ - 'e', 0x00, /* wcChar8 */ - 'e', 0x00, /* wcChar9 */ - 'f', 0x00, /* wcChar10 */ - 'f', 0x00, /* wcChar11 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -463,12 +357,9 @@ void cdc_ecm_init(uint8_t busid, uintptr_t reg_base) { cdc_ecm_lwip_init(); -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_ecm_descriptor); -#else - usbd_desc_register(busid, cdc_ecm_descriptor); -#endif + usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf0, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP)); usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf1, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP)); usbd_initialize(busid, reg_base, usbd_event_handler); -} +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c index c7bda9316b8..1b5874934dd 100644 --- a/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c +++ b/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c @@ -29,7 +29,6 @@ #define CDC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -91,88 +90,6 @@ const struct usb_descriptor cdc_rndis_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t cdc_rndis_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x2A, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'R', 0x00, /* wcChar10 */ - 'N', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - 'I', 0x00, /* wcChar13 */ - 'S', 0x00, /* wcChar14 */ - ' ', 0x00, /* wcChar15 */ - 'D', 0x00, /* wcChar16 */ - 'E', 0x00, /* wcChar17 */ - 'M', 0x00, /* wcChar18 */ - 'O', 0x00, /* wcChar19 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -438,11 +355,8 @@ void cdc_rndis_init(uint8_t busid, uintptr_t reg_base) { rndis_lwip_init(); -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_rndis_descriptor); -#else - usbd_desc_register(busid, cdc_rndis_descriptor); -#endif + usbd_add_interface(busid, usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, (uint8_t *)mac)); usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, (uint8_t *)mac)); usbd_initialize(busid, reg_base, usbd_event_handler); diff --git a/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c b/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c index 9c36433a085..0127c58ae80 100644 --- a/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c +++ b/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c @@ -15,7 +15,6 @@ #define USB_CONFIG_SIZE (9 + 9 + 9) -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01) }; @@ -77,134 +76,6 @@ const struct usb_descriptor dfu_flash_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t dfu_flash_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - DFU_DESCRIPTOR_INIT(), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x1e, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'D', 0x00, /* wcChar0 */ - 'F', 0x00, /* wcChar1 */ - 'U', 0x00, /* wcChar2 */ - 'W', 0x00, /* wcChar3 */ - 'i', 0x00, /* wcChar4 */ - 't', 0x00, /* wcChar5 */ - 'h', 0x00, /* wcChar6 */ - 's', 0x00, /* wcChar7 */ - 't', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 't', 0x00, /* wcChar10 */ - 'o', 0x00, /* wcChar11 */ - 'o', 0x00, /* wcChar12 */ - 'l', 0x00, /* wcChar13 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ - /////////////////////////////////////// - /// string4 descriptor - /////////////////////////////////////// - 0x60, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '@', 0x00, /* wcChar0 */ - 'I', 0x00, /* wcChar1 */ - 'n', 0x00, /* wcChar2 */ - 't', 0x00, /* wcChar3 */ - 'e', 0x00, /* wcChar4 */ - 'r', 0x00, /* wcChar5 */ - 'n', 0x00, /* wcChar6 */ - 'a', 0x00, /* wcChar7 */ - 'l', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'F', 0x00, /* wcChar10 */ - 'l', 0x00, /* wcChar11*/ - 'a', 0x00, /* wcChar12 */ - 's', 0x00, /* wcChar13 */ - 'h', 0x00, /* wcChar14 */ - ' ', 0x00, /* wcChar15 */ - ' ', 0x00, /* wcChar16 */ - ' ', 0x00, /* wcChar17 */ - '/', 0x00, /* wcChar18 */ - '0', 0x00, /* wcChar19 */ - 'x', 0x00, /* wcChar20 */ - '0', 0x00, /* wcChar21*/ - '8', 0x00, /* wcChar22 */ - '0', 0x00, /* wcChar23 */ - '0', 0x00, /* wcChar24 */ - '0', 0x00, /* wcChar25 */ - '0', 0x00, /* wcChar26 */ - '0', 0x00, /* wcChar27 */ - '0', 0x00, /* wcChar28 */ - '/', 0x00, /* wcChar29 */ - '1', 0x00, /* wcChar30 */ - '6', 0x00, /* wcChar31*/ - '*', 0x00, /* wcChar32 */ - '0', 0x00, /* wcChar33 */ - '0', 0x00, /* wcChar34 */ - '1', 0x00, /* wcChar35 */ - 'K', 0x00, /* wcChar36 */ - 'a', 0x00, /* wcChar37 */ - ',', 0x00, /* wcChar38 */ - '1', 0x00, /* wcChar39 */ - '1', 0x00, /* wcChar40 */ - '2', 0x00, /* wcChar41*/ - '*', 0x00, /* wcChar42 */ - '0', 0x00, /* wcChar43 */ - '1', 0x00, /* wcChar44 */ - 'K', 0x00, /* wcChar45 */ - 'g', 0x00, /* wcChar46 */ - -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static void usbd_event_handler(uint8_t busid, uint8_t event) { @@ -235,11 +106,8 @@ struct usbd_interface intf0; void dfu_flash_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &dfu_flash_descriptor); -#else - usbd_desc_register(busid, dfu_flash_descriptor); -#endif + usbd_add_interface(busid, usbd_dfu_init_intf(&intf0)); usbd_initialize(busid, reg_base, usbd_event_handler); } diff --git a/components/drivers/usb/cherryusb/demo/gamepad_template.c b/components/drivers/usb/cherryusb/demo/gamepad_template.c new file mode 100644 index 00000000000..2decbc7c082 --- /dev/null +++ b/components/drivers/usb/cherryusb/demo/gamepad_template.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" +#include "usbd_gamepad.h" + +#define GAMEPAD_IN_EP 0x81 +#define GAMEPAD_OUT_EP 0x02 + +#define USBD_MAX_POWER 500 + +static const uint8_t xinput_device_descriptor[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, XINPUT_VID, XINPUT_PID, XINPUT_BCD_DEVICE, 0x01) +}; + +static const uint8_t switch_device_descriptor[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, SWITCH_VID, SWITCH_PID, SWITCH_BCD_DEVICE, 0x01) +}; + +static const uint8_t xinput_config_descriptor[] = { + USB_CONFIG_DESCRIPTOR_INIT((9 + XINPUT_DESCRIPTOR_LEN), 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + XINPUT_DESCRIPTOR_INIT(0x00, GAMEPAD_OUT_EP, GAMEPAD_IN_EP) +}; + +static const uint8_t switch_config_descriptor[] = { + USB_CONFIG_DESCRIPTOR_INIT((9 + SWITCH_DESCRIPTOR_LEN), 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + SWITCH_DESCRIPTOR_INIT(0x00, GAMEPAD_OUT_EP, GAMEPAD_IN_EP) +}; + +static const char *xinput_string_descriptors[] = { + (const char[]){ 0x09, 0x04 }, /* Langid */ + "Microsoft", /* Manufacturer */ + "XInput STANDARD GAMEPAD", /* Product */ + "1.0", /* Serial Number */ +}; + +static const char *switch_string_descriptors[] = { + (const char[]){ 0x09, 0x04 }, /* Langid */ + "HORI", /* Manufacturer */ + "Switch Pro Controller", /* Product */ + "1.0", /* Serial Number */ +}; + +uint8_t gamepad_mode = USBD_GAMEPAD_MODE_XINPUT; +bool gamepad_init_flag = false; + +static const uint8_t *device_descriptor_callback(uint8_t speed) +{ + switch (gamepad_mode) { + case USBD_GAMEPAD_MODE_XINPUT: + return xinput_device_descriptor; + case USBD_GAMEPAD_MODE_SWITCH: + return switch_device_descriptor; + case USBD_GAMEPAD_MODE_XBOXONE: + break; + case USBD_GAMEPAD_MODE_PS4: + break; + + default: + break; + } + return NULL; +} + +static const uint8_t *config_descriptor_callback(uint8_t speed) +{ + switch (gamepad_mode) { + case USBD_GAMEPAD_MODE_XINPUT: + return xinput_config_descriptor; + case USBD_GAMEPAD_MODE_SWITCH: + return switch_config_descriptor; + case USBD_GAMEPAD_MODE_XBOXONE: + break; + case USBD_GAMEPAD_MODE_PS4: + break; + + default: + break; + } + return NULL; +} + +static const uint8_t *device_quality_descriptor_callback(uint8_t speed) +{ + return NULL; +} + +static const char *string_descriptor_callback(uint8_t speed, uint8_t index) +{ + if (index > 3) { + return NULL; + } + + switch (gamepad_mode) { + case USBD_GAMEPAD_MODE_XINPUT: + return xinput_string_descriptors[index]; + case USBD_GAMEPAD_MODE_SWITCH: + return switch_string_descriptors[index]; + case USBD_GAMEPAD_MODE_XBOXONE: + break; + case USBD_GAMEPAD_MODE_PS4: + break; + + default: + break; + } + return NULL; +} + +const struct usb_descriptor gamepad_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 +}; + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t gamepad_read_buffer[64]; +struct usb_gamepad_report gamepad_report; + +#define GAMEPAD_STATE_IDLE 0 +#define GAMEPAD_STATE_BUSY 1 + +volatile uint8_t gamepad_state = GAMEPAD_STATE_IDLE; + +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: + usbd_ep_start_read(busid, GAMEPAD_OUT_EP, gamepad_read_buffer, usbd_get_ep_mps(busid, GAMEPAD_OUT_EP)); + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +static void usbd_gamepad_int_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + gamepad_state = GAMEPAD_STATE_IDLE; +} + +void usbd_gamepad_int_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + usbd_ep_start_read(busid, GAMEPAD_OUT_EP, gamepad_read_buffer, usbd_get_ep_mps(busid, GAMEPAD_OUT_EP)); +} + +/*!< endpoint call back */ +static struct usbd_endpoint gamepad_in_ep = { + .ep_cb = usbd_gamepad_int_in_callback, + .ep_addr = GAMEPAD_IN_EP +}; + +static struct usbd_endpoint gamepad_out_ep = { + .ep_cb = usbd_gamepad_int_out_callback, + .ep_addr = GAMEPAD_OUT_EP +}; + +static struct usbd_interface intf0; + +void gamepad_init(uint8_t busid, uintptr_t reg_base) +{ + if (gamepad_init_flag) { + return; + } + + gamepad_init_flag = true; + + usbd_desc_register(busid, &gamepad_descriptor); + + switch (gamepad_mode) { + case USBD_GAMEPAD_MODE_XINPUT: + usbd_add_interface(busid, usbd_gamepad_xinput_init_intf(&intf0)); + break; + case USBD_GAMEPAD_MODE_SWITCH: + usbd_add_interface(busid, usbd_gamepad_switch_init_intf(&intf0)); + break; + case USBD_GAMEPAD_MODE_XBOXONE: + break; + case USBD_GAMEPAD_MODE_PS4: + break; + + default: + break; + } + + usbd_add_endpoint(busid, &gamepad_in_ep); + usbd_add_endpoint(busid, &gamepad_out_ep); + usbd_initialize(busid, reg_base, usbd_event_handler); +} + +void gamepad_change_mode(uint8_t mode, uintptr_t reg_base) +{ + gamepad_mode = mode; + + if (gamepad_init_flag) { + usbd_deinitialize(0); + } + gamepad_init_flag = false; + gamepad_init(0, reg_base); +} + +void gamepad_test(uint8_t busid) +{ + static uint32_t test_counter = 0; + + if (usb_device_is_configured(busid) == false) { + return; + } + + gamepad_state = GAMEPAD_STATE_BUSY; + memset(&gamepad_report, 0, sizeof(gamepad_report)); + + gamepad_report.buttons = (1 << (test_counter % 18)); + + switch (gamepad_mode) { + case USBD_GAMEPAD_MODE_XINPUT: + usbd_gamepad_xinput_send_report(GAMEPAD_IN_EP, &gamepad_report); + break; + case USBD_GAMEPAD_MODE_SWITCH: + usbd_gamepad_switch_send_report(GAMEPAD_IN_EP, &gamepad_report); + break; + case USBD_GAMEPAD_MODE_XBOXONE: + break; + case USBD_GAMEPAD_MODE_PS4: + break; + + default: + break; + } + + test_counter++; + while (gamepad_state == GAMEPAD_STATE_BUSY) { + } +} \ No newline at end of file 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 419fee2dc8f..8a43d0a5fb5 100644 --- a/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c @@ -8,25 +8,8 @@ #include "usbd_core.h" #include "usbd_hid.h" - -/*!< hidraw in endpoint */ -#define HIDRAW_IN_EP 0x81 -#ifdef CONFIG_USB_HS -#define HIDRAW_IN_EP_SIZE 1024 -#define HIDRAW_IN_INTERVAL 4 -#else -#define HIDRAW_IN_EP_SIZE 64 -#define HIDRAW_IN_INTERVAL 10 -#endif -/*!< hidraw out endpoint */ -#define HIDRAW_OUT_EP 0x02 -#ifdef CONFIG_USB_HS -#define HIDRAW_OUT_EP_SIZE 1024 -#define HIDRAW_OUT_EP_INTERVAL 4 -#else -#define HIDRAW_OUT_EP_SIZE 64 -#define HIDRAW_OUT_EP_INTERVAL 10 -#endif +#define HIDRAW_IN_EP 0x81 +#define HIDRAW_OUT_EP 0x02 #define USBD_VID 0xffff #define USBD_PID 0xffff @@ -34,53 +17,26 @@ #define USBD_LANGID_STRING 1033 /*!< config descriptor size */ -#define USB_HID_CONFIG_DESC_SIZ (9 + 9 + 9 + 7 + 7) +#define USB_CONFIG_SIZE (9 + 9 + 9 + 7 + 7) /*!< custom hid report descriptor size */ #define HID_CUSTOM_REPORT_DESC_SIZE 38 -#ifdef CONFIG_USBDEV_ADVANCE_DESC +#ifdef CONFIG_USB_HS +#define HID_MAX_MPS 1024 +#define HIDRAW_IN_INTERVAL 1 +#else +#define HID_MAX_MPS 64 +#define HIDRAW_IN_INTERVAL 1 +#endif + static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - /************** Descriptor of Custom interface *****************/ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Custom HID ********************/ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Custom in endpoint ********************/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HIDRAW_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - WBVAL(HIDRAW_IN_EP_SIZE), /* wMaxPacketSize: 4 Byte max */ - HIDRAW_IN_INTERVAL, /* bInterval: Polling Interval */ - /******************** Descriptor of Custom out endpoint ********************/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HIDRAW_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - WBVAL(HIDRAW_OUT_EP_SIZE), /* wMaxPacketSize: 4 Byte max */ - HIDRAW_OUT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 73 */ + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + HID_CUSTOM_INOUT_DESCRIPTOR_INIT(0x00, 0x01, HID_CUSTOM_REPORT_DESC_SIZE, HIDRAW_OUT_EP, HIDRAW_IN_EP, HID_MAX_MPS, HIDRAW_IN_INTERVAL), }; static const uint8_t device_quality_descriptor[] = { @@ -135,120 +91,6 @@ const struct usb_descriptor hid_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -static const uint8_t hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - /************** Descriptor of Custom interface *****************/ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Custom HID ********************/ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Custom in endpoint ********************/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HIDRAW_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - WBVAL(HIDRAW_IN_EP_SIZE), /* wMaxPacketSize: 4 Byte max */ - HIDRAW_IN_INTERVAL, /* bInterval: Polling Interval */ - /******************** Descriptor of Custom out endpoint ********************/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HIDRAW_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - WBVAL(HIDRAW_OUT_EP_SIZE), /* wMaxPacketSize: 4 Byte max */ - HIDRAW_OUT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 73 */ - /* - * string0 descriptor - */ - USB_LANGID_INIT(USBD_LANGID_STRING), - /* - * string1 descriptor - */ - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /* - * string2 descriptor - */ - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /* - * string3 descriptor - */ - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /* - * device qualifier descriptor - */ - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif /*!< custom hid report descriptor */ static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = { @@ -261,16 +103,16 @@ static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = { 0x09, 0x02, /* USAGE (Vendor Usage 1) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ 0x25, 0xff, /*LOGICAL_MAXIMUM (255) */ - 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ 0x96, 0xff, 0x03, /* REPORT_COUNT (63) */ 0x81, 0x02, /* INPUT (Data,Var,Abs) */ /* <___________________________________________________> */ 0x85, 0x01, /* REPORT ID (0x01) */ 0x09, 0x03, /* USAGE (Vendor Usage 1) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ - 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ + 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ 0x75, 0x08, /* REPORT_SIZE (8) */ - 0x96, 0xff, 0x03, /* REPORT_COUNT (63) */ + 0x96, 0xff, 0x03, /* REPORT_COUNT (63) */ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ /* USER CODE END 0 */ 0xC0 /* END_COLLECTION */ @@ -299,8 +141,8 @@ static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = { #endif }; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[HIDRAW_OUT_EP_SIZE]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t send_buffer[HIDRAW_IN_EP_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[HID_MAX_MPS]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t send_buffer[HID_MAX_MPS]; #define HID_STATE_IDLE 0 #define HID_STATE_BUSY 1 @@ -311,27 +153,27 @@ static volatile uint8_t custom_state; 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: - /* setup first out ep read transfer */ - usbd_ep_start_read(busid, HIDRAW_OUT_EP, read_buffer, HIDRAW_OUT_EP_SIZE); - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; + 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: + /* setup first out ep read transfer */ + usbd_ep_start_read(busid, HIDRAW_OUT_EP, read_buffer, HID_MAX_MPS); + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; } } @@ -346,7 +188,7 @@ static void usbd_hid_custom_in_callback(uint8_t busid, uint8_t ep, uint32_t nbyt static void usbd_hid_custom_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) { USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes); - usbd_ep_start_read(busid, ep, read_buffer, HIDRAW_IN_EP_SIZE); + usbd_ep_start_read(busid, ep, read_buffer, HID_MAX_MPS); read_buffer[0] = 0x02; /* IN: report id */ usbd_ep_start_write(busid, HIDRAW_IN_EP, read_buffer, nbytes); } @@ -372,11 +214,8 @@ struct usbd_interface intf0; void hid_custom_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &hid_descriptor); -#else - usbd_desc_register(busid, hid_descriptor); -#endif + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE)); usbd_add_endpoint(busid, &custom_in_ep); usbd_add_endpoint(busid, &custom_out_ep); diff --git a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c index 9fabba60ddf..843a7267292 100644 --- a/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c @@ -15,49 +15,16 @@ #define HID_INT_EP_SIZE 8 #define HID_INT_EP_INTERVAL 10 -#define USB_HID_CONFIG_DESC_SIZ 34 +#define USB_CONFIG_SIZE 34 #define HID_KEYBOARD_REPORT_DESC_SIZE 63 -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL), }; static const uint8_t device_quality_descriptor[] = { @@ -112,117 +79,6 @@ const struct usb_descriptor hid_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -static const uint8_t hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif /* USB HID device Configuration Descriptor */ static uint8_t hid_desc[9] __ALIGN_END = { @@ -319,11 +175,8 @@ struct usbd_interface intf0; void hid_keyboard_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &hid_descriptor); -#else - usbd_desc_register(busid, hid_descriptor); -#endif + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE)); usbd_add_endpoint(busid, &hid_in_ep); diff --git a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c index bcd03e1d176..24d32f90dfd 100644 --- a/components/drivers/usb/cherryusb/demo/hid_mouse_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_mouse_template.c @@ -17,50 +17,17 @@ #define USBD_LANGID_STRING 1033 /*!< config descriptor size */ -#define USB_HID_CONFIG_DESC_SIZ 34 +#define USB_CONFIG_SIZE 34 /*!< report descriptor size */ #define HID_MOUSE_REPORT_DESC_SIZE 74 -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL), }; static const uint8_t device_quality_descriptor[] = { @@ -115,118 +82,6 @@ const struct usb_descriptor hid_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -const uint8_t hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif /*!< hid mouse report descriptor */ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { @@ -337,11 +192,8 @@ struct usbd_interface intf0; void hid_mouse_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &hid_descriptor); -#else - usbd_desc_register(busid, hid_descriptor); -#endif + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE)); usbd_add_endpoint(busid, &hid_in_ep); 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 fa4381191d2..c2c61305e6d 100644 --- a/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c +++ b/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c @@ -17,50 +17,17 @@ #define USBD_LANGID_STRING 1033 /*!< config descriptor size */ -#define USB_HID_CONFIG_DESC_SIZ 34 +#define USB_CONFIG_SIZE 34 /*!< report descriptor size */ #define HID_MOUSE_REPORT_DESC_SIZE 74 -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER), + HID_MOUSE_DESCRIPTOR_INIT(0x00, 0x01, HID_MOUSE_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL), }; static const uint8_t device_quality_descriptor[] = { @@ -115,118 +82,6 @@ const struct usb_descriptor hid_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -/*!< global descriptor */ -const uint8_t hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif /*!< hid mouse report descriptor */ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { @@ -337,11 +192,8 @@ static struct usbd_interface intf0; void hid_mouse_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &hid_descriptor); -#else - usbd_desc_register(busid, hid_descriptor); -#endif + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE)); usbd_add_endpoint(busid, &hid_in_ep); diff --git a/components/drivers/usb/cherryusb/demo/midi_template.c b/components/drivers/usb/cherryusb/demo/midi_template.c index 0203c744456..f0e66c4be98 100644 --- a/components/drivers/usb/cherryusb/demo/midi_template.c +++ b/components/drivers/usb/cherryusb/demo/midi_template.c @@ -14,7 +14,13 @@ #define USBD_MAX_POWER 100 #define USBD_LANGID_STRING 1033 -#define USB_CONFIG_SIZE (9 + 9 + 9 + 9 + 7 + MIDI_SIZEOF_JACK_DESC + 9 + 5 + 9 + 5) +#define AUDIO_AC_SIZ AUDIO_SIZEOF_AC_HEADER_DESC(1) +#define AUDIO_MS_SIZ (7 + MIDI_SIZEOF_JACK_DESC + 9 + 5 + 9 + 5) + +#define USB_CONFIG_SIZE (unsigned long)(9 + \ + AUDIO_AC_DESCRIPTOR_LEN(1) + \ + MIDI_STANDARD_DESCRIPTOR_LEN + \ + AUDIO_MS_SIZ) #ifdef CONFIG_USB_HS #define MIDI_EP_MPS 512 @@ -22,55 +28,15 @@ #define MIDI_EP_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01) }; static const uint8_t config_descriptor[] = { USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - // Standard AC Interface Descriptor - 0x09, - 0x04, - 0x00, - 0x00, - 0x00, - 0x01, - 0x01, - 0x00, - 0x00, - // Class-specific AC Interface Descriptor - 0x09, - 0x24, - 0x01, - 0x00, - 0x01, - 0x09, - 0x00, - 0x01, - 0x01, - // MIDIStreaming Interface Descriptors - 0x09, - 0x04, - 0x01, - 0x00, - 0x02, - 0x01, - 0x03, - 0x00, - 0x00, - // Class-Specific MS Interface Header Descriptor - 0x07, - 0x24, - 0x01, - 0x00, - 0x01, - WBVAL(65), - - // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x01), - // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x02), - // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x03, 0x02), - // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x04, 0x01), + AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01), + MIDI_STANDARD_DESCRIPTOR_INIT(0x01, 0x02), + MIDI_CS_HEADER_DESCRIPTOR_INIT(AUDIO_MS_SIZ), MIDI_JACK_DESCRIPTOR_INIT(0x01), // OUT endpoint descriptor 0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00, @@ -133,136 +99,6 @@ const struct usb_descriptor midi_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t midi_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - // Standard AC Interface Descriptor - 0x09, - 0x04, - 0x00, - 0x00, - 0x00, - 0x01, - 0x01, - 0x00, - 0x00, - // Class-specific AC Interface Descriptor - 0x09, - 0x24, - 0x01, - 0x00, - 0x01, - 0x09, - 0x00, - 0x01, - 0x01, - // MIDIStreaming Interface Descriptors - 0x09, - 0x04, - 0x01, - 0x00, - 0x02, - 0x01, - 0x03, - 0x00, - 0x00, - // Class-Specific MS Interface Header Descriptor - 0x07, - 0x24, - 0x01, - 0x00, - 0x01, - WBVAL(65), - - // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x01), - // MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x02), - // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x03, 0x02), - // MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x04, 0x01), - MIDI_JACK_DESCRIPTOR_INIT(0x01), - // OUT endpoint descriptor - 0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00, - 0x05, 0x25, 0x01, 0x01, 0x01, - - // IN endpoint descriptor - 0x09, 0x05, MIDI_IN_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00, - 0x05, 0x25, 0x01, 0x01, 0x03, - - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x28, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'M', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - 'I', 0x00, /* wcChar13 */ - ' ', 0x00, /* wcChar14 */ - 'D', 0x00, /* wcChar15 */ - 'E', 0x00, /* wcChar16 */ - 'M', 0x00, /* wcChar17 */ - 'O', 0x00, /* wcChar18 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ - '0', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[MIDI_EP_MPS]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[MIDI_EP_MPS]; @@ -317,11 +153,8 @@ struct usbd_endpoint midi_in_ep = { void midi_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &midi_descriptor); -#else - usbd_desc_register(busid, midi_descriptor); -#endif + usbd_add_interface(busid, &intf0); usbd_add_interface(busid, &intf1); usbd_add_endpoint(busid, &midi_out_ep); diff --git a/components/drivers/usb/cherryusb/demo/msc_ram_template.c b/components/drivers/usb/cherryusb/demo/msc_ram_template.c index ac7d9dbd08c..cd8f6464638 100644 --- a/components/drivers/usb/cherryusb/demo/msc_ram_template.c +++ b/components/drivers/usb/cherryusb/demo/msc_ram_template.c @@ -22,7 +22,6 @@ #define MSC_MAX_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01) }; @@ -84,85 +83,6 @@ const struct usb_descriptor msc_ram_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t msc_ram_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'M', 0x00, /* wcChar10 */ - 'S', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static void usbd_event_handler(uint8_t busid, uint8_t event) { @@ -267,11 +187,8 @@ void msc_ram_init(uint8_t busid, uintptr_t reg_base) res = rt_device_open(blk_dev, RT_DEVICE_OFLAG_RDWR); RT_ASSERT(res == RT_EOK); #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &msc_ram_descriptor); -#else - usbd_desc_register(busid, msc_ram_descriptor); -#endif + usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP)); usbd_initialize(busid, reg_base, usbd_event_handler); diff --git a/components/drivers/usb/cherryusb/demo/usb_host.c b/components/drivers/usb/cherryusb/demo/usb_host.c index 0863970eda9..5f6e6e92674 100644 --- a/components/drivers/usb/cherryusb/demo/usb_host.c +++ b/components/drivers/usb/cherryusb/demo/usb_host.c @@ -4,79 +4,73 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "usbh_core.h" -#include "usbh_cdc_acm.h" +#include "usbh_serial.h" #include "usbh_hid.h" #include "usbh_msc.h" -#include "usbh_video.h" -#include "usbh_audio.h" -#ifndef CONFIG_TEST_USBH_CDC_ACM -#define CONFIG_TEST_USBH_CDC_ACM 1 -#endif -#ifndef TEST_USBH_CDC_SPEED -#define TEST_USBH_CDC_SPEED 0 -#endif -#ifndef CONFIG_TEST_USBH_HID -#define CONFIG_TEST_USBH_HID 1 -#endif -#ifndef CONFIG_TEST_USBH_MSC -#define CONFIG_TEST_USBH_MSC 1 -#endif -#ifndef TEST_USBH_MSC_FATFS -#define TEST_USBH_MSC_FATFS 0 -#endif -#ifndef TEST_USBH_MSC_FATFS_SPEED -#define TEST_USBH_MSC_FATFS_SPEED 0 -#endif -#ifndef CONFIG_TEST_USBH_AUDIO -#define CONFIG_TEST_USBH_AUDIO 0 -#endif -#ifndef CONFIG_TEST_USBH_VIDEO -#define CONFIG_TEST_USBH_VIDEO 0 -#endif +// net class demos use socket api -#if defined(TEST_USBH_CDC_ECM) || defined(TEST_USBH_CDC_RNDIS) || defined(TEST_USBH_ASIX) || defined(TEST_USBH_RTL8152) -#error we have move those class implements into platform/none/usbh_lwip.c, and you should call tcpip_init(NULL, NULL) in your app +#ifdef CONFIG_TEST_USBH_SERIAL +#define SERIAL_TEST_LEN (1 * 1024) + +#if SERIAL_TEST_LEN >= CONFIG_USBHOST_SERIAL_RX_SIZE +#error SERIAL_TEST_LEN is larger than CONFIG_USBHOST_SERIAL_RX_SIZE, please reduce SERIAL_TEST_LEN or increase CONFIG_USBHOST_SERIAL_RX_SIZE #endif -#if CONFIG_TEST_USBH_CDC_ACM -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[4096]; +volatile uint32_t serial_tx_bytes = 0; +volatile uint32_t serial_rx_bytes = 0; +volatile bool serial_is_opened = false; + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t serial_tx_buffer[SERIAL_TEST_LEN]; +uint8_t serial_rx_data[SERIAL_TEST_LEN]; -#if TEST_USBH_CDC_SPEED +#ifdef CONFIG_TEST_USBH_CDC_SPEED #define TEST_LEN (16 * 1024) #define TEST_COUNT (10240) -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_speed_buffer[TEST_LEN]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t serial_speed_buffer[TEST_LEN]; #endif -void usbh_cdc_acm_callback(void *arg, int nbytes) +static void usbh_serial_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) { - //struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg; - - if (nbytes > 0) { - for (size_t i = 0; i < nbytes; i++) { - USB_LOG_RAW("0x%02x ", cdc_buffer[i]); + int ret; + struct usbh_serial *serial; + bool serial_test_success = false; + + serial = usbh_serial_open("/dev/ttyACM0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK); + if (serial == NULL) { + serial = usbh_serial_open("/dev/ttyUSB0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK); + if (serial == NULL) { + USB_LOG_RAW("no serial device found\r\n"); + goto delete; } - USB_LOG_RAW("nbytes:%d\r\n", (unsigned int)nbytes); } -} -static void usbh_cdc_acm_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) -{ - int ret; - struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)CONFIG_USB_OSAL_THREAD_GET_ARGV; + struct usbh_serial_termios termios; + + memset(&termios, 0, sizeof(termios)); + termios.baudrate = 115200; + termios.stopbits = 0; + termios.parity = 0; + termios.databits = 8; + termios.rtscts = false; + termios.rx_timeout = 0; + ret = usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios); + if (ret < 0) { + USB_LOG_RAW("set serial attr error, ret:%d\r\n", ret); + goto delete_with_close; + } /* test with only one buffer, if you have more cdc acm class, modify by yourself */ -#if TEST_USBH_CDC_SPEED +#ifdef CONFIG_TEST_USBH_CDC_SPEED const uint32_t test_len[] = { 512, 1 * 1024, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024 }; - memset(cdc_speed_buffer, 0xAA, TEST_LEN); + memset(serial_speed_buffer, 0xAA, TEST_LEN); for (uint8_t j = 0; j < 6; j++) { uint32_t start_time = (uint32_t)xTaskGetTickCount(); for (uint32_t i = 0; i < TEST_COUNT; i++) { - usbh_bulk_urb_fill(&cdc_acm_class->bulkout_urb, cdc_acm_class->hport, cdc_acm_class->bulkout, cdc_speed_buffer, test_len[j], 0XFFFFFFF, NULL, NULL); - ret = usbh_submit_urb(&cdc_acm_class->bulkout_urb); + usbh_serial_write(serial, serial_speed_buffer, test_len[j]); if (ret < 0) { USB_LOG_RAW("bulk out error,ret:%d\r\n", ret); while (1) { @@ -87,35 +81,75 @@ static void usbh_cdc_acm_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) uint32_t time_ms = xTaskGetTickCount() - start_time; USB_LOG_RAW("per packet len:%d, out speed:%f MB/S\r\n", (unsigned int)test_len[j], (test_len[j] * TEST_COUNT / 1024 / 1024) * 1000 / ((float)time_ms)); } + usbh_serial_close(serial); + goto delete; #endif - memset(cdc_buffer, 0x55, 4096); + memset(serial_tx_buffer, 0xA5, sizeof(serial_tx_buffer)); + USB_LOG_RAW("start serial loopback test, len: %d\r\n", SERIAL_TEST_LEN); + + serial_tx_bytes = 0; + while (1) { + ret = usbh_serial_write(serial, serial_tx_buffer, sizeof(serial_tx_buffer)); + if (ret < 0) { + USB_LOG_RAW("serial write error, ret:%d\r\n", ret); + goto delete_with_close; + } else { + serial_tx_bytes += ret; - /* for common, we use timeout with 0xffffffff, this is just a test */ - usbh_bulk_urb_fill(&cdc_acm_class->bulkout_urb, cdc_acm_class->hport, cdc_acm_class->bulkout, cdc_buffer, sizeof(cdc_buffer), 3000, NULL, NULL); - ret = usbh_submit_urb(&cdc_acm_class->bulkout_urb); - if (ret < 0) { - USB_LOG_RAW("bulk out error,ret:%d\r\n", ret); - goto delete; - } else { - USB_LOG_RAW("send over:%d\r\n", (unsigned int)cdc_acm_class->bulkout_urb.actual_length); + if (serial_tx_bytes == SERIAL_TEST_LEN) { + USB_LOG_RAW("send over\r\n"); + break; + } + } } - /* we can change cdc_acm_class->bulkin->wMaxPacketSize with 4096 for testing zlp, default is ep mps */ - usbh_bulk_urb_fill(&cdc_acm_class->bulkin_urb, cdc_acm_class->hport, cdc_acm_class->bulkin, cdc_buffer, cdc_acm_class->bulkin->wMaxPacketSize, 0xffffffff, usbh_cdc_acm_callback, cdc_acm_class); - ret = usbh_submit_urb(&cdc_acm_class->bulkin_urb); - if (ret < 0) { - USB_LOG_RAW("bulk in error,ret:%d\r\n", ret); - goto delete; - } else { + volatile uint32_t wait_timeout = 0; + serial_rx_bytes = 0; + while (1) { + ret = usbh_serial_read(serial, &serial_rx_data[serial_rx_bytes], SERIAL_TEST_LEN - serial_rx_bytes); + if (ret < 0) { + USB_LOG_RAW("serial read error, ret:%d\r\n", ret); + goto delete_with_close; + } else { + serial_rx_bytes += ret; + + if (serial_rx_bytes == SERIAL_TEST_LEN) { + USB_LOG_RAW("receive over\r\n"); + for (uint32_t i = 0; i < SERIAL_TEST_LEN; i++) { + if (serial_rx_data[i] != 0xa5) { + USB_LOG_RAW("serial loopback data error at index %d, data: 0x%02x\r\n", (unsigned int)i, serial_rx_data[i]); + goto delete_with_close; + } + } + serial_test_success = true; + break; + } + } + wait_timeout++; + + if (wait_timeout > 500) { // 5s + USB_LOG_RAW("serial read timeout\r\n"); + goto delete_with_close; + } + + usb_osal_msleep(10); } + // clang-format off +delete_with_close: + if (serial_test_success) { + USB_LOG_RAW("serial loopback test success\r\n"); + } else { + USB_LOG_RAW("serial loopback test failed\r\n"); + } + usbh_serial_close(serial); delete: usb_osal_thread_delete(NULL); // clang-format on } #endif -#if CONFIG_TEST_USBH_HID +#ifdef CONFIG_TEST_USBH_HID USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128]; void usbh_hid_callback(void *arg, int nbytes) @@ -140,7 +174,6 @@ static void usbh_hid_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) { int ret; struct usbh_hid *hid_class = (struct usbh_hid *)CONFIG_USB_OSAL_THREAD_GET_ARGV; - ; /* test with only one buffer, if you have more hid class, modify by yourself */ @@ -157,15 +190,15 @@ static void usbh_hid_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) } #endif -#if CONFIG_TEST_USBH_MSC +#ifdef CONFIG_TEST_USBH_MSC -#if TEST_USBH_MSC_FATFS +#ifdef CONFIG_TEST_USBH_MSC_FATFS #include "ff.h" -#if TEST_USBH_MSC_FATFS_SPEED +#ifdef CONFIG_TEST_USBH_MSC_FATFS_SPEED #define WRITE_SIZE_MB (128UL) -#define WRITE_SIZE (1024UL * 1024UL * WRITE_SIZE_MB) -#define BUF_SIZE (1024UL * 128UL) +#define WRITE_SIZE (1024UL * 1024UL * WRITE_SIZE_MB) +#define BUF_SIZE (1024UL * 128UL) USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_write_buffer[BUF_SIZE]; #else USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_write_buffer[25 * 100]; @@ -223,7 +256,7 @@ int usb_msc_fatfs_test() goto unmount; } -#if TEST_USBH_MSC_FATFS_SPEED +#ifdef CONFIG_TEST_USBH_MSC_FATFS_SPEED for (uint32_t i = 0; i < BUF_SIZE; i++) { read_write_buffer[i] = i % 256; } @@ -234,9 +267,9 @@ int usb_msc_fatfs_test() uint32_t write_size = WRITE_SIZE; uint32_t start_time = (uint32_t)xTaskGetTickCount(); while (write_size > 0) { - res_sd = f_write(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum); + res_sd = f_write(&fnew, read_write_buffer, BUF_SIZE, (UINT *)&fnum); if (res_sd != FR_OK) { - printf("Write file failed, cause: %s\n", res_sd); + USB_LOG_RAW("Write file failed, cause: %s\n", res_sd); goto unmount; } write_size -= BUF_SIZE; @@ -260,9 +293,9 @@ int usb_msc_fatfs_test() uint32_t write_size = WRITE_SIZE; uint32_t start_time = (uint32_t)xTaskGetTickCount(); while (write_size > 0) { - res_sd = f_read(&fnew, read_write_buffer, BUF_SIZE, (UINT*)&fnum); + res_sd = f_read(&fnew, read_write_buffer, BUF_SIZE, (UINT *)&fnum); if (res_sd != FR_OK) { - printf("Read file failed, cause: %s\n", res_sd); + USB_LOG_RAW("Read file failed, cause: %s\n", res_sd); goto unmount; } write_size -= BUF_SIZE; @@ -295,8 +328,10 @@ static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) int ret; struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV; + (void)msc_class; + /* test with only one buffer, if you have more msc class, modify by yourself */ -#if TEST_USBH_MSC_FATFS == 0 +#ifndef TEST_USBH_MSC_FATFS ret = usbh_msc_scsi_init(msc_class); if (ret < 0) { USB_LOG_RAW("scsi_init error,ret:%d\r\n", ret); @@ -326,18 +361,23 @@ static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV) } #endif -#if CONFIG_TEST_USBH_CDC_ACM -void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class) +#ifdef CONFIG_TEST_USBH_SERIAL +void usbh_serial_run(struct usbh_serial *serial) { - usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class); + if (serial_is_opened) { + return; + } + serial_is_opened = true; + usb_osal_thread_create("usbh_serial", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_serial_thread, serial); } -void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class) +void usbh_serial_stop(struct usbh_serial *serial) { + serial_is_opened = false; } #endif -#if CONFIG_TEST_USBH_HID +#ifdef CONFIG_TEST_USBH_HID void usbh_hid_run(struct usbh_hid *hid_class) { usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class); @@ -348,7 +388,7 @@ void usbh_hid_stop(struct usbh_hid *hid_class) } #endif -#if CONFIG_TEST_USBH_MSC +#ifdef CONFIG_TEST_USBH_MSC void usbh_msc_run(struct usbh_msc *msc_class) { usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class); @@ -359,14 +399,6 @@ void usbh_msc_stop(struct usbh_msc *msc_class) } #endif -#if CONFIG_TEST_USBH_AUDIO -#error "commercial charge" -#endif - -#if CONFIG_TEST_USBH_VIDEO -#error "commercial charge" -#endif - #if 0 #include "usbh_aoa.h" diff --git a/components/drivers/usb/cherryusb/demo/usbh_bl616_wifi_cli.c b/components/drivers/usb/cherryusb/demo/usbh_bl616_wifi_cli.c new file mode 100644 index 00000000000..125a26394d7 --- /dev/null +++ b/components/drivers/usb/cherryusb/demo/usbh_bl616_wifi_cli.c @@ -0,0 +1,182 @@ +#include "usbh_core.h" +#include "usbh_cdc_acm.h" +#include "shell.h" + +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[8 * 1024]; + +int wifi_scan(int argc, char **argv) +{ + struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0"); + uint32_t len; + int ret; + + if (cdc_acm_class == NULL) { + printf("cdc acm class not found\r\n"); + return -1; + } + + len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_scan\r\n"); + ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000); + if (ret < 0) { + printf("wifi scan failed1, ret:%d\r\n", ret); + return -1; + } + + ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000); + if (ret < 0) { + printf("wifi scan failed2, ret:%d\r\n", ret); + return -1; + } + cdc_buffer[ret] = '\0'; + printf("%s\r\n", cdc_buffer); + return 0; +} +CSH_CMD_EXPORT(wifi_scan, wifi_scan); + +int wifi_scan_result(int argc, char **argv) +{ + struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0"); + uint32_t len; + int ret; + + if (cdc_acm_class == NULL) { + printf("cdc acm class not found\r\n"); + return -1; + } + + len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_scan_result {\"offset\":0, \"count\":0}\r\n"); + ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000); + if (ret < 0) { + printf("wifi scan failed1, ret:%d\r\n", ret); + return -1; + } + + ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000); + if (ret < 0) { + printf("wifi scan failed2, ret:%d\r\n", ret); + return -1; + } + cdc_buffer[ret] = '\0'; + printf("%s\r\n", cdc_buffer); + return 0; +} +CSH_CMD_EXPORT(wifi_scan_result, wifi_scan_result); + +int wifi_connect(int argc, char **argv) +{ + struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0"); + uint32_t len; + int ret; + + if (cdc_acm_class == NULL) { + printf("cdc acm class not found\r\n"); + return -1; + } + + if (argc < 3) { + printf("please input correct command: wifi_connect ssid password\r\n"); + return -1; + } + + len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_connect {\"ssid\":\"%s\", \"password\":\"%s\"}\r\n", argv[1], argv[2]); + ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000); + if (ret < 0) { + printf("wifi connect failed1, ret:%d\r\n", ret); + return -1; + } + ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000); + if (ret < 0) { + printf("wifi connect failed2, ret:%d\r\n", ret); + return -1; + } + cdc_buffer[ret] = '\0'; + printf("%s\r\n", cdc_buffer); + return 0; +} +CSH_CMD_EXPORT(wifi_connect, wifi_connect); + +int wifi_disconnect(int argc, char **argv) +{ + struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0"); + uint32_t len; + int ret; + + if (cdc_acm_class == NULL) { + printf("cdc acm class not found\r\n"); + return -1; + } + + len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_disconnect\r\n"); + ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000); + if (ret < 0) { + printf("wifi disconnect failed1, ret:%d\r\n", ret); + return -1; + } + ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000); + if (ret < 0) { + printf("wifi disconnect failed2, ret:%d\r\n", ret); + return -1; + } + cdc_buffer[ret] = '\0'; + printf("%s\r\n", cdc_buffer); + return 0; +} +CSH_CMD_EXPORT(wifi_disconnect, wifi_disconnect); + +int wifi_status(int argc, char **argv) +{ + struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0"); + uint32_t len; + int ret; + + if (cdc_acm_class == NULL) { + printf("cdc acm class not found\r\n"); + return -1; + } + + len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "ap_status\r\n"); + ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000); + if (ret < 0) { + printf("wifi status failed1, ret:%d\r\n", ret); + return -1; + } + + ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000); + if (ret < 0) { + printf("wifi status failed2, ret:%d\r\n", ret); + return -1; + } + cdc_buffer[ret] = '\0'; + printf("%s\r\n", cdc_buffer); + return 0; +} +CSH_CMD_EXPORT(wifi_status, wifi_status); + +int wifi_version(int argc, char **argv) +{ + struct usbh_cdc_acm *cdc_acm_class = usbh_find_class_instance("/dev/ttyACM0"); + uint32_t len; + int ret; + + if (cdc_acm_class == NULL) { + printf("cdc acm class not found\r\n"); + return -1; + } + + len = snprintf((char *)cdc_buffer, sizeof(cdc_buffer), "sys_version\r\n"); + ret = usbh_cdc_acm_bulk_out_transfer(cdc_acm_class, cdc_buffer, len, 3000); + if (ret < 0) { + printf("wifi status failed1, ret:%d\r\n", ret); + return -1; + } + + ret = usbh_cdc_acm_bulk_in_transfer(cdc_acm_class, cdc_buffer, sizeof(cdc_buffer), 3000); + if (ret < 0) { + printf("wifi status failed2, ret:%d\r\n", ret); + return -1; + } + cdc_buffer[ret] = '\0'; + printf("%s\r\n", cdc_buffer); + return 0; +} +CSH_CMD_EXPORT(wifi_version, wifi_version); \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c index 99df89b995a..fab4044fe12 100644 --- a/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c +++ b/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c @@ -46,15 +46,15 @@ VS_HEADER_SIZ + \ 9 + \ 7 + \ - AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \ + AUDIO_AC_DESCRIPTOR_LEN(2) + \ AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \ AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ - AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \ - AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \ + AUDIO_AS_DESCRIPTOR_LEN(1) + \ + AUDIO_AS_DESCRIPTOR_LEN(1) + \ 25) #define USBD_VID 0xffff @@ -103,7 +103,6 @@ #define HID_KEYBOARD_REPORT_DESC_SIZE 63 -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01) }; @@ -130,38 +129,7 @@ static const uint8_t config_descriptor[] = { EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), AUDIO_AS_DESCRIPTOR_INIT(0x04, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)), - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x05, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ + HID_KEYBOARD_DESCRIPTOR_INIT(0x05, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL), }; static const uint8_t device_quality_descriptor[] = { @@ -216,136 +184,6 @@ const struct usb_descriptor video_audio_hid_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t video_audio_hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x06, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00), - VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00), - VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01), - VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01), - /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */ - USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01), - AUDIO_AC_DESCRIPTOR_INIT(0x02, 0x03, AUDIO_AC_SIZ, 0x00, 0x03, 0x04), - AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02), - AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05), - AUDIO_AS_DESCRIPTOR_INIT(0x03, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, - EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), - AUDIO_AS_DESCRIPTOR_INIT(0x04, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, - EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)), - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x05, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'A', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '4', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ - '0', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) @@ -469,11 +307,11 @@ void usbd_audio_open(uint8_t busid, uint8_t intf) audio_rx_flag = 1; /* setup first out ep read transfer */ usbd_ep_start_read(busid, AUDIO_OUT_EP, audio_read_buffer, AUDIO_OUT_PACKET); - printf("OPEN1\r\n"); + USB_LOG_RAW("OPEN1\r\n"); } else if (intf == 4) { audio_tx_flag = 1; audio_iso_tx_busy = false; - printf("OPEN2\r\n"); + USB_LOG_RAW("OPEN2\r\n"); } } @@ -481,11 +319,11 @@ void usbd_audio_close(uint8_t busid, uint8_t intf) { if (intf == 3) { audio_rx_flag = 0; - printf("CLOSE1\r\n"); + USB_LOG_RAW("CLOSE1\r\n"); } else if (intf == 4) { audio_tx_flag = 0; audio_iso_tx_busy = false; - printf("CLOSE2\r\n"); + USB_LOG_RAW("CLOSE2\r\n"); } } @@ -541,11 +379,8 @@ struct audio_entity_info audio_entity_table[] = { void composite_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &video_audio_hid_descriptor); -#else - usbd_desc_register(busid, video_audio_hid_descriptor); -#endif + usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_endpoint(busid, &video_in_ep); 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 7337f5f7ede..a45566f6c4e 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_h264_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_h264_template.c @@ -48,7 +48,6 @@ #define USBD_MAX_POWER 100 #define USBD_LANGID_STRING 1033 -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01) }; @@ -118,94 +117,6 @@ const struct usb_descriptor video_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t video_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00), - VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00), - VIDEO_VS_FORMAT_H264_DESCRIPTOR_INIT(0x01, 0x01), - VIDEO_VS_FRAME_H264_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01), - /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */ - USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01), - - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'V', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ - '0', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif volatile bool tx_flag = 0; volatile bool iso_tx_busy = false; @@ -272,11 +183,8 @@ struct usbd_interface intf1; void video_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &video_descriptor); -#else - usbd_desc_register(busid, video_descriptor); -#endif + usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_endpoint(busid, &video_in_ep); 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 3fc923f8d81..0f1bcef6ef3 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c @@ -48,7 +48,6 @@ #define USBD_MAX_POWER 100 #define USBD_LANGID_STRING 1033 -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01) }; @@ -118,94 +117,6 @@ const struct usb_descriptor video_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t video_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00), - VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00), - VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01), - VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01), - /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */ - USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01), - - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'V', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ - '0', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif volatile bool tx_flag = 0; volatile bool iso_tx_busy = false; @@ -272,11 +183,8 @@ struct usbd_interface intf1; void video_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &video_descriptor); -#else - usbd_desc_register(busid, video_descriptor); -#endif + usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_endpoint(busid, &video_in_ep); 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 7c7d1789924..1d51d8dbbc8 100644 --- a/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c +++ b/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c @@ -49,7 +49,6 @@ #define USBD_MAX_POWER 100 #define USBD_LANGID_STRING 1033 -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01) }; @@ -121,95 +120,6 @@ const struct usb_descriptor video_descriptor = { .device_quality_descriptor_callback = device_quality_descriptor_callback, .string_descriptor_callback = string_descriptor_callback }; -#else -const uint8_t video_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - //VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00), - VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00), - VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, 0x01, VIDEO_GUID_YUY2), - VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)), - VIDEO_VS_COLOR_MATCHING_DESCRIPTOR_INIT(), - VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01), - /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */ - USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01), - - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'V', 0x00, /* wcChar11 */ - 'C', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ - '0', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif volatile bool tx_flag = 0; volatile bool iso_tx_busy = false; @@ -276,11 +186,8 @@ struct usbd_interface intf1; void video_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &video_descriptor); -#else - usbd_desc_register(busid, video_descriptor); -#endif + usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); usbd_add_endpoint(busid, &video_in_ep); diff --git a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c index 1019e0541c9..ffb2498b81f 100644 --- a/components/drivers/usb/cherryusb/demo/webusb_hid_template.c +++ b/components/drivers/usb/cherryusb/demo/webusb_hid_template.c @@ -6,76 +6,17 @@ #include "usbd_core.h" #include "usbd_hid.h" -#define USBD_VID 0xffff -#define USBD_PID 0xffff -#define USBD_MAX_POWER 100 -#define USBD_LANGID_STRING 1033 - -#define HID_INT_EP 0x81 -#define HID_INT_EP_SIZE 8 -#define HID_INT_EP_INTERVAL 10 - -#define USB_HID_CONFIG_DESC_SIZ (34 + 9) -#define HID_KEYBOARD_REPORT_DESC_SIZE 63 - -#define USBD_WEBUSB_VENDOR_CODE (0x22) -#define USBD_WINUSB_VENDOR_CODE (0x21) +#define WEBUSB_VENDOR_CODE (0x22) +#define WINUSB_VENDOR_CODE (0x21) -#define USBD_WINUSB_DESC_SET_LEN (0xB2) #define URL_DESCRIPTOR_LENGTH (3 + 36) -#define USBD_WEBUSB_INTF_NUM 0x01 +#define WEBUSB_INTF_NUM 0x01 #define WEBUSB_URL_STRINGS \ 'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', \ 'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '/', 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B', -const uint8_t USBD_WinUSBDescriptorSetDescriptor[USBD_WINUSB_DESC_SET_LEN] = { - // Microsoft OS 2.0 描述符集标头 - 0x0A, 0x00, // Descriptor size (10 bytes) - 0x00, 0x00, // MS OS 2.0 descriptor set header - 0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000) - USBD_WINUSB_DESC_SET_LEN, 0x00, // Size, MS OS 2.0 descriptor set - - // Microsoft OS 2.0 配置子集标头 - 0x08, 0x00, // wLength - 0x01, 0x00, // wDescriptorType - 0x00, // 适用于配置 1 - 0x00, // bReserved - 0XA8, 0X00, // Size, MS OS 2.0 configuration subset - - // Microsoft OS 2.0 功能子集头 - 0x08, 0x00, // Descriptor size (8 bytes) - 0x02, 0x00, // MS OS 2.0 function subset header - USBD_WEBUSB_INTF_NUM, // bFirstInterface - 0x00, // 必须设置为 0 - 0xA0, 0x00, - - // Microsoft OS 2.0 兼容 ID 描述符 - // 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容 - 0x14, 0x00, // wLength 20 - 0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - // Microsoft OS 2.0 注册表属性描述符 - // 注册表属性分配设备接口 GUID - 0x84, 0x00, //wLength: 132 - 0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9) - 0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15) - 0x2a, 0x00, //wPropertyNameLength: - //bPropertyName: “DeviceInterfaceGUID” - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, - 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, - 0x00, 0x00, - 0x50, 0x00, // wPropertyDataLength - //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”. - '{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00, - 'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00, - '9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00, - '8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 -}; - const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = { URL_DESCRIPTOR_LENGTH, WEBUSB_URL_TYPE, @@ -83,113 +24,54 @@ const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = { WEBUSB_URL_STRINGS }; -#define USBD_BOS_WTOTALLENGTH 0x39 - -#define LANDING_PAGE 0x01 -uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = { - // BOS描述符 - 0x05, // bLength 固长为5 - 0x0F, // bDescriptorType 固定为15 - USBD_BOS_WTOTALLENGTH, 0x00, // wTotalLength BOS描述符的总大小 - 0x02, // bNumDeviceCaps BOS描述符中独立设备功能特性描述符的数量 - - // WebUSB 平台功能描述符 - 0x18, // Descriptor size (24 bytes) - 0x10, // Descriptor type (Device Capability) 设备功能描述符 - 0x05, // Capability type (Platform) 平台描述符 - 0x00, // Reserved - - // WebUSB Platform Capability ID (3408b638-09a9-47a0-8bfd-a0768815b665) - // 平台功能 UUID 将此标识为WebUSB 平台功能描述符,它提供有关设备的基本信息 - 0x38, 0xB6, 0x08, 0x34, - 0xA9, 0x09, - 0xA0, 0x47, - 0x8B, 0xFD, - 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65, - - 0x00, 0x01, // WebUSB version 1.0 - USBD_WEBUSB_VENDOR_CODE, // Vendor-assigned WebUSB request code - LANDING_PAGE, // Landing page - - // Microsoft 平台功能描述符 - // 标头 - 0x1C, // Descriptor size (28 bytes) - 0x10, // Descriptor type (Device Capability) - 0x05, // Capability type (Platform) - 0x00, // Reserved - - 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */ - 0x89, 0x45, 0xC7, 0x4C, - 0x9C, 0xD2, 0x65, 0x9D, - 0x9E, 0x64, 0x8A, 0x9F, - - // 描述符集信息结构 - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 * dwWindowsVersion 最低兼容 Windows 版本 */ - - USBD_WINUSB_DESC_SET_LEN, 0X00, /* wDescriptorSetTotalLength */ - - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0X00 /* bAltEnumCode */ +const uint8_t WINUSB_WCIDDescriptor[] = { + USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN), + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(WEBUSB_INTF_NUM), +}; + +__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = { + USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_LEN + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 2), + USB_BOS_CAP_PLATFORM_WEBUSB_DESCRIPTOR_INIT(WEBUSB_VENDOR_CODE, 0x01), + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)), }; struct usb_webusb_descriptor webusb_url_desc = { - .vendor_code = USBD_WEBUSB_VENDOR_CODE, + .vendor_code = WEBUSB_VENDOR_CODE, .string = USBD_WebUSBURLDescriptor, .string_len = URL_DESCRIPTOR_LENGTH }; struct usb_msosv2_descriptor msosv2_desc = { - .vendor_code = USBD_WINUSB_VENDOR_CODE, - .compat_id = USBD_WinUSBDescriptorSetDescriptor, - .compat_id_len = USBD_WINUSB_DESC_SET_LEN, + .vendor_code = WINUSB_VENDOR_CODE, + .compat_id = WINUSB_WCIDDescriptor, + .compat_id_len = sizeof(WINUSB_WCIDDescriptor), }; struct usb_bos_descriptor bos_desc = { .string = USBD_BinaryObjectStoreDescriptor, - .string_len = USBD_BOS_WTOTALLENGTH + .string_len = sizeof(USBD_BinaryObjectStoreDescriptor) }; -#ifdef CONFIG_USBDEV_ADVANCE_DESC +#define USBD_VID 0xffff +#define USBD_PID 0xffff +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +#define HID_INT_EP 0x81 +#define HID_INT_EP_SIZE 8 +#define HID_INT_EP_INTERVAL 10 + +#define USB_CONFIG_SIZE (34 + 9) +#define HID_KEYBOARD_REPORT_DESC_SIZE 63 + static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01) }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00) + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + HID_KEYBOARD_DESCRIPTOR_INIT(0x00, 0x01, HID_KEYBOARD_REPORT_DESC_SIZE, HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL), + USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00) }; static const uint8_t device_quality_descriptor[] = { @@ -247,121 +129,6 @@ const struct usb_descriptor webusb_hid_descriptor = { .webusb_url_descriptor = &webusb_url_desc, .bos_descriptor = &bos_desc }; -#else -static const uint8_t webusb_hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x2C, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'W', 0x00, /* wcChar10 */ - 'E', 0x00, /* wcChar11 */ - 'B', 0x00, /* wcChar12 */ - 'U', 0x00, /* wcChar13 */ - 'S', 0x00, /* wcChar14 */ - 'B', 0x00, /* wcChar15 */ - ' ', 0x00, /* wcChar16 */ - 'D', 0x00, /* wcChar17 */ - 'E', 0x00, /* wcChar18 */ - 'M', 0x00, /* wcChar19 */ - 'O', 0x00, /* wcChar20 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif /* USB HID device Configuration Descriptor */ static uint8_t hid_desc[9] __ALIGN_END = { @@ -458,16 +225,8 @@ static struct usbd_interface intf0; void webusb_hid_keyboard_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &webusb_hid_descriptor); -#else - usbd_desc_register(busid, webusb_hid_descriptor); -#endif -#ifndef CONFIG_USBDEV_ADVANCE_DESC - usbd_bos_desc_register(busid, &bos_desc); - usbd_msosv2_desc_register(busid, &msosv2_desc); - usbd_webusb_desc_register(busid, &webusb_url_desc); -#endif + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE)); usbd_add_endpoint(busid, &hid_in_ep); @@ -480,7 +239,7 @@ void hid_keyboard_test(uint8_t busid) { const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 }; - if(usb_device_is_configured(busid) == false) { + if (usb_device_is_configured(busid) == false) { return; } diff --git a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c index c8fd406a25d..f203f2109e0 100644 --- a/components/drivers/usb/cherryusb/demo/winusb1.0_template.c +++ b/components/drivers/usb/cherryusb/demo/winusb1.0_template.c @@ -4,161 +4,106 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "usbd_core.h" -#include "usbd_cdc_acm.h" -#define WCID_VENDOR_CODE 0x17 +#define WINUSB_VENDOR_CODE 0x17 -#define DOUBLE_WINUSB 0 +#define WINUSB_NUM 1 -__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = { - /////////////////////////////////////// - /// MS OS string descriptor - /////////////////////////////////////// - 0x12, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - /* MSFT100 */ - 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */ - '1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */ - WCID_VENDOR_CODE, /* bVendorCode */ - 0x00, /* bReserved */ +const uint8_t WCID_StringDescriptor_MSOS[18] = { + USB_MSOSV1_STRING_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE) }; -#if DOUBLE_WINUSB == 0 -__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = { +const uint8_t WINUSB_WCIDDescriptor[] = { + USB_MSOSV1_COMP_ID_HEADER_DESCRIPTOR_INIT(WINUSB_NUM), + USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(0), +#if WINUSB_NUM == 2 + USB_MSOSV1_COMP_ID_FUNCTION_WINUSB_DESCRIPTOR_INIT(1), +#endif +}; + +const uint8_t WINUSB_IF0_WCIDProperties[142] = { /////////////////////////////////////// - /// WCID descriptor + /// WCID property descriptor /////////////////////////////////////// - 0x28, 0x00, 0x00, 0x00, /* dwLength */ - 0x00, 0x01, /* bcdVersion */ - 0x04, 0x00, /* wIndex */ - 0x01, /* bCount */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */ + 0x8e, 0x00, 0x00, 0x00, /* dwLength */ + 0x00, 0x01, /* bcdVersion */ + 0x05, 0x00, /* wIndex */ + 0x01, 0x00, /* wCount */ /////////////////////////////////////// - /// WCID function descriptor + /// registry propter descriptor /////////////////////////////////////// - 0x00, /* bFirstInterfaceNumber */ - 0x01, /* bReserved */ - /* WINUSB */ - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */ - /* */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */ + 0x84, 0x00, 0x00, 0x00, /* dwSize */ + 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */ + 0x28, 0x00, /* wPropertyNameLength */ + /* DeviceInterfaceGUID */ + 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */ + 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */ + 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */ + 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */ + 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */ + 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */ + /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */ + '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */ + 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */ + '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */ + '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */ + '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */ + 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */ + '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */ + 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */ + 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */ + '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */ }; -#else -__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[64] __ALIGN_END = { - /////////////////////////////////////// - /// WCID descriptor - /////////////////////////////////////// - 0x40, 0x00, 0x00, 0x00, /* dwLength */ - 0x00, 0x01, /* bcdVersion */ - 0x04, 0x00, /* wIndex */ - 0x02, /* bCount */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */ +#if WINUSB_NUM == 2 +#define WINUSB_IF1_WCID_PROPERTIES_SIZE (142) +const uint8_t WINUSB_IF1_WCIDProperties[142] = { /////////////////////////////////////// - /// WCID function descriptor + /// WCID property descriptor /////////////////////////////////////// - 0x00, /* bFirstInterfaceNumber */ - 0x01, /* bReserved */ - /* WINUSB */ - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */ - /* */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */ + 0x8e, 0x00, 0x00, 0x00, /* dwLength */ + 0x00, 0x01, /* bcdVersion */ + 0x05, 0x00, /* wIndex */ + 0x01, 0x00, /* wCount */ /////////////////////////////////////// - /// WCID function descriptor + /// registry propter descriptor /////////////////////////////////////// - 0x01, /* bFirstInterfaceNumber */ - 0x01, /* bReserved */ - /* WINUSB */ - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */ - /* */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */ + 0x84, 0x00, 0x00, 0x00, /* dwSize */ + 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */ + 0x28, 0x00, /* wPropertyNameLength */ + /* DeviceInterfaceGUID */ + 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */ + 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */ + 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */ + 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */ + 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */ + 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */ + /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */ + '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */ + 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */ + '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */ + '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */ + '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */ + 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */ + '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */ + 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */ + 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */ + '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */ }; #endif -__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties [142] __ALIGN_END = { - /////////////////////////////////////// - /// WCID property descriptor - /////////////////////////////////////// - 0x8e, 0x00, 0x00, 0x00, /* dwLength */ - 0x00, 0x01, /* bcdVersion */ - 0x05, 0x00, /* wIndex */ - 0x01, 0x00, /* wCount */ - - /////////////////////////////////////// - /// registry propter descriptor - /////////////////////////////////////// - 0x84, 0x00, 0x00, 0x00, /* dwSize */ - 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */ - 0x28, 0x00, /* wPropertyNameLength */ - /* DeviceInterfaceGUID */ - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */ - 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */ - 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */ - 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */ - 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */ - 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */ - /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */ - '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */ - 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */ - '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */ - '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */ - '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */ - 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */ - '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */ - 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */ - 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */ - '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */ -}; -#define WINUSB_IF1_WCID_PROPERTIES_SIZE (142) -__ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = { - /////////////////////////////////////// - /// WCID property descriptor - /////////////////////////////////////// - 0x8e, 0x00, 0x00, 0x00, /* dwLength */ - 0x00, 0x01, /* bcdVersion */ - 0x05, 0x00, /* wIndex */ - 0x01, 0x00, /* wCount */ - - /////////////////////////////////////// - /// registry propter descriptor - /////////////////////////////////////// - 0x84, 0x00, 0x00, 0x00, /* dwSize */ - 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */ - 0x28, 0x00, /* wPropertyNameLength */ - /* DeviceInterfaceGUID */ - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */ - 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */ - 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */ - 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */ - 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */ - 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */ - /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */ - '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */ - 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */ - '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */ - '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */ - '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */ - 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */ - '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */ - 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */ - 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */ - '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */ -}; const uint8_t *WINUSB_IFx_WCIDProperties[] = { WINUSB_IF0_WCIDProperties, -#if DOUBLE_WINUSB == 1 +#if WINUSB_NUM == 2 WINUSB_IF1_WCIDProperties, #endif }; struct usb_msosv1_descriptor msosv1_desc = { .string = WCID_StringDescriptor_MSOS, - .vendor_code = WCID_VENDOR_CODE, + .vendor_code = WINUSB_VENDOR_CODE, .compat_id = WINUSB_WCIDDescriptor, .comp_id_property = WINUSB_IFx_WCIDProperties, }; @@ -166,20 +111,20 @@ struct usb_msosv1_descriptor msosv1_desc = { #define WINUSB_IN_EP 0x81 #define WINUSB_OUT_EP 0x02 -#define USBD_VID 0xefff +#define USBD_VID 0xFFFE #define USBD_PID 0xffff #define USBD_MAX_POWER 100 #define USBD_LANGID_STRING 1033 -#if DOUBLE_WINUSB == 0 +#if WINUSB_NUM == 1 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7) -#define INTF_NUM 1 +#define INTF_NUM 1 #else #define WINUSB_IN_EP2 0x83 #define WINUSB_OUT_EP2 0x04 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 7 + 7) -#define INTF_NUM 2 +#define INTF_NUM 2 #endif #ifdef CONFIG_USB_HS @@ -188,7 +133,6 @@ struct usb_msosv1_descriptor msosv1_desc = { #define WINUSB_EP_MPS 64 #endif -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01) }; @@ -198,7 +142,7 @@ static const uint8_t config_descriptor[] = { USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04), USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00), USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00), -#if DOUBLE_WINUSB == 1 +#if WINUSB_NUM == 2 USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05), USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00), USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00), @@ -253,158 +197,13 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index) return string_descriptors[index]; } -const struct usb_descriptor winusb_descriptor = { +const struct usb_descriptor winusbv1_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, .msosv1_descriptor = &msosv1_desc }; -#else -const uint8_t winusb_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04), - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00), - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00), -#if DOUBLE_WINUSB == 1 - USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05), - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00), - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00), -#endif - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x2C, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'W', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'N', 0x00, /* wcChar12 */ - 'U', 0x00, /* wcChar13 */ - 'S', 0x00, /* wcChar14 */ - 'B', 0x00, /* wcChar15 */ - ' ', 0x00, /* wcChar16 */ - 'D', 0x00, /* wcChar17 */ - 'E', 0x00, /* wcChar18 */ - 'M', 0x00, /* wcChar19 */ - 'O', 0x00, /* wcChar20 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '1', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ - /////////////////////////////////////// - /// string4 descriptor - /////////////////////////////////////// - 0x30, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'W', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'N', 0x00, /* wcChar12 */ - 'U', 0x00, /* wcChar13 */ - 'S', 0x00, /* wcChar14 */ - 'B', 0x00, /* wcChar15 */ - ' ', 0x00, /* wcChar16 */ - 'D', 0x00, /* wcChar17 */ - 'E', 0x00, /* wcChar18 */ - 'M', 0x00, /* wcChar19 */ - 'O', 0x00, /* wcChar20 */ - ' ', 0x00, /* wcChar16 */ - '1', 0x00, /* wcChar21 */ - /////////////////////////////////////// - /// string5 descriptor - /////////////////////////////////////// - 0x30, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'W', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'N', 0x00, /* wcChar12 */ - 'U', 0x00, /* wcChar13 */ - 'S', 0x00, /* wcChar14 */ - 'B', 0x00, /* wcChar15 */ - ' ', 0x00, /* wcChar16 */ - 'D', 0x00, /* wcChar17 */ - 'E', 0x00, /* wcChar18 */ - 'M', 0x00, /* wcChar19 */ - 'O', 0x00, /* wcChar20 */ - ' ', 0x00, /* wcChar16 */ - '2', 0x00, /* wcChar21 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; -#endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; @@ -428,7 +227,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event) ep_tx_busy_flag = false; /* setup first out ep read transfer */ usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048); -#if DOUBLE_WINUSB == 1 +#if WINUSB_NUM == 2 usbd_ep_start_read(busid, WINUSB_OUT_EP2, read_buffer, 2048); #endif break; @@ -478,7 +277,7 @@ struct usbd_endpoint winusb_in_ep1 = { struct usbd_interface intf0; -#if DOUBLE_WINUSB == 1 +#if WINUSB_NUM == 2 void usbd_winusb_out2(uint8_t busid, uint8_t ep, uint32_t nbytes) { @@ -518,20 +317,14 @@ struct usbd_interface intf1; #endif -void winusb_init(uint8_t busid, uintptr_t reg_base) +void winusbv1_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC - usbd_desc_register(busid, &winusb_descriptor); -#else - usbd_desc_register(busid, winusb_descriptor); -#endif -#ifndef CONFIG_USBDEV_ADVANCE_DESC - usbd_msosv1_desc_register(busid, &msosv1_desc); -#endif + usbd_desc_register(busid, &winusbv1_descriptor); + usbd_add_interface(busid, &intf0); usbd_add_endpoint(busid, &winusb_out_ep1); usbd_add_endpoint(busid, &winusb_in_ep1); -#if DOUBLE_WINUSB == 1 +#if WINUSB_NUM == 2 usbd_add_interface(busid, &intf1); usbd_add_endpoint(busid, &winusb_out_ep2); usbd_add_endpoint(busid, &winusb_in_ep2); 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 3ccafe324d9..13d6eb07da6 100644 --- a/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c +++ b/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c @@ -6,6 +6,29 @@ #include "usbd_core.h" #include "usbd_cdc_acm.h" +#define WINUSB_VENDOR_CODE 0x17 + +const uint8_t WINUSB_WCIDDescriptor[] = { + USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN), + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(0x00), +}; + +__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = { + USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 1), + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)), +}; + +const struct usb_msosv2_descriptor msosv2_desc = { + .vendor_code = WINUSB_VENDOR_CODE, + .compat_id = WINUSB_WCIDDescriptor, + .compat_id_len = sizeof(WINUSB_WCIDDescriptor), +}; + +const struct usb_bos_descriptor bos_desc = { + .string = USBD_BinaryObjectStoreDescriptor, + .string_len = sizeof(USBD_BinaryObjectStoreDescriptor), +}; + #define WINUSB_IN_EP 0x81 #define WINUSB_OUT_EP 0x02 @@ -27,136 +50,6 @@ #define WINUSB_EP_MPS 64 #endif -#define USBD_WINUSB_VENDOR_CODE 0x20 - -#define USBD_WEBUSB_ENABLE 0 -#define USBD_BULK_ENABLE 1 -#define USBD_WINUSB_ENABLE 1 - -/* WinUSB Microsoft OS 2.0 descriptor sizes */ -#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10 -#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8 -#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20 - -#define FUNCTION_SUBSET_LEN 160 -#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132 - -#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN) - -__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = { - WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */ - WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */ - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ - WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ -#if (USBD_WEBUSB_ENABLE) - WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength - WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType - 0, // bFirstInterface USBD_WINUSB_IF_NUM - 0, // bReserved - WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType - 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId - 0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId - WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength - WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType - WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType - WBVAL(42), // wPropertyNameLength - 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, - 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, - 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, - WBVAL(80), // wPropertyDataLength - '{', 0, - '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0, - '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0, - '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0, - '9', 0, '3', 0, '3', 0, 'B', 0, '-', - 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0, - '}', 0, 0, 0, 0, 0 -#endif -#if USBD_BULK_ENABLE - WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */ - WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */ - 0, /* bFirstInterface USBD_BULK_IF_NUM*/ - 0, /* bReserved */ - WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */ - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ - 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ - 0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ - WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */ - WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ - WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */ - WBVAL(42), /* wPropertyNameLength */ - 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, - 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, - 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, - WBVAL(80), /* wPropertyDataLength */ - '{', 0, - 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, - '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, - '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, - 'A', 0, 'A', 0, '3', 0, '6', 0, '-', - 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, - '}', 0, 0, 0, 0, 0 -#endif -}; - -#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE) - -#define USBD_WEBUSB_DESC_LEN 24 -#define USBD_WINUSB_DESC_LEN 28 - -#define USBD_BOS_WTOTALLENGTH (0x05 + \ - USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \ - USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE) - -__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = { - 0x05, /* bLength */ - 0x0f, /* bDescriptorType */ - WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */ - USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */ -#if (USBD_WEBUSB_ENABLE) - USBD_WEBUSB_DESC_LEN, /* bLength */ - 0x10, /* bDescriptorType */ - USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ - 0x00, /* bReserved */ - 0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */ - 0xA9, 0x09, 0xA0, 0x47, - 0x8B, 0xFD, 0xA0, 0x76, - 0x88, 0x15, 0xB6, 0x65, - WBVAL(0x0100), /* 1.00 */ /* bcdVersion */ - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0, /* iLandingPage */ -#endif -#if (USBD_WINUSB_ENABLE) - USBD_WINUSB_DESC_LEN, /* bLength */ - 0x10, /* bDescriptorType */ - USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ - 0x00, /* bReserved */ - 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */ - 0x89, 0x45, 0xC7, 0x4C, - 0x9C, 0xD2, 0x65, 0x9D, - 0x9E, 0x64, 0x8A, 0x9F, - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ - WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0, /* bAltEnumCode */ -#endif -}; - -struct usb_msosv2_descriptor msosv2_desc = { - .vendor_code = USBD_WINUSB_VENDOR_CODE, - .compat_id = USBD_WinUSBDescriptorSetDescriptor, - .compat_id_len = USBD_WINUSB_DESC_SET_LEN, -}; - -struct usb_bos_descriptor bos_desc = { - .string = USBD_BinaryObjectStoreDescriptor, - .string_len = USBD_BOS_WTOTALLENGTH -}; - -#ifdef CONFIG_USBDEV_ADVANCE_DESC static const uint8_t device_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) }; @@ -219,7 +112,7 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index) return string_descriptors[index]; } -const struct usb_descriptor winusbv2_descriptor = { +const struct usb_descriptor winusbv2_cdc_descriptor = { .device_descriptor_callback = device_descriptor_callback, .config_descriptor_callback = config_descriptor_callback, .device_quality_descriptor_callback = device_quality_descriptor_callback, @@ -227,90 +120,6 @@ const struct usb_descriptor winusbv2_descriptor = { .msosv2_descriptor = &msosv2_desc, .bos_descriptor = &bos_desc }; -#else -const uint8_t winusbv2_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - /* Configuration 0 */ - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - /* Interface 0 */ - USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), - /* Endpoint OUT 2 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - /* Endpoint IN 1 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, WINUSB_EP_MPS, 0x00), - /* String 0 (LANGID) */ - USB_LANGID_INIT(USBD_LANGID_STRING), - /* String 1 (Manufacturer) */ - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x2C, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'W', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'N', 0x00, /* wcChar12 */ - 'U', 0x00, /* wcChar13 */ - 'S', 0x00, /* wcChar14 */ - 'B', 0x00, /* wcChar15 */ - ' ', 0x00, /* wcChar16 */ - 'D', 0x00, /* wcChar17 */ - 'E', 0x00, /* wcChar18 */ - 'M', 0x00, /* wcChar19 */ - 'O', 0x00, /* wcChar20 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /* Device Qualifier */ - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x10, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - /* End */ - 0x00 -}; -#endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; @@ -418,17 +227,10 @@ struct usbd_interface winusb_intf; struct usbd_interface intf1; struct usbd_interface intf2; -void winusbv2_init(uint8_t busid, uintptr_t reg_base) +void winusbv2_cdc_init(uint8_t busid, uintptr_t reg_base) { -#ifdef CONFIG_USBDEV_ADVANCE_DESC - usbd_desc_register(busid, &winusbv2_descriptor); -#else - usbd_desc_register(busid, winusbv2_descriptor); -#endif -#ifndef CONFIG_USBDEV_ADVANCE_DESC - usbd_bos_desc_register(busid, &bos_desc); - usbd_msosv2_desc_register(busid, &msosv2_desc); -#endif + usbd_desc_register(busid, &winusbv2_cdc_descriptor); + /*!< winusb */ usbd_add_interface(busid, &winusb_intf); usbd_add_endpoint(busid, &winusb_out_ep1); diff --git a/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c b/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c deleted file mode 100644 index d0c1774afa9..00000000000 --- a/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_hid.h" - -#define WINUSB_IN_EP 0x81 -#define WINUSB_OUT_EP 0x02 - -/*!< endpoint address */ -#define HID_INT_EP 0x83 -#define HID_INT_EP_SIZE 4 -#define HID_INT_EP_INTERVAL 10 - -#define USBD_VID 0xFFFE -#define USBD_PID 0xFFFF -#define USBD_MAX_POWER 500 -#define USBD_LANGID_STRING 1033 - -#define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 9 + 7) -#define INTF_NUM 2 - -/*!< config descriptor size */ -#define USB_HID_CONFIG_DESC_SIZ 34 -/*!< report descriptor size */ -#define HID_MOUSE_REPORT_DESC_SIZE 74 - -#ifdef CONFIG_USB_HS -#define WINUSB_EP_MPS 512 -#else -#define WINUSB_EP_MPS 64 -#endif - -#define USBD_WINUSB_VENDOR_CODE 0x20 - -#define USBD_WEBUSB_ENABLE 0 -#define USBD_BULK_ENABLE 1 -#define USBD_WINUSB_ENABLE 1 - -/* WinUSB Microsoft OS 2.0 descriptor sizes */ -#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10 -#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8 -#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20 - -#define FUNCTION_SUBSET_LEN 160 -#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132 - -#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN) - -__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = { - WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */ - WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */ - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ - WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ -#if (USBD_WEBUSB_ENABLE) - WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength - WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType - 0, // bFirstInterface USBD_WINUSB_IF_NUM - 0, // bReserved - WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType - 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId - 0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId - WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength - WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType - WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType - WBVAL(42), // wPropertyNameLength - 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, - 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, - 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, - WBVAL(80), // wPropertyDataLength - '{', 0, - '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0, - '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0, - '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0, - '9', 0, '3', 0, '3', 0, 'B', 0, '-', - 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0, - '}', 0, 0, 0, 0, 0 -#endif -#if USBD_BULK_ENABLE - WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */ - WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */ - 0, /* bFirstInterface USBD_BULK_IF_NUM*/ - 0, /* bReserved */ - WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */ - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ - 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ - 0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ - WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */ - WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ - WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */ - WBVAL(42), /* wPropertyNameLength */ - 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, - 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, - 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, - WBVAL(80), /* wPropertyDataLength */ - '{', 0, - 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, - '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, - '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, - 'A', 0, 'A', 0, '3', 0, '6', 0, '-', - 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, - '}', 0, 0, 0, 0, 0 -#endif -}; - -#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE) - -#define USBD_WEBUSB_DESC_LEN 24 -#define USBD_WINUSB_DESC_LEN 28 - -#define USBD_BOS_WTOTALLENGTH (0x05 + \ - USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \ - USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE) - -__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = { - 0x05, /* bLength */ - 0x0f, /* bDescriptorType */ - WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */ - USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */ -#if (USBD_WEBUSB_ENABLE) - USBD_WEBUSB_DESC_LEN, /* bLength */ - 0x10, /* bDescriptorType */ - USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ - 0x00, /* bReserved */ - 0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */ - 0xA9, 0x09, 0xA0, 0x47, - 0x8B, 0xFD, 0xA0, 0x76, - 0x88, 0x15, 0xB6, 0x65, - WBVAL(0x0100), /* 1.00 */ /* bcdVersion */ - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0, /* iLandingPage */ -#endif -#if (USBD_WINUSB_ENABLE) - USBD_WINUSB_DESC_LEN, /* bLength */ - 0x10, /* bDescriptorType */ - USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ - 0x00, /* bReserved */ - 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */ - 0x89, 0x45, 0xC7, 0x4C, - 0x9C, 0xD2, 0x65, 0x9D, - 0x9E, 0x64, 0x8A, 0x9F, - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ - WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0, /* bAltEnumCode */ -#endif -}; - -struct usb_msosv2_descriptor msosv2_desc = { - .vendor_code = USBD_WINUSB_VENDOR_CODE, - .compat_id = USBD_WinUSBDescriptorSetDescriptor, - .compat_id_len = USBD_WINUSB_DESC_SET_LEN, -}; - -struct usb_bos_descriptor bos_desc = { - .string = USBD_BinaryObjectStoreDescriptor, - .string_len = USBD_BOS_WTOTALLENGTH -}; - -#ifdef CONFIG_USBDEV_ADVANCE_DESC -static const uint8_t device_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01) -}; - -static const uint8_t config_descriptor[] = { - /* Configuration 0 */ - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - /* Interface 0 */ - USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), - /* Endpoint OUT 2 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - /* Endpoint IN 1 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ -}; - -static const uint8_t device_quality_descriptor[] = { - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x10, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -}; - -static const char *string_descriptors[] = { - (const char[]){ 0x09, 0x04 }, /* Langid */ - "CherryUSB", /* Manufacturer */ - "CherryUSB WINUSB DEMO", /* 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 > 3) { - return NULL; - } - return string_descriptors[index]; -} - -const struct usb_descriptor winusbv2_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, - .msosv2_descriptor = &msosv2_desc, - .bos_descriptor = &bos_desc -}; -#else -const uint8_t winusbv2_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - /* Configuration 0 */ - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - /* Interface 0 */ - USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), - /* Endpoint OUT 2 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - /* Endpoint IN 1 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* String 0 (LANGID) */ - USB_LANGID_INIT(USBD_LANGID_STRING), - /* String 1 (Manufacturer) */ - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x2C, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'W', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'N', 0x00, /* wcChar12 */ - 'U', 0x00, /* wcChar13 */ - 'S', 0x00, /* wcChar14 */ - 'B', 0x00, /* wcChar15 */ - ' ', 0x00, /* wcChar16 */ - 'D', 0x00, /* wcChar17 */ - 'E', 0x00, /* wcChar18 */ - 'M', 0x00, /* wcChar19 */ - 'O', 0x00, /* wcChar20 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /* Device Qualifier */ - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x10, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - /* End */ - 0x00 -}; -#endif - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; - -volatile bool ep_tx_busy_flag = false; - -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: - ep_tx_busy_flag = false; - /* setup first out ep read transfer */ - usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048); - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; - } -} - -void usbd_winusb_out(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes); - // for (int i = 0; i < 100; i++) { - // printf("%02x ", read_buffer[i]); - // } - // printf("\r\n"); - usbd_ep_start_write(busid, WINUSB_IN_EP, read_buffer, nbytes); - /* setup next out ep read transfer */ - usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048); -} - -void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes); - - if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { - /* send zlp */ - usbd_ep_start_write(busid, WINUSB_IN_EP, NULL, 0); - } else { - ep_tx_busy_flag = false; - } -} - -struct usbd_endpoint winusb_out_ep1 = { - .ep_addr = WINUSB_OUT_EP, - .ep_cb = usbd_winusb_out -}; - -struct usbd_endpoint winusb_in_ep1 = { - .ep_addr = WINUSB_IN_EP, - .ep_cb = usbd_winusb_in -}; - -/*!< hid mouse report descriptor */ -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 -}; - -/*!< mouse report struct */ -struct hid_mouse { - uint8_t buttons; - int8_t x; - int8_t y; - int8_t wheel; -}; - -/*!< mouse report */ -static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg; - -#define HID_STATE_IDLE 0 -#define HID_STATE_BUSY 1 - -/*!< hid state ! Data can be sent only when state is idle */ -static volatile uint8_t hid_state = HID_STATE_IDLE; - -/* function ------------------------------------------------------------------*/ -static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - hid_state = HID_STATE_IDLE; -} - -/*!< endpoint call back */ -static struct usbd_endpoint hid_in_ep = { - .ep_cb = usbd_hid_int_callback, - .ep_addr = HID_INT_EP -}; - -struct usbd_interface winusb_intf; -struct usbd_interface intf1; - -void winusbv2_init(uint8_t busid, uintptr_t reg_base) -{ -#ifdef CONFIG_USBDEV_ADVANCE_DESC - usbd_desc_register(busid, &winusbv2_descriptor); -#else - usbd_desc_register(busid, winusbv2_descriptor); -#endif -#ifndef CONFIG_USBDEV_ADVANCE_DESC - usbd_bos_desc_register(busid, &bos_desc); - usbd_msosv2_desc_register(busid, &msosv2_desc); -#endif - /*!< winusb */ - usbd_add_interface(busid, &winusb_intf); - usbd_add_endpoint(busid, &winusb_out_ep1); - usbd_add_endpoint(busid, &winusb_in_ep1); - - usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf1, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE)); - usbd_add_endpoint(busid, &hid_in_ep); - - usbd_initialize(busid, reg_base, usbd_event_handler); -} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/demo/winusb2.0_template.c b/components/drivers/usb/cherryusb/demo/winusb2.0_template.c new file mode 100644 index 00000000000..0530d0d1ec7 --- /dev/null +++ b/components/drivers/usb/cherryusb/demo/winusb2.0_template.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" + +#define WINUSB_VENDOR_CODE 0x17 + +#define WINUSB_NUM 1 + +// note that if device is composite device, you should use USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT +const uint8_t WINUSB_WCIDDescriptor[] = { +#if WINUSB_NUM == 1 + USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_LEN), + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_SINGLE_DESCRIPTOR_INIT(), +#else + USB_MSOSV2_COMP_ID_SET_HEADER_DESCRIPTOR_INIT(10 + WINUSB_NUM * USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_LEN), + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(0x00), + USB_MSOSV2_COMP_ID_FUNCTION_WINUSB_MULTI_DESCRIPTOR_INIT(0x01), +#endif +}; + +const uint8_t USBD_BinaryObjectStoreDescriptor[] = { + USB_BOS_HEADER_DESCRIPTOR_INIT(5 + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_LEN, 1), + USB_BOS_CAP_PLATFORM_WINUSB_DESCRIPTOR_INIT(WINUSB_VENDOR_CODE, sizeof(WINUSB_WCIDDescriptor)), +}; + +const struct usb_msosv2_descriptor msosv2_desc = { + .vendor_code = WINUSB_VENDOR_CODE, + .compat_id = WINUSB_WCIDDescriptor, + .compat_id_len = sizeof(WINUSB_WCIDDescriptor), +}; + +const struct usb_bos_descriptor bos_desc = { + .string = USBD_BinaryObjectStoreDescriptor, + .string_len = sizeof(USBD_BinaryObjectStoreDescriptor), +}; + +#define WINUSB_IN_EP 0x81 +#define WINUSB_OUT_EP 0x02 + +#define USBD_VID 0xFFFE +#define USBD_PID 0xffff +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +#if WINUSB_NUM == 1 +#define USB_CONFIG_SIZE (9 + 9 + 7 + 7) +#define INTF_NUM 1 +#else +#define WINUSB_IN_EP2 0x83 +#define WINUSB_OUT_EP2 0x04 + +#define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 7 + 7) +#define INTF_NUM 2 +#endif + +#ifdef CONFIG_USB_HS +#define WINUSB_EP_MPS 512 +#else +#define WINUSB_EP_MPS 64 +#endif + +static const uint8_t device_descriptor[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01) +}; + +static const uint8_t config_descriptor[] = { + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04), + USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00), + USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00), +#if WINUSB_NUM == 2 + USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05), + USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00), + USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00), +#endif +}; + +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 WINUSB DEMO", /* Product */ + "2022123456", /* Serial Number */ + "CherryUSB WINUSB DEMO 1", /* STRING4 */ + "CherryUSB WINUSB DEMO 2", /* STRING5 */ +}; + +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 > 5) { + return NULL; + } + return string_descriptors[index]; +} + +const struct usb_descriptor winusbv2_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, + .msosv2_descriptor = &msosv2_desc, + .bos_descriptor = &bos_desc, +}; + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; + +volatile bool ep_tx_busy_flag = false; + +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: + ep_tx_busy_flag = false; + /* setup first out ep read transfer */ + usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048); +#if WINUSB_NUM == 2 + usbd_ep_start_read(busid, WINUSB_OUT_EP2, read_buffer, 2048); +#endif + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +void usbd_winusb_out(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes); + // for (int i = 0; i < 100; i++) { + // printf("%02x ", read_buffer[i]); + // } + // printf("\r\n"); + usbd_ep_start_write(busid, WINUSB_IN_EP, read_buffer, nbytes); + /* setup next out ep read transfer */ + usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048); +} + +void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes); + + if ((nbytes % WINUSB_EP_MPS) == 0 && nbytes) { + /* send zlp */ + usbd_ep_start_write(busid, WINUSB_IN_EP, NULL, 0); + } else { + ep_tx_busy_flag = false; + } +} + +struct usbd_endpoint winusb_out_ep1 = { + .ep_addr = WINUSB_OUT_EP, + .ep_cb = usbd_winusb_out +}; + +struct usbd_endpoint winusb_in_ep1 = { + .ep_addr = WINUSB_IN_EP, + .ep_cb = usbd_winusb_in +}; + +struct usbd_interface intf0; + +#if WINUSB_NUM == 2 + +void usbd_winusb_out2(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes); + // for (int i = 0; i < 100; i++) { + // printf("%02x ", read_buffer[i]); + // } + // printf("\r\n"); + usbd_ep_start_write(busid, WINUSB_IN_EP2, read_buffer, nbytes); + /* setup next out ep read transfer */ + usbd_ep_start_read(busid, WINUSB_OUT_EP2, read_buffer, 2048); +} + +void usbd_winusb_in2(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes); + + if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { + /* send zlp */ + usbd_ep_start_write(busid, WINUSB_IN_EP2, NULL, 0); + } else { + ep_tx_busy_flag = false; + } +} + +struct usbd_endpoint winusb_out_ep2 = { + .ep_addr = WINUSB_OUT_EP2, + .ep_cb = usbd_winusb_out2 +}; + +struct usbd_endpoint winusb_in_ep2 = { + .ep_addr = WINUSB_IN_EP2, + .ep_cb = usbd_winusb_in2 +}; + +struct usbd_interface intf1; + +#endif + +void winusbv2_init(uint8_t busid, uintptr_t reg_base) +{ + usbd_desc_register(busid, &winusbv2_descriptor); + + usbd_add_interface(busid, &intf0); + usbd_add_endpoint(busid, &winusb_out_ep1); + usbd_add_endpoint(busid, &winusb_in_ep1); +#if WINUSB_NUM == 2 + usbd_add_interface(busid, &intf1); + usbd_add_endpoint(busid, &winusb_out_ep2); + usbd_add_endpoint(busid, &winusb_in_ep2); +#endif + usbd_initialize(busid, reg_base, usbd_event_handler); +} \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/idf_component.yml b/components/drivers/usb/cherryusb/idf_component.yml index 9cfebea7290..bcae2d659f5 100644 --- a/components/drivers/usb/cherryusb/idf_component.yml +++ b/components/drivers/usb/cherryusb/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.5.2" +version: "1.6.0" 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/platform/daplink/dap_main.c b/components/drivers/usb/cherryusb/platform/daplink/dap_main.c index f977cffd3d1..27e0355b16e 100644 --- a/components/drivers/usb/cherryusb/platform/daplink/dap_main.c +++ b/components/drivers/usb/cherryusb/platform/daplink/dap_main.c @@ -5,175 +5,313 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "dap_main.h" -#include "DAP_config.h" -#include "DAP.h" -#define USB_CONFIG_SIZE (9 + CMSIS_DAP_INTERFACE_SIZE + CDC_ACM_DESCRIPTOR_LEN + CONFIG_MSC_DESCRIPTOR_LEN) -#define INTF_NUM (2 + 1 + CONFIG_MSC_INTF_NUM) +#define CMSIS_DAP_INTERFACE_SIZE (9 + 7 + 7) +#define CUSTOM_HID_LEN (9 + 9 + 7 + 7) + +#define HIDRAW_INTERVAL 4 + +#define HID_CUSTOM_REPORT_DESC_SIZE 53 + +#define USBD_WINUSB_VENDOR_CODE 0x20 +#define USBD_WEBUSB_VENDOR_CODE 0x21 + +#define USBD_WEBUSB_ENABLE 1 +#define USBD_BULK_ENABLE 1 +#define USBD_WINUSB_ENABLE 1 + +/* WinUSB Microsoft OS 2.0 descriptor sizes */ +#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10 +#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8 +#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20 + +#define FUNCTION_SUBSET_LEN 160 +#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132 + +#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN) + +#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE) + +#define USBD_WEBUSB_DESC_LEN 24 +#define USBD_WINUSB_DESC_LEN 28 + +#define USBD_BOS_WTOTALLENGTH (0x05 + \ + USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \ + USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE) + +#define USB_CONFIG_SIZE (9 + CMSIS_DAP_INTERFACE_SIZE + CDC_ACM_DESCRIPTOR_LEN + \ + CONFIG_CHERRYDAP_USE_CUSTOM_HID * CUSTOM_HID_LEN + \ + CONFIG_CHERRYDAP_USE_MSC * MSC_DESCRIPTOR_LEN + USBD_WEBUSB_ENABLE * 9) + +#define INTF_NUM (1 + 2 + CONFIG_CHERRYDAP_USE_CUSTOM_HID + CONFIG_CHERRYDAP_USE_MSC + USBD_WEBUSB_ENABLE) + +#define MSC_INTF_NUM (3 + CONFIG_CHERRYDAP_USE_CUSTOM_HID) + +#define WEBUSB_INTF_NUM (3 + CONFIG_CHERRYDAP_USE_CUSTOM_HID + CONFIG_CHERRYDAP_USE_MSC) + +#define WEBUSB_URL_STRINGS \ + 'c', 'h', 'e', 'r', 'r', 'y', 'd', 'a', 'p', '.', 'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '.', 'o', 'r', 'g', __ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = { - WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */ - WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */ - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ - WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ + WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */ + WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */ + 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ + WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ #if (USBD_WEBUSB_ENABLE) - WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength - WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType - 0, // bFirstInterface USBD_WINUSB_IF_NUM - 0, // bReserved - WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType - 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId - 0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId - WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength - WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType - WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType - WBVAL(42), // wPropertyNameLength - 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, - 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, - 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, - WBVAL(80), // wPropertyDataLength - '{', 0, - '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0, - '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0, - '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0, - '9', 0, '3', 0, '3', 0, 'B', 0, '-', - 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0, - '}', 0, 0, 0, 0, 0 + WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength + WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType + WEBUSB_INTF_NUM, // bFirstInterface USBD_WINUSB_IF_NUM + 0, // bReserved + WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType + 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId + 0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId + WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength + WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType + WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType + WBVAL(42), // wPropertyNameLength + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, + 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, + WBVAL(80), // wPropertyDataLength + '{', 0, + '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0, + '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0, + '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0, + '9', 0, '3', 0, '3', 0, 'B', 0, '-', + 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0, + '}', 0, 0, 0, 0, 0, #endif #if USBD_BULK_ENABLE - WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */ - WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */ - 0, /* bFirstInterface USBD_BULK_IF_NUM*/ - 0, /* bReserved */ - WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */ - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ - WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ - 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ - 0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ - WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */ - WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ - WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */ - WBVAL(42), /* wPropertyNameLength */ - 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, - 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, - 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, - WBVAL(80), /* wPropertyDataLength */ - '{', 0, - 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, - '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, - '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, - 'A', 0, 'A', 0, '3', 0, '6', 0, '-', - 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, - '}', 0, 0, 0, 0, 0 + WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */ + WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */ + 0, /* bFirstInterface USBD_BULK_IF_NUM*/ + 0, /* bReserved */ + WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */ + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */ + WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */ + 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/ + 0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/ + WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */ + WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */ + WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */ + WBVAL(42), /* wPropertyNameLength */ + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, + 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0, + WBVAL(80), /* wPropertyDataLength */ + '{', 0, + 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0, + '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0, + '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, + 'A', 0, 'A', 0, '3', 0, '6', 0, '-', + 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0, + '}', 0, 0, 0, 0, 0 #endif }; __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = { - 0x05, /* bLength */ - 0x0f, /* bDescriptorType */ - WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */ - USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */ + 0x05, /* bLength */ + 0x0f, /* bDescriptorType */ + WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */ + USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */ #if (USBD_WEBUSB_ENABLE) - USBD_WEBUSB_DESC_LEN, /* bLength */ - 0x10, /* bDescriptorType */ - USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ - 0x00, /* bReserved */ - 0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */ - 0xA9, 0x09, 0xA0, 0x47, - 0x8B, 0xFD, 0xA0, 0x76, - 0x88, 0x15, 0xB6, 0x65, - WBVAL(0x0100), /* 1.00 */ /* bcdVersion */ - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0, /* iLandingPage */ + USBD_WEBUSB_DESC_LEN, /* bLength */ + 0x10, /* bDescriptorType */ + USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ + 0x00, /* bReserved */ + 0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */ + 0xA9, 0x09, 0xA0, 0x47, + 0x8B, 0xFD, 0xA0, 0x76, + 0x88, 0x15, 0xB6, 0x65, + WBVAL(0x0100), /* 1.00 */ /* bcdVersion */ + USBD_WEBUSB_VENDOR_CODE, /* bVendorCode */ + 1, /* iLandingPage */ #endif #if (USBD_WINUSB_ENABLE) - USBD_WINUSB_DESC_LEN, /* bLength */ - 0x10, /* bDescriptorType */ - USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ - 0x00, /* bReserved */ - 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */ - 0x89, 0x45, 0xC7, 0x4C, - 0x9C, 0xD2, 0x65, 0x9D, - 0x9E, 0x64, 0x8A, 0x9F, - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ - WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0, /* bAltEnumCode */ + USBD_WINUSB_DESC_LEN, /* bLength */ + 0x10, /* bDescriptorType */ + USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */ + 0x00, /* bReserved */ + 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */ + 0x89, 0x45, 0xC7, 0x4C, + 0x9C, 0xD2, 0x65, 0x9D, + 0x9E, 0x64, 0x8A, 0x9F, + 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/ + WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */ + USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ + 0, /* bAltEnumCode */ #endif }; +#define URL_DESCRIPTOR_LENGTH (3 + 29) + +const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = { + URL_DESCRIPTOR_LENGTH, + WEBUSB_URL_TYPE, + WEBUSB_URL_SCHEME_HTTPS, + WEBUSB_URL_STRINGS +}; + +// clang-format off +#define HID_DESC() \ + /************** Descriptor of Custom interface *****************/ \ + 0x09, /* bLength: Interface Descriptor size */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \ + 0X03, /* bInterfaceNumber: Number of Interface */ \ + 0x00, /* bAlternateSetting: Alternate setting */ \ + 0x02, /* bNumEndpoints */ \ + 0x03, /* bInterfaceClass: HID */ \ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \ + 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \ + 0, /* iInterface: Index of string descriptor */ /******************** Descriptor of Custom HID ********************/ \ + 0x09, /* bLength: HID Descriptor size */ \ + HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \ + 0x11, /* bcdHID: HID Class Spec release number */ \ + 0x01, \ + 0x00, /* bCountryCode: Hardware target country */ \ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \ + 0x22, /* bDescriptorType */ \ + HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ \ + 0x00, /******************** Descriptor of Custom in endpoint ********************/ \ + 0x07, /* bLength: Endpoint Descriptor size */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \ + HID_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ \ + 0x03, /* bmAttributes: Interrupt endpoint */ \ + WBVAL(HID_PACKET_SIZE), /* wMaxPacketSize: 4 Byte max */ \ + HIDRAW_INTERVAL, /* bInterval: Polling Interval */ /******************** Descriptor of Custom out endpoint ********************/ \ + 0x07, /* bLength: Endpoint Descriptor size */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \ + HID_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ \ + 0x03, /* bmAttributes: Interrupt endpoint */ \ + WBVAL(HID_PACKET_SIZE), /* wMaxPacketSize: 4 Byte max */ \ + HIDRAW_INTERVAL /* bInterval: Polling Interval */ +// clang-format on + static const uint8_t device_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), + USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), }; static const uint8_t config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - /* Interface 0 */ - USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), - /* Endpoint OUT 2 */ - USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), - /* Endpoint IN 1 */ - USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), - CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00), -#ifdef CONFIG_CHERRYDAP_USE_MSC - MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + /* Interface 0 */ + USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), + /* Endpoint OUT 2 */ + USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), + /* Endpoint IN 1 */ + USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), + CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00), +#if CONFIG_CHERRYDAP_USE_CUSTOM_HID + HID_DESC(), +#endif +#if CONFIG_CHERRYDAP_USE_MSC + MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00), +#endif +#if USBD_WEBUSB_ENABLE + USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x04), #endif }; static const uint8_t other_speed_config_descriptor[] = { - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - /* Interface 0 */ - USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), - /* Endpoint OUT 2 */ - USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), - /* Endpoint IN 1 */ - USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), - CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00), -#ifdef CONFIG_CHERRYDAP_USE_MSC - MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + /* Interface 0 */ + USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), + /* Endpoint OUT 2 */ + USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), + /* Endpoint IN 1 */ + USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00), + CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00), +#if CONFIG_CHERRYDAP_USE_CUSTOM_HID + HID_DESC(), +#endif +#if CONFIG_CHERRYDAP_USE_MSC + MSC_DESCRIPTOR_INIT(0x04, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00), +#endif +#if USBD_WEBUSB_ENABLE + USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x04), #endif }; +/*!< custom hid report descriptor */ +const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = { + /* USER CODE BEGIN 0 */ + 0x06, 0x00, 0xff, /* USAGE_PAGE (Vendor Defined Page 1) */ + 0x09, 0x01, /* USAGE (Vendor Usage 1) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, 0x02, /* REPORT ID (0x02) */ + 0x09, 0x02, /* USAGE (Vendor Usage 1) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xff, /*LOGICAL_MAXIMUM (255) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + /* <___________________________________________________> */ + 0x85, 0x01, /* REPORT ID (0x01) */ + 0x09, 0x03, /* USAGE (Vendor Usage 1) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + + /* <___________________________________________________> */ + 0x85, 0x03, /* REPORT ID (0x03) */ + 0x09, 0x04, /* USAGE (Vendor Usage 1) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */ + 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */ + /* USER CODE END 0 */ + 0xC0 /* END_COLLECTION */ +}; + +char serial_number_dynamic[36] = "00000000000000000123456789ABCDEF"; // Dynamic serial number + char *string_descriptors[] = { - (char[]) {0x09, 0x04}, /* Langid */ - "CherryUSB", /* Manufacturer */ - "CherryUSB CMSIS-DAP", /* Product */ - "00000000000000000123456789ABCDEF", /* Serial Number */ + (char[]){ 0x09, 0x04 }, /* Langid */ + "CherryUSB", /* Manufacturer */ + "CherryUSB CMSIS-DAP", /* Product */ + "00000000000000000123456789ABCDEF", /* Serial Number */ + "CherryUSB WebUSB", }; static const uint8_t device_quality_descriptor[] = { - USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01), + USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01), }; __WEAK const uint8_t *device_descriptor_callback(uint8_t speed) { - (void) speed; + (void)speed; return device_descriptor; } __WEAK const uint8_t *config_descriptor_callback(uint8_t speed) { - (void) speed; + (void)speed; return config_descriptor; } __WEAK const uint8_t *device_quality_descriptor_callback(uint8_t speed) { - (void) speed; + (void)speed; return device_quality_descriptor; } __WEAK const uint8_t *other_speed_config_descriptor_callback(uint8_t speed) { - (void) speed; + (void)speed; return other_speed_config_descriptor; } __WEAK const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - (void) speed; + (void)speed; + + if (index == 3) { + return serial_number_dynamic; + } if (index >= (sizeof(string_descriptors) / sizeof(char *))) { return NULL; @@ -214,7 +352,7 @@ USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_usbrx; void usbd_event_handler(uint8_t busid, uint8_t event) { - (void) busid; + (void)busid; switch (event) { case USBD_EVENT_RESET: usbrx_idle_flag = 0; @@ -250,7 +388,7 @@ void usbd_event_handler(uint8_t busid, uint8_t event) void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void) busid; + (void)busid; if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) { DAP_TransferAbort = 1U; } else { @@ -262,7 +400,7 @@ void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) } // Start reception of next request packet - if ((uint16_t) (USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) { + if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) { usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE); } else { USB_RequestIdle = 1U; @@ -271,7 +409,7 @@ void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) void dap_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void) busid; + (void)busid; if (USB_ResponseCountI != USB_ResponseCountO) { // Load data from response buffer to be sent back usbd_ep_start_write(0, DAP_IN_EP, USB_Response[USB_ResponseIndexO], USB_RespSize[USB_ResponseIndexO]); @@ -287,7 +425,7 @@ void dap_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void) busid; + (void)busid; chry_ringbuffer_write(&g_usbrx, usb_tmpbuffer, nbytes); if (chry_ringbuffer_get_free(&g_usbrx) >= DAP_PACKET_SIZE) { usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE); @@ -298,7 +436,7 @@ void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void) busid; + (void)busid; uint32_t size; uint8_t *buffer; @@ -317,52 +455,110 @@ void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) } struct usbd_endpoint dap_out_ep = { - .ep_addr = DAP_OUT_EP, - .ep_cb = dap_out_callback + .ep_addr = DAP_OUT_EP, + .ep_cb = dap_out_callback }; struct usbd_endpoint dap_in_ep = { - .ep_addr = DAP_IN_EP, - .ep_cb = dap_in_callback + .ep_addr = DAP_IN_EP, + .ep_cb = dap_in_callback }; struct usbd_endpoint cdc_out_ep = { - .ep_addr = CDC_OUT_EP, - .ep_cb = usbd_cdc_acm_bulk_out + .ep_addr = CDC_OUT_EP, + .ep_cb = usbd_cdc_acm_bulk_out }; struct usbd_endpoint cdc_in_ep = { - .ep_addr = CDC_IN_EP, - .ep_cb = usbd_cdc_acm_bulk_in + .ep_addr = CDC_IN_EP, + .ep_cb = usbd_cdc_acm_bulk_in +}; + +#if CONFIG_CHERRYDAP_USE_CUSTOM_HID +struct usbd_endpoint hid_custom_in_ep = { + .ep_addr = HID_IN_EP, + .ep_cb = usbd_hid_custom_in_callback, +}; + +struct usbd_endpoint hid_custom_out_ep = { + .ep_addr = HID_OUT_EP, + .ep_cb = usbd_hid_custom_out_callback, }; +#endif struct usbd_interface dap_intf; struct usbd_interface intf1; struct usbd_interface intf2; -struct usbd_interface intf3; +#if CONFIG_CHERRYDAP_USE_CUSTOM_HID struct usbd_interface hid_intf; +#endif + +#if CONFIG_CHERRYDAP_USE_MSC +struct usbd_interface intf3; +#endif struct usb_msosv2_descriptor msosv2_desc = { - .vendor_code = USBD_WINUSB_VENDOR_CODE, - .compat_id = USBD_WinUSBDescriptorSetDescriptor, - .compat_id_len = USBD_WINUSB_DESC_SET_LEN, + .vendor_code = USBD_WINUSB_VENDOR_CODE, + .compat_id = USBD_WinUSBDescriptorSetDescriptor, + .compat_id_len = USBD_WINUSB_DESC_SET_LEN, }; struct usb_bos_descriptor bos_desc = { - .string = USBD_BinaryObjectStoreDescriptor, - .string_len = USBD_BOS_WTOTALLENGTH + .string = USBD_BinaryObjectStoreDescriptor, + .string_len = USBD_BOS_WTOTALLENGTH +}; + +struct usb_webusb_descriptor webusb_url_desc = { + .vendor_code = USBD_WEBUSB_VENDOR_CODE, + .string = USBD_WebUSBURLDescriptor, + .string_len = URL_DESCRIPTOR_LENGTH }; const struct usb_descriptor cmsisdap_descriptor = { - .device_descriptor_callback = device_descriptor_callback, - .config_descriptor_callback = config_descriptor_callback, - .device_quality_descriptor_callback = device_quality_descriptor_callback, - .other_speed_descriptor_callback = other_speed_config_descriptor_callback, - .string_descriptor_callback = string_descriptor_callback, - .bos_descriptor = &bos_desc, - .msosv2_descriptor = &msosv2_desc, + .device_descriptor_callback = device_descriptor_callback, + .config_descriptor_callback = config_descriptor_callback, + .device_quality_descriptor_callback = device_quality_descriptor_callback, + .other_speed_descriptor_callback = other_speed_config_descriptor_callback, + .string_descriptor_callback = string_descriptor_callback, + .bos_descriptor = &bos_desc, + .msosv2_descriptor = &msosv2_desc, + .webusb_url_descriptor = &webusb_url_desc }; +void chry_dap_init(uint8_t busid, uint32_t reg_base) +{ + chry_ringbuffer_init(&g_uartrx, uartrx_ringbuffer, CONFIG_UARTRX_RINGBUF_SIZE); + chry_ringbuffer_init(&g_usbrx, usbrx_ringbuffer, CONFIG_USBRX_RINGBUF_SIZE); + + DAP_Setup(); + + usbd_desc_register(0, &cmsisdap_descriptor); + + /*!< winusb */ + usbd_add_interface(0, &dap_intf); + usbd_add_endpoint(0, &dap_out_ep); + usbd_add_endpoint(0, &dap_in_ep); + + /*!< cdc acm */ + usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf1)); + usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf2)); + usbd_add_endpoint(0, &cdc_out_ep); + usbd_add_endpoint(0, &cdc_in_ep); + +#if CONFIG_CHERRYDAP_USE_CUSTOM_HID + /*!< hid */ + usbd_add_interface(0, usbd_hid_init_intf(0, &hid_intf, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE)); + hid_intf.notify_handler = hid_custom_notify_handler; + usbd_add_endpoint(0, &hid_custom_in_ep); + usbd_add_endpoint(0, &hid_custom_out_ep); +#endif + +#if CONFIG_CHERRYDAP_USE_MSC + usbd_add_interface(0, usbd_msc_init_intf(0, &intf3, MSC_OUT_EP, MSC_IN_EP)); +#endif + usbd_initialize(busid, reg_base, usbd_event_handler); +} + void chry_dap_handle(void) { uint32_t n; @@ -387,7 +583,7 @@ void chry_dap_handle(void) // Execute DAP Command (process request and prepare response) USB_RespSize[USB_ResponseIndexI] = - (uint16_t) DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]); + (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]); // Update Request Index and Count USB_RequestIndexO++; @@ -397,7 +593,7 @@ void chry_dap_handle(void) USB_RequestCountO++; if (USB_RequestIdle) { - if ((uint16_t) (USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) { + if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) { USB_RequestIdle = 0U; usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE); } @@ -427,9 +623,9 @@ void chry_dap_handle(void) void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding) { - (void) busid; - if (memcmp(line_coding, (uint8_t *) &g_cdc_lincoding, sizeof(struct cdc_line_coding)) != 0) { - memcpy((uint8_t *) &g_cdc_lincoding, line_coding, sizeof(struct cdc_line_coding)); + (void)busid; + if (memcmp(line_coding, (uint8_t *)&g_cdc_lincoding, sizeof(struct cdc_line_coding)) != 0) { + memcpy((uint8_t *)&g_cdc_lincoding, line_coding, sizeof(struct cdc_line_coding)); config_uart = 1; config_uart_transfer = 0; } @@ -437,8 +633,8 @@ void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_c void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding) { - (void) busid; - memcpy(line_coding, (uint8_t *) &g_cdc_lincoding, sizeof(struct cdc_line_coding)); + (void)busid; + memcpy(line_coding, (uint8_t *)&g_cdc_lincoding, sizeof(struct cdc_line_coding)); } void chry_dap_usb2uart_handle(void) @@ -450,7 +646,7 @@ void chry_dap_usb2uart_handle(void) /* disable irq here */ config_uart = 0; /* config uart here */ - chry_dap_usb2uart_uart_config_callback((struct cdc_line_coding *) &g_cdc_lincoding); + chry_dap_usb2uart_uart_config_callback((struct cdc_line_coding *)&g_cdc_lincoding); usbtx_idle_flag = 1; uarttx_idle_flag = 1; config_uart_transfer = 1; @@ -521,7 +717,7 @@ __WEAK void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len) { } -#ifdef CONFIG_CHERRYDAP_USE_MSC +#if CONFIG_CHERRYDAP_USE_MSC #define BLOCK_SIZE 512 #define BLOCK_COUNT 10 diff --git a/components/drivers/usb/cherryusb/platform/daplink/dap_main.h b/components/drivers/usb/cherryusb/platform/daplink/dap_main.h index 082cb996e70..596f7a47e1c 100644 --- a/components/drivers/usb/cherryusb/platform/daplink/dap_main.h +++ b/components/drivers/usb/cherryusb/platform/daplink/dap_main.h @@ -10,6 +10,7 @@ #include "usbd_core.h" #include "usbd_cdc.h" #include "usbd_msc.h" +#include "usbd_hid.h" #include "chry_ringbuffer.h" #include "DAP_config.h" #include "DAP.h" @@ -24,23 +25,14 @@ #define MSC_IN_EP 0x86 #define MSC_OUT_EP 0x07 +#define HID_IN_EP 0x88 +#define HID_OUT_EP 0x09 + #define USBD_VID 0x0D28 #define USBD_PID 0x0204 #define USBD_MAX_POWER 500 #define USBD_LANGID_STRING 1033 -#define CMSIS_DAP_INTERFACE_SIZE (9 + 7 + 7) - -#ifdef CONFIG_CHERRYDAP_USE_MSC -#define CONFIG_MSC_DESCRIPTOR_LEN CDC_ACM_DESCRIPTOR_LEN -#define CONFIG_MSC_INTF_NUM 1 -#define MSC_INTF_NUM (0x02 + 1) -#else -#define CONFIG_MSC_DESCRIPTOR_LEN 0 -#define CONFIG_MSC_INTF_NUM 0 -#define MSC_INTF_NUM (0x02) -#endif - #ifdef CONFIG_USB_HS #if DAP_PACKET_SIZE != 512 #error "DAP_PACKET_SIZE must be 512 in hs" @@ -51,99 +43,57 @@ #endif #endif -#define USBD_WINUSB_VENDOR_CODE 0x20 - -#define USBD_WEBUSB_ENABLE 0 -#define USBD_BULK_ENABLE 1 -#define USBD_WINUSB_ENABLE 1 - -/* WinUSB Microsoft OS 2.0 descriptor sizes */ -#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10 -#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8 -#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20 - -#define FUNCTION_SUBSET_LEN 160 -#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132 - -#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN) - -#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE) - -#define USBD_WEBUSB_DESC_LEN 24 -#define USBD_WINUSB_DESC_LEN 28 - -#define USBD_BOS_WTOTALLENGTH (0x05 + \ - USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \ - USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE) +#ifdef CONFIG_USB_HS +#define HID_PACKET_SIZE 1024 +#else +#define HID_PACKET_SIZE 64 +#endif #define CONFIG_UARTRX_RINGBUF_SIZE (8 * 1024) #define CONFIG_USBRX_RINGBUF_SIZE (8 * 1024) -#ifdef __cplusplus -extern "C" -{ +#ifndef CONFIG_CHERRYDAP_USE_MSC +#define CONFIG_CHERRYDAP_USE_MSC 0 #endif -extern USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t uartrx_ringbuffer[CONFIG_UARTRX_RINGBUF_SIZE]; -extern USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usbrx_ringbuffer[CONFIG_USBRX_RINGBUF_SIZE]; -extern USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_tmpbuffer[DAP_PACKET_SIZE]; +#ifndef CONFIG_CHERRYDAP_USE_CUSTOM_HID +#define CONFIG_CHERRYDAP_USE_CUSTOM_HID 0 +#endif -extern const struct usb_descriptor cmsisdap_descriptor; -extern __ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[]; -extern __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[]; -extern char *string_descriptors[]; +#ifdef __cplusplus +extern "C" { +#endif -extern struct usbd_interface dap_intf; -extern struct usbd_interface intf1; -extern struct usbd_interface intf2; -extern struct usbd_interface intf3; -extern struct usbd_interface hid_intf; +extern char serial_number_dynamic[36]; -extern struct usbd_endpoint dap_out_ep; -extern struct usbd_endpoint dap_in_ep; -extern struct usbd_endpoint cdc_out_ep; -extern struct usbd_endpoint cdc_in_ep; +extern struct usbd_interface hid_intf; extern chry_ringbuffer_t g_uartrx; extern chry_ringbuffer_t g_usbrx; -__STATIC_INLINE void chry_dap_init(uint8_t busid, uint32_t reg_base) -{ - chry_ringbuffer_init(&g_uartrx, uartrx_ringbuffer, CONFIG_UARTRX_RINGBUF_SIZE); - chry_ringbuffer_init(&g_usbrx, usbrx_ringbuffer, CONFIG_USBRX_RINGBUF_SIZE); - - DAP_Setup(); - - usbd_desc_register(0, &cmsisdap_descriptor); - - /*!< winusb */ - usbd_add_interface(0, &dap_intf); - usbd_add_endpoint(0, &dap_out_ep); - usbd_add_endpoint(0, &dap_in_ep); - - /*!< cdc acm */ - usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf1)); - usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf2)); - usbd_add_endpoint(0, &cdc_out_ep); - usbd_add_endpoint(0, &cdc_in_ep); - -#ifdef CONFIG_CHERRYDAP_USE_MSC - usbd_add_interface(0, usbd_msc_init_intf(0, &intf3, MSC_OUT_EP, MSC_IN_EP)); -#endif - extern void usbd_event_handler(uint8_t busid, uint8_t event); - usbd_initialize(busid, reg_base, usbd_event_handler); -} +void chry_dap_init(uint8_t busid, uint32_t reg_base); void chry_dap_handle(void); void chry_dap_usb2uart_handle(void); -void chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding *line_coding); +/* implment by user */ +extern void chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding *line_coding); -void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len); +/* implment by user */ +extern void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len); void chry_dap_usb2uart_uart_send_complete(uint32_t size); +/* implment by user */ +extern void hid_custom_notify_handler(uint8_t busid, uint8_t event, void *arg); + +/* implment by user */ +extern void usbd_hid_custom_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes); + +/* implment by user */ +extern void usbd_hid_custom_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes); + #ifdef __cplusplus } #endif diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c b/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c index 4a5fb8c329d..154d89f0b63 100644 --- a/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c +++ b/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c @@ -17,8 +17,11 @@ #endif #endif -#if defined(ARCH_ARM_CORTEX_M7) || \ - defined(SOC_HPM6000) || defined(SOC_HPM6E00) || defined(SOC_HPM6P00) || \ +#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 @@ -27,6 +30,6 @@ #ifdef RT_USING_CACHE #ifndef CONFIG_USB_DCACHE_ENABLE -#warning CONFIG_USB_DCACHE_ENABLE must be enabled if you do not config nocache ram +#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 index a153ed053d2..8dd61164071 100644 --- a/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c +++ b/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c @@ -21,7 +21,7 @@ int usbh_init(int argc, char **argv) busid = atoi(argv[1]); reg_base = strtoll(argv[2], NULL, 16); - usbh_initialize(busid, reg_base); + usbh_initialize(busid, reg_base, NULL); return 0; } @@ -44,4 +44,10 @@ int usbh_deinit(int argc, char **argv) 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_serial.c b/components/drivers/usb/cherryusb/platform/rtthread/usbd_serial.c index aeb53a9bf1d..2f6d484bca4 100644 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbd_serial.c +++ b/components/drivers/usb/cherryusb/platform/rtthread/usbd_serial.c @@ -76,9 +76,8 @@ static rt_err_t usbd_serial_open(struct rt_device *dev, rt_uint16_t oflag) serial = (struct usbd_serial *)dev; - if (!usb_device_is_configured(serial->busid)) { - USB_LOG_ERR("USB device is not configured\n"); - return -RT_EPERM; + while(!usb_device_is_configured(serial->busid)) { + rt_thread_mdelay(10); } usbd_ep_start_read(serial->busid, serial->out_ep, @@ -123,9 +122,8 @@ static rt_ssize_t usbd_serial_write(struct rt_device *dev, } align_buf = (rt_uint8_t *)buffer; -#ifdef CONFIG_USB_DCACHE_ENABLE if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE); + 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; @@ -133,7 +131,7 @@ static rt_ssize_t usbd_serial_write(struct rt_device *dev, usb_memcpy(align_buf, buffer, size); } -#endif + 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); @@ -144,11 +142,9 @@ static rt_ssize_t usbd_serial_write(struct rt_device *dev, ret = size; } -#ifdef CONFIG_USB_DCACHE_ENABLE if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { rt_free_align(align_buf); } -#endif return ret; } diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c b/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c index 1344f539268..77846665269 100644 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c +++ b/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c @@ -38,7 +38,7 @@ static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_uint8_t *align_buf; align_buf = (rt_uint8_t *)buffer; -#ifdef CONFIG_USB_DCACHE_ENABLE + 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) { @@ -47,18 +47,18 @@ static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer, } } else { } -#endif + 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; } -#ifdef CONFIG_USB_DCACHE_ENABLE + if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { usb_memcpy(buffer, align_buf, size * msc_class->blocksize); rt_free_align(align_buf); } -#endif + return size; } @@ -70,7 +70,7 @@ static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buff rt_uint8_t *align_buf; align_buf = (rt_uint8_t *)buffer; -#ifdef CONFIG_USB_DCACHE_ENABLE + 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) { @@ -80,17 +80,16 @@ static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buff usb_memcpy(align_buf, buffer, size * msc_class->blocksize); } -#endif + 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; } -#ifdef CONFIG_USB_DCACHE_ENABLE + if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { rt_free_align(align_buf); } -#endif return size; } diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c b/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c index 34dc385075f..292e5e3c880 100644 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c +++ b/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c @@ -25,7 +25,7 @@ #endif #ifndef LWIP_NO_RX_THREAD -#error must enable LWIP_NO_RX_THREAD, we do not use rtthread eth 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 @@ -33,7 +33,7 @@ #endif #if LWIP_TCPIP_CORE_LOCKING_INPUT != 1 -#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread +#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 @@ -48,6 +48,14 @@ #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 diff --git a/components/drivers/usb/cherryusb/platform/rtthread/usbh_serial.c b/components/drivers/usb/cherryusb/platform/rtthread/usbh_serial.c deleted file mode 100644 index cbfbc49e4d3..00000000000 --- a/components/drivers/usb/cherryusb/platform/rtthread/usbh_serial.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Copyright (c) 2025, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include - -#include "usbh_core.h" -#include "usbh_cdc_acm.h" -#include "usbh_ftdi.h" -#include "usbh_cp210x.h" -#include "usbh_ch34x.h" -#include "usbh_pl2303.h" - -#define DEV_FORMAT_VENDOR "ttyUSB%d" -#define DEV_FORMAT_CDC_ACM "ttyACM%d" - -#define USBH_RX_MAX_SIZE 2048 - -#ifndef CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS -#define CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS (4) -#endif - -#ifndef CONFIG_USBHOST_SERIAL_RX_BUFSIZE -#define CONFIG_USBHOST_SERIAL_RX_BUFSIZE (USBH_RX_MAX_SIZE * 2) -#endif - -enum usbh_serial_type { - USBH_SERIAL_TYPE_CDC_ACM = 0, - USBH_SERIAL_TYPE_FTDI, - USBH_SERIAL_TYPE_CP210X, - USBH_SERIAL_TYPE_CH34X, - USBH_SERIAL_TYPE_PL2303, -}; - -struct usbh_serial { - struct rt_device parent; - enum usbh_serial_type type; - uint8_t minor; - char name[CONFIG_USBHOST_DEV_NAMELEN]; - struct rt_ringbuffer rx_rb; - rt_uint8_t rx_rb_buffer[CONFIG_USBHOST_SERIAL_RX_BUFSIZE]; -}; - -static uint32_t g_devinuse_vendor = 0; -static uint32_t g_devinuse_cdc_acm = 0; - -static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_vendor_rx_buf[CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)]; -static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_cdc_acm_rx_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)]; - -static struct usbh_serial *usbh_serial_alloc(uint8_t type) -{ - uint8_t devno; - struct usbh_serial *serial; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS; devno++) { - if ((g_devinuse_vendor & (1U << devno)) == 0) { - g_devinuse_vendor |= (1U << devno); - - serial = rt_malloc(sizeof(struct usbh_serial)); - memset(serial, 0, sizeof(struct usbh_serial)); - serial->type = type; - serial->minor = devno; - snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_VENDOR, serial->minor); - return serial; - } - } - return NULL; -} - -static void usbh_serial_free(struct usbh_serial *serial) -{ - uint8_t devno = serial->minor; - - if (devno < 32) { - g_devinuse_vendor &= ~(1U << devno); - } - memset(serial, 0, sizeof(struct usbh_serial)); - rt_free(serial); -} - -static struct usbh_serial *usbh_serial_cdc_acm_alloc(uint8_t type) -{ - uint8_t devno; - struct usbh_serial *serial; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) { - if ((g_devinuse_cdc_acm & (1U << devno)) == 0) { - g_devinuse_cdc_acm |= (1U << devno); - - serial = rt_malloc(sizeof(struct usbh_serial)); - memset(serial, 0, sizeof(struct usbh_serial)); - serial->type = type; - serial->minor = devno; - snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->minor); - return serial; - } - } - return NULL; -} - -static void usbh_serial_cdc_acm_free(struct usbh_serial *serial) -{ - uint8_t devno = serial->minor; - - if (devno < 32) { - g_devinuse_cdc_acm &= ~(1U << devno); - } - memset(serial, 0, sizeof(struct usbh_serial)); - rt_free(serial); -} - -static rt_err_t usbh_serial_open(struct rt_device *dev, rt_uint16_t oflag) -{ - struct usbh_serial *serial; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbh_serial *)dev; - - switch (serial->type) { - case USBH_SERIAL_TYPE_CDC_ACM: - break; - case USBH_SERIAL_TYPE_FTDI: - break; - case USBH_SERIAL_TYPE_CP210X: - break; - case USBH_SERIAL_TYPE_CH34X: - break; - case USBH_SERIAL_TYPE_PL2303: - break; - - default: - break; - } - - return RT_EOK; -} - -static rt_err_t usbh_serial_close(struct rt_device *dev) -{ - struct usbh_serial *serial; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbh_serial *)dev; - - switch (serial->type) { - case USBH_SERIAL_TYPE_CDC_ACM: - break; - case USBH_SERIAL_TYPE_FTDI: - break; - case USBH_SERIAL_TYPE_CP210X: - break; - case USBH_SERIAL_TYPE_CH34X: - break; - case USBH_SERIAL_TYPE_PL2303: - break; - - default: - break; - } - - return RT_EOK; -} - -static rt_ssize_t usbh_serial_read(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct usbh_serial *serial; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbh_serial *)dev; - - return rt_ringbuffer_get(&serial->rx_rb, (rt_uint8_t *)buffer, size); -} - -static rt_ssize_t usbh_serial_write(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct usbh_serial *serial; - int ret = 0; - rt_uint8_t *align_buf; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbh_serial *)dev; - - align_buf = (rt_uint8_t *)buffer; -#ifdef CONFIG_USB_DCACHE_ENABLE - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE); - if (!align_buf) { - USB_LOG_ERR("serial get align buf failed\n"); - return 0; - } - - usb_memcpy(align_buf, buffer, size); - } -#endif - - switch (serial->type) { -#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM) - case USBH_SERIAL_TYPE_CDC_ACM: - ret = usbh_cdc_acm_bulk_out_transfer((struct usbh_cdc_acm *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER); - if (ret < 0) { - USB_LOG_ERR("usbh_cdc_acm_bulk_out_transfer failed: %d\n", ret); -#ifdef CONFIG_USB_DCACHE_ENABLE - rt_free_align(align_buf); -#endif - return 0; - } - break; -#endif -#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI) - case USBH_SERIAL_TYPE_FTDI: - ret = usbh_ftdi_bulk_out_transfer((struct usbh_ftdi *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER); - if (ret < 0) { - USB_LOG_ERR("usbh_ftdi_bulk_out_transfer failed: %d\n", ret); -#ifdef CONFIG_USB_DCACHE_ENABLE - rt_free_align(align_buf); -#endif - return 0; - } - break; -#endif -#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X) - case USBH_SERIAL_TYPE_CH34X: - ret = usbh_ch34x_bulk_out_transfer((struct usbh_ch34x *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER); - if (ret < 0) { - USB_LOG_ERR("usbh_ch34x_bulk_out_transfer failed: %d\n", ret); -#ifdef CONFIG_USB_DCACHE_ENABLE - rt_free_align(align_buf); -#endif - return 0; - } - break; -#endif -#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303) - case USBH_SERIAL_TYPE_PL2303: - ret = usbh_pl2303_bulk_out_transfer((struct usbh_pl2303 *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER); - if (ret < 0) { - USB_LOG_ERR("usbh_pl2303_bulk_out_transfer failed: %d\n", ret); -#ifdef CONFIG_USB_DCACHE_ENABLE - rt_free_align(align_buf); -#endif - return 0; - } - break; -#endif - default: - break; - } - -#ifdef CONFIG_USB_DCACHE_ENABLE - if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) { - rt_free_align(align_buf); - } -#endif - - return ret; -} - -static rt_err_t usbh_serial_control(struct rt_device *dev, - int cmd, - void *args) -{ - struct usbh_serial *serial; - struct serial_configure *config; - struct cdc_line_coding line_coding; - int ret = -RT_EINVAL; - - RT_ASSERT(dev != RT_NULL); - - serial = (struct usbh_serial *)dev; - - switch (serial->type) { -#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM) - case USBH_SERIAL_TYPE_CDC_ACM: - if (cmd == RT_DEVICE_CTRL_CONFIG) { - struct usbh_cdc_acm *cdc_acm_class; - cdc_acm_class = (struct usbh_cdc_acm *)dev->user_data; - - config = (struct serial_configure *)args; - - line_coding.dwDTERate = config->baud_rate; - line_coding.bDataBits = config->data_bits; - line_coding.bCharFormat = 0; // STOP_BITS_1 - line_coding.bParityType = config->parity; - - usbh_cdc_acm_set_line_coding(cdc_acm_class, &line_coding); - } - - ret = RT_EOK; - break; -#endif -#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI) - case USBH_SERIAL_TYPE_FTDI: - if (cmd == RT_DEVICE_CTRL_CONFIG) { - struct usbh_ftdi *ftdi_class; - ftdi_class = (struct usbh_ftdi *)dev->user_data; - - config = (struct serial_configure *)args; - - line_coding.dwDTERate = config->baud_rate; - line_coding.bDataBits = config->data_bits; - line_coding.bCharFormat = 0; // STOP_BITS_1 - line_coding.bParityType = config->parity; - - usbh_ftdi_set_line_coding(ftdi_class, &line_coding); - } - - ret = RT_EOK; - break; -#endif -#if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X) - case USBH_SERIAL_TYPE_CP210X: - if (cmd == RT_DEVICE_CTRL_CONFIG) { - struct usbh_cp210x *cp210x_class; - cp210x_class = (struct usbh_cp210x *)dev->user_data; - - config = (struct serial_configure *)args; - - line_coding.dwDTERate = config->baud_rate; - line_coding.bDataBits = config->data_bits; - line_coding.bCharFormat = 0; // STOP_BITS_1 - line_coding.bParityType = config->parity; - - usbh_cp210x_set_line_coding(cp210x_class, &line_coding); - } - - ret = RT_EOK; - break; -#endif -#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X) - case USBH_SERIAL_TYPE_CH34X: - if (cmd == RT_DEVICE_CTRL_CONFIG) { - struct usbh_ch34x *ch34x_class; - ch34x_class = (struct usbh_ch34x *)dev->user_data; - - config = (struct serial_configure *)args; - - line_coding.dwDTERate = config->baud_rate; - line_coding.bDataBits = config->data_bits; - line_coding.bCharFormat = 0; // STOP_BITS_1 - line_coding.bParityType = config->parity; - - usbh_ch34x_set_line_coding(ch34x_class, &line_coding); - } - - ret = RT_EOK; - break; -#endif -#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303) - case USBH_SERIAL_TYPE_PL2303: - if (cmd == RT_DEVICE_CTRL_CONFIG) { - struct usbh_pl2303 *pl2303_class; - pl2303_class = (struct usbh_pl2303 *)dev->user_data; - - config = (struct serial_configure *)args; - - line_coding.dwDTERate = config->baud_rate; - line_coding.bDataBits = config->data_bits; - line_coding.bCharFormat = 0; // STOP_BITS_1 - line_coding.bParityType = config->parity; - - usbh_pl2303_set_line_coding(pl2303_class, &line_coding); - } - - ret = RT_EOK; - break; -#endif - default: - break; - } - - return ret; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops usbh_serial_ops = { - NULL, - usbh_serial_open, - usbh_serial_close, - usbh_serial_read, - usbh_serial_write, - usbh_serial_control -}; -#endif - -#ifdef RT_USING_POSIX_DEVIO -#include -#include -#include -#include -#include - -#ifdef RT_USING_POSIX_TERMIOS -#include -#endif - -static rt_err_t usbh_serial_fops_rx_ind(rt_device_t dev, rt_size_t size) -{ - rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN); - - return RT_EOK; -} - -/* fops for serial */ -static int usbh_serial_fops_open(struct dfs_file *fd) -{ - rt_err_t ret = 0; - rt_uint16_t flags = 0; - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - RT_ASSERT(device != RT_NULL); - - switch (fd->flags & O_ACCMODE) - { - case O_RDONLY: - USB_LOG_DBG("fops open: O_RDONLY!"); - flags = RT_DEVICE_FLAG_RDONLY; - break; - case O_WRONLY: - USB_LOG_DBG("fops open: O_WRONLY!"); - flags = RT_DEVICE_FLAG_WRONLY; - break; - case O_RDWR: - USB_LOG_DBG("fops open: O_RDWR!"); - flags = RT_DEVICE_FLAG_RDWR; - break; - default: - USB_LOG_ERR("fops open: unknown mode - %d!", fd->flags & O_ACCMODE); - break; - } - - if ((fd->flags & O_ACCMODE) != O_WRONLY) - rt_device_set_rx_indicate(device, usbh_serial_fops_rx_ind); - ret = rt_device_open(device, flags); - if (ret == RT_EOK) return 0; - - return ret; -} - -static int usbh_serial_fops_close(struct dfs_file *fd) -{ - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - - rt_device_set_rx_indicate(device, RT_NULL); - rt_device_close(device); - - return 0; -} - -static int usbh_serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args) -{ - rt_device_t device; - int flags = (int)(rt_base_t)args; - int mask = O_NONBLOCK | O_APPEND; - - device = (rt_device_t)fd->vnode->data; - switch (cmd) - { - case FIONREAD: - break; - case FIONWRITE: - break; - case F_SETFL: - flags &= mask; - fd->flags &= ~mask; - fd->flags |= flags; - break; - } - - return rt_device_control(device, cmd, args); -} - -static int usbh_serial_fops_read(struct dfs_file *fd, void *buf, size_t count) -{ - int size = 0; - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - - do - { - size = rt_device_read(device, -1, buf, count); - if (size <= 0) - { - if (fd->flags & O_NONBLOCK) - { - size = -EAGAIN; - break; - } - - rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER); - } - }while (size <= 0); - - return size; -} - -static int usbh_serial_fops_write(struct dfs_file *fd, const void *buf, size_t count) -{ - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - return rt_device_write(device, -1, buf, count); -} - -static int usbh_serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req) -{ - int mask = 0; - int flags = 0; - rt_device_t device; - struct usbh_serial *serial; - - device = (rt_device_t)fd->vnode->data; - RT_ASSERT(device != RT_NULL); - - serial = (struct usbh_serial *)device; - - /* only support POLLIN */ - flags = fd->flags & O_ACCMODE; - if (flags == O_RDONLY || flags == O_RDWR) - { - rt_base_t level; - - rt_poll_add(&(device->wait_queue), req); - - level = rt_hw_interrupt_disable(); - - if (rt_ringbuffer_data_len(&serial->rx_rb)) - mask |= POLLIN; - rt_hw_interrupt_enable(level); - } - // mask|=POLLOUT; - return mask; -} - -const static struct dfs_file_ops usbh_serial_fops = -{ - usbh_serial_fops_open, - usbh_serial_fops_close, - usbh_serial_fops_ioctl, - usbh_serial_fops_read, - usbh_serial_fops_write, - RT_NULL, /* flush */ - RT_NULL, /* lseek */ - RT_NULL, /* getdents */ - usbh_serial_fops_poll, -}; -#endif /* RT_USING_POSIX_DEVIO */ - -rt_err_t usbh_serial_register(struct usbh_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 = &usbh_serial_ops; -#else - device->init = NULL; - device->open = usbh_serial_open; - device->close = usbh_serial_close; - device->read = usbh_serial_read; - device->write = usbh_serial_write; - device->control = usbh_serial_control; -#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 = &usbh_serial_fops; -#endif - rt_ringbuffer_init(&serial->rx_rb, serial->rx_rb_buffer, sizeof(serial->rx_rb_buffer)); - - return ret; -} - -void usbh_serial_unregister(struct usbh_serial *serial) -{ - RT_ASSERT(serial != NULL); - - rt_device_unregister(&serial->parent); - - if (serial->type == USBH_SERIAL_TYPE_CDC_ACM) { - usbh_serial_cdc_acm_free(serial); - } else { - usbh_serial_free(serial); - } -} - -#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM) -void usbh_cdc_acm_callback(void *arg, int nbytes) -{ - struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg; - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &cdc_acm_class->bulkin_urb; - - if (nbytes > 0) { - serial = (struct usbh_serial *)cdc_acm_class->user_data; - rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_cdc_acm_rx_buf[serial->minor], nbytes); - - if (serial->parent.rx_indicate) { - serial->parent.rx_indicate(&serial->parent, nbytes); - } - - usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - } - } -} - -void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class) -{ - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &cdc_acm_class->bulkin_urb; - - serial = usbh_serial_cdc_acm_alloc(USBH_SERIAL_TYPE_CDC_ACM); - cdc_acm_class->user_data = serial; - - usbh_serial_register(serial, cdc_acm_class); - - struct cdc_line_coding linecoding; - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_cdc_acm_set_line_coding(cdc_acm_class, &linecoding); - - usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - usbh_serial_unregister(serial); - return; - } -} - -void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class) -{ - struct usbh_serial *serial; - - serial = (struct usbh_serial *)cdc_acm_class->user_data; - usbh_serial_unregister(serial); -} -#endif - -#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI) -void usbh_ftdi_callback(void *arg, int nbytes) -{ - struct usbh_ftdi *ftdi_class = (struct usbh_ftdi *)arg; - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &ftdi_class->bulkin_urb; - - if (nbytes >= 2) { - serial = (struct usbh_serial *)ftdi_class->user_data; - - nbytes -= 2; // Skip the first two bytes (header) - rt_ringbuffer_put(&serial->rx_rb, &g_usbh_serial_vendor_rx_buf[serial->minor][2], nbytes); - - if (serial->parent.rx_indicate && nbytes) { - serial->parent.rx_indicate(&serial->parent, nbytes); - } - - usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - } - } -} - -void usbh_ftdi_run(struct usbh_ftdi *ftdi_class) -{ - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &ftdi_class->bulkin_urb; - - serial = usbh_serial_alloc(USBH_SERIAL_TYPE_FTDI); - ftdi_class->user_data = serial; - - usbh_serial_register(serial, ftdi_class); - - struct cdc_line_coding linecoding; - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_ftdi_set_line_coding(ftdi_class, &linecoding); - - usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - usbh_serial_unregister(serial); - return; - } -} - -void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class) -{ - struct usbh_serial *serial; - - serial = (struct usbh_serial *)ftdi_class->user_data; - usbh_serial_unregister(serial); -} -#endif - -#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X) -void usbh_ch34x_callback(void *arg, int nbytes) -{ - struct usbh_ch34x *ch34x_class = (struct usbh_ch34x *)arg; - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &ch34x_class->bulkin_urb; - - if (nbytes > 0) { - serial = (struct usbh_serial *)ch34x_class->user_data; - rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes); - - if (serial->parent.rx_indicate) { - serial->parent.rx_indicate(&serial->parent, nbytes); - } - - usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - } - } -} - -void usbh_ch34x_run(struct usbh_ch34x *ch34x_class) -{ - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &ch34x_class->bulkin_urb; - - serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CH34X); - ch34x_class->user_data = serial; - - usbh_serial_register(serial, ch34x_class); - - struct cdc_line_coding linecoding; - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_ch34x_set_line_coding(ch34x_class, &linecoding); - - usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - usbh_serial_unregister(serial); - return; - } -} - -void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class) -{ - struct usbh_serial *serial; - - serial = (struct usbh_serial *)ch34x_class->user_data; - usbh_serial_unregister(serial); -} -#endif - -#if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X) -void usbh_cp210x_callback(void *arg, int nbytes) -{ - struct usbh_cp210x *cp210x_class = (struct usbh_cp210x *)arg; - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &cp210x_class->bulkin_urb; - - if (nbytes > 0) { - serial = (struct usbh_serial *)cp210x_class->user_data; - rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes); - - if (serial->parent.rx_indicate) { - serial->parent.rx_indicate(&serial->parent, nbytes); - } - - usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - } - } -} - -void usbh_cp210x_run(struct usbh_cp210x *cp210x_class) -{ - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &cp210x_class->bulkin_urb; - - serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CP210X); - cp210x_class->user_data = serial; - - usbh_serial_register(serial, cp210x_class); - - struct cdc_line_coding linecoding; - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_cp210x_set_line_coding(cp210x_class, &linecoding); - - usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - usbh_serial_unregister(serial); - return; - } -} - -void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class) -{ - struct usbh_serial *serial; - - serial = (struct usbh_serial *)cp210x_class->user_data; - usbh_serial_unregister(serial); -} -#endif - -#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303) -void usbh_pl2303_callback(void *arg, int nbytes) -{ - struct usbh_pl2303 *pl2303_class = (struct usbh_pl2303 *)arg; - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &pl2303_class->bulkin_urb; - - if (nbytes > 0) { - serial = (struct usbh_serial *)pl2303_class->user_data; - rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes); - - if (serial->parent.rx_indicate) { - serial->parent.rx_indicate(&serial->parent, nbytes); - } - - usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - } - } -} - -void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class) -{ - struct usbh_serial *serial; - int ret; - struct usbh_urb *urb = &pl2303_class->bulkin_urb; - - serial = usbh_serial_alloc(USBH_SERIAL_TYPE_PL2303); - pl2303_class->user_data = serial; - - usbh_serial_register(serial, pl2303_class); - - struct cdc_line_coding linecoding; - linecoding.dwDTERate = 115200; - linecoding.bDataBits = 8; - linecoding.bParityType = 0; - linecoding.bCharFormat = 0; - usbh_pl2303_set_line_coding(pl2303_class, &linecoding); - - usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class); - ret = usbh_submit_urb(urb); - if (ret < 0) { - USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret); - usbh_serial_unregister(serial); - return; - } -} - -void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class) -{ - struct usbh_serial *serial; - - serial = (struct usbh_serial *)pl2303_class->user_data; - usbh_serial_unregister(serial); -} -#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 106f8af535f..ddead2b9db7 100644 --- a/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c +++ b/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c @@ -594,10 +594,15 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui return -2; } +#ifdef CONFIG_USB_DCACHE_ENABLE + USB_ASSERT_MSG(!((uintptr_t)data % CONFIG_USB_ALIGN_SIZE), "data is not aligned %d", CONFIG_USB_ALIGN_SIZE); +#endif + g_chipidea_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data; g_chipidea_udc[busid].in_ep[ep_idx].xfer_len = data_len; g_chipidea_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)); chipidea_start_xfer(busid, ep, (uint8_t *)data, data_len); return 0; @@ -614,10 +619,15 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t return -2; } +#ifdef CONFIG_USB_DCACHE_ENABLE + USB_ASSERT_MSG(!((uintptr_t)data % CONFIG_USB_ALIGN_SIZE), "data is not aligned %d", CONFIG_USB_ALIGN_SIZE); +#endif + g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data; g_chipidea_udc[busid].out_ep[ep_idx].xfer_len = data_len; g_chipidea_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)); chipidea_start_xfer(busid, ep, data, data_len); return 0; @@ -649,7 +659,7 @@ void USBD_IRQHandler(uint8_t busid) memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM); memset(g_chipidea_udc[busid].out_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM); usbd_event_reset_handler(busid); - chipidea_bus_reset(busid, 64); + chipidea_bus_reset(busid, g_chipidea_udc[busid].in_ep[0].ep_mps); } if (int_status & intr_suspend) { @@ -712,6 +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)); usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len); } } diff --git a/components/drivers/usb/cherryusb/port/dwc2/README.md b/components/drivers/usb/cherryusb/port/dwc2/README.md index 2861cde737f..db82c6cfb29 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/README.md +++ b/components/drivers/usb/cherryusb/port/dwc2/README.md @@ -48,4 +48,8 @@ Please note that host must support dma mode. ### Nationstech -- N32H4X \ No newline at end of file +- N32H4X + +### Infineon + +- PSOC Edge E8X \ No newline at end of file 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 a5de3f29d7d..31be0d55db0 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c @@ -7,51 +7,6 @@ #include "usb_dwc2_reg.h" #include "usb_dwc2_param.h" -// clang-format off -#if defined ( __CC_ARM ) -#ifndef __UNALIGNED_UINT32_WRITE - #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) -#endif -#ifndef __UNALIGNED_UINT32_READ - #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) -#endif -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#ifndef __UNALIGNED_UINT32_WRITE - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wpacked" -/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ - __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; - #pragma clang diagnostic pop - #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) -#endif -#ifndef __UNALIGNED_UINT32_READ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wpacked" -/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ - __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; - #pragma clang diagnostic pop - #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) -#endif -#elif defined ( __GNUC__ ) -#ifndef __UNALIGNED_UINT32_WRITE - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpacked" - #pragma GCC diagnostic ignored "-Wattributes" - __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; - #pragma GCC diagnostic pop - #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) -#endif -#ifndef __UNALIGNED_UINT32_READ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpacked" - #pragma GCC diagnostic ignored "-Wattributes" - __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; - #pragma GCC diagnostic pop - #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) -#endif -#endif -// clang-format on - #define USBD_BASE (g_usbdev_bus[busid].reg_base) #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE)) @@ -61,8 +16,6 @@ #define USB_OTG_OUTEP(i) ((DWC2_OUTEndpointTypeDef *)(USBD_BASE + USB_OTG_OUT_ENDPOINT_BASE + ((i)*USB_OTG_EP_REG_SIZE))) #define USB_OTG_FIFO(i) *(__IO uint32_t *)(USBD_BASE + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE)) -extern uint32_t SystemCoreClock; - /* Endpoint state */ struct dwc2_ep_state { uint16_t ep_mps; /* Endpoint max packet size */ @@ -328,12 +281,11 @@ static uint8_t dwc2_get_devspeed(uint8_t busid) static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup) { - USB_OTG_OUTEP(0U)->DOEPTSIZ = 0U; - USB_OTG_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)); - USB_OTG_OUTEP(0U)->DOEPTSIZ |= (3U * 8U); - USB_OTG_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT; + USB_OTG_OUTEP(0U)->DOEPTSIZ = (1U * 8U) | (1U << 19) | (1U << 29); if (g_dwc2_udc[busid].user_params.device_dma_enable) { + usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE)); + USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup; /* EP enable */ USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP; @@ -342,25 +294,61 @@ static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup) void dwc2_ep_write(uint8_t busid, uint8_t ep_idx, uint8_t *src, uint16_t len) { - uint32_t *pSrc = (uint32_t *)src; - uint32_t count32b, i; + uint32_t *p32; + uint8_t *p8; + uint32_t val; + uint8_t remain; + + p32 = (uint32_t *)src; + for (uint32_t i = 0U; i < (len / 4); i++) { + USB_OTG_FIFO((uint32_t)ep_idx) = *p32++; + } - count32b = ((uint32_t)len + 3U) / 4U; - for (i = 0U; i < count32b; i++) { - USB_OTG_FIFO((uint32_t)ep_idx) = __UNALIGNED_UINT32_READ(pSrc); - pSrc++; + remain = len % 4; + + if (remain) { + p8 = (uint8_t *)p32; + val = (uint32_t)(*p8++); + + if (remain > 1) { + val |= (uint32_t)((*p8++) << 8); + } + + if (remain > 2) { + val |= (uint32_t)((*p8++) << 16); + } + + USB_OTG_FIFO((uint32_t)ep_idx) = val; } } void dwc2_ep_read(uint8_t busid, uint8_t *dest, uint16_t len) { - uint32_t *pDest = (uint32_t *)dest; - uint32_t i; - uint32_t count32b = ((uint32_t)len + 3U) / 4U; + uint32_t *p32; + uint8_t *p8; + uint32_t val; + uint8_t remain; + + p32 = (uint32_t *)dest; + for (uint32_t i = 0U; i < (len / 4); i++) { + *p32++ = USB_OTG_FIFO(0U); + } + + remain = len % 4; + + if (remain) { + p8 = (uint8_t *)p32; + val = USB_OTG_FIFO(0U); + + *p8++ = (uint8_t)(val & 0xFFU); - for (i = 0U; i < count32b; i++) { - __UNALIGNED_UINT32_WRITE(pDest, USB_OTG_FIFO(0U)); - pDest++; + if (remain > 1) { + *p8++ = (uint8_t)((val >> 8) & 0xFFU); + } + + if (remain > 2) { + *p8++ = (uint8_t)((val >> 16) & 0xFFU); + } } } @@ -530,6 +518,19 @@ int usb_dc_init(uint8_t busid) /* Force Device Mode*/ dwc2_set_mode(busid, USB_OTG_MODE_DEVICE); + USB_ASSERT_MSG((USB_OTG_GLB->GRXFSIZ & 0xffff) >= g_dwc2_udc[busid].user_params.device_rx_fifo_size, + "device_rx_fifo_size cannot be larger than power_on_value %u", (unsigned int)(USB_OTG_GLB->GRXFSIZ & 0xffff)); + for (uint8_t i = 0; i < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1); i++) { + uint16_t reset_txfifo_size; + if (i == 0) { + reset_txfifo_size = USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ >> 16 & 0xffff; + } else { + reset_txfifo_size = USB_OTG_GLB->DIEPTXF[i - 1] >> 16 & 0xffff; + } + USB_ASSERT_MSG(reset_txfifo_size >= g_dwc2_udc[busid].user_params.device_tx_fifo_size[i], + "device_tx_fifo_size[%u] cannot be larger than power_on_value %u", i, reset_txfifo_size); + } + if (g_dwc2_udc[busid].user_params.b_session_valid_override) { /* B-peripheral session valid override enable */ USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; @@ -675,6 +676,7 @@ uint8_t usbd_get_port_speed(uint8_t busid) int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) { uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress); + uint16_t ep_mps; USB_ASSERT_MSG(ep_idx < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1), "Ep addr %02x overflow", ep->bEndpointAddress); @@ -682,14 +684,34 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); g_dwc2_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx)); + ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + if (ep_idx == 0) { + switch (ep_mps) { + case 64: + ep_mps = EP_MPS_64; + break; + case 32: + ep_mps = EP_MPS_32; + break; + case 16: + ep_mps = EP_MPS_16; + break; + case 8: + ep_mps = EP_MPS_8; + break; - if ((USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_USBAEP) == 0) { - USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & USB_OTG_DOEPCTL_MPSIZ) | - ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | - USB_OTG_DIEPCTL_SD0PID_SEVNFRM | - USB_OTG_DOEPCTL_USBAEP; + default: + ep_mps = EP_MPS_64; + break; + } } + + USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx)); + + USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (ep_mps & USB_OTG_DOEPCTL_MPSIZ) | + ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DOEPCTL_USBAEP; } else { uint16_t fifo_size; if (ep_idx == 0) { @@ -703,14 +725,34 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) g_dwc2_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); g_dwc2_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx); + ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + if (ep_idx == 0) { + switch (ep_mps) { + case 64: + ep_mps = EP_MPS_64; + break; + case 32: + ep_mps = EP_MPS_32; + break; + case 16: + ep_mps = EP_MPS_16; + break; + case 8: + ep_mps = EP_MPS_8; + break; - if ((USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0) { - USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & USB_OTG_DIEPCTL_MPSIZ) | - ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | (ep_idx << 22) | - USB_OTG_DIEPCTL_SD0PID_SEVNFRM | - USB_OTG_DIEPCTL_USBAEP; + default: + ep_mps = EP_MPS_64; + break; + } } + + USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx); + + USB_OTG_INEP(ep_idx)->DIEPCTL |= (ep_mps & USB_OTG_DIEPCTL_MPSIZ) | + ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | (ep_idx << 22) | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DIEPCTL_USBAEP; dwc2_flush_txfifo(busid, ep_idx); } return 0; @@ -782,7 +824,6 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep) } if ((ep_idx == 0) && g_dwc2_udc[busid].user_params.device_dma_enable) { - usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE)); dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); } @@ -1046,7 +1087,7 @@ void USBD_IRQHandler(uint8_t busid) usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len); } } - // clang-format off + // clang-format off process_setup: // clang-format on if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) { @@ -1132,14 +1173,15 @@ void USBD_IRQHandler(uint8_t busid) memset(g_dwc2_udc[busid].in_ep, 0, sizeof(struct dwc2_ep_state) * 16); memset(g_dwc2_udc[busid].out_ep, 0, sizeof(struct dwc2_ep_state) * 16); usbd_event_reset_handler(busid); - /* Start reading setup */ - dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); } if (gint_status & USB_OTG_GINTSTS_ENUMDNE) { USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - dwc2_set_turnaroundtime(busid, SystemCoreClock, dwc2_get_devspeed(busid)); + dwc2_set_turnaroundtime(busid, usbd_dwc2_get_system_clock(), dwc2_get_devspeed(busid)); USB_OTG_DEV->DCTL |= USB_OTG_DCTL_CGINAK; + + /* Start reading setup */ + dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); } if (gint_status & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) { USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_PXFR_INCOMPISOOUT; diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h index 599d4ea58ff..69b0960032f 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h @@ -1733,4 +1733,6 @@ typedef struct void usb_dc_low_level_init(uint8_t busid); void usb_dc_low_level_deinit(uint8_t busid); void usbd_dwc2_delay_ms(uint8_t ms); +uint32_t usbd_dwc2_get_system_clock(void); + #endif diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c index 17dec47f3db..5fcb8151f16 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c @@ -9,8 +9,6 @@ extern unsigned int system_core_clock; -uint32_t SystemCoreClock; - const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, @@ -80,8 +78,6 @@ const struct dwc2_user_params param_pb14_pb15 = { #ifndef CONFIG_USB_DWC2_CUSTOM_PARAM void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) { - SystemCoreClock = system_core_clock; - #if __has_include("at32f402_405.h") if (reg_base == OTGHS_BASE) { memcpy(params, ¶m_pb14_pb15, sizeof(struct dwc2_user_params)); @@ -106,8 +102,13 @@ void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) void usbd_dwc2_delay_ms(uint8_t ms) { - uint32_t count = SystemCoreClock / 1000 * ms; + uint32_t count = system_core_clock / 1000 * ms; while (count--) { __asm volatile("nop"); } } + +uint32_t usbd_dwc2_get_system_clock(void) +{ + return system_core_clock; +} diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c index 03110fb8ce7..60231292891 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c @@ -151,7 +151,7 @@ void usb_dc_low_level_init(uint8_t busid) }; phy_config.target = GET_USB_PHY_TARGET(reg_base); phy_config.otg_speed = GET_USB_PHY_SPEED(reg_base); - + ret = usb_new_phy(&phy_config, &s_phy_handle[GET_USB_INDEX(reg_base)]); if (ret != ESP_OK) { USB_LOG_ERR("USB Phy Init Failed!\r\n"); @@ -262,6 +262,11 @@ void usbd_dwc2_delay_ms(uint8_t ms) vTaskDelay(pdMS_TO_TICKS(ms)); } +uint32_t usbd_dwc2_get_system_clock(void) +{ + return SystemCoreClock; +} + #ifdef CONFIG_USB_DCACHE_ENABLE #include "esp_cache.h" diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c index 15ba5d69a95..38e065ab135 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c @@ -1,30 +1,297 @@ /* - * Copyright (c) 2024, sakumisu + * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2025-08-08 CDT first version */ -#include "usb_config.h" -#include "usb_dwc2_reg.h" -/* When using [GPIO_SetFunc(USBF_VBUS_PORT, USBF_VBUS_PIN, USBF_VBUS_FUNC);], there is no need to configure GOTGCTL */ +#include "usbd_core.h" +#include "usbh_core.h" +#include "usb_dwc2_param.h" + +#include "board_config.h" + +#if defined(RT_CHERRYUSB_HOST) && defined(RT_CHERRYUSB_DEVICE) + #if defined(HC32F460) || defined(HC32F472) + #error "Only one USB role can be selected!" + #endif +#endif + +const struct dwc2_user_params param_fs_core = +{ + .phy_type = DWC2_PHY_TYPE_PARAM_FS, +#ifdef CONFIG_USB_DWC2_DMA_ENABLE + .device_dma_enable = true, +#else + .device_dma_enable = false, +#endif + .device_dma_desc_enable = false, + .device_rx_fifo_size = CONFIG_USB_FS_CORE_DEVICE_RX_FIFO_SIZE, + .device_tx_fifo_size = { + [0] = CONFIG_USB_FS_CORE_DEVICE_TX0_FIFO_SIZE, + [1] = CONFIG_USB_FS_CORE_DEVICE_TX1_FIFO_SIZE, + [2] = CONFIG_USB_FS_CORE_DEVICE_TX2_FIFO_SIZE, + [3] = CONFIG_USB_FS_CORE_DEVICE_TX3_FIFO_SIZE, + [4] = CONFIG_USB_FS_CORE_DEVICE_TX4_FIFO_SIZE, + [5] = CONFIG_USB_FS_CORE_DEVICE_TX5_FIFO_SIZE, +#if defined(HC32F4A0) || defined(HC32F4A8) + [6] = CONFIG_USB_FS_CORE_DEVICE_TX6_FIFO_SIZE, + [7] = CONFIG_USB_FS_CORE_DEVICE_TX7_FIFO_SIZE, + [8] = CONFIG_USB_FS_CORE_DEVICE_TX8_FIFO_SIZE, + [9] = CONFIG_USB_FS_CORE_DEVICE_TX9_FIFO_SIZE, + [10] = CONFIG_USB_FS_CORE_DEVICE_TX10_FIFO_SIZE, + [11] = CONFIG_USB_FS_CORE_DEVICE_TX11_FIFO_SIZE, + [12] = CONFIG_USB_FS_CORE_DEVICE_TX12_FIFO_SIZE, + [13] = CONFIG_USB_FS_CORE_DEVICE_TX13_FIFO_SIZE, + [14] = CONFIG_USB_FS_CORE_DEVICE_TX14_FIFO_SIZE, + [15] = CONFIG_USB_FS_CORE_DEVICE_TX15_FIFO_SIZE +#elif defined(HC32F460) || defined(HC32F472) + [6] = 0, + [7] = 0, + [8] = 0, + [9] = 0, + [10] = 0, + [11] = 0, + [12] = 0, + [13] = 0, + [14] = 0, + [15] = 0 +#endif + }, + .total_fifo_size = CONFIG_USB_FS_CORE_TOTAL_FIFO_SIZE, -#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(reg_base)) + .host_dma_desc_enable = false, + .host_rx_fifo_size = CONFIG_USB_FS_CORE_HOST_RX_FIFO_SIZE, + .host_nperio_tx_fifo_size = CONFIG_USB_FS_CORE_HOST_NP_FIFO_SIZE, + .host_perio_tx_fifo_size = CONFIG_USB_FS_CORE_HOST_PE_FIFO_SIZE, + .device_gccfg = 0, + .host_gccfg = 0, +#if defined(HC32F4A0) || defined(HC32F4A8) || defined(HC32F460) + .b_session_valid_override = false, +#elif defined(HC32F472) + .b_session_valid_override = true, +#endif +}; -uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) +#if defined(HC32F4A0) || defined(HC32F4A8) +const struct dwc2_user_params param_hs_core = { +#ifdef CONFIG_USB_HS + .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, +#else + .phy_type = DWC2_PHY_TYPE_PARAM_FS, +#endif +#ifdef CONFIG_USB_DWC2_DMA_ENABLE + .device_dma_enable = true, +#else + .device_dma_enable = false, +#endif + .device_dma_desc_enable = false, + .device_rx_fifo_size = CONFIG_USB_HS_CORE_DEVICE_RX_FIFO_SIZE, + .device_tx_fifo_size = { + [0] = CONFIG_USB_HS_CORE_DEVICE_TX0_FIFO_SIZE, + [1] = CONFIG_USB_HS_CORE_DEVICE_TX1_FIFO_SIZE, + [2] = CONFIG_USB_HS_CORE_DEVICE_TX2_FIFO_SIZE, + [3] = CONFIG_USB_HS_CORE_DEVICE_TX3_FIFO_SIZE, + [4] = CONFIG_USB_HS_CORE_DEVICE_TX4_FIFO_SIZE, + [5] = CONFIG_USB_HS_CORE_DEVICE_TX5_FIFO_SIZE, + [6] = CONFIG_USB_HS_CORE_DEVICE_TX6_FIFO_SIZE, + [7] = CONFIG_USB_HS_CORE_DEVICE_TX7_FIFO_SIZE, + [8] = CONFIG_USB_HS_CORE_DEVICE_TX8_FIFO_SIZE, + [9] = CONFIG_USB_HS_CORE_DEVICE_TX9_FIFO_SIZE, + [10] = CONFIG_USB_HS_CORE_DEVICE_TX10_FIFO_SIZE, + [11] = CONFIG_USB_HS_CORE_DEVICE_TX11_FIFO_SIZE, + [12] = CONFIG_USB_HS_CORE_DEVICE_TX12_FIFO_SIZE, + [13] = CONFIG_USB_HS_CORE_DEVICE_TX13_FIFO_SIZE, + [14] = CONFIG_USB_HS_CORE_DEVICE_TX14_FIFO_SIZE, + [15] = CONFIG_USB_HS_CORE_DEVICE_TX15_FIFO_SIZE + }, + .total_fifo_size = CONFIG_USB_HS_CORE_TOTAL_FIFO_SIZE, + + .host_dma_desc_enable = false, + .host_rx_fifo_size = CONFIG_USB_HS_CORE_HOST_RX_FIFO_SIZE, + .host_nperio_tx_fifo_size = CONFIG_USB_HS_CORE_HOST_NP_FIFO_SIZE, + .host_perio_tx_fifo_size = CONFIG_USB_HS_CORE_HOST_PE_FIFO_SIZE, + .device_gccfg = 0, + .host_gccfg = 0, + .b_session_valid_override = false, +}; +#endif - USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; - USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; - return 0; +#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM +void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) +{ +#if defined(HC32F4A0) || defined(HC32F4A8) + if (reg_base == CM_USBHS_BASE) + { + memcpy(params, ¶m_hs_core, sizeof(struct dwc2_user_params)); + } + else +#endif + { + memcpy(params, ¶m_fs_core, sizeof(struct dwc2_user_params)); + } +#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO + struct usb_dwc2_user_fifo_config s_dwc2_fifo_config; + + dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); + + params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) + { + params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; + } +#endif } +#endif -uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) +#define BOARD_INIT_USB_HOST_MODE (0U) +#define BOARD_INIT_USB_DEVICE_MODE (1U) +extern rt_err_t rt_hw_usbfs_board_init(uint8_t devmode); +static uint8_t g_usb_fs_busid = 0U; +#if defined(HC32F4A0) || defined(HC32F4A8) + extern rt_err_t rt_hw_usbhs_board_init(uint8_t devmode); + static uint8_t g_usb_hs_busid = 0U; +#endif + +#if defined(RT_CHERRYUSB_HOST) +static void usbh_fs_irq_handler(void) { - USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN; - USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL; - return 0; + USBH_IRQHandler(g_usb_fs_busid); } +#if defined(HC32F4A0) || defined(HC32F4A8) +static void usbh_hs_irq_handler(void) +{ + USBH_IRQHandler(g_usb_hs_busid); +} +#endif + +#if defined(HC32F472) +void USBFS_Handler(void) +{ + usbh_fs_irq_handler(); +} +#endif + +void usb_hc_low_level_init(struct usbh_bus *bus) +{ + struct hc32_irq_config irq_config; + +#if defined(HC32F4A0) || defined(HC32F4A8) + if (bus->hcd.reg_base == CM_USBHS_BASE) + { + g_usb_hs_busid = bus->hcd.hcd_id; + + rt_hw_usbhs_board_init(BOARD_INIT_USB_HOST_MODE); + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBHS, ENABLE); +#ifndef CONFIG_USB_HS + /* enable the embedded PHY in USBHS mode */ + CM_PERIC->USB_SYCTLREG |= PERIC_USB_SYCTLREG_USBHS_FSPHYE; +#endif + + irq_config.irq_num = BSP_USBHS_GLB_IRQ_NUM; + irq_config.int_src = INT_SRC_USBHS_GLB; + irq_config.irq_prio = BSP_USBHS_GLB_IRQ_PRIO; + /* register interrupt */ + hc32_install_irq_handler(&irq_config, + usbh_hs_irq_handler, + RT_TRUE); + } + else +#endif + { + g_usb_fs_busid = bus->hcd.hcd_id; + + rt_hw_usbfs_board_init(BOARD_INIT_USB_HOST_MODE); + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBFS, ENABLE); + + irq_config.irq_num = BSP_USBFS_GLB_IRQ_NUM; + irq_config.int_src = INT_SRC_USBFS_GLB; + irq_config.irq_prio = BSP_USBFS_GLB_IRQ_PRIO; + /* register interrupt */ + hc32_install_irq_handler(&irq_config, + usbh_fs_irq_handler, + RT_TRUE); + } + +} +#endif + +#if defined(RT_CHERRYUSB_DEVICE) +static void usbd_fs_irq_handler(void) +{ + USBD_IRQHandler(g_usb_fs_busid); +} + +#if defined(HC32F4A0) || defined(HC32F4A8) +static void usbd_hs_irq_handler(void) +{ + USBD_IRQHandler(g_usb_hs_busid); +} +#endif + +#if defined(HC32F472) +void USBFS_Handler(void) +{ + usbd_fs_irq_handler(); +} +#endif + +void usb_dc_low_level_init(uint8_t busid) +{ + struct hc32_irq_config irq_config; + +#if defined(HC32F4A0) || defined(HC32F4A8) + if (g_usbdev_bus[busid].reg_base == CM_USBHS_BASE) + { + g_usb_hs_busid = busid; + + rt_hw_usbhs_board_init(BOARD_INIT_USB_DEVICE_MODE); + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBHS, ENABLE); + +#ifndef CONFIG_USB_HS + /* enable the embedded PHY in USBHS mode */ + CM_PERIC->USB_SYCTLREG |= PERIC_USB_SYCTLREG_USBHS_FSPHYE; +#endif + + irq_config.irq_num = BSP_USBHS_GLB_IRQ_NUM; + irq_config.int_src = INT_SRC_USBHS_GLB; + irq_config.irq_prio = BSP_USBHS_GLB_IRQ_PRIO; + /* register interrupt */ + hc32_install_irq_handler(&irq_config, + usbd_hs_irq_handler, + RT_TRUE); + } + else +#endif + { + g_usb_fs_busid = busid; + + rt_hw_usbfs_board_init(BOARD_INIT_USB_DEVICE_MODE); + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBFS, ENABLE); + + irq_config.irq_num = BSP_USBFS_GLB_IRQ_NUM; + irq_config.int_src = INT_SRC_USBFS_GLB; + irq_config.irq_prio = BSP_USBFS_GLB_IRQ_PRIO; + /* register interrupt */ + hc32_install_irq_handler(&irq_config, + usbd_fs_irq_handler, + RT_TRUE); + } +} + +void usb_dc_low_level_deinit(uint8_t busid) +{ + (void)busid; + /* reserved */ +} + +#endif + extern uint32_t SystemCoreClock; void usbd_dwc2_delay_ms(uint8_t ms) @@ -34,3 +301,8 @@ void usbd_dwc2_delay_ms(uint8_t ms) __asm volatile("nop"); } } + +uint32_t usbd_dwc2_get_system_clock(void) +{ + return SystemCoreClock; +} diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c new file mode 100644 index 00000000000..19239ec891e --- /dev/null +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_infineon.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" +#include "usbh_core.h" +#include "usb_dwc2_param.h" +#include "rtthread.h" +#include "cybsp.h" + +#if defined (COMPONENT_CM55) + +#if defined(CONFIG_USB_DWC2_DMA_ENABLE) && !defined(CONFIG_USB_DCACHE_ENABLE) +#error "Please enable CONFIG_USB_DCACHE_ENABLE and put USB_NOCACHE_RAM_SECTION to section ".cy_socmem_data" when using DMA" +#endif + +#else +#define CONFIG_USB_DWC2_DMA_ENABLE +#endif + +const struct dwc2_user_params param_common = { + .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, +#ifdef CONFIG_USB_DWC2_DMA_ENABLE + .device_dma_enable = true, +#else + .device_dma_enable = false, +#endif + .device_dma_desc_enable = false, + .device_rx_fifo_size = 0x21F, + .device_tx_fifo_size = { + [0] = 16, // 64 byte + [1] = 0x300, // 1024 byte, tripple buffer + [2] = 0x300, // 1024 byte, tripple buffer + [3] = 0x300, // 1024 byte, tripple buffer + [4] = 0x300, // 1024 byte, tripple buffer + [5] = 0x300, // 1024 byte, tripple buffer + [6] = 0x300, // 1024 byte, tripple buffer + [7] = 0x300, // 1024 byte, tripple buffer + [8] = 0x300, // 1024 byte, tripple buffer + [9] = 0, + [10] = 0, + [11] = 0, + [12] = 0, + [13] = 0, + [14] = 0, + [15] = 0 }, + + .host_dma_desc_enable = false, + .host_rx_fifo_size = 0x21F, + .host_nperio_tx_fifo_size = 0x100, // 512 byte, double buffer + .host_perio_tx_fifo_size = 0x400, // 1024 byte, four buffer + + .device_gccfg = 0, + .host_gccfg = 0 +}; + +#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM +void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) +{ + memcpy(params, ¶m_common, sizeof(struct dwc2_user_params)); +#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO + struct usb_dwc2_user_fifo_config s_dwc2_fifo_config; + + dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); + + params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) { + params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; + } +#endif +} +#endif + +void USBHS_DEVICE_IRQHandler(void) +{ + USBD_IRQHandler(0); +} + +void usb_dc_low_level_init(uint8_t busid) +{ + USBHS_SS->SUBSYSTEM_CTL = (1 << USBHS_SS_SUBSYSTEM_CTL_AHB_MASTER_SYNC_Pos) | USBHS_SS_SUBSYSTEM_CTL_SS_ENABLE_Msk; + 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); + + cy_stc_sysint_t usb_int_cfg = { + .intrSrc = usbhs_interrupt_usbhsctrl_IRQn, + .intrPriority = 3 + }; + + /* Install the interrupt service routine */ + Cy_SysInt_Init(&usb_int_cfg, USBHS_DEVICE_IRQHandler); + + NVIC_EnableIRQ(usbhs_interrupt_usbhsctrl_IRQn); +} + +void usb_dc_low_level_deinit(uint8_t busid) +{ + NVIC_DisableIRQ(usbhs_interrupt_usbhsctrl_IRQn); +} + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + rt_thread_mdelay(ms); +} + +uint32_t usbd_dwc2_get_system_clock(void) +{ + return SystemCoreClock; +} + +void USBHS_HOST_IRQHandler(void) +{ + USBH_IRQHandler(0); +} + +void usb_hc_low_level_init(struct usbh_bus *bus) +{ + USBHS_SS->SUBSYSTEM_CTL = (1 << USBHS_SS_SUBSYSTEM_CTL_AHB_MASTER_SYNC_Pos) | USBHS_SS_SUBSYSTEM_CTL_USB_MODE_Msk | USBHS_SS_SUBSYSTEM_CTL_SS_ENABLE_Msk; + 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); + + cy_stc_sysint_t usb_int_cfg = { + .intrSrc = usbhs_interrupt_usbhsctrl_IRQn, + .intrPriority = 3 + }; + + /* Install the interrupt service routine */ + Cy_SysInt_Init(&usb_int_cfg, USBHS_HOST_IRQHandler); + + NVIC_EnableIRQ(usbhs_interrupt_usbhsctrl_IRQn); +} + +void usb_hc_low_level_deinit(struct usbh_bus *bus) +{ + NVIC_DisableIRQ(usbhs_interrupt_usbhsctrl_IRQn); +} + +#ifdef CONFIG_USB_DCACHE_ENABLE +void usb_dcache_clean(uintptr_t addr, size_t size) +{ + SCB_CleanDCache_by_Addr((void *)addr, size); +} + +void usb_dcache_invalidate(uintptr_t addr, size_t size) +{ + SCB_InvalidateDCache_by_Addr((void *)addr, size); +} + +void usb_dcache_flush(uintptr_t addr, size_t size) +{ + SCB_CleanInvalidateDCache_by_Addr((void *)addr, size); +} +#endif diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c index 36c7791eebb..4e111ddb955 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c @@ -50,11 +50,7 @@ const uintptr_t usb_dev_addr[2] = { 0x91500000UL, 0x91540000UL }; const struct dwc2_user_params param_common = { .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, -#ifdef CONFIG_USB_DWC2_DMA_ENABLE .device_dma_enable = true, -#else - .device_dma_enable = false, -#endif .device_dma_desc_enable = false, .device_rx_fifo_size = (3016 - 16 - 256 * 8), .device_tx_fifo_size = { @@ -204,6 +200,11 @@ void usbd_dwc2_delay_ms(uint8_t ms) rt_thread_mdelay(ms); } +uint32_t usbd_dwc2_get_system_clock(void) +{ + return SystemCoreClock; +} + #ifdef CONFIG_USB_DCACHE_ENABLE void usb_dcache_clean(uintptr_t addr, size_t size) { diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c index 5e6391fc2c5..b766ca4b5d7 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c @@ -16,10 +16,10 @@ const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, .device_dma_desc_enable = false, - .device_rx_fifo_size = (320 - 16 - 16 - 16 - 16), + .device_rx_fifo_size = (320 - 16 - 64 - 16 - 16), .device_tx_fifo_size = { [0] = 16, // 64 byte - [1] = 16, // 64 byte + [1] = 64, // 256 byte [2] = 16, // 64 byte [3] = 16, // 64 byte [4] = 0, @@ -50,10 +50,10 @@ const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, .device_dma_desc_enable = false, - .device_rx_fifo_size = (320 - 16 - 16 - 16 - 16), + .device_rx_fifo_size = (320 - 16 - 64 - 16 - 16), .device_tx_fifo_size = { [0] = 16, // 64 byte - [1] = 16, // 64 byte + [1] = 64, // 256 byte [2] = 16, // 64 byte [3] = 16, // 64 byte [4] = 0, @@ -124,10 +124,10 @@ const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, .device_dma_desc_enable = false, - .device_rx_fifo_size = (320 - 16 - 16 - 16 - 16), + .device_rx_fifo_size = (320 - 16 - 64 - 16 - 16), .device_tx_fifo_size = { [0] = 16, // 64 byte - [1] = 16, // 64 byte + [1] = 64, // 256 byte [2] = 16, // 64 byte [3] = 16, // 64 byte [4] = 0, @@ -212,10 +212,10 @@ const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, .device_dma_desc_enable = false, - .device_rx_fifo_size = (320 - 16 - 16 - 16 - 16), + .device_rx_fifo_size = (320 - 16 - 64 - 16 - 16), .device_tx_fifo_size = { [0] = 16, // 64 byte - [1] = 16, // 64 byte + [1] = 64, // 256 byte [2] = 16, // 64 byte [3] = 16, // 64 byte [4] = 0, @@ -380,10 +380,10 @@ const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, .device_dma_desc_enable = false, - .device_rx_fifo_size = (320 - 16 - 16 - 16 - 16), + .device_rx_fifo_size = (320 - 16 - 64 - 16 - 16), .device_tx_fifo_size = { [0] = 16, // 64 byte - [1] = 16, // 64 byte + [1] = 64, // 256 byte [2] = 16, // 64 byte [3] = 16, // 64 byte [4] = 0, @@ -446,10 +446,10 @@ const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, .device_dma_desc_enable = false, - .device_rx_fifo_size = (320 - 16 - 16 - 16 - 16), + .device_rx_fifo_size = (320 - 16 - 64 - 16 - 16), .device_tx_fifo_size = { [0] = 16, // 64 byte - [1] = 16, // 64 byte + [1] = 64, // 256 byte [2] = 16, // 64 byte [3] = 16, // 64 byte [4] = 0, @@ -481,10 +481,10 @@ const struct dwc2_user_params param_pa11_pa12 = { .phy_type = DWC2_PHY_TYPE_PARAM_FS, .device_dma_enable = false, .device_dma_desc_enable = false, - .device_rx_fifo_size = (320 - 16 - 16 - 16 - 16), + .device_rx_fifo_size = (320 - 16 - 64 - 16 - 16), .device_tx_fifo_size = { [0] = 16, // 64 byte - [1] = 16, // 64 byte + [1] = 64, // 256 byte [2] = 16, // 64 byte [3] = 16, // 64 byte [4] = 0, @@ -722,6 +722,11 @@ void usbd_dwc2_delay_ms(uint8_t ms) } } +uint32_t usbd_dwc2_get_system_clock(void) +{ + return SystemCoreClock; +} + void OTG_FS_IRQHandler(void) { g_usb_dwc2_irq[0](g_usb_dwc2_busid[0]); 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 df706eda166..bf0adae5719 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c @@ -339,22 +339,6 @@ static inline void dwc2_chan_enable_csplit(struct usbh_bus *bus, uint8_t ch_num, } } -static inline void dwc2_chan_reenable(struct usbh_bus *bus, uint8_t ch_num) -{ - __IO uint32_t tmpreg; - uint8_t is_oddframe; - - is_oddframe = (((uint32_t)USB_OTG_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U; - USB_OTG_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM; - USB_OTG_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29; - - /* Set host channel enable */ - tmpreg = USB_OTG_HC(ch_num)->HCCHAR; - tmpreg &= ~USB_OTG_HCCHAR_CHDIS; - tmpreg |= USB_OTG_HCCHAR_CHENA; - USB_OTG_HC(ch_num)->HCCHAR = tmpreg; -} - static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num) { volatile uint32_t ChannelEna = (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31; @@ -731,6 +715,13 @@ int usb_hc_init(struct usbh_bus *bus) /* Force Host Mode*/ dwc2_set_mode(bus, USB_OTG_MODE_HOST); + USB_ASSERT_MSG((USB_OTG_GLB->GRXFSIZ & 0xffff) >= g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size, + "host_rx_fifo_size cannot be larger than power_on_value %u", (unsigned int)(USB_OTG_GLB->GRXFSIZ & 0xffff)); + USB_ASSERT_MSG((USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ & 0xffff) >= g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size, + "host_nperio_tx_fifo_size cannot be larger than power_on_value %u", (unsigned int)(USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ & 0xffff)); + USB_ASSERT_MSG((USB_OTG_GLB->HPTXFSIZ & 0xffff) >= g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_perio_tx_fifo_size, + "host_perio_tx_fifo_size cannot be larger than power_on_value %u", (unsigned int)(USB_OTG_GLB->HPTXFSIZ & 0xffff)); + /* B-peripheral session valid override enable */ USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN; USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL; @@ -745,13 +736,15 @@ int usb_hc_init(struct usbh_bus *bus) USB_OTG_HOST->HCFG &= ~USB_OTG_HCFG_FSLSPCS; if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) { + bus->hcd.roothub.speed = USB_SPEED_FULL; USB_OTG_HOST->HCFG |= USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ; } else { + bus->hcd.roothub.speed = USB_SPEED_HIGH; USB_OTG_HOST->HCFG |= USB_OTG_HCFG_FSLSPCLKSEL_30_60_MHZ; } if (g_dwc2_hcd[bus->hcd.hcd_id].hw_params.snpsid > 0x4F54292AU) { - USB_OTG_HOST->HCFG |= USB_OTG_HFIR_RELOAD_CTRL; + USB_OTG_HOST->HFIR |= USB_OTG_HFIR_RELOAD_CTRL; } /* Clear all pending HC Interrupts */ @@ -766,7 +759,7 @@ int usb_hc_init(struct usbh_bus *bus) /* Clear any pending interrupts */ USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU; - /* set Rx FIFO size */ + /* set FIFO size */ USB_OTG_GLB->GRXFSIZ = g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size; USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size << 16) & USB_OTG_NPTXFD) | g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size); @@ -794,36 +787,14 @@ int usb_hc_init(struct usbh_bus *bus) int usb_hc_deinit(struct usbh_bus *bus) { - volatile uint32_t count = 0U; - uint32_t value; - USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; dwc2_flush_txfifo(bus, 0x10U); dwc2_flush_rxfifo(bus); /* Flush out any leftover queued requests. */ - for (uint32_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) { - value = USB_OTG_HC(i)->HCCHAR; - value |= USB_OTG_HCCHAR_CHDIS; - value &= ~USB_OTG_HCCHAR_CHENA; - value &= ~USB_OTG_HCCHAR_EPDIR; - USB_OTG_HC(i)->HCCHAR = value; - } - - /* Halt all channels to put them into a known state. */ - for (uint32_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) { - value = USB_OTG_HC(i)->HCCHAR; - value |= USB_OTG_HCCHAR_CHDIS; - value |= USB_OTG_HCCHAR_CHENA; - value &= ~USB_OTG_HCCHAR_EPDIR; - USB_OTG_HC(i)->HCCHAR = value; - - do { - if (++count > 1000U) { - return -USB_ERR_TIMEOUT; - } - } while ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + for (uint8_t chidx = 0; chidx < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; chidx++) { + dwc2_halt(bus, chidx); } /* Disable all interrupts. */ @@ -1235,12 +1206,15 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) /* restart ssplit transfer */ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { case USB_ENDPOINT_TYPE_CONTROL: + chan->do_csplit = 0; + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; case USB_ENDPOINT_TYPE_BULK: chan->do_csplit = 0; - dwc2_chan_enable_csplit(bus, ch_num, false); - dwc2_chan_reenable(bus, ch_num); + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); break; case USB_ENDPOINT_TYPE_INTERRUPT: + chan->do_csplit = 0; dwc2_chan_enable_csplit(bus, ch_num, false); urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb); @@ -1255,17 +1229,39 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) } } else if (chan_intstatus & USB_OTG_HCINT_ACK) { if (chan->do_ssplit) { - /* start ssplit transfer */ + /* start csplit transfer */ chan->do_csplit = 1; chan->ssplit_frame = dwc2_get_full_frame_num(bus); - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } } else if (chan_intstatus & USB_OTG_HCINT_NYET) { if (chan->do_ssplit) { /* restart csplit transfer */ - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + chan->do_csplit = 1; + chan->ssplit_frame = dwc2_get_full_frame_num(bus); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } else { urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb); @@ -1372,12 +1368,15 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) /* restart ssplit transfer */ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { case USB_ENDPOINT_TYPE_CONTROL: + chan->do_csplit = 0; + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; case USB_ENDPOINT_TYPE_BULK: chan->do_csplit = 0; - dwc2_chan_enable_csplit(bus, ch_num, false); - dwc2_chan_reenable(bus, ch_num); + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); break; case USB_ENDPOINT_TYPE_INTERRUPT: + chan->do_csplit = 0; dwc2_chan_enable_csplit(bus, ch_num, false); urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb); @@ -1392,17 +1391,39 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) } } else if (chan_intstatus & USB_OTG_HCINT_ACK) { if (chan->do_ssplit) { - /* start ssplit transfer */ + /* start csplit transfer */ chan->do_csplit = 1; chan->ssplit_frame = dwc2_get_full_frame_num(bus); - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } } else if (chan_intstatus & USB_OTG_HCINT_NYET) { if (chan->do_ssplit) { /* restart csplit transfer */ - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + chan->do_csplit = 1; + chan->ssplit_frame = dwc2_get_full_frame_num(bus); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } else { urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb); diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c b/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c index 500bc02a40d..2db67bc5739 100644 --- a/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c +++ b/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2022, Artinchip Technology Co., Ltd * * SPDX-License-Identifier: Apache-2.0 @@ -46,37 +46,31 @@ typedef struct aic_ehci_config { uint32_t phy_clk_id; uint32_t phy_rst_id; uint32_t irq_num; -}aic_ehci_config_t; +} aic_ehci_config_t; aic_ehci_config_t config[] = { #ifdef AIC_USING_USB0_HOST - { - USB_HOST0_BASE, - CLK_USBH0, - RESET_USBH0, - CLK_USB_PHY0, - RESET_USBPHY0, - USB_HOST0_EHCI_IRQn - }, + { USB_HOST0_BASE, + CLK_USBH0, + RESET_USBH0, + CLK_USB_PHY0, + RESET_USBPHY0, + USB_HOST0_EHCI_IRQn }, #else - { - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF - }, + { 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF }, #endif #ifdef AIC_USING_USB1_HOST - { - USB_HOST1_BASE, - CLK_USBH1, - RESET_USBH1, - CLK_USB_PHY1, - RESET_USBPHY1, - USB_HOST1_EHCI_IRQn - } + { USB_HOST1_BASE, + CLK_USBH1, + RESET_USBH1, + CLK_USB_PHY1, + RESET_USBPHY1, + USB_HOST1_EHCI_IRQn } #endif }; @@ -85,12 +79,12 @@ void usb_hc_low_level_init(struct usbh_bus *bus) uint32_t val; int i = 0; - for (i=0; ihcd.reg_base == config[i].base_addr) break; } - if (i == sizeof(config)/sizeof(aic_ehci_config_t)) + if (i == sizeof(config) / sizeof(aic_ehci_config_t)) return; /* set usb0 phy switch: Host/Device */ @@ -109,20 +103,20 @@ void usb_hc_low_level_init(struct usbh_bus *bus) aicos_udelay(300); /* set phy type: UTMI/ULPI */ - val = readl((volatile void *)(unsigned long)(config[i].base_addr+0x800)); + val = readl((volatile void *)(unsigned long)(config[i].base_addr + 0x800)); #ifdef FPGA_BOARD_ARTINCHIP /* fpga phy type = ULPI */ - writel((val & ~0x1U), (volatile void *)(unsigned long)(config[i].base_addr+0x800)); + writel((val & ~0x1U), (volatile void *)(unsigned long)(config[i].base_addr + 0x800)); #else /* board phy type = UTMI */ - writel((val | 0x1), (volatile void *)(unsigned long)(config[i].base_addr+0x800)); + writel((val | 0x1), (volatile void *)(unsigned long)(config[i].base_addr + 0x800)); #endif /* Set AHB2STBUS_INSREG01 Set EHCI packet buffer IN/OUT threshold (in DWORDs) Must increase the OUT threshold to avoid underrun. (FIFO size - 4) */ - writel((32 | (127 << 16)), (volatile void *)(unsigned long)(config[i].base_addr+0x94)); + writel((32 | (127 << 16)), (volatile void *)(unsigned long)(config[i].base_addr + 0x94)); /* register interrupt callback */ aicos_request_irq(config[i].irq_num, (irq_handler_t)aic_ehci_isr, @@ -160,12 +154,12 @@ int __usbh_init(void) #endif #ifdef AIC_USING_USB0_HOST - usbh_initialize(bus_id, USB_HOST0_BASE); + usbh_initialize(bus_id, USB_HOST0_BASE, NULL); bus_id++; #endif #ifdef AIC_USING_USB1_HOST - usbh_initialize(bus_id, USB_HOST1_BASE); + usbh_initialize(bus_id, USB_HOST1_BASE, NULL); bus_id++; #endif return 0; diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_glue_t113.c b/components/drivers/usb/cherryusb/port/ehci/usb_glue_t113.c index 0c99897fd58..ec46dea61d8 100644 --- a/components/drivers/usb/cherryusb/port/ehci/usb_glue_t113.c +++ b/components/drivers/usb/cherryusb/port/ehci/usb_glue_t113.c @@ -1,18 +1,27 @@ /* - * Copyright (c) 2025, YC113 + * Copyright (c) 2026, HakumenJean * * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-01-06 HakumenJean first version */ + +#include +#include +#include +#include + #include "usbh_core.h" #include "usb_hc_ehci.h" - #ifdef CONFIG_USB_EHCI_WITH_OHCI #include "usb_hc_ohci.h" #endif +#include "hal_clk.h" +#include "hal_reset.h" #include "interrupt.h" -#include "drv_reg_base.h" -#include "drv_clock.h" #if CONFIG_USBHOST_MAX_BUS != 2 #error "t113 has 2 usb host controller" @@ -34,6 +43,13 @@ #error "t113 usb ehci no iso register" #endif +#define USB0_OTG_BASE_ADDR (0x04100000U) +#define USB0_PHY_BASE_ADDR (0x04100400U) +#define USB0_EHCI_BASE_ADDR (0x04101000U) + +#define USB1_EHCI_BASE_ADDR (0x04200000U) +#define USB1_PHY_BASE_ADDR (0x04200800U) + void usb_select_phyTohci(void) { *(volatile rt_uint32_t *)(USB0_OTG_BASE_ADDR + 0x420) &= ~(1 << 0); @@ -41,55 +57,52 @@ void usb_select_phyTohci(void) void usb_gate_open(rt_uint8_t busid) { - rt_uint32_t addr; - - addr = (rt_uint32_t)&CCU->usb0_clk + busid * 4; - - if(busid == 0) { + if (busid == 0) { /* otg gate open*/ - CCU->usb_bgr |= 1 << 8; + hal_clock_enable(hal_clock_get(HAL_SUNXI_CCU, CLK_BUS_OTG)); /* otg bus reset */ - CCU->usb_bgr &= ~(1 << 24); - sdelay(10); - CCU->usb_bgr |= (1 << 24); - sdelay(10); - } + hal_reset_control_reset(hal_reset_control_get(HAL_SUNXI_RESET, RST_BUS_OTG)); + + /* ehci gate open */ + hal_clock_enable(hal_clock_get(HAL_SUNXI_CCU, CLK_BUS_EHCI0)); + + /* ehci bus reset */ + hal_reset_control_reset(hal_reset_control_get(HAL_SUNXI_RESET, RST_BUS_EHCI0)); + + /* ohci gate open */ + hal_clock_enable(hal_clock_get(HAL_SUNXI_CCU, CLK_BUS_OHCI0)); - /* ehci gate open */ - CCU->usb_bgr |= (1 << 4) << busid; + /* ohci bus reset */ + hal_reset_control_reset(hal_reset_control_get(HAL_SUNXI_RESET, RST_BUS_OHCI0)); - /* ehci bus reset */ - CCU->usb_bgr &= ~((1 << 20) << busid); - sdelay(10); - CCU->usb_bgr |= (1 << 20) << busid; - sdelay(10); + /* clock enable */ + hal_clock_enable(hal_clock_get(HAL_SUNXI_CCU, CLK_USB_OHCI0)); - /* ohci gate open */ - CCU->usb_bgr |= 1 << busid; + /* reset phy */ + hal_reset_control_reset(hal_reset_control_get(HAL_SUNXI_RESET, RST_USB_PHY0)); - /* ohci bus reset */ - CCU->usb_bgr &= ~((1 << 16) << busid); - sdelay(10); - CCU->usb_bgr |= (1 << 16) << busid; - sdelay(10); + /* otg phy select */ + usb_select_phyTohci(); + } else { + /* ehci gate open */ + hal_clock_enable(hal_clock_get(HAL_SUNXI_CCU, CLK_BUS_EHCI1)); - sdelay(10); + /* ehci bus reset */ + hal_reset_control_reset(hal_reset_control_get(HAL_SUNXI_RESET, RST_BUS_EHCI1)); - /* clock enable */ - *(volatile rt_uint32_t *)addr &= ~(3 << 24); - *(volatile rt_uint32_t *)addr |= (1 << 31) | (1 << 24); + /* ohci gate open */ + hal_clock_enable(hal_clock_get(HAL_SUNXI_CCU, CLK_BUS_OHCI1)); - /* reset phy */ - *(volatile rt_uint32_t *)addr &= ~(1 << 30); - sdelay(10); - *(volatile rt_uint32_t *)addr |= 1 << 30; - sdelay(10); + /* ohci bus reset */ + hal_reset_control_reset(hal_reset_control_get(HAL_SUNXI_RESET, RST_BUS_OHCI1)); - /* otg phy select */ - if(busid == 0) usb_select_phyTohci(); + /* clock enable */ + hal_clock_enable(hal_clock_get(HAL_SUNXI_CCU, CLK_USB_OHCI1)); - USB_LOG_DBG("usb%d gate : %X, clock : %X\n", busid, CCU->usb_bgr, *(volatile rt_uint32_t *)addr); + /* reset phy */ + hal_reset_control_reset(hal_reset_control_get(HAL_SUNXI_RESET, RST_USB_PHY1)); + } } void usb_clean_siddp(struct usbh_bus *bus) @@ -109,10 +122,10 @@ void usb_hci_set_passby(struct usbh_bus *bus) void t113_ehci_isr(int vector, void *arg) { - rt_interrupt_enter(); - struct usbh_bus *bus = (struct usbh_bus *)arg; + rt_interrupt_enter(); + USB_LOG_DBG("t113_ehci_isr"); extern void USBH_IRQHandler(uint8_t busid); @@ -125,10 +138,10 @@ void t113_ehci_isr(int vector, void *arg) void t113_ohci_isr(int vector, void *arg) { - rt_interrupt_enter(); - struct usbh_bus *bus = (struct usbh_bus *)arg; + rt_interrupt_enter(); + USB_LOG_DBG("t113_ohci_isr"); extern void OHCI_IRQHandler(uint8_t busid); @@ -149,8 +162,9 @@ void usb_hc_low_level_init(struct usbh_bus *bus) usb_hci_set_passby(bus); /* register EHCI interrupt callback */ - vector = T113_IRQ_USB0_EHCI + (bus->busid > 0 ? 3 : 0); + vector = SUNXI_IRQ_USB0_EHCI + (bus->busid > 0 ? 3 : 0); rt_hw_interrupt_install(vector, t113_ehci_isr, bus, RT_NULL); + rt_hw_interrupt_set_priority(vector, 11 << 4); rt_hw_interrupt_umask(vector); /* register OHCI interrupt callback */ @@ -183,12 +197,12 @@ int __usbh_init(void) { #ifdef T113_USING_USB0_HOST /* USB0 MSC test OK */ - usbh_initialize(0, USB0_BASE_ADDR); + usbh_initialize(0, USB0_EHCI_BASE_ADDR, NULL); #endif #ifdef T113_USING_USB1_HOST /* USB1 MSC test OK */ - usbh_initialize(1, USB1_BASE_ADDR); + usbh_initialize(1, USB1_EHCI_BASE_ADDR, NULL); #endif return 0; } @@ -196,8 +210,26 @@ int __usbh_init(void) #ifdef PKG_CHERRYUSB_HOST #include +#include #include INIT_ENV_EXPORT(__usbh_init); +#ifdef CONFIG_USB_DCACHE_ENABLE +void usb_dcache_clean(uintptr_t addr, size_t size) +{ + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)addr, size); +} + +void usb_dcache_invalidate(uintptr_t addr, size_t size) +{ + rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, (void *)addr, size); +} + +void usb_dcache_flush(uintptr_t addr, size_t size) +{ + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)addr, size); +} +#endif + #endif diff --git a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c index 2ebe11347cb..fd72907f89d 100644 --- a/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c +++ b/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c @@ -774,6 +774,8 @@ int usb_hc_init(struct usbh_bus *bus) volatile uint32_t timeout = 0; uint32_t regval; + bus->hcd.roothub.speed = USB_SPEED_HIGH; + memset(&g_ehci_hcd[bus->hcd.hcd_id], 0, sizeof(struct ehci_hcd)); memset(ehci_qh_pool[bus->hcd.hcd_id], 0, sizeof(struct ehci_qh_hw) * CONFIG_USB_EHCI_QH_NUM); memset(ehci_qtd_pool[bus->hcd.hcd_id], 0, sizeof(struct ehci_qtd_hw) * CONFIG_USB_EHCI_QTD_NUM); @@ -1337,6 +1339,7 @@ int usbh_kill_urb(struct usbh_urb *urb) EHCI_HCOR->usbcmd |= (EHCI_USBCMD_PSEN | EHCI_USBCMD_ASEN); qh = (struct ehci_qh_hw *)urb->hcpriv; + qh->remove_in_iaad = 0; urb->errorcode = -USB_ERR_SHUTDOWN; if (urb->timeout) { @@ -1347,6 +1350,7 @@ int usbh_kill_urb(struct usbh_urb *urb) if (remove_in_iaad) { volatile uint32_t timeout = 0; + EHCI_HCOR->usbsts = EHCI_USBSTS_IAA; EHCI_HCOR->usbcmd |= EHCI_USBCMD_IAAD; while (!(EHCI_HCOR->usbsts & EHCI_USBSTS_IAA)) { timeout++; 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 09896549abb..a3a9fdc10d9 100644 --- a/components/drivers/usb/cherryusb/port/hpmicro/usb_dc_hpm.c +++ b/components/drivers/usb/cherryusb/port/hpmicro/usb_dc_hpm.c @@ -102,7 +102,9 @@ int usb_dc_init(uint8_t busid) #endif usb_device_init(g_hpm_udc[busid].handle, int_mask); - +#ifdef CONFIG_USB_OTG_ENABLE + usb_otgsc_enable_id_chg_int(g_hpm_udc[busid].handle->regs); +#endif usb_dc_isr_connect(busid); return 0; @@ -240,10 +242,15 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui return -2; } +#ifdef CONFIG_USB_DCACHE_ENABLE + USB_ASSERT_MSG(!((uintptr_t)data % CONFIG_USB_ALIGN_SIZE), "data is not aligned %d", CONFIG_USB_ALIGN_SIZE); +#endif + g_hpm_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data; g_hpm_udc[busid].in_ep[ep_idx].xfer_len = data_len; 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); return 0; @@ -261,10 +268,15 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t return -2; } +#ifdef CONFIG_USB_DCACHE_ENABLE + USB_ASSERT_MSG(!((uintptr_t)data % CONFIG_USB_ALIGN_SIZE), "data is not aligned %d", CONFIG_USB_ALIGN_SIZE); +#endif + g_hpm_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data; g_hpm_udc[busid].out_ep[ep_idx].xfer_len = data_len; 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); return 0; @@ -297,7 +309,7 @@ void USBD_IRQHandler(uint8_t busid) memset(g_hpm_udc[busid].in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); 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, 64); + usb_device_bus_reset(handle, g_hpm_udc[busid].in_ep[0].ep_mps); } if (int_status & intr_suspend) { @@ -362,6 +374,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)); usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len); } } diff --git a/components/drivers/usb/cherryusb/port/hpmicro/usb_glue_hpm.c b/components/drivers/usb/cherryusb/port/hpmicro/usb_glue_hpm.c index 51aa9aa452e..aa5f9cec664 100644 --- a/components/drivers/usb/cherryusb/port/hpmicro/usb_glue_hpm.c +++ b/components/drivers/usb/cherryusb/port/hpmicro/usb_glue_hpm.c @@ -7,11 +7,73 @@ #include "hpm_common.h" #include "hpm_soc.h" #include "hpm_l1c_drv.h" +#include "hpm_usb_drv.h" #include "usb_config.h" void (*g_usb_hpm_irq[2])(uint8_t busid); uint8_t g_usb_hpm_busid[2]; +#ifndef CONFIG_CHERRYUSB_CUSTOM_IRQ_HANDLER +SDK_DECLARE_EXT_ISR_M(IRQn_USB0, hpm_isr_usb0) +#ifdef HPM_USB1_BASE +SDK_DECLARE_EXT_ISR_M(IRQn_USB1, hpm_isr_usb1) +#endif +#endif + +#ifdef CONFIG_USB_OTG_ENABLE +#include "usbotg_core.h" +int usb_otg_init(uint8_t busid) +{ + (void)busid; + + return 0; +} + +int usb_otg_deinit(uint8_t busid) +{ + (void)busid; + + return 0; +} + +void hpm_isr_usb0(void) +{ + if (usb_otgsc_get_id_chg_flag(HPM_USB0)) { + usb_otgsc_clear_id_chg_flag(HPM_USB0); + usbotg_trigger_role_change(g_usb_hpm_busid[0], usb_otgsc_get_id_status(HPM_USB0) ? USBOTG_MODE_DEVICE : USBOTG_MODE_HOST); + } + + USBOTG_IRQHandler(g_usb_hpm_busid[0]); +} + +#ifdef HPM_USB1_BASE +void hpm_isr_usb1(void) +{ + if (usb_otgsc_get_id_chg_flag(HPM_USB1)) { + usb_otgsc_clear_id_chg_flag(HPM_USB1); + usbotg_trigger_role_change(g_usb_hpm_busid[1], usb_otgsc_get_id_status(HPM_USB1) ? USBOTG_MODE_DEVICE : USBOTG_MODE_HOST); + } + + USBOTG_IRQHandler(g_usb_hpm_busid[1]); +} +#endif + +#else + +void hpm_isr_usb0(void) +{ + g_usb_hpm_irq[0](g_usb_hpm_busid[0]); +} + +#ifdef HPM_USB1_BASE +void hpm_isr_usb1(void) +{ + g_usb_hpm_irq[1](g_usb_hpm_busid[1]); +} +#endif + +#endif + ATTR_WEAK void hpm_usb_isr_enable(uint32_t base) { if (base == HPM_USB0_BASE) { @@ -34,24 +96,6 @@ ATTR_WEAK void hpm_usb_isr_disable(uint32_t base) } } -#ifndef CONFIG_CHERRYUSB_CUSTOM_IRQ_HANDLER -SDK_DECLARE_EXT_ISR_M(IRQn_USB0, hpm_isr_usb0) -#endif -void hpm_isr_usb0(void) -{ - g_usb_hpm_irq[0](g_usb_hpm_busid[0]); -} - -#ifdef HPM_USB1_BASE -#ifndef CONFIG_CHERRYUSB_CUSTOM_IRQ_HANDLER -SDK_DECLARE_EXT_ISR_M(IRQn_USB1, hpm_isr_usb1) -#endif -void hpm_isr_usb1(void) -{ - g_usb_hpm_irq[1](g_usb_hpm_busid[1]); -} -#endif - #ifdef CONFIG_USB_DCACHE_ENABLE void usb_dcache_clean(uintptr_t addr, size_t size) { @@ -67,4 +111,4 @@ void usb_dcache_flush(uintptr_t addr, size_t size) { l1c_dc_flush(addr, size); } -#endif \ No newline at end of file +#endif diff --git a/components/drivers/usb/cherryusb/port/hpmicro/usb_hc_hpm.c b/components/drivers/usb/cherryusb/port/hpmicro/usb_hc_hpm.c index 9ee515008b6..2c340573ca5 100644 --- a/components/drivers/usb/cherryusb/port/hpmicro/usb_hc_hpm.c +++ b/components/drivers/usb/cherryusb/port/hpmicro/usb_hc_hpm.c @@ -57,31 +57,29 @@ void usb_hc_low_level2_init(struct usbh_bus *bus) if (bus->hcd.reg_base == HPM_USB0_BASE) { g_usb_hpm_busid[0] = bus->hcd.hcd_id; g_usb_hpm_irq[0] = USBH_IRQHandler; - - hpm_usb_isr_enable(HPM_USB0_BASE); } else { #ifdef HPM_USB1_BASE g_usb_hpm_busid[1] = bus->hcd.hcd_id; g_usb_hpm_irq[1] = USBH_IRQHandler; - - hpm_usb_isr_enable(HPM_USB1_BASE); #endif } + +#ifdef CONFIG_USB_OTG_ENABLE + usb_otgsc_enable_id_chg_int((USB_Type *)(bus->hcd.reg_base)); +#endif + hpm_usb_isr_enable(bus->hcd.reg_base); } void usb_hc_low_level_deinit(struct usbh_bus *bus) { usb_phy_deinit((USB_Type *)(bus->hcd.reg_base)); + hpm_usb_isr_disable(bus->hcd.reg_base); if (bus->hcd.reg_base == HPM_USB0_BASE) { - hpm_usb_isr_disable(HPM_USB0_BASE); - g_usb_hpm_busid[0] = 0; g_usb_hpm_irq[0] = NULL; } else { #ifdef HPM_USB1_BASE - hpm_usb_isr_disable(HPM_USB1_BASE); - g_usb_hpm_busid[1] = 0; g_usb_hpm_irq[1] = NULL; #endif diff --git a/components/drivers/usb/cherryusb/port/kinetis/usb_glue_mcx.c b/components/drivers/usb/cherryusb/port/kinetis/usb_glue_mcx.c index 4ae73f1ca06..b3d767a0a46 100644 --- a/components/drivers/usb/cherryusb/port/kinetis/usb_glue_mcx.c +++ b/components/drivers/usb/cherryusb/port/kinetis/usb_glue_mcx.c @@ -86,8 +86,8 @@ void usbd_kinetis_delay_ms(uint8_t ms) rt_thread_mdelay(ms); #else for (uint32_t i = 0; i < ms; i++) - { - for (volatile uint32_t j = 0; j < 10000; j++); + { + for (volatile uint32_t j = 0; j < 10000; j++); } #endif } \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/port/musb/usb_glue_sifli.c b/components/drivers/usb/cherryusb/port/musb/usb_glue_sifli.c index 106dc3a7062..00194820554 100644 --- a/components/drivers/usb/cherryusb/port/musb/usb_glue_sifli.c +++ b/components/drivers/usb/cherryusb/port/musb/usb_glue_sifli.c @@ -17,7 +17,7 @@ #undef USB_POWER_RESUME #ifndef CONFIG_USB_MUSB_SIFLI -#error must define CONFIG_USB_MUSB_SIFLI when use sunxi chips +#error must define CONFIG_USB_MUSB_SIFLI when use sifli chips #endif #include "bf0_hal.h" diff --git a/components/drivers/usb/cherryusb/port/musb/usb_glue_ti.c b/components/drivers/usb/cherryusb/port/musb/usb_glue_ti.c new file mode 100644 index 00000000000..576a517f629 --- /dev/null +++ b/components/drivers/usb/cherryusb/port/musb/usb_glue_ti.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2026, sakumisu + * Copyright (c) 2026, MDLZCOOL + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" +#include "usbh_core.h" +#include "usb_musb_reg.h" + +#include "inc/hw_memmap.h" +#include "inc/hw_types.h" +#include "inc/hw_ints.h" +#include "inc/hw_gpio.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_usb.h" +#include "driverlib/sysctl.h" +#include "driverlib/gpio.h" +#include "driverlib/interrupt.h" +#include "driverlib/pin_map.h" +#include "driverlib/rom.h" + +#define TM4C_MUSB_RAM_SIZE 4096 + +// clang-format off +static struct musb_fifo_cfg musb_device_table[] = { +{ .ep_num = 0, .style = FIFO_TXRX, .maxpacket = 64, }, +{ .ep_num = 1, .style = FIFO_TXRX, .maxpacket = 1024, }, +{ .ep_num = 2, .style = FIFO_TXRX, .maxpacket = 1024, }, +{ .ep_num = 3, .style = FIFO_TXRX, .maxpacket = 1024, }, +{ .ep_num = 4, .style = FIFO_TXRX, .maxpacket = 512, }, +{ .ep_num = 5, .style = FIFO_TXRX, .maxpacket = 256, }, +{ .ep_num = 6, .style = FIFO_TXRX, .maxpacket = 128, }, +{ .ep_num = 7, .style = FIFO_TXRX, .maxpacket = 64, }, +}; + +static struct musb_fifo_cfg musb_host_table[] = { +{ .ep_num = 0, .style = FIFO_TXRX, .maxpacket = 64, }, +{ .ep_num = 1, .style = FIFO_TXRX, .maxpacket = 1024, }, +{ .ep_num = 2, .style = FIFO_TXRX, .maxpacket = 1024, }, +{ .ep_num = 3, .style = FIFO_TXRX, .maxpacket = 1024, }, +{ .ep_num = 4, .style = FIFO_TXRX, .maxpacket = 512, }, +{ .ep_num = 5, .style = FIFO_TXRX, .maxpacket = 256, }, +{ .ep_num = 6, .style = FIFO_TXRX, .maxpacket = 128, }, +{ .ep_num = 7, .style = FIFO_TXRX, .maxpacket = 64, }, +}; +// clang-format on + +static void (*g_usb_irq_handler)(uint8_t busid) = NULL; + +extern void USBH_IRQHandler(uint8_t busid); +extern void USBD_IRQHandler(uint8_t busid); + +__WEAK void USBD_IRQHandler(uint8_t busid) +{ + (void)busid; +} + +__WEAK void USBH_IRQHandler(uint8_t busid) +{ + (void)busid; +} + +void USB0_Handler(void) +{ + if (g_usb_irq_handler) { + g_usb_irq_handler(0); + } +} + +uint8_t usbd_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) +{ + *cfg = musb_device_table; + return sizeof(musb_device_table) / sizeof(musb_device_table[0]); +} + +uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) +{ + *cfg = musb_host_table; + return sizeof(musb_host_table) / sizeof(musb_host_table[0]); +} + +uint32_t usb_get_musb_ram_size(void) +{ + return TM4C_MUSB_RAM_SIZE; +} + +void usbd_musb_delay_ms(uint8_t ms) +{ + /* implement later */ +} + +void usb_dc_low_level_init(void) +{ + SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); + + while (!SysCtlPeripheralReady(SYSCTL_PERIPH_USB0)) + ; + while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD)) + ; + while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB)) + ; + + SysCtlPeripheralReset(SYSCTL_PERIPH_USB0); + for (volatile int i = 0; i < 1000; i++) + ; + + GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5); + GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); + + HWREGB(USB0_BASE + USB_O_GPCS) = USB_GPCS_DEVMOD; + SysCtlUSBPLLEnable(); + + g_usb_irq_handler = USBD_IRQHandler; + + IntPrioritySet(INT_USB0, (6 << 5)); + IntEnable(INT_USB0); +} + +void usb_dc_low_level_deinit(void) +{ + IntDisable(INT_USB0); + g_usb_irq_handler = NULL; + SysCtlPeripheralDisable(SYSCTL_PERIPH_USB0); +} + +void usb_hc_low_level_init(struct usbh_bus *bus) +{ + SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); + + while (!SysCtlPeripheralReady(SYSCTL_PERIPH_USB0)) + ; + while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD)) + ; + while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB)) + ; + + SysCtlPeripheralReset(SYSCTL_PERIPH_USB0); + for (volatile int i = 0; i < 1000; i++) + ; + + GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5); + GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); + + HWREGB(USB0_BASE + USB_O_GPCS) &= ~(USB_GPCS_DEVMOD); + SysCtlUSBPLLEnable(); + + g_usb_irq_handler = USBH_IRQHandler; + + IntPrioritySet(INT_USB0, (6 << 5)); + IntEnable(INT_USB0); +} + +void usb_hc_low_level_deinit(struct usbh_bus *bus) +{ + IntDisable(INT_USB0); + g_usb_irq_handler = NULL; + SysCtlPeripheralDisable(SYSCTL_PERIPH_USB0); +} \ No newline at end of file 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 eea625cc731..26d2ce74caf 100644 --- a/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c +++ b/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c @@ -328,10 +328,16 @@ void musb_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb speed = USB_TYPE0_SPEED_LOW; } +#ifdef CONFIG_USB_MUSB_WITHOUT_MULTIPOINT + /* Without multipoint, use FADDR for host target addressing and do not access Hub/FuncAddr regs */ + HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = (urb->hport->dev_addr & 0x7F); + HWREGB(USB_TXTYPE_BASE(chidx)) = speed; +#else HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr; HWREGB(USB_TXTYPE_BASE(chidx)) = speed; HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0; HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0; +#endif musb_write_packet(bus, chidx, (uint8_t *)setup, 8); HWREGB(USB_TXCSRL_BASE(chidx)) = USB_CSRL0_TXRDY | USB_CSRL0_SETUP; @@ -360,12 +366,19 @@ int musb_bulk_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb return -USB_ERR_RANGE; } +#ifdef CONFIG_USB_MUSB_WITHOUT_MULTIPOINT + HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = (urb->hport->dev_addr & 0x7F); + HWREGB(USB_RXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK; + HWREGH(USB_RXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); + HWREGB(USB_RXINTERVAL_BASE(chidx)) = 0; +#else HWREGB(USB_RXADDR_BASE(chidx)) = urb->hport->dev_addr; HWREGB(USB_RXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK; HWREGH(USB_RXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); HWREGB(USB_RXINTERVAL_BASE(chidx)) = 0; HWREGB(USB_RXHUBADDR_BASE(chidx)) = 0; HWREGB(USB_RXHUBPORT_BASE(chidx)) = 0; +#endif HWREGB(USB_TXCSRH_BASE(chidx)) &= ~USB_TXCSRH1_MODE; HWREGB(USB_RXCSRL_BASE(chidx)) = USB_RXCSRL1_REQPKT; @@ -376,12 +389,19 @@ int musb_bulk_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb return -USB_ERR_RANGE; } +#ifdef CONFIG_USB_MUSB_WITHOUT_MULTIPOINT + HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = (urb->hport->dev_addr & 0x7F); + HWREGB(USB_TXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK; + HWREGH(USB_TXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); + HWREGB(USB_TXINTERVAL_BASE(chidx)) = 0; +#else HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr; HWREGB(USB_TXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_BULK; HWREGH(USB_TXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); HWREGB(USB_TXINTERVAL_BASE(chidx)) = 0; HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0; HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0; +#endif if (buflen > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) { buflen = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); @@ -419,12 +439,19 @@ int musb_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb return -USB_ERR_RANGE; } +#ifdef CONFIG_USB_MUSB_WITHOUT_MULTIPOINT + HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = (urb->hport->dev_addr & 0x7F); + HWREGB(USB_RXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT; + HWREGH(USB_RXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); + HWREGB(USB_RXINTERVAL_BASE(chidx)) = urb->ep->bInterval; +#else HWREGB(USB_RXADDR_BASE(chidx)) = urb->hport->dev_addr; HWREGB(USB_RXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT; HWREGH(USB_RXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); HWREGB(USB_RXINTERVAL_BASE(chidx)) = urb->ep->bInterval; HWREGB(USB_RXHUBADDR_BASE(chidx)) = 0; HWREGB(USB_RXHUBPORT_BASE(chidx)) = 0; +#endif HWREGB(USB_TXCSRH_BASE(chidx)) &= ~USB_TXCSRH1_MODE; HWREGB(USB_RXCSRL_BASE(chidx)) = USB_RXCSRL1_REQPKT; @@ -435,12 +462,19 @@ int musb_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb return -USB_ERR_RANGE; } +#ifdef CONFIG_USB_MUSB_WITHOUT_MULTIPOINT + HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = (urb->hport->dev_addr & 0x7F); + HWREGB(USB_TXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT; + HWREGH(USB_TXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); + HWREGB(USB_TXINTERVAL_BASE(chidx)) = urb->ep->bInterval; +#else HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr; HWREGB(USB_TXTYPE_BASE(chidx)) = (urb->ep->bEndpointAddress & 0x0f) | speed | USB_TXTYPE1_PROTO_INT; HWREGH(USB_TXMAP_BASE(chidx)) = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); HWREGB(USB_TXINTERVAL_BASE(chidx)) = urb->ep->bInterval; HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0; HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0; +#endif if (buflen > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) { buflen = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize); @@ -490,31 +524,36 @@ static uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port) return speed; } -#if 0 -static int musb_pipe_alloc(void) +static int musb_pipe_alloc(struct usbh_bus *bus) { int chidx; + uintptr_t flags; + flags = usb_osal_enter_critical_section(); for (chidx = 1; chidx < CONFIG_USB_MUSB_PIPE_NUM; chidx++) { if (!g_musb_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse) { g_musb_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse = true; + usb_osal_leave_critical_section(flags); return chidx; } } + usb_osal_leave_critical_section(flags); return -1; } -#endif static void musb_pipe_free(struct musb_pipe *pipe) { + uintptr_t flags; + + flags = usb_osal_enter_critical_section(); if (pipe->urb) { pipe->urb->hcpriv = NULL; pipe->urb = NULL; } -#if 0 + pipe->inuse = false; -#endif + usb_osal_leave_critical_section(flags); } __WEAK void usb_hc_low_level_init(struct usbh_bus *bus) @@ -730,10 +769,9 @@ int usbh_submit_urb(struct usbh_urb *urb) if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) { chidx = 0; } else { - chidx = (urb->ep->bEndpointAddress & 0x0f); - - if (chidx > (CONFIG_USB_MUSB_PIPE_NUM - 1)) { - return -USB_ERR_RANGE; + chidx = musb_pipe_alloc(bus); + if (chidx == -1) { + return -USB_ERR_NOMEM; } } @@ -839,8 +877,6 @@ static void musb_urb_waitup(struct usbh_urb *urb) struct musb_pipe *pipe; pipe = (struct musb_pipe *)urb->hcpriv; - pipe->urb = NULL; - urb->hcpriv = NULL; if (urb->timeout) { usb_osal_sem_give(pipe->waitsem); @@ -987,9 +1023,11 @@ void USBH_IRQHandler(uint8_t busid) bus = &g_usbhost_bus[busid]; +#if 0 if (!(HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_HOST)) { return; } +#endif is = HWREGB(USB_BASE + MUSB_IS_OFFSET); txis = HWREGH(USB_BASE + MUSB_TXIS_OFFSET); diff --git a/components/drivers/usb/cherryusb/tools/audacity/url b/components/drivers/usb/cherryusb/tools/audacity/url new file mode 100644 index 00000000000..4f690e40642 --- /dev/null +++ b/components/drivers/usb/cherryusb/tools/audacity/url @@ -0,0 +1 @@ +https://audacity.onl/ \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/tools/chryusb_configurator/url b/components/drivers/usb/cherryusb/tools/chryusb_configurator/url new file mode 100644 index 00000000000..ed063b51676 --- /dev/null +++ b/components/drivers/usb/cherryusb/tools/chryusb_configurator/url @@ -0,0 +1 @@ +https://github.com/Egahp/chryusb_configurator/releases/tag/1.0.0 \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/tools/packet capture/url b/components/drivers/usb/cherryusb/tools/packet capture/url new file mode 100644 index 00000000000..a5fba08e606 --- /dev/null +++ b/components/drivers/usb/cherryusb/tools/packet capture/url @@ -0,0 +1,3 @@ +QQ群内获取 + +Get it after joining the qq chat \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/tools/stm32_dfuse/url b/components/drivers/usb/cherryusb/tools/stm32_dfuse/url new file mode 100644 index 00000000000..808c6f73860 --- /dev/null +++ b/components/drivers/usb/cherryusb/tools/stm32_dfuse/url @@ -0,0 +1 @@ +http://www.st.com/en/development-tools/stsw-stm32080.html \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/tools/test_srcipts/test_cdc_speed.py b/components/drivers/usb/cherryusb/tools/test_srcipts/test_cdc_speed.py new file mode 100644 index 00000000000..f11b70a4a2a --- /dev/null +++ b/components/drivers/usb/cherryusb/tools/test_srcipts/test_cdc_speed.py @@ -0,0 +1,49 @@ +import serial +import time +try: + from serial.tools.list_ports import comports +except ImportError: + raise serial.serialutil.SerialException + + +test_comx = 'COM66' +test_baudrate = 2000000 +test_maxsize = 10*1024*1024 + +test_data = '0xAA' * 4096 + +test_serial = serial.Serial(test_comx, test_baudrate, timeout = 1) + +def test_cdc_out(): + send_count = 0 + begin = time.time() + + while True: + if send_count < test_maxsize: + txdatalen = test_serial.write(test_data.encode("utf-8")) + send_count += txdatalen + else: + print("cdc out speed %f MB/s" %(send_count//1024//1024/(time.time() - begin))) + break + +def test_cdc_in(): + read_count = 0 + begin = time.time() + + while True: + if read_count < test_maxsize: + data = test_serial.read(test_maxsize).decode(encoding='utf-8',errors='ignore') + read_count += len(data) + else: + print("cdc in speed %f MB/s" %(read_count//1024//1024/(time.time() - begin))) + break + +if __name__ == '__main__': + print('test cdc out speed') + + test_serial.setDTR(0) + test_cdc_out() + + print('test cdc in speed') + test_serial.setDTR(1) + test_cdc_in() \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/tools/test_srcipts/test_hid_inout.py b/components/drivers/usb/cherryusb/tools/test_srcipts/test_hid_inout.py new file mode 100644 index 00000000000..df512d24efe --- /dev/null +++ b/components/drivers/usb/cherryusb/tools/test_srcipts/test_hid_inout.py @@ -0,0 +1,68 @@ +# Copyright (c) 2021 HPMicro +# SPDX-License-Identifier: BSD-3-Clause + +import pywinusb.hid as hid +import os +import time +import sys +import operator + +# VID and PID customization changes here... + +VID = 0xFFFF +PID = 0xFFFF + +# Send buffer +buffer = [0xff]*64 + +# Const +TIMEOUT = -1 +PASS = 0 +FAIL = 1 + +# Result +result = TIMEOUT + +def search_dev(): + filter = hid.HidDeviceFilter(vendor_id = VID, product_id = PID) + hid_device = filter.get_devices() + return hid_device + +def recv_data(data): + print("<=================== USB HID Read ========================>") + for i in range(0, len(data)): + print("0x{0:02x}" .format(data[i]), end=" ") + print("\n") + + global result + result = (PASS if (operator.eq(data[1:-1], buffer[1:-1]) == True) else FAIL) + + return None + +def send_data(report): + print("<=================== USB HID Write ========================>") + buffer[0] = report[0].report_id + print("0x{0:02x}" .format(buffer[0]), end=" ") + + for i in range(1,64): + buffer[i] = i % 256 + print("0x{0:02x}" .format(buffer[i]), end=" ") + print("\n") + + report[0].set_raw_data(buffer) + report[0].send() + return None + +if __name__ == '__main__': + device = search_dev()[0] + device.open() + device.set_raw_data_handler(recv_data) + send_data(device.find_output_reports()) + time.sleep(1) + + if result == PASS: + print("USB hid echo passed!") + elif result == FAIL: + print("USB HID echo failed!") + else: + print("USB HID echo timed out!") \ No newline at end of file diff --git a/components/drivers/usb/cherryusb/tools/uf2/uf2conv.py b/components/drivers/usb/cherryusb/tools/uf2/uf2conv.py new file mode 100644 index 00000000000..53c5e8bc6da --- /dev/null +++ b/components/drivers/usb/cherryusb/tools/uf2/uf2conv.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python3 +import sys +import struct +import subprocess +import re +import os +import os.path +import argparse +import json +from time import sleep + + +UF2_MAGIC_START0 = 0x0A324655 # "UF2\n" +UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected +UF2_MAGIC_END = 0x0AB16F30 # Ditto + +INFO_FILE = "/INFO_UF2.TXT" + +appstartaddr = 0x2000 +familyid = 0x0 + + +def is_uf2(buf): + w = struct.unpack(" 476: + assert False, "Invalid UF2 data size at " + ptr + newaddr = hd[3] + if (hd[2] & 0x2000) and (currfamilyid == None): + currfamilyid = hd[7] + if curraddr == None or ((hd[2] & 0x2000) and hd[7] != currfamilyid): + currfamilyid = hd[7] + curraddr = newaddr + if familyid == 0x0 or familyid == hd[7]: + appstartaddr = newaddr + padding = newaddr - curraddr + if padding < 0: + assert False, "Block out of order at " + ptr + if padding > 10*1024*1024: + assert False, "More than 10M of padding needed at " + ptr + if padding % 4 != 0: + assert False, "Non-word padding size at " + ptr + while padding > 0: + padding -= 4 + outp.append(b"\x00\x00\x00\x00") + if familyid == 0x0 or ((hd[2] & 0x2000) and familyid == hd[7]): + outp.append(block[32 : 32 + datalen]) + curraddr = newaddr + datalen + if hd[2] & 0x2000: + if hd[7] in families_found.keys(): + if families_found[hd[7]] > newaddr: + families_found[hd[7]] = newaddr + else: + families_found[hd[7]] = newaddr + if prev_flag == None: + prev_flag = hd[2] + if prev_flag != hd[2]: + all_flags_same = False + if blockno == (numblocks - 1): + print("--- UF2 File Header Info ---") + families = load_families() + for family_hex in families_found.keys(): + family_short_name = "" + for name, value in families.items(): + if value == family_hex: + family_short_name = name + print("Family ID is {:s}, hex value is 0x{:08x}".format(family_short_name,family_hex)) + print("Target Address is 0x{:08x}".format(families_found[family_hex])) + if all_flags_same: + print("All block flag values consistent, 0x{:04x}".format(hd[2])) + else: + print("Flags were not all the same") + print("----------------------------") + if len(families_found) > 1 and familyid == 0x0: + outp = [] + appstartaddr = 0x0 + return b"".join(outp) + +def convert_to_carray(file_content): + outp = "const unsigned long bindata_len = %d;\n" % len(file_content) + outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {" + for i in range(len(file_content)): + if i % 16 == 0: + outp += "\n" + outp += "0x%02x, " % file_content[i] + outp += "\n};\n" + return bytes(outp, "utf-8") + +def convert_to_uf2(file_content): + global familyid + datapadding = b"" + while len(datapadding) < 512 - 256 - 32 - 4: + datapadding += b"\x00\x00\x00\x00" + numblocks = (len(file_content) + 255) // 256 + outp = [] + for blockno in range(numblocks): + ptr = 256 * blockno + chunk = file_content[ptr:ptr + 256] + flags = 0x0 + if familyid: + flags |= 0x2000 + hd = struct.pack(b"= 3 and words[1] == "2" and words[2] == "FAT": + drives.append(words[0]) + else: + searchpaths = ["/media"] + if sys.platform == "darwin": + searchpaths = ["/Volumes"] + elif sys.platform == "linux": + searchpaths += ["/media/" + os.environ["USER"], '/run/media/' + os.environ["USER"]] + + for rootpath in searchpaths: + if os.path.isdir(rootpath): + for d in os.listdir(rootpath): + if os.path.isdir(rootpath): + drives.append(os.path.join(rootpath, d)) + + + def has_info(d): + try: + return os.path.isfile(d + INFO_FILE) + except: + return False + + return list(filter(has_info, drives)) + + +def board_id(path): + with open(path + INFO_FILE, mode='r') as file: + file_content = file.read() + return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1) + + +def list_drives(): + for d in get_drives(): + print(d, board_id(d)) + + +def write_file(name, buf): + with open(name, "wb") as f: + f.write(buf) + print("Wrote %d bytes to %s" % (len(buf), name)) + + +def load_families(): + # The expectation is that the `uf2families.json` file is in the same + # directory as this script. Make a path that works using `__file__` + # which contains the full path to this script. + filename = "uf2families.json" + pathname = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) + with open(pathname) as f: + raw_families = json.load(f) + + families = {} + for family in raw_families: + families[family["short_name"]] = int(family["id"], 0) + + return families + + +def main(): + global appstartaddr, familyid + def error(msg): + print(msg, file=sys.stderr) + sys.exit(1) + parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.') + parser.add_argument('input', metavar='INPUT', type=str, nargs='?', + help='input file (HEX, BIN or UF2)') + parser.add_argument('-b', '--base', dest='base', type=str, + default="0x2000", + help='set base address of application for BIN format (default: 0x2000)') + parser.add_argument('-f', '--family', dest='family', type=str, + default="0x0", + help='specify familyID - number or name (default: 0x0)') + parser.add_argument('-o', '--output', metavar="FILE", dest='output', type=str, + help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible') + parser.add_argument('-d', '--device', dest="device_path", + help='select a device path to flash') + parser.add_argument('-l', '--list', action='store_true', + help='list connected devices') + parser.add_argument('-c', '--convert', action='store_true', + help='do not flash, just convert') + parser.add_argument('-D', '--deploy', action='store_true', + help='just flash, do not convert') + parser.add_argument('-w', '--wait', action='store_true', + help='wait for device to flash') + parser.add_argument('-C', '--carray', action='store_true', + help='convert binary file to a C array, not UF2') + parser.add_argument('-i', '--info', action='store_true', + help='display header information from UF2, do not convert') + args = parser.parse_args() + appstartaddr = int(args.base, 0) + + families = load_families() + + if args.family.upper() in families: + familyid = families[args.family.upper()] + else: + try: + familyid = int(args.family, 0) + except ValueError: + error("Family ID needs to be a number or one of: " + ", ".join(families.keys())) + + if args.list: + list_drives() + else: + if not args.input: + error("Need input file") + with open(args.input, mode='rb') as f: + inpbuf = f.read() + from_uf2 = is_uf2(inpbuf) + ext = "uf2" + if args.deploy: + outbuf = inpbuf + elif from_uf2 and not args.info: + outbuf = convert_from_uf2(inpbuf) + ext = "bin" + elif from_uf2 and args.info: + outbuf = "" + convert_from_uf2(inpbuf) + elif is_hex(inpbuf): + outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8")) + elif args.carray: + outbuf = convert_to_carray(inpbuf) + ext = "h" + else: + outbuf = convert_to_uf2(inpbuf) + if not args.deploy and not args.info: + print("Converted to %s, output size: %d, start address: 0x%x" % + (ext, len(outbuf), appstartaddr)) + if args.convert or ext != "uf2": + if args.output == None: + args.output = "flash." + ext + if args.output: + write_file(args.output, outbuf) + if ext == "uf2" and not args.convert and not args.info: + drives = get_drives() + if len(drives) == 0: + if args.wait: + print("Waiting for drive to deploy...") + while len(drives) == 0: + sleep(0.1) + drives = get_drives() + elif not args.output: + error("No drive to deploy.") + for d in drives: + print("Flashing %s (%s)" % (d, board_id(d))) + write_file(d + "/NEW.UF2", outbuf) + + +if __name__ == "__main__": + main() \ No newline at end of file