From c27458d71aaf7f46744e75082251e4a570517b1f Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Tue, 29 Apr 2025 18:28:30 +0800 Subject: [PATCH] update(platform): update platform code Signed-off-by: sakumisu <1203593632@qq.com> --- CMakeLists.txt | 6 +- platform/README.md | 58 ++- platform/blackmagic/bmp_port_cdc_acm.c | 294 ++++++++++++ platform/daplink/dap_main.c | 553 +++++++++++++++++++++++ platform/daplink/dap_main.h | 151 +++++++ platform/{none => fatfs}/usbh_fatfs.c | 0 platform/{none => lwip}/usbh_lwip.c | 0 platform/qmk/.gitkeep | 1 + {demo/bootuf2 => platform/uf2}/bootuf2.c | 0 {demo/bootuf2 => platform/uf2}/bootuf2.h | 0 10 files changed, 1050 insertions(+), 13 deletions(-) create mode 100644 platform/blackmagic/bmp_port_cdc_acm.c create mode 100644 platform/daplink/dap_main.c create mode 100644 platform/daplink/dap_main.h rename platform/{none => fatfs}/usbh_fatfs.c (100%) rename platform/{none => lwip}/usbh_lwip.c (100%) create mode 100644 platform/qmk/.gitkeep rename {demo/bootuf2 => platform/uf2}/bootuf2.c (100%) rename {demo/bootuf2 => platform/uf2}/bootuf2.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36b8374..9d3dbc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ if(BL_SDK_BASE) sdk_add_include_directories(${cherryusb_incs}) sdk_library_add_sources(${cherryusb_srcs}) - sdk_library_add_sources(platform/none/usbh_lwip.c) + sdk_library_add_sources(platform/lwip/usbh_lwip.c) elseif(HPM_SDK_BASE) set(CONFIG_CHERRYUSB_HOST 1) @@ -62,7 +62,7 @@ elseif(HPM_SDK_BASE) sdk_inc(${cherryusb_incs}) sdk_src(${cherryusb_srcs}) - sdk_src(platform/none/usbh_lwip.c) + sdk_src(platform/lwip/usbh_lwip.c) elseif(ESP_PLATFORM) @@ -81,7 +81,7 @@ elseif(ESP_PLATFORM) OR CONFIG_CHERRYUSB_HOST_RTL8152 OR CONFIG_CHERRYUSB_HOST_BL616 ) - list(APPEND cherryusb_srcs platform/none/usbh_lwip.c) + list(APPEND cherryusb_srcs platform/lwip/usbh_lwip.c) idf_component_get_property(lwip lwip COMPONENT_LIB) target_compile_definitions(${lwip} PRIVATE "-DPBUF_POOL_BUFSIZE=1600") endif() diff --git a/platform/README.md b/platform/README.md index a6afc93..74b3f0f 100644 --- a/platform/README.md +++ b/platform/README.md @@ -1,14 +1,52 @@ # Platform Support -This is a platform support for other os with their own components. +This is a platform support for other opensource projects. -| Platform | fs | net | serial | -|:---------:|:------------:|:------------:|:------------:| -|none | fatfs | lwip | none | -|rtthread | dfs | lwip | rt_device | -|nuttx | nuttx block driver | nuttx net | nuttx char driver| -|threadx | filex | netx | none | -- **fs** is for usbd_msc and usbh_msc -- **net** is for cdc_ecm, cdc_rndis, cdc_ncm, asix, rtl8152 and so on. -- **serial** is for cdc_acm, ch340, ftdi, cp210x, pl2303 and so on. \ No newline at end of file +## Fatfs + +Fatfs support with usb host msc. + +## lwip + +lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl616_wifi). + +## RT-Thread + +- rt_device support with usb device msc. +- DFS support with usb host msc. +- lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl616_wifi). +- msh support with lsusb + + +## Nuttx + +- char device support fowithr usb device cdc acm. +- char device support with usb host cdc acm. +- fs support with usb device msc. +- fs support with usb host msc. +- net support with usb host net class(cdc_rndis). + +## Threadx + +- filx support with usb host msc. + +## LVGL + +- lvgl index support with usb host mouse and keyboard. + +## Blackmagic + +Blackmagic support with usb device cdc acm. + +## DAPLINK + +DAPLINK v2.1 support with usb device cdc acm + winusb(hid and msc optional). + +## UF2 + +UF2 support with usb device msc. + +## QMK + +QMK support with usb device hid. \ No newline at end of file diff --git a/platform/blackmagic/bmp_port_cdc_acm.c b/platform/blackmagic/bmp_port_cdc_acm.c new file mode 100644 index 0000000..ae4e545 --- /dev/null +++ b/platform/blackmagic/bmp_port_cdc_acm.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2025, A_Stupid_Liberal + * Copyright (c) 2025, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "usbd_core.h" +#include "usbd_cdc_acm.h" +#include "general.h" +#include "gdb_if.h" +#include "hpm_l1c_drv.h" + +#define CDC_IN_EP 0x81 +#define CDC_OUT_EP 0x01 +#define CDC_INT_EP 0x83 + +#define CDC_MAX_PACKET_SIZE 512 + +#ifdef CONFIG_USB_HS +#if CDC_MAX_PACKET_SIZE != 512 +#error "CDC_MAX_PACKET_SIZE must be 512 in hs" +#endif +#else +#if CDC_MAX_PACKET_SIZE != 64 +#error "CDC_MAX_PACKET_SIZE must be 64 in fs" +#endif +#endif + +/*!< config descriptor size */ +#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN) + +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_hs[] = { + 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, USB_BULK_EP_MPS_HS, 0x02), +}; + +static const uint8_t config_descriptor_fs[] = { + 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, USB_BULK_EP_MPS_FS, 0x02), +}; + +static const uint8_t device_quality_descriptor[] = { + USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, 0x01), +}; + +static const uint8_t other_speed_config_descriptor_hs[] = { + USB_OTHER_SPEED_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, USB_BULK_EP_MPS_FS, 0x02), +}; + +static const uint8_t other_speed_config_descriptor_fs[] = { + USB_OTHER_SPEED_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, USB_BULK_EP_MPS_HS, 0x02), +}; + +static const char *string_descriptors[] = { + (const char[]){ 0x09, 0x04 }, /* Langid */ + "CherryUSB", /* Manufacturer */ + "CherryUSB BMP DEMO", /* Product */ + "20250501", /* Serial Number */ +}; + +static const uint8_t *device_descriptor_callback(uint8_t speed) +{ + (void)speed; + + return device_descriptor; +} + +static const uint8_t *config_descriptor_callback(uint8_t speed) +{ + if (speed == USB_SPEED_HIGH) { + return config_descriptor_hs; + } else if (speed == USB_SPEED_FULL) { + return config_descriptor_fs; + } else { + return NULL; + } +} + +static const uint8_t *device_quality_descriptor_callback(uint8_t speed) +{ + (void)speed; + + return device_quality_descriptor; +} + +static const uint8_t *other_speed_config_descriptor_callback(uint8_t speed) +{ + if (speed == USB_SPEED_HIGH) { + return other_speed_config_descriptor_hs; + } else if (speed == USB_SPEED_FULL) { + return other_speed_config_descriptor_fs; + } else { + return NULL; + } +} + +static const char *string_descriptor_callback(uint8_t speed, uint8_t index) +{ + (void)speed; + + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { + return NULL; + } + return string_descriptors[index]; +} + +const struct usb_descriptor cdc_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, +}; + +#define USB_RX_BUFFER_SIZE 16384 +__attribute__((aligned(64))) uint8_t g_usb_write_buffer[USB_RX_BUFFER_SIZE]; +__attribute__((aligned(64))) uint8_t g_usb_read_buffer[USB_RX_BUFFER_SIZE]; + +volatile bool g_usb_tx_busy_flag = false; +volatile uint32_t g_usb_tx_count = 0; +volatile uint32_t g_usb_rx_count = 0; +volatile uint32_t g_usb_rx_offset = 0; + +static void usbd_event_handler(uint8_t busid, uint8_t event) +{ + switch (event) { + case USBD_EVENT_RESET: + g_usb_tx_busy_flag = false; + g_usb_rx_offset = 0; + g_usb_rx_count = 0; + g_usb_tx_count = 0; + break; + case USBD_EVENT_CONNECTED: + break; + case USBD_EVENT_DISCONNECTED: + g_usb_tx_busy_flag = false; + g_usb_rx_offset = 0; + g_usb_rx_count = 0; + g_usb_tx_count = 0; + 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, CDC_OUT_EP, g_usb_read_buffer, USB_RX_BUFFER_SIZE); + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (void)busid; + + usb_dcache_invalidate((uint32_t)g_usb_read_buffer, USB_ALIGN_UP(nbytes, 64)); + g_usb_rx_count = nbytes; + g_usb_rx_offset = 0; +} + +void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (void)busid; + + if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { + /* send zlp */ + usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0); + } else { + g_usb_tx_busy_flag = false; + } +} + +/*!< endpoint call back */ +struct usbd_endpoint cdc_out_ep = { + .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 +}; + +static struct usbd_interface intf0; +static struct usbd_interface intf1; + +/* function ------------------------------------------------------------------*/ + +void cdc_acm_init(uint8_t busid, uint32_t reg_base) +{ + usbd_desc_register(busid, &cdc_descriptor); + 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); + usbd_add_endpoint(busid, &cdc_in_ep); + usbd_initialize(busid, reg_base, usbd_event_handler); +} + +volatile bool dtr_enable = false; + +void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr) +{ + if (dtr) { + //printf("remote attach \r\n"); + } else { + //printf("remote detach \r\n"); + } + + dtr_enable = dtr; +} + +void gdb_if_putchar(const char c, const bool flush) +{ + g_usb_write_buffer[g_usb_tx_count++] = c; + + if (flush) { + g_usb_tx_busy_flag = true; + usb_dcache_clean((uint32_t)g_usb_write_buffer, USB_ALIGN_UP(g_usb_tx_count, 64)); + usbd_ep_start_write(0, CDC_IN_EP, (uint8_t *)core_local_mem_to_sys_address(0, (uint32_t)g_usb_write_buffer), g_usb_tx_count); + while (g_usb_tx_busy_flag) { + } + g_usb_tx_count = 0; + } +} + +void gdb_if_flush(const bool force) +{ + g_usb_tx_busy_flag = true; + usb_dcache_clean((uint32_t)g_usb_write_buffer, USB_ALIGN_UP(g_usb_tx_count, 64)); + usbd_ep_start_write(0, CDC_IN_EP, (uint8_t *)core_local_mem_to_sys_address(0, (uint32_t)g_usb_write_buffer), g_usb_tx_count); + while (g_usb_tx_busy_flag) { + } + g_usb_tx_count = 0; +} + +static int __gdb_if_getchar(void) +{ + if (dtr_enable == false) { + return '\04'; + } + + if (g_usb_rx_count > 0) { + if (g_usb_rx_offset < g_usb_rx_count) { + return g_usb_read_buffer[g_usb_rx_offset++]; + } else { + g_usb_rx_count = 0; + /* setup first out ep read transfer */ + usbd_ep_start_read(0, CDC_OUT_EP, g_usb_read_buffer, USB_RX_BUFFER_SIZE); + return -1; + } + } else { + return -1; + } +} + +char gdb_if_getchar(void) +{ + int c; + + while ((c = __gdb_if_getchar()) == -1) { + } + + return (char)c; +} + +char gdb_if_getchar_to(const uint32_t timeout) +{ + int c = 0; + platform_timeout_s receive_timeout; + platform_timeout_set(&receive_timeout, timeout); + + /* Wait while we need more data or until the timeout expires */ + while (!platform_timeout_is_expired(&receive_timeout)) { + c = __gdb_if_getchar(); + if (c != -1) { + return (char)c; + } + } + return -1; +} \ No newline at end of file diff --git a/platform/daplink/dap_main.c b/platform/daplink/dap_main.c new file mode 100644 index 0000000..f977cff --- /dev/null +++ b/platform/daplink/dap_main.c @@ -0,0 +1,553 @@ +/* + * Copyright (c) 2023 ~ 2025, sakumisu + * Copyright (c) 2023 ~ 2025, HalfSweet + * + * 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) + +__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 +}; + +__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 +}; + +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[] = { + 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), +#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), +#endif +}; + +char *string_descriptors[] = { + (char[]) {0x09, 0x04}, /* Langid */ + "CherryUSB", /* Manufacturer */ + "CherryUSB CMSIS-DAP", /* Product */ + "00000000000000000123456789ABCDEF", /* Serial Number */ +}; + +static const uint8_t device_quality_descriptor[] = { + USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01), +}; + +__WEAK const uint8_t *device_descriptor_callback(uint8_t speed) +{ + (void) speed; + return device_descriptor; +} + +__WEAK const uint8_t *config_descriptor_callback(uint8_t speed) +{ + (void) speed; + return config_descriptor; +} + +__WEAK const uint8_t *device_quality_descriptor_callback(uint8_t speed) +{ + (void) speed; + return device_quality_descriptor; +} + +__WEAK const uint8_t *other_speed_config_descriptor_callback(uint8_t speed) +{ + (void) speed; + return other_speed_config_descriptor; +} + +__WEAK const char *string_descriptor_callback(uint8_t speed, uint8_t index) +{ + (void) speed; + + if (index >= (sizeof(string_descriptors) / sizeof(char *))) { + return NULL; + } + return string_descriptors[index]; +} + +static volatile uint16_t USB_RequestIndexI = 0; // Request Index In +static volatile uint16_t USB_RequestIndexO = 0; // Request Index Out +static volatile uint16_t USB_RequestCountI = 0; // Request Count In +static volatile uint16_t USB_RequestCountO = 0; // Request Count Out +static volatile uint8_t USB_RequestIdle = 1; // Request Idle Flag + +static volatile uint16_t USB_ResponseIndexI = 0; // Response Index In +static volatile uint16_t USB_ResponseIndexO = 0; // Response Index Out +static volatile uint16_t USB_ResponseCountI = 0; // Response Count In +static volatile uint16_t USB_ResponseCountO = 0; // Response Count Out +static volatile uint8_t USB_ResponseIdle = 1; // Response Idle Flag + +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Request[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Request Buffer +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Response Buffer +static uint16_t USB_RespSize[DAP_PACKET_COUNT]; // Response Size + +volatile struct cdc_line_coding g_cdc_lincoding; +volatile uint8_t config_uart = 0; +volatile uint8_t config_uart_transfer = 0; + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t uartrx_ringbuffer[CONFIG_UARTRX_RINGBUF_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usbrx_ringbuffer[CONFIG_USBRX_RINGBUF_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_tmpbuffer[DAP_PACKET_SIZE]; + +static volatile uint8_t usbrx_idle_flag = 0; +static volatile uint8_t usbtx_idle_flag = 0; +static volatile uint8_t uarttx_idle_flag = 0; + +USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_uartrx; +USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_usbrx; + +void usbd_event_handler(uint8_t busid, uint8_t event) +{ + (void) busid; + switch (event) { + case USBD_EVENT_RESET: + usbrx_idle_flag = 0; + usbtx_idle_flag = 0; + uarttx_idle_flag = 0; + config_uart_transfer = 0; + 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 */ + USB_RequestIdle = 0U; + + usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[0], DAP_PACKET_SIZE); + usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE); + + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (void) busid; + if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) { + DAP_TransferAbort = 1U; + } else { + USB_RequestIndexI++; + if (USB_RequestIndexI == DAP_PACKET_COUNT) { + USB_RequestIndexI = 0U; + } + USB_RequestCountI++; + } + + // Start reception of next request packet + 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; + } +} + +void dap_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (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]); + USB_ResponseIndexO++; + if (USB_ResponseIndexO == DAP_PACKET_COUNT) { + USB_ResponseIndexO = 0U; + } + USB_ResponseCountO++; + } else { + USB_ResponseIdle = 1U; + } +} + +void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (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); + } else { + usbrx_idle_flag = 1; + } +} + +void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (void) busid; + uint32_t size; + uint8_t *buffer; + + chry_ringbuffer_linear_read_done(&g_uartrx, nbytes); + if ((nbytes % DAP_PACKET_SIZE) == 0 && nbytes) { + /* send zlp */ + usbd_ep_start_write(0, CDC_IN_EP, NULL, 0); + } else { + if (chry_ringbuffer_get_used(&g_uartrx)) { + buffer = chry_ringbuffer_linear_read_setup(&g_uartrx, &size); + usbd_ep_start_write(0, CDC_IN_EP, buffer, size); + } else { + usbtx_idle_flag = 1; + } + } +} + +struct usbd_endpoint dap_out_ep = { + .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 +}; + +struct usbd_endpoint cdc_out_ep = { + .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 +}; + +struct usbd_interface dap_intf; +struct usbd_interface intf1; +struct usbd_interface intf2; +struct usbd_interface intf3; +struct usbd_interface hid_intf; + +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 +}; + +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, +}; + +void chry_dap_handle(void) +{ + uint32_t n; + + // Process pending requests + while (USB_RequestCountI != USB_RequestCountO) { + // Handle Queue Commands + n = USB_RequestIndexO; + while (USB_Request[n][0] == ID_DAP_QueueCommands) { + USB_Request[n][0] = ID_DAP_ExecuteCommands; + n++; + if (n == DAP_PACKET_COUNT) { + n = 0U; + } + if (n == USB_RequestIndexI) { + // flags = osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever); + // if (flags & 0x80U) { + // break; + // } + } + } + + // Execute DAP Command (process request and prepare response) + USB_RespSize[USB_ResponseIndexI] = + (uint16_t) DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]); + + // Update Request Index and Count + USB_RequestIndexO++; + if (USB_RequestIndexO == DAP_PACKET_COUNT) { + USB_RequestIndexO = 0U; + } + USB_RequestCountO++; + + if (USB_RequestIdle) { + 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); + } + } + + // Update Response Index and Count + USB_ResponseIndexI++; + if (USB_ResponseIndexI == DAP_PACKET_COUNT) { + USB_ResponseIndexI = 0U; + } + USB_ResponseCountI++; + + if (USB_ResponseIdle) { + if (USB_ResponseCountI != USB_ResponseCountO) { + // Load data from response buffer to be sent back + n = USB_ResponseIndexO++; + if (USB_ResponseIndexO == DAP_PACKET_COUNT) { + USB_ResponseIndexO = 0U; + } + USB_ResponseCountO++; + USB_ResponseIdle = 0U; + usbd_ep_start_write(0, DAP_IN_EP, USB_Response[n], USB_RespSize[n]); + } + } + } +} + +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)); + config_uart = 1; + config_uart_transfer = 0; + } +} + +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 chry_dap_usb2uart_handle(void) +{ + uint32_t size; + uint8_t *buffer; + + if (config_uart) { + /* disable irq here */ + config_uart = 0; + /* config uart here */ + 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; + //chry_ringbuffer_reset_read(&g_uartrx); + /* enable irq here */ + } + + if (config_uart_transfer == 0) { + return; + } + + /* why we use chry_ringbuffer_linear_read_setup? + * becase we use dma and we do not want to use temp buffer to memcpy from ringbuffer + * + */ + + /* uartrx to usb tx */ + if (usbtx_idle_flag) { + if (chry_ringbuffer_get_used(&g_uartrx)) { + usbtx_idle_flag = 0; + /* start first transfer */ + buffer = chry_ringbuffer_linear_read_setup(&g_uartrx, &size); + usbd_ep_start_write(0, CDC_IN_EP, buffer, size); + } + } + + /* usbrx to uart tx */ + if (uarttx_idle_flag) { + if (chry_ringbuffer_get_used(&g_usbrx)) { + uarttx_idle_flag = 0; + /* start first transfer */ + buffer = chry_ringbuffer_linear_read_setup(&g_usbrx, &size); + chry_dap_usb2uart_uart_send_bydma(buffer, size); + } + } + + /* check whether usb rx ringbuffer have space to store */ + if (usbrx_idle_flag) { + if (chry_ringbuffer_get_free(&g_usbrx) >= DAP_PACKET_SIZE) { + usbrx_idle_flag = 0; + usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE); + } + } +} + +/* implment by user */ +__WEAK void chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding *line_coding) +{ +} + +/* called by user */ +void chry_dap_usb2uart_uart_send_complete(uint32_t size) +{ + uint8_t *buffer; + + chry_ringbuffer_linear_read_done(&g_usbrx, size); + + if (chry_ringbuffer_get_used(&g_usbrx)) { + buffer = chry_ringbuffer_linear_read_setup(&g_usbrx, &size); + chry_dap_usb2uart_uart_send_bydma(buffer, size); + } else { + uarttx_idle_flag = 1; + } +} + +/* implment by user */ +__WEAK void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len) +{ +} + +#ifdef CONFIG_CHERRYDAP_USE_MSC +#define BLOCK_SIZE 512 +#define BLOCK_COUNT 10 + +typedef struct +{ + uint8_t BlockSpace[BLOCK_SIZE]; +} BLOCK_TYPE; + +BLOCK_TYPE mass_block[BLOCK_COUNT]; + +void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size) +{ + *block_num = 1000; //Pretend having so many buffer,not has actually. + *block_size = BLOCK_SIZE; +} +int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length) +{ + if (sector < 10) + memcpy(buffer, mass_block[sector].BlockSpace, length); + return 0; +} + +int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length) +{ + if (sector < 10) + memcpy(mass_block[sector].BlockSpace, buffer, length); + return 0; +} +#endif diff --git a/platform/daplink/dap_main.h b/platform/daplink/dap_main.h new file mode 100644 index 0000000..082cb99 --- /dev/null +++ b/platform/daplink/dap_main.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023 ~ 2025, sakumisu + * Copyright (c) 2023 ~ 2025, HalfSweet + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef DAP_MAIN_H +#define DAP_MAIN_H + +#include "usbd_core.h" +#include "usbd_cdc.h" +#include "usbd_msc.h" +#include "chry_ringbuffer.h" +#include "DAP_config.h" +#include "DAP.h" + +#define DAP_IN_EP 0x81 +#define DAP_OUT_EP 0x02 + +#define CDC_IN_EP 0x83 +#define CDC_OUT_EP 0x04 +#define CDC_INT_EP 0x85 + +#define MSC_IN_EP 0x86 +#define MSC_OUT_EP 0x07 + +#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" +#endif +#else +#if DAP_PACKET_SIZE != 64 +#error "DAP_PACKET_SIZE must be 64 in fs" +#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) + +#define CONFIG_UARTRX_RINGBUF_SIZE (8 * 1024) +#define CONFIG_USBRX_RINGBUF_SIZE (8 * 1024) + +#ifdef __cplusplus +extern "C" +{ +#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]; + +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[]; + +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 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 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_handle(void); + +void chry_dap_usb2uart_handle(void); + +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); + +void chry_dap_usb2uart_uart_send_complete(uint32_t size); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/platform/none/usbh_fatfs.c b/platform/fatfs/usbh_fatfs.c similarity index 100% rename from platform/none/usbh_fatfs.c rename to platform/fatfs/usbh_fatfs.c diff --git a/platform/none/usbh_lwip.c b/platform/lwip/usbh_lwip.c similarity index 100% rename from platform/none/usbh_lwip.c rename to platform/lwip/usbh_lwip.c diff --git a/platform/qmk/.gitkeep b/platform/qmk/.gitkeep new file mode 100644 index 0000000..91fe8b9 --- /dev/null +++ b/platform/qmk/.gitkeep @@ -0,0 +1 @@ +TODO Release \ No newline at end of file diff --git a/demo/bootuf2/bootuf2.c b/platform/uf2/bootuf2.c similarity index 100% rename from demo/bootuf2/bootuf2.c rename to platform/uf2/bootuf2.c diff --git a/demo/bootuf2/bootuf2.h b/platform/uf2/bootuf2.h similarity index 100% rename from demo/bootuf2/bootuf2.h rename to platform/uf2/bootuf2.h