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 21 enum { 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 29 static 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 51 static const uint8_t desc_hid_kbd_report[] = { 52 TUD_HID_REPORT_DESC_KEYBOARD() 53 }; 54 55 static 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 62 static 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 82 static 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 101 static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; 102 103 static 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 119 static 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 129 static uint16_t _desc_str[32]; 130 131 const uint8_t * 132 tud_descriptor_device_cb(void) 133 { 134 return (const uint8_t *) &desc_device; 135 } 136 137 const uint8_t * 138 tud_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 146 const uint8_t * 147 tud_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 159 const uint16_t * 160 tud_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 190 const uint8_t * 191 tud_descriptor_device_qualifier_cb(void) 192 { 193 return (const uint8_t *) &desc_device_qualifier; 194 } 195 196 const uint8_t * 197 tud_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