#ifndef USB_DESCRIPTORS_H #define USB_DESCRIPTORS_H #include "hid.h" /* * TODO: Move into a source file and use extern so there's only ever one copy * LTO should take care of the rest. */ #define U16LE(d) ((d) & 0xff), (((uint16_t)(d) >> 8) & 0xff) /* Device descriptor */ unsigned char ds_dev[] = { 18, // Length 1, // Descriptor type U16LE(0x0200), // USB Release 0x00, // Device class 0x00, // Device sub class 0x00, // Device protocol 64, // Max packet size U16LE(0x16c0), // VID U16LE(0x05dc), // PID U16LE(0x0001), // Device relase 1, // Manufacturer string 0, // Product string 0, // Serial number string 1, // Number of configurations }; /* Configuration descriptor */ #define DS_CONF_SIZE 34 unsigned char ds_conf[] = { /* Configuration */ 9, // Length 2, // Descriptor type U16LE(DS_CONF_SIZE), // Total length 1, // Number of interfaces 1, // Configuration value 0, // Configuration string 0xc0, // Attributes (1SR00000, S - Self powered, R - Remote wakeup) 50, // Maximum current (multiples of 2mA) /* Interface */ 9, // Length 4, // Descriptor type 0, // Interface number 0, // Alternate setting 1, // Number of endpoints 3, // Interface class 1, // Interface sub class 2, // Interface protocol 0, // Interface string /* HID */ 9, // Length 33, // Descriptor type U16LE(0x0111), // HID Class spec version 0, // Country code 1, // Number of descriptors 34, // Descriptor type U16LE(52), // Descriptor length /* Endpoint */ 7, // Length 5, // Descriptor type 0x81, // Endpoint address (D000NNNN, D - Direction (0 OUT, 1 IN), N - Endpoint No.) 0x03, // Attributes (00UUSSTT, U - Usage type, S - Synch type, T - Transfer type) U16LE(64), // Max packet size 64, // Interval (1ms Frames) }; _Static_assert(sizeof ds_conf == DS_CONF_SIZE, "sizeof ds_conf != DS_CONF_SIZE"); /* HID Report descriptor */ #define DS_HIDREP_SIZE 52 unsigned char ds_hidrep[] = { HR_USAGE_PAGE(1), HR_GENERIC_DESKTOP, HR_USAGE(1), HR_MOUSE, HR_COLLECTION(1), HR_APPLICATION, HR_USAGE(1), HR_POINTER, HR_COLLECTION(1), HR_PHYSICAL, HR_USAGE_PAGE(1), HR_BUTTON, HR_USAGE_MINIMUM(1), 1, HR_USAGE_MAXIMUM(1), 5, HR_LOGICAL_MINIMUM(1), 0, HR_LOGICAL_MAXIMUM(1), 1, HR_REPORT_COUNT(1), 5, HR_REPORT_SIZE(1), 1, HR_INPUT(1), HR_DATA | HR_VARIABLE | HR_ABSOLUTE | HR_BIT_FIELD, HR_REPORT_COUNT(1), 1, HR_REPORT_SIZE(1), 3, HR_INPUT(1), HR_CONSTANT | HR_ARRAY | HR_ABSOLUTE | HR_BIT_FIELD, HR_USAGE_PAGE(1), HR_GENERIC_DESKTOP, HR_USAGE(1), HR_X, HR_USAGE(1), HR_Y, HR_USAGE(1), HR_WHEEL, HR_LOGICAL_MINIMUM(1), -127, HR_LOGICAL_MAXIMUM(1), 127, HR_REPORT_SIZE(1), 8, HR_REPORT_COUNT(1), 3, HR_INPUT(1), HR_DATA | HR_VARIABLE | HR_RELATIVE | HR_BIT_FIELD, HR_END_COLLECTION(0), HR_END_COLLECTION(0), }; _Static_assert(sizeof ds_hidrep == DS_HIDREP_SIZE, "sizeof ds_hidrep != DS_HIDREP_SIZE"); /* Language descriptor */ unsigned char ds_lang[] = { 4, // Length 3, // Descriptor type 0x09, 0x04 // Language ID }; _Static_assert(sizeof ds_lang == 4, "sizeof ds_lang != 4"); /* String descriptor 1 */ #define DS_STR1_SIZE 22 unsigned char ds_str1[] = { 22, // Length 3, // Descriptor type U16LE(0x74), // t U16LE(0x68), // h U16LE(0x65), // e U16LE(0x2d), // - U16LE(0x74), // t U16LE(0x6b), // k U16LE(0x2e), // . U16LE(0x63), // c U16LE(0x6f), // o U16LE(0x6d), // m }; _Static_assert(sizeof ds_str1 == DS_STR1_SIZE, "sizeof ds_str1 != DS_STR1_SIZE"); #endif /* USB_DESCRIPTORS_H */