usb_descriptors.c (5638B)
1#include "hid.h" 2 3#include "class/hid/hid_device.h" 4#include "tusb.h" 5#include "tusb_types.h" 6 7#define ARRLEN(x) (sizeof(x) / sizeof((x)[0])) 8 9#define CONFIG_TOTAL_LEN \ 10 (TUD_CONFIG_DESC_LEN + 2 * TUD_HID_DESC_LEN + TUD_CDC_DESC_LEN) 11 12/* MCU-specific! */ 13#define EPNUM_HID_KBD 0x81 14#define EPNUM_HID_MISC 0x82 15#define EPNUM_CDC_NOTIF 0x84 16#define EPNUM_CDC_IN 0x85 17#define EPNUM_CDC_OUT 0x05 18 19/* NOTE: same VID/PID with different interface can cause issues! */ 20 21enum { 22 ITF_NUM_HID_KBD, 23 ITF_NUM_HID_MISC, 24 ITF_NUM_CDC, 25 ITF_NUM_CDC_DATA, 26 ITF_NUM_TOTAL 27}; 28 29static const tusb_desc_device_t desc_device = { 30 .bLength = sizeof(tusb_desc_device_t), 31 .bDescriptorType = TUSB_DESC_DEVICE, 32 .bcdUSB = 0x200, 33 34 .bDeviceClass = 0x00, 35 .bDeviceSubClass = 0x00, 36 .bDeviceProtocol = 0x00, 37 38 .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, 39 40 .idVendor = 0x1209, 41 .idProduct = 0xDEF0, 42 .bcdDevice = 0x0100, 43 44 .iManufacturer = 0x01, 45 .iProduct = 0x02, 46 .iSerialNumber = 0x03, 47 48 .bNumConfigurations = 0x01 49}; 50 51static const uint8_t desc_hid_kbd_report[] = { 52 TUD_HID_REPORT_DESC_KEYBOARD() 53}; 54 55static const uint8_t desc_hid_misc_report[] = { 56 TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE)), 57 TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(REPORT_ID_CONSUMER)), 58 TUD_HID_REPORT_DESC_SYSTEM_CONTROL(HID_REPORT_ID(REPORT_ID_SYSTEM)), 59 TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(REPORT_ID_GAMEPAD)) 60}; 61 62static const uint8_t desc_fs_configuration[] = { 63 /* Config number, interface count, string index, 64 * total length, attribute, power in mA */ 65 TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 66 TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), 67 68 /* Interface number, string index, protocol, report descriptor len, 69 * EP In address, size & polling interval */ 70 TUD_HID_DESCRIPTOR(ITF_NUM_HID_KBD, 5, HID_ITF_PROTOCOL_KEYBOARD, 71 sizeof(desc_hid_kbd_report), EPNUM_HID_KBD, 8, 1), 72 TUD_HID_DESCRIPTOR(ITF_NUM_HID_MISC, 6, HID_ITF_PROTOCOL_NONE, 73 sizeof(desc_hid_misc_report), EPNUM_HID_MISC, 16, 1), 74 75 /* Interface number, string index, EP notification address and size, 76 * EP data address (out, in) and size */ 77 TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, 78 EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), 79}; 80 81#if TUD_OPT_HIGH_SPEED 82static const uint8_t desc_hs_configuration[] = { 83 /* Config number, interface count, string index, 84 * total length, attribute, power in mA */ 85 TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 86 TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), 87 88 /* Interface number, string index, protocol, report descriptor len, 89 * EP In address, size & polling interval */ 90 TUD_HID_DESCRIPTOR(ITF_NUM_HID_KBD, 5, HID_ITF_PROTOCOL_KEYBOARD, 91 sizeof(desc_hid_kbd_report), EPNUM_HID_KBD, 8, 1), 92 TUD_HID_DESCRIPTOR(ITF_NUM_HID_MISC, 6, HID_ITF_PROTOCOL_NONE, 93 sizeof(desc_hid_misc_report), EPNUM_HID_MISC, 16, 1), 94 95 /* Interface number, string index, EP notification address and size, 96 * EP data address (out, in) and size */ 97 TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, 98 EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), 99}; 100 101static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; 102 103static const tusb_desc_device_qualifier_t desc_device_qualifier = 104{ 105 .bLength = sizeof(tusb_desc_device_qualifier_t), 106 .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, 107 .bcdUSB = 0x200, 108 109 .bDeviceClass = 0x00, 110 .bDeviceSubClass = 0x00, 111 .bDeviceProtocol = 0x00, 112 113 .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, 114 .bNumConfigurations = 0x01, 115 .bReserved = 0x00 116}; 117#endif 118 119static const char *string_desc_arr[] = { 120 [0] = "\x07\x04", /* LangID: German (0x0407) */ 121 [1] = "SNX", /* Manufacturer */ 122 [2] = "SXKBD Keyboard", /* Product */ 123 [3] = "000001", /* Serial Number */ 124 [4] = "CDC", 125 [5] = "HID-KBD", 126 [6] = "HID-MISC" 127}; 128 129static uint16_t _desc_str[32]; 130 131const uint8_t * 132tud_descriptor_device_cb(void) 133{ 134 return (const uint8_t *) &desc_device; 135} 136 137const uint8_t * 138tud_hid_descriptor_report_cb(uint8_t instance) 139{ 140 if (instance == INST_HID_KBD) 141 return desc_hid_kbd_report; 142 else 143 return desc_hid_misc_report; 144} 145 146const uint8_t * 147tud_descriptor_configuration_cb(uint8_t instance) 148{ 149#if TUD_OPT_HIGH_SPEED 150 if (tud_speed_get() == TUSB_SPEED_HIGH) 151 return desc_hs_configuration; 152 else 153 return desc_fs_configuration; 154#else 155 return desc_fs_configuration; 156#endif 157} 158 159const uint16_t * 160tud_descriptor_string_cb(uint8_t index, uint16_t langid) 161{ 162 const char *str; 163 uint8_t i, chr_count; 164 165 if (index == 0) { 166 memcpy(&_desc_str[1], string_desc_arr[0], 2); 167 chr_count = 1; 168 } else { 169 if (index >= ARRLEN(string_desc_arr)) 170 return NULL; 171 172 str = string_desc_arr[index]; 173 174 chr_count = (uint8_t) strlen(str); 175 if (chr_count > 31) chr_count = 31; 176 177 /* Convert ASCII string into UTF-16 */ 178 for (i = 0; i < chr_count; i++) 179 _desc_str[i+1] = str[i]; 180 } 181 182 /* first byte is length (including header), second byte is type */ 183 _desc_str[0] = (uint8_t) (2 * chr_count + 2); 184 _desc_str[0] |= (uint16_t) (TUSB_DESC_STRING << 8); 185 186 return _desc_str; 187} 188 189#if TUD_OPT_HIGH_SPEED 190const uint8_t * 191tud_descriptor_device_qualifier_cb(void) 192{ 193 return (const uint8_t *) &desc_device_qualifier; 194} 195 196const uint8_t * 197tud_descriptor_other_speed_configuration_cb(uint8_t instance) 198{ 199 if (tud_speed_get() == TUSB_SPEED_HIGH) { 200 memcpy(desc_other_speed_config, desc_hs_configuration, 201 CONFIG_TOTAL_LEN); 202 } else { 203 memcpy(desc_other_speed_config, desc_fs_configuration, 204 CONFIG_TOTAL_LEN); 205 } 206 207 desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; 208 209 return desc_other_speed_config; 210} 211#endif