From 5bd8ea8925a9a95a33528d5945f2f21493121900 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Tue, 12 Mar 2024 21:35:26 +0800 Subject: [PATCH] add winusbv2 template --- demo/winusb1.0_template.c | 4 +- demo/winusb2.0_cdc_template.c | 333 ++++++++++++++++++++++++++ demo/winusb2.0_hid_template.c | 434 ++++++++++++++++++++++++++++++++++ 3 files changed, 769 insertions(+), 2 deletions(-) create mode 100644 demo/winusb2.0_cdc_template.c create mode 100644 demo/winusb2.0_hid_template.c diff --git a/demo/winusb1.0_template.c b/demo/winusb1.0_template.c index 9fb19199..4b8e2bb0 100644 --- a/demo/winusb1.0_template.c +++ b/demo/winusb1.0_template.c @@ -281,7 +281,7 @@ const uint8_t winusb_descriptor[] = { 'E', 0x00, /* wcChar18 */ 'M', 0x00, /* wcChar19 */ 'O', 0x00, /* wcChar20 */ - ' ', 0x00, /* wcChar16 */ + ' ', 0x00, /* wcChar16 */ '1', 0x00, /* wcChar21 */ /////////////////////////////////////// /// string5 descriptor @@ -309,7 +309,7 @@ const uint8_t winusb_descriptor[] = { 'E', 0x00, /* wcChar18 */ 'M', 0x00, /* wcChar19 */ 'O', 0x00, /* wcChar20 */ - ' ', 0x00, /* wcChar16 */ + ' ', 0x00, /* wcChar16 */ '2', 0x00, /* wcChar21 */ #ifdef CONFIG_USB_HS /////////////////////////////////////// diff --git a/demo/winusb2.0_cdc_template.c b/demo/winusb2.0_cdc_template.c new file mode 100644 index 00000000..3a50856b --- /dev/null +++ b/demo/winusb2.0_cdc_template.c @@ -0,0 +1,333 @@ +#include "usbd_core.h" +#include "usbd_cdc.h" + +#define WINUSB_IN_EP 0x81 +#define WINUSB_OUT_EP 0x02 + +#define CDC_IN_EP 0x83 +#define CDC_OUT_EP 0x04 +#define CDC_INT_EP 0x85 + +#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 + CDC_ACM_DESCRIPTOR_LEN) +#define INTF_NUM 3 + +#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 +}; + +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 */ + /* String 2 (Product) */ + 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 */ + /* String 3 (Serial Number) */ + 0x1A, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + '0', 0, // wcChar0 + '1', 0, // wcChar1 + '2', 0, // wcChar2 + '3', 0, // wcChar3 + '4', 0, // wcChar4 + '5', 0, // wcChar5 + 'A', 0, // wcChar6 + 'B', 0, // wcChar7 + 'C', 0, // wcChar8 + 'D', 0, // wcChar9 + 'E', 0, // wcChar10 + 'F', 0, // wcChar11 +#ifdef CONFIG_USB_HS + /* Device Qualifier */ + 0x0a, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x10, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +#endif + /* End */ + 0x00 +}; + +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: + /* 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", 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", 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 +}; + +static struct usbd_endpoint cdc_out_ep = { + .ep_addr = CDC_OUT_EP, + .ep_cb = NULL +}; + +static struct usbd_endpoint cdc_in_ep = { + .ep_addr = CDC_IN_EP, + .ep_cb = NULL +}; + +struct usbd_interface winusb_intf; +struct usbd_interface intf1; +struct usbd_interface intf2; + +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 +}; + +void winusbv2_init(uint8_t busid, uint32_t reg_base) +{ + usbd_desc_register(busid, winusbv2_descriptor); + usbd_bos_desc_register(busid, &bos_desc); + usbd_msosv2_desc_register(busid, &msosv2_desc); + + /*!< winusb */ + usbd_add_interface(busid, &winusb_intf); + usbd_add_endpoint(busid, &winusb_out_ep1); + usbd_add_endpoint(busid, &winusb_in_ep1); + + /*!< cdc acm */ + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1)); + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf2)); + usbd_add_endpoint(busid, &cdc_out_ep); + usbd_add_endpoint(busid, &cdc_in_ep); + + usbd_initialize(busid, reg_base, usbd_event_handler); +} \ No newline at end of file diff --git a/demo/winusb2.0_hid_template.c b/demo/winusb2.0_hid_template.c new file mode 100644 index 00000000..16926656 --- /dev/null +++ b/demo/winusb2.0_hid_template.c @@ -0,0 +1,434 @@ +#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 +}; + +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 */ + /* String 2 (Product) */ + 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 */ + /* String 3 (Serial Number) */ + 0x1A, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + '0', 0, // wcChar0 + '1', 0, // wcChar1 + '2', 0, // wcChar2 + '3', 0, // wcChar3 + '4', 0, // wcChar4 + '5', 0, // wcChar5 + 'A', 0, // wcChar6 + 'B', 0, // wcChar7 + 'C', 0, // wcChar8 + 'D', 0, // wcChar9 + 'E', 0, // wcChar10 + 'F', 0, // wcChar11 +#ifdef CONFIG_USB_HS + /* Device Qualifier */ + 0x0a, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x10, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +#endif + /* End */ + 0x00 +}; + +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: + /* 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", 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", 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 +}; + +/*!< 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; + +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 +}; + +void winusbv2_init(uint8_t busid, uint32_t reg_base) +{ + usbd_desc_register(busid, winusbv2_descriptor); + usbd_bos_desc_register(busid, &bos_desc); + usbd_msosv2_desc_register(busid, &msosv2_desc); + + /*!< 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