#ifndef _USB_CONFIG_H #define _USB_CONFIG_H #define FUSB_5V_OPERATION 0 #define FUSB_CONFIG_EPS 3 // Include EP0 in this count #define FUSB_SUPPORTS_SLEEP 0 #define FUSB_HID_INTERFACES 2 #define FUSB_CURSED_TURBO_DMA 0 // Hacky, but seems fine, shaves 2.5us off filling 64-byte buffers. #define FUSB_HID_USER_REPORTS 1 #define FUSB_USE_HPE 1 // Use hardware stack. #define FUSB_IO_PROFILE 1 #include "usb_defines.h" //Taken from http://www.usbmadesimple.co.uk/ums_ms_desc_dev.htm static const uint8_t device_descriptor[] = { 18, //Length 1, //Type (Device) 0x00, 0x02, //Spec 0x0, //Device Class 0x0, //Device Subclass 0x0, //Device Protocol (000 = use config descriptor) 64, //Max packet size for EP0 (This has to be 8 because of the USB Low-Speed Standard) 0xaa, 0xaa, //ID Vendor 0x04, 0xd0, //ID Product 0x03, 0x00, //ID Rev 1, //Manufacturer string 2, //Product string 3, //Serial string 1, //Max number of configurations }; /* Configuration Descriptor Set */ static const uint8_t config_descriptor[ ] = { /* Configuration Descriptor */ 0x09, // bLength 0x02, // bDescriptorType 0x3B, 0x00, // wTotalLength 0x02, // bNumInterfaces 0x01, // bConfigurationValue 0x00, // iConfiguration 0xA0, // bmAttributes: Bus Powered; Remote Wakeup 0x32, // MaxPower: 100mA /* Interface Descriptor (Keyboard) */ 0x09, // bLength 0x04, // bDescriptorType 0x00, // bInterfaceNumber 0x00, // bAlternateSetting 0x01, // bNumEndpoints 0x03, // bInterfaceClass 0x01, // bInterfaceSubClass 0x01, // bInterfaceProtocol: Keyboard 0x00, // iInterface /* HID Descriptor (Keyboard) */ 0x09, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0x00, // bCountryCode 0x01, // bNumDescriptors 0x22, // bDescriptorType 0x3E, 0x00, // wDescriptorLength /* Endpoint Descriptor (Keyboard) */ 0x07, // bLength 0x05, // bDescriptorType 0x81, // bEndpointAddress: IN Endpoint 1 0x03, // bmAttributes 0x08, 0x00, // wMaxPacketSize 0x0A, // bInterval: 10mS /* Interface Descriptor (Mouse) */ 0x09, // bLength 0x04, // bDescriptorType 0x01, // bInterfaceNumber 0x00, // bAlternateSetting 0x01, // bNumEndpoints 0x03, // bInterfaceClass 0x01, // bInterfaceSubClass 0x02, // bInterfaceProtocol: Mouse 0x00, // iInterface /* HID Descriptor (Mouse) */ 0x09, // bLength 0x21, // bDescriptorType 0x10, 0x01, // bcdHID 0x00, // bCountryCode 0x01, // bNumDescriptors 0x22, // bDescriptorType 0x34, 0x00, // wDescriptorLength /* Endpoint Descriptor (Mouse) */ 0x07, // bLength 0x05, // bDescriptorType 0x82, // bEndpointAddress: IN Endpoint 2 0x03, // bmAttributes 0x08, 0x00, // wMaxPacketSize 0x01 // bInterval: 1mS }; /* Keyboard Report Descriptor */ static const uint8_t KeyRepDesc[ ] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x06, // Usage (Keyboard) 0xA1, 0x01, // Collection (Application) 0x05, 0x07, // Usage Page (Key Codes) 0x19, 0xE0, // Usage Minimum (224) 0x29, 0xE7, // Usage Maximum (231) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Variable,Absolute) 0x95, 0x01, // Report Count (1) 0x75, 0x08, // Report Size (8) 0x81, 0x01, // Input (Constant) 0x95, 0x03, // Report Count (3) 0x75, 0x01, // Report Size (1) 0x05, 0x08, // Usage Page (LEDs) 0x19, 0x01, // Usage Minimum (1) 0x29, 0x03, // Usage Maximum (3) 0x91, 0x02, // Output (Data,Variable,Absolute) 0x95, 0x05, // Report Count (5) 0x75, 0x01, // Report Size (1) 0x91, 0x01, // Output (Constant,Array,Absolute) 0x95, 0x06, // Report Count (6) 0x75, 0x08, // Report Size (8) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x05, 0x07, // Usage Page (Key Codes) 0x19, 0x00, // Usage Minimum (0) 0x29, 0x91, // Usage Maximum (145) 0x81, 0x00, // Input(Data,Array,Absolute) 0xC0 // End Collection , // TODO - Figure out how to work this in. HID_USAGE_PAGE ( 0xff ), // Vendor-defined page. HID_USAGE ( 0x00 ), HID_REPORT_SIZE ( 8 ), HID_COLLECTION ( HID_COLLECTION_LOGICAL ), HID_REPORT_COUNT ( 254 ), HID_REPORT_ID ( 0xaa ) HID_USAGE ( 0x01 ), HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , HID_REPORT_COUNT ( 63 ), // For use with `hidapitester --vidpid 1209/D003 --open --read-feature 171` HID_REPORT_ID ( 0xab ) HID_USAGE ( 0x01 ), HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , HID_COLLECTION_END, }; /* Mouse Report Descriptor */ static const uint8_t MouseRepDesc[ ] = { 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) 0x75, 0x01, // Report Size (1) 0x95, 0x03, // Report Count (3) 0x81, 0x02, // Input (Data,Variable,Absolute) 0x75, 0x05, // Report Size (5) 0x95, 0x01, // Report Count (1) 0x81, 0x01, // Input (Constant,Array,Absolute) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x09, 0x38, // Usage (Wheel) 0x15, 0x81, // Logical Minimum (-127) 0x25, 0x7F, // Logical Maximum (127) 0x75, 0x08, // Report Size (8) 0x95, 0x03, // Report Count (3) 0x81, 0x06, // Input (Data,Variable,Relative) 0xC0, // End Collection 0xC0 // End Collection }; #define STR_MANUFACTURER u"WCH-TEST" #define STR_PRODUCT u"ch32v003fun ch32x035 test" #define STR_SERIAL u"CUSTOMDEVICE000" struct usb_string_descriptor_struct { uint8_t bLength; uint8_t bDescriptorType; uint16_t wString[]; }; const static struct usb_string_descriptor_struct string0 __attribute__((section(".rodata"))) = { 4, 3, {0x0409} }; const static struct usb_string_descriptor_struct string1 __attribute__((section(".rodata"))) = { sizeof(STR_MANUFACTURER), 3, STR_MANUFACTURER }; const static struct usb_string_descriptor_struct string2 __attribute__((section(".rodata"))) = { sizeof(STR_PRODUCT), 3, STR_PRODUCT }; const static struct usb_string_descriptor_struct string3 __attribute__((section(".rodata"))) = { sizeof(STR_SERIAL), 3, STR_SERIAL }; // This table defines which descriptor data is sent for each specific // request from the host (in wValue and wIndex). const static struct descriptor_list_struct { uint32_t lIndexValue; const uint8_t *addr; uint8_t length; } descriptor_list[] = { {0x00000100, device_descriptor, sizeof(device_descriptor)}, {0x00000200, config_descriptor, sizeof(config_descriptor)}, // interface number // 2200 for hid descriptors. {0x00002200, KeyRepDesc, sizeof(KeyRepDesc)}, {0x00012200, MouseRepDesc, sizeof(MouseRepDesc)}, {0x00002100, config_descriptor + 18, 9 }, // Not sure why, this seems to be useful for Windows + Android. {0x00000300, (const uint8_t *)&string0, 4}, {0x04090301, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, {0x04090302, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}, {0x04090303, (const uint8_t *)&string3, sizeof(STR_SERIAL)} }; #define DESCRIPTOR_LIST_ENTRIES ((sizeof(descriptor_list))/(sizeof(struct descriptor_list_struct)) ) #endif