usb_descriptor.c (51878B)
1 /* 2 * Copyright 2012 Jun Wako <wakojun@gmail.com> 3 * This file is based on: 4 * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse 5 * LUFA-120219/Demos/Device/Lowlevel/GenericHID 6 */ 7 8 /* 9 LUFA Library 10 Copyright (C) Dean Camera, 2012. 11 12 dean [at] fourwalledcubicle [dot] com 13 www.lufa-lib.org 14 */ 15 16 /* 17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) 18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) 19 20 Permission to use, copy, modify, distribute, and sell this 21 software and its documentation for any purpose is hereby granted 22 without fee, provided that the above copyright notice appear in 23 all copies and that both that the copyright notice and this 24 permission notice and warranty disclaimer appear in supporting 25 documentation, and that the name of the author not be used in 26 advertising or publicity pertaining to distribution of the 27 software without specific, written prior permission. 28 29 The author disclaim all warranties with regard to this 30 software, including all implied warranties of merchantability 31 and fitness. In no event shall the author be liable for any 32 special, indirect or consequential damages or any damages 33 whatsoever resulting from loss of use, data or profits, whether 34 in an action of contract, negligence or other tortious action, 35 arising out of or in connection with the use or performance of 36 this software. 37 */ 38 39 #include "util.h" 40 #include "report.h" 41 #include "usb_descriptor.h" 42 #include "usb_descriptor_common.h" 43 44 #ifdef JOYSTICK_ENABLE 45 # include "joystick.h" 46 #endif 47 48 #ifdef OS_DETECTION_ENABLE 49 # include "os_detection.h" 50 #endif 51 52 #if defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE) 53 54 # define HAS_SERIAL_NUMBER 55 56 # if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE 57 # include "hardware_id.h" 58 # endif 59 60 #endif // defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE) 61 62 // clang-format off 63 64 /* 65 * HID report descriptors 66 */ 67 #ifdef KEYBOARD_SHARED_EP 68 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { 69 # define SHARED_REPORT_STARTED 70 #else 71 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { 72 #endif 73 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 74 HID_RI_USAGE(8, 0x06), // Keyboard 75 HID_RI_COLLECTION(8, 0x01), // Application 76 #ifdef KEYBOARD_SHARED_EP 77 HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD), 78 #endif 79 // Modifiers (8 bits) 80 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad 81 HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control 82 HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI 83 HID_RI_LOGICAL_MINIMUM(8, 0x00), 84 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 85 HID_RI_REPORT_COUNT(8, 0x08), 86 HID_RI_REPORT_SIZE(8, 0x01), 87 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 88 // Reserved (1 byte) 89 HID_RI_REPORT_COUNT(8, 0x01), 90 HID_RI_REPORT_SIZE(8, 0x08), 91 HID_RI_INPUT(8, HID_IOF_CONSTANT), 92 // Keycodes (6 bytes) 93 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad 94 HID_RI_USAGE_MINIMUM(8, 0x00), 95 HID_RI_USAGE_MAXIMUM(8, 0xFF), 96 HID_RI_LOGICAL_MINIMUM(8, 0x00), 97 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), 98 HID_RI_REPORT_COUNT(8, 0x06), 99 HID_RI_REPORT_SIZE(8, 0x08), 100 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), 101 102 // Status LEDs (5 bits) 103 HID_RI_USAGE_PAGE(8, 0x08), // LED 104 HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock 105 HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana 106 HID_RI_LOGICAL_MINIMUM(8, 0x00), 107 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 108 HID_RI_REPORT_COUNT(8, 0x05), 109 HID_RI_REPORT_SIZE(8, 0x01), 110 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), 111 // LED padding (3 bits) 112 HID_RI_REPORT_COUNT(8, 0x01), 113 HID_RI_REPORT_SIZE(8, 0x03), 114 HID_RI_OUTPUT(8, HID_IOF_CONSTANT), 115 HID_RI_END_COLLECTION(0), 116 #ifndef KEYBOARD_SHARED_EP 117 }; 118 #endif 119 120 #ifdef MOUSE_ENABLE 121 # ifndef MOUSE_SHARED_EP 122 const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = { 123 # elif !defined(SHARED_REPORT_STARTED) 124 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { 125 # define SHARED_REPORT_STARTED 126 # endif 127 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 128 HID_RI_USAGE(8, 0x02), // Mouse 129 HID_RI_COLLECTION(8, 0x01), // Application 130 # ifdef MOUSE_SHARED_EP 131 HID_RI_REPORT_ID(8, REPORT_ID_MOUSE), 132 # endif 133 HID_RI_USAGE(8, 0x01), // Pointer 134 HID_RI_COLLECTION(8, 0x00), // Physical 135 // Buttons (8 bits) 136 HID_RI_USAGE_PAGE(8, 0x09), // Button 137 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 138 HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8 139 HID_RI_LOGICAL_MINIMUM(8, 0x00), 140 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 141 HID_RI_REPORT_COUNT(8, 0x08), 142 HID_RI_REPORT_SIZE(8, 0x01), 143 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 144 145 # ifdef MOUSE_EXTENDED_REPORT 146 // Boot protocol XY ignored in Report protocol 147 HID_RI_REPORT_COUNT(8, 0x02), 148 HID_RI_REPORT_SIZE(8, 0x08), 149 HID_RI_INPUT(8, HID_IOF_CONSTANT), 150 # endif 151 // X/Y position (2 or 4 bytes) 152 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 153 HID_RI_USAGE(8, 0x30), // X 154 HID_RI_USAGE(8, 0x31), // Y 155 # ifndef MOUSE_EXTENDED_REPORT 156 HID_RI_LOGICAL_MINIMUM(8, -127), 157 HID_RI_LOGICAL_MAXIMUM(8, 127), 158 HID_RI_REPORT_COUNT(8, 0x02), 159 HID_RI_REPORT_SIZE(8, 0x08), 160 # else 161 HID_RI_LOGICAL_MINIMUM(16, -32767), 162 HID_RI_LOGICAL_MAXIMUM(16, 32767), 163 HID_RI_REPORT_COUNT(8, 0x02), 164 HID_RI_REPORT_SIZE(8, 0x10), 165 # endif 166 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), 167 168 # ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE 169 HID_RI_COLLECTION(8, 0x02), 170 // Feature report and padding (1 byte) 171 HID_RI_USAGE(8, 0x48), // Resolution Multiplier 172 HID_RI_REPORT_COUNT(8, 0x01), 173 HID_RI_REPORT_SIZE(8, 0x02), 174 HID_RI_LOGICAL_MINIMUM(8, 0x00), 175 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 176 HID_RI_PHYSICAL_MINIMUM(8, 1), 177 HID_RI_PHYSICAL_MAXIMUM(8, POINTING_DEVICE_HIRES_SCROLL_MULTIPLIER), 178 HID_RI_UNIT_EXPONENT(8, POINTING_DEVICE_HIRES_SCROLL_EXPONENT), 179 HID_RI_FEATURE(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 180 HID_RI_PHYSICAL_MINIMUM(8, 0x00), 181 HID_RI_PHYSICAL_MAXIMUM(8, 0x00), 182 HID_RI_REPORT_SIZE(8, 0x06), 183 HID_RI_FEATURE(8, HID_IOF_CONSTANT), 184 # endif 185 186 // Vertical wheel (1 or 2 bytes) 187 HID_RI_USAGE(8, 0x38), // Wheel 188 # ifndef WHEEL_EXTENDED_REPORT 189 HID_RI_LOGICAL_MINIMUM(8, -127), 190 HID_RI_LOGICAL_MAXIMUM(8, 127), 191 HID_RI_REPORT_COUNT(8, 0x01), 192 HID_RI_REPORT_SIZE(8, 0x08), 193 # else 194 HID_RI_LOGICAL_MINIMUM(16, -32767), 195 HID_RI_LOGICAL_MAXIMUM(16, 32767), 196 HID_RI_REPORT_COUNT(8, 0x01), 197 HID_RI_REPORT_SIZE(8, 0x10), 198 # endif 199 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), 200 201 // Horizontal wheel (1 or 2 bytes) 202 HID_RI_USAGE_PAGE(8, 0x0C),// Consumer 203 HID_RI_USAGE(16, 0x0238), // AC Pan 204 # ifndef WHEEL_EXTENDED_REPORT 205 HID_RI_LOGICAL_MINIMUM(8, -127), 206 HID_RI_LOGICAL_MAXIMUM(8, 127), 207 HID_RI_REPORT_COUNT(8, 0x01), 208 HID_RI_REPORT_SIZE(8, 0x08), 209 # else 210 HID_RI_LOGICAL_MINIMUM(16, -32767), 211 HID_RI_LOGICAL_MAXIMUM(16, 32767), 212 HID_RI_REPORT_COUNT(8, 0x01), 213 HID_RI_REPORT_SIZE(8, 0x10), 214 # endif 215 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), 216 217 # ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE 218 HID_RI_END_COLLECTION(0), 219 # endif 220 221 HID_RI_END_COLLECTION(0), 222 HID_RI_END_COLLECTION(0), 223 # ifndef MOUSE_SHARED_EP 224 }; 225 # endif 226 #endif 227 228 #ifdef JOYSTICK_ENABLE 229 # ifndef JOYSTICK_SHARED_EP 230 const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = { 231 # elif !defined(SHARED_REPORT_STARTED) 232 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { 233 # define SHARED_REPORT_STARTED 234 # endif 235 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 236 HID_RI_USAGE(8, 0x04), // Joystick 237 HID_RI_COLLECTION(8, 0x01), // Application 238 # ifdef JOYSTICK_SHARED_EP 239 HID_RI_REPORT_ID(8, REPORT_ID_JOYSTICK), 240 # endif 241 HID_RI_COLLECTION(8, 0x00), // Physical 242 # if JOYSTICK_AXIS_COUNT > 0 243 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 244 HID_RI_USAGE(8, 0x30), // X 245 # if JOYSTICK_AXIS_COUNT > 1 246 HID_RI_USAGE(8, 0x31), // Y 247 # endif 248 # if JOYSTICK_AXIS_COUNT > 2 249 HID_RI_USAGE(8, 0x32), // Z 250 # endif 251 # if JOYSTICK_AXIS_COUNT > 3 252 HID_RI_USAGE(8, 0x33), // Rx 253 # endif 254 # if JOYSTICK_AXIS_COUNT > 4 255 HID_RI_USAGE(8, 0x34), // Ry 256 # endif 257 # if JOYSTICK_AXIS_COUNT > 5 258 HID_RI_USAGE(8, 0x35), // Rz 259 # endif 260 # if JOYSTICK_AXIS_RESOLUTION == 8 261 HID_RI_LOGICAL_MINIMUM(8, -JOYSTICK_MAX_VALUE), 262 HID_RI_LOGICAL_MAXIMUM(8, JOYSTICK_MAX_VALUE), 263 HID_RI_REPORT_COUNT(8, JOYSTICK_AXIS_COUNT), 264 HID_RI_REPORT_SIZE(8, 0x08), 265 # else 266 HID_RI_LOGICAL_MINIMUM(16, -JOYSTICK_MAX_VALUE), 267 HID_RI_LOGICAL_MAXIMUM(16, JOYSTICK_MAX_VALUE), 268 HID_RI_REPORT_COUNT(8, JOYSTICK_AXIS_COUNT), 269 HID_RI_REPORT_SIZE(8, 0x10), 270 # endif 271 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 272 # endif 273 274 # ifdef JOYSTICK_HAS_HAT 275 // Hat Switch (4 bits) 276 HID_RI_USAGE(8, 0x39), // Hat Switch 277 HID_RI_LOGICAL_MINIMUM(8, 0x00), 278 HID_RI_LOGICAL_MAXIMUM(8, 0x07), 279 HID_RI_PHYSICAL_MINIMUM(8, 0), 280 HID_RI_PHYSICAL_MAXIMUM(16, 315), 281 HID_RI_UNIT(8, 0x14), // Degree, English Rotation 282 HID_RI_REPORT_COUNT(8, 1), 283 HID_RI_REPORT_SIZE(8, 4), 284 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NULLSTATE), 285 // Padding (4 bits) 286 HID_RI_REPORT_COUNT(8, 0x04), 287 HID_RI_REPORT_SIZE(8, 0x01), 288 HID_RI_INPUT(8, HID_IOF_CONSTANT), 289 # endif 290 291 # if JOYSTICK_BUTTON_COUNT > 0 292 HID_RI_USAGE_PAGE(8, 0x09), // Button 293 HID_RI_USAGE_MINIMUM(8, 0x01), 294 HID_RI_USAGE_MAXIMUM(8, JOYSTICK_BUTTON_COUNT), 295 HID_RI_LOGICAL_MINIMUM(8, 0x00), 296 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 297 HID_RI_REPORT_COUNT(8, JOYSTICK_BUTTON_COUNT), 298 HID_RI_REPORT_SIZE(8, 0x01), 299 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 300 301 # if (JOYSTICK_BUTTON_COUNT % 8) != 0 302 HID_RI_REPORT_COUNT(8, 8 - (JOYSTICK_BUTTON_COUNT % 8)), 303 HID_RI_REPORT_SIZE(8, 0x01), 304 HID_RI_INPUT(8, HID_IOF_CONSTANT), 305 # endif 306 # endif 307 HID_RI_END_COLLECTION(0), 308 HID_RI_END_COLLECTION(0), 309 # ifndef JOYSTICK_SHARED_EP 310 }; 311 # endif 312 #endif 313 314 #ifdef DIGITIZER_ENABLE 315 # ifndef DIGITIZER_SHARED_EP 316 const USB_Descriptor_HIDReport_Datatype_t PROGMEM DigitizerReport[] = { 317 # elif !defined(SHARED_REPORT_STARTED) 318 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { 319 # define SHARED_REPORT_STARTED 320 # endif 321 HID_RI_USAGE_PAGE(8, 0x0D), // Digitizers 322 HID_RI_USAGE(8, 0x01), // Digitizer 323 HID_RI_COLLECTION(8, 0x01), // Application 324 # ifdef DIGITIZER_SHARED_EP 325 HID_RI_REPORT_ID(8, REPORT_ID_DIGITIZER), 326 # endif 327 HID_RI_USAGE(8, 0x20), // Stylus 328 HID_RI_COLLECTION(8, 0x00), // Physical 329 // In Range, Tip Switch & Barrel Switch (3 bits) 330 HID_RI_USAGE(8, 0x32), // In Range 331 HID_RI_USAGE(8, 0x42), // Tip Switch 332 HID_RI_USAGE(8, 0x44), // Barrel Switch 333 HID_RI_LOGICAL_MINIMUM(8, 0x00), 334 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 335 HID_RI_REPORT_COUNT(8, 0x03), 336 HID_RI_REPORT_SIZE(8, 0x01), 337 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 338 // Padding (5 bits) 339 HID_RI_REPORT_COUNT(8, 0x05), 340 HID_RI_INPUT(8, HID_IOF_CONSTANT), 341 342 // X/Y Position (4 bytes) 343 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 344 HID_RI_USAGE(8, 0x30), // X 345 HID_RI_USAGE(8, 0x31), // Y 346 HID_RI_LOGICAL_MAXIMUM(16, 0x7FFF), 347 HID_RI_REPORT_COUNT(8, 0x02), 348 HID_RI_REPORT_SIZE(8, 0x10), 349 HID_RI_UNIT(8, 0x13), // Inch, English Linear 350 HID_RI_UNIT_EXPONENT(8, 0x0E), // -2 351 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 352 HID_RI_END_COLLECTION(0), 353 HID_RI_END_COLLECTION(0), 354 # ifndef DIGITIZER_SHARED_EP 355 }; 356 # endif 357 #endif 358 359 #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED) 360 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { 361 #endif 362 363 #ifdef EXTRAKEY_ENABLE 364 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 365 HID_RI_USAGE(8, 0x80), // System Control 366 HID_RI_COLLECTION(8, 0x01), // Application 367 HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM), 368 HID_RI_USAGE_MINIMUM(8, 0x01), // Pointer 369 HID_RI_USAGE_MAXIMUM(16, 0x00B7), // System Display LCD Autoscale 370 HID_RI_LOGICAL_MINIMUM(8, 0x01), 371 HID_RI_LOGICAL_MAXIMUM(16, 0x00B7), 372 HID_RI_REPORT_COUNT(8, 1), 373 HID_RI_REPORT_SIZE(8, 16), 374 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), 375 HID_RI_END_COLLECTION(0), 376 377 HID_RI_USAGE_PAGE(8, 0x0C), // Consumer 378 HID_RI_USAGE(8, 0x01), // Consumer Control 379 HID_RI_COLLECTION(8, 0x01), // Application 380 HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER), 381 HID_RI_USAGE_MINIMUM(8, 0x01), // Consumer Control 382 HID_RI_USAGE_MAXIMUM(16, 0x02A0), // AC Desktop Show All Applications 383 HID_RI_LOGICAL_MINIMUM(8, 0x01), 384 HID_RI_LOGICAL_MAXIMUM(16, 0x02A0), 385 HID_RI_REPORT_COUNT(8, 1), 386 HID_RI_REPORT_SIZE(8, 16), 387 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), 388 HID_RI_END_COLLECTION(0), 389 #endif 390 391 #ifdef PROGRAMMABLE_BUTTON_ENABLE 392 HID_RI_USAGE_PAGE(8, 0x0C), // Consumer 393 HID_RI_USAGE(8, 0x01), // Consumer Control 394 HID_RI_COLLECTION(8, 0x01), // Application 395 HID_RI_REPORT_ID(8, REPORT_ID_PROGRAMMABLE_BUTTON), 396 HID_RI_USAGE(8, 0x03), // Programmable Buttons 397 HID_RI_COLLECTION(8, 0x04), // Named Array 398 HID_RI_USAGE_PAGE(8, 0x09), // Button 399 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 400 HID_RI_USAGE_MAXIMUM(8, 0x20), // Button 32 401 HID_RI_LOGICAL_MINIMUM(8, 0x00), 402 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 403 HID_RI_REPORT_COUNT(8, 32), 404 HID_RI_REPORT_SIZE(8, 1), 405 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 406 HID_RI_END_COLLECTION(0), 407 HID_RI_END_COLLECTION(0), 408 #endif 409 410 #ifdef NKRO_ENABLE 411 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 412 HID_RI_USAGE(8, 0x06), // Keyboard 413 HID_RI_COLLECTION(8, 0x01), // Application 414 HID_RI_REPORT_ID(8, REPORT_ID_NKRO), 415 // Modifiers (8 bits) 416 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad 417 HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control 418 HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI 419 HID_RI_LOGICAL_MINIMUM(8, 0x00), 420 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 421 HID_RI_REPORT_COUNT(8, 0x08), 422 HID_RI_REPORT_SIZE(8, 0x01), 423 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 424 // Keycodes 425 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad 426 HID_RI_USAGE_MINIMUM(8, 0x00), 427 HID_RI_USAGE_MAXIMUM(8, NKRO_REPORT_BITS * 8 - 1), 428 HID_RI_LOGICAL_MINIMUM(8, 0x00), 429 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 430 HID_RI_REPORT_COUNT(8, NKRO_REPORT_BITS * 8), 431 HID_RI_REPORT_SIZE(8, 0x01), 432 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 433 434 // Status LEDs (5 bits) 435 HID_RI_USAGE_PAGE(8, 0x08), // LED 436 HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock 437 HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana 438 HID_RI_REPORT_COUNT(8, 0x05), 439 HID_RI_REPORT_SIZE(8, 0x01), 440 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), 441 // LED padding (3 bits) 442 HID_RI_REPORT_COUNT(8, 0x01), 443 HID_RI_REPORT_SIZE(8, 0x03), 444 HID_RI_OUTPUT(8, HID_IOF_CONSTANT), 445 HID_RI_END_COLLECTION(0), 446 #endif 447 448 #ifdef SHARED_EP_ENABLE 449 }; 450 #endif 451 452 #ifdef RAW_ENABLE 453 const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = { 454 HID_RI_USAGE_PAGE(16, RAW_USAGE_PAGE), // Vendor Defined 455 HID_RI_USAGE(8, RAW_USAGE_ID), // Vendor Defined 456 HID_RI_COLLECTION(8, 0x01), // Application 457 // Data to host 458 HID_RI_USAGE(8, 0x62), // Vendor Defined 459 HID_RI_LOGICAL_MINIMUM(8, 0x00), 460 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), 461 HID_RI_REPORT_COUNT(8, RAW_EPSIZE), 462 HID_RI_REPORT_SIZE(8, 0x08), 463 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 464 465 // Data from host 466 HID_RI_USAGE(8, 0x63), // Vendor Defined 467 HID_RI_LOGICAL_MINIMUM(8, 0x00), 468 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), 469 HID_RI_REPORT_COUNT(8, RAW_EPSIZE), 470 HID_RI_REPORT_SIZE(8, 0x08), 471 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), 472 HID_RI_END_COLLECTION(0), 473 }; 474 #endif 475 476 #ifdef CONSOLE_ENABLE 477 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = { 478 HID_RI_USAGE_PAGE(16, 0xFF31), // Vendor Defined (PJRC Teensy compatible) 479 HID_RI_USAGE(8, 0x74), // Vendor Defined (PJRC Teensy compatible) 480 HID_RI_COLLECTION(8, 0x01), // Application 481 // Data to host 482 HID_RI_USAGE(8, 0x75), // Vendor Defined 483 HID_RI_LOGICAL_MINIMUM(8, 0x00), 484 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), 485 HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), 486 HID_RI_REPORT_SIZE(8, 0x08), 487 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 488 HID_RI_END_COLLECTION(0), 489 }; 490 #endif 491 492 /* 493 * Device descriptor 494 */ 495 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = { 496 .Header = { 497 .Size = sizeof(USB_Descriptor_Device_t), 498 .Type = DTYPE_Device 499 }, 500 .USBSpecification = VERSION_BCD(2, 0, 0), 501 502 #if VIRTSER_ENABLE 503 .Class = USB_CSCP_IADDeviceClass, 504 .SubClass = USB_CSCP_IADDeviceSubclass, 505 .Protocol = USB_CSCP_IADDeviceProtocol, 506 #else 507 .Class = USB_CSCP_NoDeviceClass, 508 .SubClass = USB_CSCP_NoDeviceSubclass, 509 .Protocol = USB_CSCP_NoDeviceProtocol, 510 #endif 511 512 .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, 513 // Specified in config.h 514 .VendorID = VENDOR_ID, 515 .ProductID = PRODUCT_ID, 516 .ReleaseNumber = DEVICE_VER, 517 .ManufacturerStrIndex = 0x01, 518 .ProductStrIndex = 0x02, 519 #ifdef HAS_SERIAL_NUMBER 520 .SerialNumStrIndex = 0x03, 521 #else // HAS_SERIAL_NUMBER 522 .SerialNumStrIndex = 0x00, 523 #endif // HAS_SERIAL_NUMBER 524 .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS 525 }; 526 527 #ifndef USB_MAX_POWER_CONSUMPTION 528 # define USB_MAX_POWER_CONSUMPTION 500 529 #endif 530 531 #ifndef USB_POLLING_INTERVAL_MS 532 # define USB_POLLING_INTERVAL_MS 1 533 #endif 534 535 /* 536 * Configuration descriptors 537 */ 538 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = { 539 .Config = { 540 .Header = { 541 .Size = sizeof(USB_Descriptor_Configuration_Header_t), 542 .Type = DTYPE_Configuration 543 }, 544 .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), 545 .TotalInterfaces = TOTAL_INTERFACES, 546 .ConfigurationNumber = 1, 547 .ConfigurationStrIndex = NO_DESCRIPTOR, 548 .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP), 549 .MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION) 550 }, 551 #ifndef KEYBOARD_SHARED_EP 552 /* 553 * Keyboard 554 */ 555 .Keyboard_Interface = { 556 .Header = { 557 .Size = sizeof(USB_Descriptor_Interface_t), 558 .Type = DTYPE_Interface 559 }, 560 .InterfaceNumber = KEYBOARD_INTERFACE, 561 .AlternateSetting = 0x00, 562 .TotalEndpoints = 1, 563 .Class = HID_CSCP_HIDClass, 564 .SubClass = HID_CSCP_BootSubclass, 565 .Protocol = HID_CSCP_KeyboardBootProtocol, 566 .InterfaceStrIndex = NO_DESCRIPTOR 567 }, 568 .Keyboard_HID = { 569 .Header = { 570 .Size = sizeof(USB_HID_Descriptor_HID_t), 571 .Type = HID_DTYPE_HID 572 }, 573 .HIDSpec = VERSION_BCD(1, 1, 1), 574 .CountryCode = 0x00, 575 .TotalReportDescriptors = 1, 576 .HIDReportType = HID_DTYPE_Report, 577 .HIDReportLength = sizeof(KeyboardReport) 578 }, 579 .Keyboard_INEndpoint = { 580 .Header = { 581 .Size = sizeof(USB_Descriptor_Endpoint_t), 582 .Type = DTYPE_Endpoint 583 }, 584 .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM), 585 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 586 .EndpointSize = KEYBOARD_EPSIZE, 587 .PollingIntervalMS = USB_POLLING_INTERVAL_MS 588 }, 589 #endif 590 591 #ifdef RAW_ENABLE 592 /* 593 * Raw HID 594 */ 595 .Raw_Interface = { 596 .Header = { 597 .Size = sizeof(USB_Descriptor_Interface_t), 598 .Type = DTYPE_Interface 599 }, 600 .InterfaceNumber = RAW_INTERFACE, 601 .AlternateSetting = 0x00, 602 .TotalEndpoints = 2, 603 .Class = HID_CSCP_HIDClass, 604 .SubClass = HID_CSCP_NonBootSubclass, 605 .Protocol = HID_CSCP_NonBootProtocol, 606 .InterfaceStrIndex = NO_DESCRIPTOR 607 }, 608 .Raw_HID = { 609 .Header = { 610 .Size = sizeof(USB_HID_Descriptor_HID_t), 611 .Type = HID_DTYPE_HID 612 }, 613 .HIDSpec = VERSION_BCD(1, 1, 1), 614 .CountryCode = 0x00, 615 .TotalReportDescriptors = 1, 616 .HIDReportType = HID_DTYPE_Report, 617 .HIDReportLength = sizeof(RawReport) 618 }, 619 .Raw_INEndpoint = { 620 .Header = { 621 .Size = sizeof(USB_Descriptor_Endpoint_t), 622 .Type = DTYPE_Endpoint 623 }, 624 .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM), 625 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 626 .EndpointSize = RAW_EPSIZE, 627 .PollingIntervalMS = 0x01 628 }, 629 .Raw_OUTEndpoint = { 630 .Header = { 631 .Size = sizeof(USB_Descriptor_Endpoint_t), 632 .Type = DTYPE_Endpoint 633 }, 634 .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM), 635 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 636 .EndpointSize = RAW_EPSIZE, 637 .PollingIntervalMS = 0x01 638 }, 639 #endif 640 641 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) 642 /* 643 * Mouse 644 */ 645 .Mouse_Interface = { 646 .Header = { 647 .Size = sizeof(USB_Descriptor_Interface_t), 648 .Type = DTYPE_Interface 649 }, 650 .InterfaceNumber = MOUSE_INTERFACE, 651 .AlternateSetting = 0x00, 652 .TotalEndpoints = 1, 653 .Class = HID_CSCP_HIDClass, 654 .SubClass = HID_CSCP_BootSubclass, 655 .Protocol = HID_CSCP_MouseBootProtocol, 656 .InterfaceStrIndex = NO_DESCRIPTOR 657 }, 658 .Mouse_HID = { 659 .Header = { 660 .Size = sizeof(USB_HID_Descriptor_HID_t), 661 .Type = HID_DTYPE_HID 662 }, 663 .HIDSpec = VERSION_BCD(1, 1, 1), 664 .CountryCode = 0x00, 665 .TotalReportDescriptors = 1, 666 .HIDReportType = HID_DTYPE_Report, 667 .HIDReportLength = sizeof(MouseReport) 668 }, 669 .Mouse_INEndpoint = { 670 .Header = { 671 .Size = sizeof(USB_Descriptor_Endpoint_t), 672 .Type = DTYPE_Endpoint 673 }, 674 .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM), 675 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 676 .EndpointSize = MOUSE_EPSIZE, 677 .PollingIntervalMS = USB_POLLING_INTERVAL_MS 678 }, 679 #endif 680 681 #ifdef SHARED_EP_ENABLE 682 /* 683 * Shared 684 */ 685 .Shared_Interface = { 686 .Header = { 687 .Size = sizeof(USB_Descriptor_Interface_t), 688 .Type = DTYPE_Interface 689 }, 690 .InterfaceNumber = SHARED_INTERFACE, 691 .AlternateSetting = 0x00, 692 .TotalEndpoints = 1, 693 .Class = HID_CSCP_HIDClass, 694 # ifdef KEYBOARD_SHARED_EP 695 .SubClass = HID_CSCP_BootSubclass, 696 .Protocol = HID_CSCP_KeyboardBootProtocol, 697 # else 698 .SubClass = HID_CSCP_NonBootSubclass, 699 .Protocol = HID_CSCP_NonBootProtocol, 700 # endif 701 .InterfaceStrIndex = NO_DESCRIPTOR 702 }, 703 .Shared_HID = { 704 .Header = { 705 .Size = sizeof(USB_HID_Descriptor_HID_t), 706 .Type = HID_DTYPE_HID 707 }, 708 .HIDSpec = VERSION_BCD(1, 1, 1), 709 .CountryCode = 0x00, 710 .TotalReportDescriptors = 1, 711 .HIDReportType = HID_DTYPE_Report, 712 .HIDReportLength = sizeof(SharedReport) 713 }, 714 .Shared_INEndpoint = { 715 .Header = { 716 .Size = sizeof(USB_Descriptor_Endpoint_t), 717 .Type = DTYPE_Endpoint 718 }, 719 .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM), 720 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 721 .EndpointSize = SHARED_EPSIZE, 722 .PollingIntervalMS = USB_POLLING_INTERVAL_MS 723 }, 724 #endif 725 726 #ifdef CONSOLE_ENABLE 727 /* 728 * Console 729 */ 730 .Console_Interface = { 731 .Header = { 732 .Size = sizeof(USB_Descriptor_Interface_t), 733 .Type = DTYPE_Interface 734 }, 735 .InterfaceNumber = CONSOLE_INTERFACE, 736 .AlternateSetting = 0x00, 737 .TotalEndpoints = 1, 738 .Class = HID_CSCP_HIDClass, 739 .SubClass = HID_CSCP_NonBootSubclass, 740 .Protocol = HID_CSCP_NonBootProtocol, 741 .InterfaceStrIndex = NO_DESCRIPTOR 742 }, 743 .Console_HID = { 744 .Header = { 745 .Size = sizeof(USB_HID_Descriptor_HID_t), 746 .Type = HID_DTYPE_HID 747 }, 748 .HIDSpec = VERSION_BCD(1, 1, 1), 749 .CountryCode = 0x00, 750 .TotalReportDescriptors = 1, 751 .HIDReportType = HID_DTYPE_Report, 752 .HIDReportLength = sizeof(ConsoleReport) 753 }, 754 .Console_INEndpoint = { 755 .Header = { 756 .Size = sizeof(USB_Descriptor_Endpoint_t), 757 .Type = DTYPE_Endpoint 758 }, 759 .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM), 760 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 761 .EndpointSize = CONSOLE_EPSIZE, 762 .PollingIntervalMS = 0x01 763 }, 764 #endif 765 766 #ifdef MIDI_ENABLE 767 /* 768 * MIDI 769 */ 770 .Audio_Interface_Association = { 771 .Header = { 772 .Size = sizeof(USB_Descriptor_Interface_Association_t), 773 .Type = DTYPE_InterfaceAssociation 774 }, 775 .FirstInterfaceIndex = AC_INTERFACE, 776 .TotalInterfaces = 2, 777 .Class = AUDIO_CSCP_AudioClass, 778 .SubClass = AUDIO_CSCP_ControlSubclass, 779 .Protocol = AUDIO_CSCP_ControlProtocol, 780 .IADStrIndex = NO_DESCRIPTOR, 781 }, 782 .Audio_ControlInterface = { 783 .Header = { 784 .Size = sizeof(USB_Descriptor_Interface_t), 785 .Type = DTYPE_Interface 786 }, 787 .InterfaceNumber = AC_INTERFACE, 788 .AlternateSetting = 0, 789 .TotalEndpoints = 0, 790 .Class = AUDIO_CSCP_AudioClass, 791 .SubClass = AUDIO_CSCP_ControlSubclass, 792 .Protocol = AUDIO_CSCP_ControlProtocol, 793 .InterfaceStrIndex = NO_DESCRIPTOR 794 }, 795 .Audio_ControlInterface_SPC = { 796 .Header = { 797 .Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), 798 .Type = AUDIO_DTYPE_CSInterface 799 }, 800 .Subtype = AUDIO_DSUBTYPE_CSInterface_Header, 801 .ACSpecification = VERSION_BCD(1, 0, 0), 802 .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t), 803 .InCollection = 1, 804 .InterfaceNumber = AS_INTERFACE, 805 }, 806 .Audio_StreamInterface = { 807 .Header = { 808 .Size = sizeof(USB_Descriptor_Interface_t), 809 .Type = DTYPE_Interface 810 }, 811 .InterfaceNumber = AS_INTERFACE, 812 .AlternateSetting = 0, 813 .TotalEndpoints = 2, 814 .Class = AUDIO_CSCP_AudioClass, 815 .SubClass = AUDIO_CSCP_MIDIStreamingSubclass, 816 .Protocol = AUDIO_CSCP_StreamingProtocol, 817 .InterfaceStrIndex = NO_DESCRIPTOR 818 }, 819 .Audio_StreamInterface_SPC = { 820 .Header = { 821 .Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), 822 .Type = AUDIO_DTYPE_CSInterface 823 }, 824 .Subtype = AUDIO_DSUBTYPE_CSInterface_General, 825 .AudioSpecification = VERSION_BCD(1, 0, 0), 826 .TotalLength = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC) + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t) - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC) 827 }, 828 .MIDI_In_Jack_Emb = { 829 .Header = { 830 .Size = sizeof(USB_MIDI_Descriptor_InputJack_t), 831 .Type = AUDIO_DTYPE_CSInterface 832 }, 833 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, 834 .JackType = MIDI_JACKTYPE_Embedded, 835 .JackID = 0x01, 836 .JackStrIndex = NO_DESCRIPTOR 837 }, 838 .MIDI_In_Jack_Ext = { 839 .Header = { 840 .Size = sizeof(USB_MIDI_Descriptor_InputJack_t), 841 .Type = AUDIO_DTYPE_CSInterface 842 }, 843 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, 844 .JackType = MIDI_JACKTYPE_External, 845 .JackID = 0x02, 846 .JackStrIndex = NO_DESCRIPTOR 847 }, 848 .MIDI_Out_Jack_Emb = { 849 .Header = { 850 .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), 851 .Type = AUDIO_DTYPE_CSInterface 852 }, 853 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, 854 .JackType = MIDI_JACKTYPE_Embedded, 855 .JackID = 0x03, 856 .NumberOfPins = 1, 857 .SourceJackID = {0x02}, 858 .SourcePinID = {0x01}, 859 .JackStrIndex = NO_DESCRIPTOR 860 }, 861 .MIDI_Out_Jack_Ext = { 862 .Header = { 863 .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), 864 .Type = AUDIO_DTYPE_CSInterface 865 }, 866 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, 867 .JackType = MIDI_JACKTYPE_External, 868 .JackID = 0x04, 869 .NumberOfPins = 1, 870 .SourceJackID = {0x01}, 871 .SourcePinID = {0x01}, 872 .JackStrIndex = NO_DESCRIPTOR 873 }, 874 .MIDI_In_Jack_Endpoint = { 875 .Endpoint = { 876 .Header = { 877 .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), 878 .Type = DTYPE_Endpoint 879 }, 880 .EndpointAddress = (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM), 881 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 882 .EndpointSize = MIDI_STREAM_EPSIZE, 883 .PollingIntervalMS = 0x05 884 }, 885 .Refresh = 0, 886 .SyncEndpointNumber = 0 887 }, 888 .MIDI_In_Jack_Endpoint_SPC = { 889 .Header = { 890 .Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), 891 .Type = AUDIO_DTYPE_CSEndpoint 892 }, 893 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, 894 .TotalEmbeddedJacks = 0x01, 895 .AssociatedJackID = {0x01} 896 }, 897 .MIDI_Out_Jack_Endpoint = { 898 .Endpoint = { 899 .Header = { 900 .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), 901 .Type = DTYPE_Endpoint 902 }, 903 .EndpointAddress = (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM), 904 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 905 .EndpointSize = MIDI_STREAM_EPSIZE, 906 .PollingIntervalMS = 0x05 907 }, 908 .Refresh = 0, 909 .SyncEndpointNumber = 0 910 }, 911 .MIDI_Out_Jack_Endpoint_SPC = { 912 .Header = { 913 .Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), 914 .Type = AUDIO_DTYPE_CSEndpoint 915 }, 916 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, 917 .TotalEmbeddedJacks = 0x01, 918 .AssociatedJackID = {0x03} 919 }, 920 #endif 921 922 #ifdef VIRTSER_ENABLE 923 /* 924 * Virtual Serial 925 */ 926 .CDC_Interface_Association = { 927 .Header = { 928 .Size = sizeof(USB_Descriptor_Interface_Association_t), 929 .Type = DTYPE_InterfaceAssociation 930 }, 931 .FirstInterfaceIndex = CCI_INTERFACE, 932 .TotalInterfaces = 2, 933 .Class = CDC_CSCP_CDCClass, 934 .SubClass = CDC_CSCP_ACMSubclass, 935 .Protocol = CDC_CSCP_ATCommandProtocol, 936 .IADStrIndex = NO_DESCRIPTOR, 937 }, 938 .CDC_CCI_Interface = { 939 .Header = { 940 .Size = sizeof(USB_Descriptor_Interface_t), 941 .Type = DTYPE_Interface 942 }, 943 .InterfaceNumber = CCI_INTERFACE, 944 .AlternateSetting = 0, 945 .TotalEndpoints = 1, 946 .Class = CDC_CSCP_CDCClass, 947 .SubClass = CDC_CSCP_ACMSubclass, 948 .Protocol = CDC_CSCP_ATCommandProtocol, 949 .InterfaceStrIndex = NO_DESCRIPTOR 950 }, 951 .CDC_Functional_Header = { 952 .Header = { 953 .Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), 954 .Type = CDC_DTYPE_CSInterface 955 }, 956 .Subtype = 0x00, 957 .CDCSpecification = VERSION_BCD(1, 1, 0), 958 }, 959 .CDC_Functional_ACM = { 960 .Header = { 961 .Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), 962 .Type = CDC_DTYPE_CSInterface 963 }, 964 .Subtype = 0x02, 965 .Capabilities = 0x02, 966 }, 967 .CDC_Functional_Union = { 968 .Header = { 969 .Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), 970 .Type = CDC_DTYPE_CSInterface 971 }, 972 .Subtype = 0x06, 973 .MasterInterfaceNumber = CCI_INTERFACE, 974 .SlaveInterfaceNumber = CDI_INTERFACE, 975 }, 976 .CDC_NotificationEndpoint = { 977 .Header = { 978 .Size = sizeof(USB_Descriptor_Endpoint_t), 979 .Type = DTYPE_Endpoint 980 }, 981 .EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM), 982 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 983 .EndpointSize = CDC_NOTIFICATION_EPSIZE, 984 .PollingIntervalMS = 0xFF 985 }, 986 .CDC_DCI_Interface = { 987 .Header = { 988 .Size = sizeof(USB_Descriptor_Interface_t), 989 .Type = DTYPE_Interface 990 }, 991 .InterfaceNumber = CDI_INTERFACE, 992 .AlternateSetting = 0, 993 .TotalEndpoints = 2, 994 .Class = CDC_CSCP_CDCDataClass, 995 .SubClass = CDC_CSCP_NoDataSubclass, 996 .Protocol = CDC_CSCP_NoDataProtocol, 997 .InterfaceStrIndex = NO_DESCRIPTOR 998 }, 999 .CDC_DataOutEndpoint = { 1000 .Header = { 1001 .Size = sizeof(USB_Descriptor_Endpoint_t), 1002 .Type = DTYPE_Endpoint 1003 }, 1004 .EndpointAddress = (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM), 1005 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 1006 .EndpointSize = CDC_EPSIZE, 1007 .PollingIntervalMS = 0x05 1008 }, 1009 .CDC_DataInEndpoint = { 1010 .Header = { 1011 .Size = sizeof(USB_Descriptor_Endpoint_t), 1012 .Type = DTYPE_Endpoint 1013 }, 1014 .EndpointAddress = (ENDPOINT_DIR_IN | CDC_IN_EPNUM), 1015 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 1016 .EndpointSize = CDC_EPSIZE, 1017 .PollingIntervalMS = 0x05 1018 }, 1019 #endif 1020 1021 #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP) 1022 /* 1023 * Joystick 1024 */ 1025 .Joystick_Interface = { 1026 .Header = { 1027 .Size = sizeof(USB_Descriptor_Interface_t), 1028 .Type = DTYPE_Interface 1029 }, 1030 .InterfaceNumber = JOYSTICK_INTERFACE, 1031 .AlternateSetting = 0x00, 1032 .TotalEndpoints = 1, 1033 .Class = HID_CSCP_HIDClass, 1034 .SubClass = HID_CSCP_NonBootSubclass, 1035 .Protocol = HID_CSCP_NonBootProtocol, 1036 .InterfaceStrIndex = NO_DESCRIPTOR 1037 }, 1038 .Joystick_HID = { 1039 .Header = { 1040 .Size = sizeof(USB_HID_Descriptor_HID_t), 1041 .Type = HID_DTYPE_HID 1042 }, 1043 .HIDSpec = VERSION_BCD(1, 1, 1), 1044 .CountryCode = 0x00, 1045 .TotalReportDescriptors = 1, 1046 .HIDReportType = HID_DTYPE_Report, 1047 .HIDReportLength = sizeof(JoystickReport) 1048 }, 1049 .Joystick_INEndpoint = { 1050 .Header = { 1051 .Size = sizeof(USB_Descriptor_Endpoint_t), 1052 .Type = DTYPE_Endpoint 1053 }, 1054 .EndpointAddress = (ENDPOINT_DIR_IN | JOYSTICK_IN_EPNUM), 1055 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 1056 .EndpointSize = JOYSTICK_EPSIZE, 1057 .PollingIntervalMS = USB_POLLING_INTERVAL_MS 1058 }, 1059 #endif 1060 1061 #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP) 1062 /* 1063 * Digitizer 1064 */ 1065 .Digitizer_Interface = { 1066 .Header = { 1067 .Size = sizeof(USB_Descriptor_Interface_t), 1068 .Type = DTYPE_Interface 1069 }, 1070 .InterfaceNumber = DIGITIZER_INTERFACE, 1071 .AlternateSetting = 0x00, 1072 .TotalEndpoints = 1, 1073 .Class = HID_CSCP_HIDClass, 1074 .SubClass = HID_CSCP_NonBootSubclass, 1075 .Protocol = HID_CSCP_NonBootProtocol, 1076 .InterfaceStrIndex = NO_DESCRIPTOR 1077 }, 1078 .Digitizer_HID = { 1079 .Header = { 1080 .Size = sizeof(USB_HID_Descriptor_HID_t), 1081 .Type = HID_DTYPE_HID 1082 }, 1083 .HIDSpec = VERSION_BCD(1, 1, 1), 1084 .CountryCode = 0x00, 1085 .TotalReportDescriptors = 1, 1086 .HIDReportType = HID_DTYPE_Report, 1087 .HIDReportLength = sizeof(DigitizerReport) 1088 }, 1089 .Digitizer_INEndpoint = { 1090 .Header = { 1091 .Size = sizeof(USB_Descriptor_Endpoint_t), 1092 .Type = DTYPE_Endpoint 1093 }, 1094 .EndpointAddress = (ENDPOINT_DIR_IN | DIGITIZER_IN_EPNUM), 1095 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 1096 .EndpointSize = DIGITIZER_EPSIZE, 1097 .PollingIntervalMS = USB_POLLING_INTERVAL_MS 1098 }, 1099 #endif 1100 }; 1101 1102 /* 1103 * String descriptors 1104 */ 1105 1106 #define USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(str) \ 1107 (sizeof(USB_Descriptor_Header_t) + sizeof(str) - sizeof(wchar_t)) // include header, don't count null terminator 1108 1109 const USB_Descriptor_String_t PROGMEM LanguageString = { 1110 .Header = { 1111 .Size = sizeof(USB_Descriptor_Header_t) + sizeof(uint16_t), 1112 .Type = DTYPE_String 1113 }, 1114 .UnicodeString = {LANGUAGE_ID_ENG} 1115 }; 1116 1117 const USB_Descriptor_String_t PROGMEM ManufacturerString = { 1118 .Header = { 1119 .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(MANUFACTURER)), 1120 .Type = DTYPE_String 1121 }, 1122 .UnicodeString = USBSTR(MANUFACTURER) 1123 }; 1124 1125 const USB_Descriptor_String_t PROGMEM ProductString = { 1126 .Header = { 1127 .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(PRODUCT)), 1128 .Type = DTYPE_String 1129 }, 1130 .UnicodeString = USBSTR(PRODUCT) 1131 }; 1132 1133 // clang-format on 1134 1135 #if defined(SERIAL_NUMBER) 1136 // clang-format off 1137 const USB_Descriptor_String_t PROGMEM SerialNumberString = { 1138 .Header = { 1139 .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(SERIAL_NUMBER)), 1140 .Type = DTYPE_String 1141 }, 1142 .UnicodeString = USBSTR(SERIAL_NUMBER) 1143 }; 1144 // clang-format on 1145 1146 #else // defined(SERIAL_NUMBER) 1147 1148 # if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE 1149 1150 # if defined(__AVR__) 1151 # error Dynamically setting the serial number on AVR is unsupported as LUFA requires the string to be in PROGMEM. 1152 # endif // defined(__AVR__) 1153 1154 # ifndef SERIAL_NUMBER_LENGTH 1155 # define SERIAL_NUMBER_LENGTH (sizeof(hardware_id_t) * 2) 1156 # endif 1157 1158 # define SERIAL_NUMBER_DESCRIPTOR_SIZE \ 1159 (sizeof(USB_Descriptor_Header_t) /* Descriptor header */ \ 1160 + (((SERIAL_NUMBER_LENGTH) + 1) * sizeof(wchar_t))) /* Length of serial number, with potential extra character as we're converting 2 nibbles at a time */ 1161 1162 uint8_t SerialNumberString[SERIAL_NUMBER_DESCRIPTOR_SIZE] = {0}; 1163 1164 void set_serial_number_descriptor(void) { 1165 static bool is_set = false; 1166 if (is_set) { 1167 return; 1168 } 1169 is_set = true; 1170 1171 static const char hex_str[] = "0123456789ABCDEF"; 1172 hardware_id_t id = get_hardware_id(); 1173 USB_Descriptor_String_t* desc = (USB_Descriptor_String_t*)SerialNumberString; 1174 1175 // Copy across nibbles from the hardware ID as unicode hex characters 1176 int length = MIN(sizeof(id) * 2, SERIAL_NUMBER_LENGTH); 1177 uint8_t* p = (uint8_t*)&id; 1178 for (int i = 0; i < length; i += 2) { 1179 desc->UnicodeString[i + 0] = hex_str[p[i / 2] >> 4]; 1180 desc->UnicodeString[i + 1] = hex_str[p[i / 2] & 0xF]; 1181 } 1182 1183 desc->Header.Size = sizeof(USB_Descriptor_Header_t) + (length * sizeof(wchar_t)); // includes header, don't count null terminator 1184 desc->Header.Type = DTYPE_String; 1185 } 1186 1187 # endif // defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE 1188 1189 #endif // defined(SERIAL_NUMBER) 1190 1191 /** 1192 * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" 1193 * documentation) by the application code so that the address and size of a requested descriptor can be given 1194 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function 1195 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the 1196 * USB host. 1197 */ 1198 uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const uint16_t wLength, const void** const DescriptorAddress) { 1199 const uint8_t DescriptorType = (wValue >> 8); 1200 const uint8_t DescriptorIndex = (wValue & 0xFF); 1201 const void* Address = NULL; 1202 uint16_t Size = NO_DESCRIPTOR; 1203 1204 switch (DescriptorType) { 1205 case DTYPE_Device: 1206 Address = &DeviceDescriptor; 1207 Size = sizeof(USB_Descriptor_Device_t); 1208 1209 break; 1210 case DTYPE_Configuration: 1211 Address = &ConfigurationDescriptor; 1212 Size = sizeof(USB_Descriptor_Configuration_t); 1213 1214 break; 1215 case DTYPE_String: 1216 switch (DescriptorIndex) { 1217 case 0x00: 1218 Address = &LanguageString; 1219 Size = pgm_read_byte(&LanguageString.Header.Size); 1220 1221 break; 1222 case 0x01: 1223 Address = &ManufacturerString; 1224 Size = pgm_read_byte(&ManufacturerString.Header.Size); 1225 1226 break; 1227 case 0x02: 1228 Address = &ProductString; 1229 Size = pgm_read_byte(&ProductString.Header.Size); 1230 1231 break; 1232 #ifdef HAS_SERIAL_NUMBER 1233 case 0x03: 1234 Address = (const USB_Descriptor_String_t*)&SerialNumberString; 1235 # if defined(SERIAL_NUMBER) 1236 Size = pgm_read_byte(&SerialNumberString.Header.Size); 1237 # else 1238 set_serial_number_descriptor(); 1239 Size = ((const USB_Descriptor_String_t*)SerialNumberString)->Header.Size; 1240 # endif 1241 1242 break; 1243 #endif // HAS_SERIAL_NUMBER 1244 } 1245 #ifdef OS_DETECTION_ENABLE 1246 process_wlength(wLength); 1247 #endif 1248 1249 break; 1250 case HID_DTYPE_HID: 1251 switch (wIndex) { 1252 #ifndef KEYBOARD_SHARED_EP 1253 case KEYBOARD_INTERFACE: 1254 Address = &ConfigurationDescriptor.Keyboard_HID; 1255 Size = sizeof(USB_HID_Descriptor_HID_t); 1256 break; 1257 #endif 1258 1259 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) 1260 case MOUSE_INTERFACE: 1261 Address = &ConfigurationDescriptor.Mouse_HID; 1262 Size = sizeof(USB_HID_Descriptor_HID_t); 1263 1264 break; 1265 #endif 1266 1267 #ifdef SHARED_EP_ENABLE 1268 case SHARED_INTERFACE: 1269 Address = &ConfigurationDescriptor.Shared_HID; 1270 Size = sizeof(USB_HID_Descriptor_HID_t); 1271 1272 break; 1273 #endif 1274 1275 #ifdef RAW_ENABLE 1276 case RAW_INTERFACE: 1277 Address = &ConfigurationDescriptor.Raw_HID; 1278 Size = sizeof(USB_HID_Descriptor_HID_t); 1279 1280 break; 1281 #endif 1282 1283 #ifdef CONSOLE_ENABLE 1284 case CONSOLE_INTERFACE: 1285 Address = &ConfigurationDescriptor.Console_HID; 1286 Size = sizeof(USB_HID_Descriptor_HID_t); 1287 1288 break; 1289 #endif 1290 #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP) 1291 case JOYSTICK_INTERFACE: 1292 Address = &ConfigurationDescriptor.Joystick_HID; 1293 Size = sizeof(USB_HID_Descriptor_HID_t); 1294 break; 1295 #endif 1296 #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP) 1297 case DIGITIZER_INTERFACE: 1298 Address = &ConfigurationDescriptor.Digitizer_HID; 1299 Size = sizeof(USB_HID_Descriptor_HID_t); 1300 1301 break; 1302 #endif 1303 } 1304 1305 break; 1306 case HID_DTYPE_Report: 1307 switch (wIndex) { 1308 #ifndef KEYBOARD_SHARED_EP 1309 case KEYBOARD_INTERFACE: 1310 Address = &KeyboardReport; 1311 Size = sizeof(KeyboardReport); 1312 1313 break; 1314 #endif 1315 1316 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) 1317 case MOUSE_INTERFACE: 1318 Address = &MouseReport; 1319 Size = sizeof(MouseReport); 1320 1321 break; 1322 #endif 1323 1324 #ifdef SHARED_EP_ENABLE 1325 case SHARED_INTERFACE: 1326 Address = &SharedReport; 1327 Size = sizeof(SharedReport); 1328 1329 break; 1330 #endif 1331 1332 #ifdef RAW_ENABLE 1333 case RAW_INTERFACE: 1334 Address = &RawReport; 1335 Size = sizeof(RawReport); 1336 1337 break; 1338 #endif 1339 1340 #ifdef CONSOLE_ENABLE 1341 case CONSOLE_INTERFACE: 1342 Address = &ConsoleReport; 1343 Size = sizeof(ConsoleReport); 1344 1345 break; 1346 #endif 1347 #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP) 1348 case JOYSTICK_INTERFACE: 1349 Address = &JoystickReport; 1350 Size = sizeof(JoystickReport); 1351 break; 1352 #endif 1353 #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP) 1354 case DIGITIZER_INTERFACE: 1355 Address = &DigitizerReport; 1356 Size = sizeof(DigitizerReport); 1357 break; 1358 #endif 1359 } 1360 1361 break; 1362 } 1363 1364 *DescriptorAddress = Address; 1365 1366 return Size; 1367 }