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 = NO_DESCRIPTOR,
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)
864 /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
865 * documentation) by the application code so that the address and size of a requested descriptor can be given
866 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
867 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
870 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
871 const uint16_t wIndex,
872 const void** const DescriptorAddress)
874 const uint8_t DescriptorType = (wValue >> 8);
875 const uint8_t DescriptorIndex = (wValue & 0xFF);
877 const void* Address = NULL;
878 uint16_t Size = NO_DESCRIPTOR;
880 switch (DescriptorType)
883 Address = &DeviceDescriptor;
884 Size = sizeof(USB_Descriptor_Device_t);
886 case DTYPE_Configuration:
887 Address = &ConfigurationDescriptor;
888 Size = sizeof(USB_Descriptor_Configuration_t);
891 switch (DescriptorIndex )
894 Address = &LanguageString;
895 Size = pgm_read_byte(&LanguageString.Header.Size);
898 Address = &ManufacturerString;
899 Size = pgm_read_byte(&ManufacturerString.Header.Size);
902 Address = &ProductString;
903 Size = pgm_read_byte(&ProductString.Header.Size);
909 case KEYBOARD_INTERFACE:
910 Address = &ConfigurationDescriptor.Keyboard_HID;
911 Size = sizeof(USB_HID_Descriptor_HID_t);
914 case MOUSE_INTERFACE:
915 Address = &ConfigurationDescriptor.Mouse_HID;
916 Size = sizeof(USB_HID_Descriptor_HID_t);
919 #ifdef EXTRAKEY_ENABLE
920 case EXTRAKEY_INTERFACE:
921 Address = &ConfigurationDescriptor.Extrakey_HID;
922 Size = sizeof(USB_HID_Descriptor_HID_t);
927 Address = &ConfigurationDescriptor.Raw_HID;
928 Size = sizeof(USB_HID_Descriptor_HID_t);
931 #ifdef CONSOLE_ENABLE
932 case CONSOLE_INTERFACE:
933 Address = &ConfigurationDescriptor.Console_HID;
934 Size = sizeof(USB_HID_Descriptor_HID_t);
939 Address = &ConfigurationDescriptor.NKRO_HID;
940 Size = sizeof(USB_HID_Descriptor_HID_t);
945 case HID_DTYPE_Report:
947 case KEYBOARD_INTERFACE:
948 Address = &KeyboardReport;
949 Size = sizeof(KeyboardReport);
952 case MOUSE_INTERFACE:
953 Address = &MouseReport;
954 Size = sizeof(MouseReport);
957 #ifdef EXTRAKEY_ENABLE
958 case EXTRAKEY_INTERFACE:
959 Address = &ExtrakeyReport;
960 Size = sizeof(ExtrakeyReport);
965 Address = &RawReport;
966 Size = sizeof(RawReport);
969 #ifdef CONSOLE_ENABLE
970 case CONSOLE_INTERFACE:
971 Address = &ConsoleReport;
972 Size = sizeof(ConsoleReport);
977 Address = &NKROReport;
978 Size = sizeof(NKROReport);
985 *DescriptorAddress = Address;