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
10 Copyright (C) Dean Camera, 2012.
12 dean [at] fourwalledcubicle [dot] com
17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
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.
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
41 #include "descriptor.h"
43 #ifndef USB_MAX_POWER_CONSUMPTION
44 #define USB_MAX_POWER_CONSUMPTION 500
47 /*******************************************************************************
48 * HID Report Descriptors
49 ******************************************************************************/
50 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
52 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
53 HID_RI_USAGE(8, 0x06), /* Keyboard */
54 HID_RI_COLLECTION(8, 0x01), /* Application */
55 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
56 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
57 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
58 HID_RI_LOGICAL_MINIMUM(8, 0x00),
59 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
60 HID_RI_REPORT_COUNT(8, 0x08),
61 HID_RI_REPORT_SIZE(8, 0x01),
62 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
64 HID_RI_REPORT_COUNT(8, 0x01),
65 HID_RI_REPORT_SIZE(8, 0x08),
66 HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */
68 HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
69 HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
70 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
71 HID_RI_REPORT_COUNT(8, 0x05),
72 HID_RI_REPORT_SIZE(8, 0x01),
73 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
74 HID_RI_REPORT_COUNT(8, 0x01),
75 HID_RI_REPORT_SIZE(8, 0x03),
76 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
78 HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
79 HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
80 HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
81 HID_RI_LOGICAL_MINIMUM(8, 0x00),
82 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
83 HID_RI_REPORT_COUNT(8, 0x06),
84 HID_RI_REPORT_SIZE(8, 0x08),
85 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
86 HID_RI_END_COLLECTION(0),
90 const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
92 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
93 HID_RI_USAGE(8, 0x02), /* Mouse */
94 HID_RI_COLLECTION(8, 0x01), /* Application */
95 HID_RI_USAGE(8, 0x01), /* Pointer */
96 HID_RI_COLLECTION(8, 0x00), /* Physical */
98 HID_RI_USAGE_PAGE(8, 0x09), /* Button */
99 HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
100 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */
101 HID_RI_LOGICAL_MINIMUM(8, 0x00),
102 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
103 HID_RI_REPORT_COUNT(8, 0x05),
104 HID_RI_REPORT_SIZE(8, 0x01),
105 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
106 HID_RI_REPORT_COUNT(8, 0x01),
107 HID_RI_REPORT_SIZE(8, 0x03),
108 HID_RI_INPUT(8, HID_IOF_CONSTANT),
110 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
111 HID_RI_USAGE(8, 0x30), /* Usage X */
112 HID_RI_USAGE(8, 0x31), /* Usage Y */
113 HID_RI_LOGICAL_MINIMUM(8, -127),
114 HID_RI_LOGICAL_MAXIMUM(8, 127),
115 HID_RI_REPORT_COUNT(8, 0x02),
116 HID_RI_REPORT_SIZE(8, 0x08),
117 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
119 HID_RI_USAGE(8, 0x38), /* Wheel */
120 HID_RI_LOGICAL_MINIMUM(8, -127),
121 HID_RI_LOGICAL_MAXIMUM(8, 127),
122 HID_RI_REPORT_COUNT(8, 0x01),
123 HID_RI_REPORT_SIZE(8, 0x08),
124 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
126 HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
127 HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */
128 HID_RI_LOGICAL_MINIMUM(8, -127),
129 HID_RI_LOGICAL_MAXIMUM(8, 127),
130 HID_RI_REPORT_COUNT(8, 0x01),
131 HID_RI_REPORT_SIZE(8, 0x08),
132 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
134 HID_RI_END_COLLECTION(0),
135 HID_RI_END_COLLECTION(0),
139 #ifdef EXTRAKEY_ENABLE
140 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
142 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
143 HID_RI_USAGE(8, 0x80), /* System Control */
144 HID_RI_COLLECTION(8, 0x01), /* Application */
145 HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
146 HID_RI_LOGICAL_MINIMUM(16, 0x0001),
147 HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
148 HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
149 HID_RI_USAGE_MAXIMUM(16, 0x0083), /* System Wake Up */
150 HID_RI_REPORT_SIZE(8, 16),
151 HID_RI_REPORT_COUNT(8, 1),
152 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
153 HID_RI_END_COLLECTION(0),
155 HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
156 HID_RI_USAGE(8, 0x01), /* Consumer Control */
157 HID_RI_COLLECTION(8, 0x01), /* Application */
158 HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
159 HID_RI_LOGICAL_MINIMUM(16, 0x0001),
160 HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
161 HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
162 HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */
163 HID_RI_REPORT_SIZE(8, 16),
164 HID_RI_REPORT_COUNT(8, 1),
165 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
166 HID_RI_END_COLLECTION(0),
171 const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
173 HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
174 HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
175 HID_RI_COLLECTION(8, 0x01), /* Application */
176 HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
177 HID_RI_LOGICAL_MINIMUM(8, 0x00),
178 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
179 HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
180 HID_RI_REPORT_SIZE(8, 0x08),
181 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
182 HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
183 HID_RI_LOGICAL_MINIMUM(8, 0x00),
184 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
185 HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
186 HID_RI_REPORT_SIZE(8, 0x08),
187 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
188 HID_RI_END_COLLECTION(0),
192 #ifdef CONSOLE_ENABLE
193 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
195 HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
196 HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
197 HID_RI_COLLECTION(8, 0x01), /* Application */
198 HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
199 HID_RI_LOGICAL_MINIMUM(8, 0x00),
200 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
201 HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
202 HID_RI_REPORT_SIZE(8, 0x08),
203 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
204 HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
205 HID_RI_LOGICAL_MINIMUM(8, 0x00),
206 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
207 HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
208 HID_RI_REPORT_SIZE(8, 0x08),
209 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
210 HID_RI_END_COLLECTION(0),
215 const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
217 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
218 HID_RI_USAGE(8, 0x06), /* Keyboard */
219 HID_RI_COLLECTION(8, 0x01), /* Application */
220 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
221 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
222 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
223 HID_RI_LOGICAL_MINIMUM(8, 0x00),
224 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
225 HID_RI_REPORT_COUNT(8, 0x08),
226 HID_RI_REPORT_SIZE(8, 0x01),
227 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
229 HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
230 HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
231 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
232 HID_RI_REPORT_COUNT(8, 0x05),
233 HID_RI_REPORT_SIZE(8, 0x01),
234 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
235 HID_RI_REPORT_COUNT(8, 0x01),
236 HID_RI_REPORT_SIZE(8, 0x03),
237 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
239 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
240 HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
241 HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
242 HID_RI_LOGICAL_MINIMUM(8, 0x00),
243 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
244 HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
245 HID_RI_REPORT_SIZE(8, 0x01),
246 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
247 HID_RI_END_COLLECTION(0),
251 /*******************************************************************************
253 ******************************************************************************/
254 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
256 .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
258 .USBSpecification = VERSION_BCD(1,1,0),
260 .Class = USB_CSCP_IADDeviceClass,
261 .SubClass = USB_CSCP_IADDeviceSubclass,
262 .Protocol = USB_CSCP_IADDeviceProtocol,
264 .Class = USB_CSCP_NoDeviceClass,
265 .SubClass = USB_CSCP_NoDeviceSubclass,
266 .Protocol = USB_CSCP_NoDeviceProtocol,
269 .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
271 /* specified in config.h */
272 .VendorID = VENDOR_ID,
273 .ProductID = PRODUCT_ID,
274 .ReleaseNumber = DEVICE_VER,
276 .ManufacturerStrIndex = 0x01,
277 .ProductStrIndex = 0x02,
278 .SerialNumStrIndex = 0x03,
280 .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
283 /*******************************************************************************
284 * Configuration Descriptors
285 ******************************************************************************/
286 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
290 .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
292 .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
293 .TotalInterfaces = TOTAL_INTERFACES,
295 .ConfigurationNumber = 1,
296 .ConfigurationStrIndex = NO_DESCRIPTOR,
298 .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
300 .MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
306 .Keyboard_Interface =
308 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
310 .InterfaceNumber = KEYBOARD_INTERFACE,
311 .AlternateSetting = 0x00,
315 .Class = HID_CSCP_HIDClass,
316 .SubClass = HID_CSCP_BootSubclass,
317 .Protocol = HID_CSCP_KeyboardBootProtocol,
319 .InterfaceStrIndex = NO_DESCRIPTOR
324 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
326 .HIDSpec = VERSION_BCD(1,1,1),
328 .TotalReportDescriptors = 1,
329 .HIDReportType = HID_DTYPE_Report,
330 .HIDReportLength = sizeof(KeyboardReport)
333 .Keyboard_INEndpoint =
335 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
337 .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
338 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
339 .EndpointSize = KEYBOARD_EPSIZE,
340 .PollingIntervalMS = 0x0A
349 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
351 .InterfaceNumber = MOUSE_INTERFACE,
352 .AlternateSetting = 0x00,
356 .Class = HID_CSCP_HIDClass,
357 .SubClass = HID_CSCP_BootSubclass,
358 .Protocol = HID_CSCP_MouseBootProtocol,
360 .InterfaceStrIndex = NO_DESCRIPTOR
365 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
367 .HIDSpec = VERSION_BCD(1,1,1),
369 .TotalReportDescriptors = 1,
370 .HIDReportType = HID_DTYPE_Report,
371 .HIDReportLength = sizeof(MouseReport)
376 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
378 .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
379 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
380 .EndpointSize = MOUSE_EPSIZE,
381 .PollingIntervalMS = 0x0A
388 #ifdef EXTRAKEY_ENABLE
389 .Extrakey_Interface =
391 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
393 .InterfaceNumber = EXTRAKEY_INTERFACE,
394 .AlternateSetting = 0x00,
398 .Class = HID_CSCP_HIDClass,
399 .SubClass = HID_CSCP_NonBootSubclass,
400 .Protocol = HID_CSCP_NonBootProtocol,
402 .InterfaceStrIndex = NO_DESCRIPTOR
407 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
409 .HIDSpec = VERSION_BCD(1,1,1),
411 .TotalReportDescriptors = 1,
412 .HIDReportType = HID_DTYPE_Report,
413 .HIDReportLength = sizeof(ExtrakeyReport)
416 .Extrakey_INEndpoint =
418 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
420 .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
421 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
422 .EndpointSize = EXTRAKEY_EPSIZE,
423 .PollingIntervalMS = 0x0A
433 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
435 .InterfaceNumber = RAW_INTERFACE,
436 .AlternateSetting = 0x00,
440 .Class = HID_CSCP_HIDClass,
441 .SubClass = HID_CSCP_NonBootSubclass,
442 .Protocol = HID_CSCP_NonBootProtocol,
444 .InterfaceStrIndex = NO_DESCRIPTOR
449 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
451 .HIDSpec = VERSION_BCD(1,1,1),
453 .TotalReportDescriptors = 1,
454 .HIDReportType = HID_DTYPE_Report,
455 .HIDReportLength = sizeof(RawReport)
460 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
462 .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
463 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
464 .EndpointSize = RAW_EPSIZE,
465 .PollingIntervalMS = 0x01
470 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
472 .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
473 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
474 .EndpointSize = RAW_EPSIZE,
475 .PollingIntervalMS = 0x01
482 #ifdef CONSOLE_ENABLE
485 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
487 .InterfaceNumber = CONSOLE_INTERFACE,
488 .AlternateSetting = 0x00,
492 .Class = HID_CSCP_HIDClass,
493 .SubClass = HID_CSCP_NonBootSubclass,
494 .Protocol = HID_CSCP_NonBootProtocol,
496 .InterfaceStrIndex = NO_DESCRIPTOR
501 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
503 .HIDSpec = VERSION_BCD(1,1,1),
505 .TotalReportDescriptors = 1,
506 .HIDReportType = HID_DTYPE_Report,
507 .HIDReportLength = sizeof(ConsoleReport)
510 .Console_INEndpoint =
512 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
514 .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
515 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
516 .EndpointSize = CONSOLE_EPSIZE,
517 .PollingIntervalMS = 0x01
520 .Console_OUTEndpoint =
522 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
524 .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
525 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
526 .EndpointSize = CONSOLE_EPSIZE,
527 .PollingIntervalMS = 0x01
537 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
539 .InterfaceNumber = NKRO_INTERFACE,
540 .AlternateSetting = 0x00,
544 .Class = HID_CSCP_HIDClass,
545 .SubClass = HID_CSCP_NonBootSubclass,
546 .Protocol = HID_CSCP_NonBootProtocol,
548 .InterfaceStrIndex = NO_DESCRIPTOR
553 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
555 .HIDSpec = VERSION_BCD(1,1,1),
557 .TotalReportDescriptors = 1,
558 .HIDReportType = HID_DTYPE_Report,
559 .HIDReportLength = sizeof(NKROReport)
564 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
566 .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
567 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
568 .EndpointSize = NKRO_EPSIZE,
569 .PollingIntervalMS = 0x01
574 .Audio_ControlInterface =
576 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
578 .InterfaceNumber = AC_INTERFACE,
579 .AlternateSetting = 0,
583 .Class = AUDIO_CSCP_AudioClass,
584 .SubClass = AUDIO_CSCP_ControlSubclass,
585 .Protocol = AUDIO_CSCP_ControlProtocol,
587 .InterfaceStrIndex = NO_DESCRIPTOR
590 .Audio_ControlInterface_SPC =
592 .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
593 .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
595 .ACSpecification = VERSION_BCD(1,0,0),
596 .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
599 .InterfaceNumber = AS_INTERFACE,
602 .Audio_StreamInterface =
604 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
606 .InterfaceNumber = AS_INTERFACE,
607 .AlternateSetting = 0,
611 .Class = AUDIO_CSCP_AudioClass,
612 .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
613 .Protocol = AUDIO_CSCP_StreamingProtocol,
615 .InterfaceStrIndex = NO_DESCRIPTOR
618 .Audio_StreamInterface_SPC =
620 .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
621 .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
623 .AudioSpecification = VERSION_BCD(1,0,0),
625 .TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
626 offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
631 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
632 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
634 .JackType = MIDI_JACKTYPE_Embedded,
637 .JackStrIndex = NO_DESCRIPTOR
642 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
643 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
645 .JackType = MIDI_JACKTYPE_External,
648 .JackStrIndex = NO_DESCRIPTOR
653 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
654 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
656 .JackType = MIDI_JACKTYPE_Embedded,
660 .SourceJackID = {0x02},
661 .SourcePinID = {0x01},
663 .JackStrIndex = NO_DESCRIPTOR
668 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
669 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
671 .JackType = MIDI_JACKTYPE_External,
675 .SourceJackID = {0x01},
676 .SourcePinID = {0x01},
678 .JackStrIndex = NO_DESCRIPTOR
681 .MIDI_In_Jack_Endpoint =
685 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
687 .EndpointAddress = MIDI_STREAM_OUT_EPADDR,
688 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
689 .EndpointSize = MIDI_STREAM_EPSIZE,
690 .PollingIntervalMS = 0x05
694 .SyncEndpointNumber = 0
697 .MIDI_In_Jack_Endpoint_SPC =
699 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
700 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
702 .TotalEmbeddedJacks = 0x01,
703 .AssociatedJackID = {0x01}
706 .MIDI_Out_Jack_Endpoint =
710 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
712 .EndpointAddress = MIDI_STREAM_IN_EPADDR,
713 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
714 .EndpointSize = MIDI_STREAM_EPSIZE,
715 .PollingIntervalMS = 0x05
719 .SyncEndpointNumber = 0
722 .MIDI_Out_Jack_Endpoint_SPC =
724 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
725 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
727 .TotalEmbeddedJacks = 0x01,
728 .AssociatedJackID = {0x03}
732 #ifdef VIRTSER_ENABLE
733 .CDC_Interface_Association =
735 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
737 .FirstInterfaceIndex = CCI_INTERFACE,
738 .TotalInterfaces = 2,
740 .Class = CDC_CSCP_CDCClass,
741 .SubClass = CDC_CSCP_ACMSubclass,
742 .Protocol = CDC_CSCP_ATCommandProtocol,
744 .IADStrIndex = NO_DESCRIPTOR,
749 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
751 .InterfaceNumber = CCI_INTERFACE,
752 .AlternateSetting = 0,
756 .Class = CDC_CSCP_CDCClass,
757 .SubClass = CDC_CSCP_ACMSubclass,
758 .Protocol = CDC_CSCP_ATCommandProtocol,
760 .InterfaceStrIndex = NO_DESCRIPTOR
763 .CDC_Functional_Header =
765 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
768 .CDCSpecification = VERSION_BCD(1,1,0),
771 .CDC_Functional_ACM =
773 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
776 .Capabilities = 0x02,
779 .CDC_Functional_Union =
781 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
784 .MasterInterfaceNumber = CCI_INTERFACE,
785 .SlaveInterfaceNumber = CDI_INTERFACE,
788 .CDC_NotificationEndpoint =
790 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
792 .EndpointAddress = CDC_NOTIFICATION_EPADDR,
793 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
794 .EndpointSize = CDC_NOTIFICATION_EPSIZE,
795 .PollingIntervalMS = 0xFF
800 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
802 .InterfaceNumber = CDI_INTERFACE,
803 .AlternateSetting = 0,
807 .Class = CDC_CSCP_CDCDataClass,
808 .SubClass = CDC_CSCP_NoDataSubclass,
809 .Protocol = CDC_CSCP_NoDataProtocol,
811 .InterfaceStrIndex = NO_DESCRIPTOR
814 .CDC_DataOutEndpoint =
816 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
818 .EndpointAddress = CDC_OUT_EPADDR,
819 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
820 .EndpointSize = CDC_EPSIZE,
821 .PollingIntervalMS = 0x05
824 .CDC_DataInEndpoint =
826 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
828 .EndpointAddress = CDC_IN_EPADDR,
829 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
830 .EndpointSize = CDC_EPSIZE,
831 .PollingIntervalMS = 0x05
837 /*******************************************************************************
839 ******************************************************************************/
840 const USB_Descriptor_String_t PROGMEM LanguageString =
842 .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
844 .UnicodeString = {LANGUAGE_ID_ENG}
847 const USB_Descriptor_String_t PROGMEM ManufacturerString =
849 /* subtract 1 for null terminator */
850 .Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
852 .UnicodeString = LSTR(MANUFACTURER)
855 const USB_Descriptor_String_t PROGMEM ProductString =
857 /* subtract 1 for null terminator */
858 .Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
860 .UnicodeString = LSTR(PRODUCT)
863 #ifndef SERIAL_NUMBER
864 #define SERIAL_NUMBER 0
867 const USB_Descriptor_String_t PROGMEM SerialNumberString =
869 /* subtract 1 for null terminator */
870 .Header = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER))-1), .Type = DTYPE_String},
872 .UnicodeString = LSTR(SERIAL_NUMBER)
876 /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
877 * documentation) by the application code so that the address and size of a requested descriptor can be given
878 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
879 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
882 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
883 const uint16_t wIndex,
884 const void** const DescriptorAddress)
886 const uint8_t DescriptorType = (wValue >> 8);
887 const uint8_t DescriptorIndex = (wValue & 0xFF);
889 const void* Address = NULL;
890 uint16_t Size = NO_DESCRIPTOR;
892 switch (DescriptorType)
895 Address = &DeviceDescriptor;
896 Size = sizeof(USB_Descriptor_Device_t);
898 case DTYPE_Configuration:
899 Address = &ConfigurationDescriptor;
900 Size = sizeof(USB_Descriptor_Configuration_t);
903 switch (DescriptorIndex )
906 Address = &LanguageString;
907 Size = pgm_read_byte(&LanguageString.Header.Size);
910 Address = &ManufacturerString;
911 Size = pgm_read_byte(&ManufacturerString.Header.Size);
914 Address = &ProductString;
915 Size = pgm_read_byte(&ProductString.Header.Size);
918 Address = &SerialNumberString;
919 Size = pgm_read_byte(&SerialNumberString.Header.Size);
925 case KEYBOARD_INTERFACE:
926 Address = &ConfigurationDescriptor.Keyboard_HID;
927 Size = sizeof(USB_HID_Descriptor_HID_t);
930 case MOUSE_INTERFACE:
931 Address = &ConfigurationDescriptor.Mouse_HID;
932 Size = sizeof(USB_HID_Descriptor_HID_t);
935 #ifdef EXTRAKEY_ENABLE
936 case EXTRAKEY_INTERFACE:
937 Address = &ConfigurationDescriptor.Extrakey_HID;
938 Size = sizeof(USB_HID_Descriptor_HID_t);
943 Address = &ConfigurationDescriptor.Raw_HID;
944 Size = sizeof(USB_HID_Descriptor_HID_t);
947 #ifdef CONSOLE_ENABLE
948 case CONSOLE_INTERFACE:
949 Address = &ConfigurationDescriptor.Console_HID;
950 Size = sizeof(USB_HID_Descriptor_HID_t);
955 Address = &ConfigurationDescriptor.NKRO_HID;
956 Size = sizeof(USB_HID_Descriptor_HID_t);
961 case HID_DTYPE_Report:
963 case KEYBOARD_INTERFACE:
964 Address = &KeyboardReport;
965 Size = sizeof(KeyboardReport);
968 case MOUSE_INTERFACE:
969 Address = &MouseReport;
970 Size = sizeof(MouseReport);
973 #ifdef EXTRAKEY_ENABLE
974 case EXTRAKEY_INTERFACE:
975 Address = &ExtrakeyReport;
976 Size = sizeof(ExtrakeyReport);
981 Address = &RawReport;
982 Size = sizeof(RawReport);
985 #ifdef CONSOLE_ENABLE
986 case CONSOLE_INTERFACE:
987 Address = &ConsoleReport;
988 Size = sizeof(ConsoleReport);
993 Address = &NKROReport;
994 Size = sizeof(NKROReport);
1001 *DescriptorAddress = Address;