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"
44 /*******************************************************************************
45 * HID Report Descriptors
46 ******************************************************************************/
47 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
49 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
50 HID_RI_USAGE(8, 0x06), /* Keyboard */
51 HID_RI_COLLECTION(8, 0x01), /* Application */
52 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
53 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
54 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
55 HID_RI_LOGICAL_MINIMUM(8, 0x00),
56 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
57 HID_RI_REPORT_COUNT(8, 0x08),
58 HID_RI_REPORT_SIZE(8, 0x01),
59 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
61 HID_RI_REPORT_COUNT(8, 0x01),
62 HID_RI_REPORT_SIZE(8, 0x08),
63 HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */
65 HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
66 HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
67 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
68 HID_RI_REPORT_COUNT(8, 0x05),
69 HID_RI_REPORT_SIZE(8, 0x01),
70 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
71 HID_RI_REPORT_COUNT(8, 0x01),
72 HID_RI_REPORT_SIZE(8, 0x03),
73 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
75 HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
76 HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
77 HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
78 HID_RI_LOGICAL_MINIMUM(8, 0x00),
79 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
80 HID_RI_REPORT_COUNT(8, 0x06),
81 HID_RI_REPORT_SIZE(8, 0x08),
82 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
83 HID_RI_END_COLLECTION(0),
87 const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
89 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
90 HID_RI_USAGE(8, 0x02), /* Mouse */
91 HID_RI_COLLECTION(8, 0x01), /* Application */
92 HID_RI_USAGE(8, 0x01), /* Pointer */
93 HID_RI_COLLECTION(8, 0x00), /* Physical */
95 HID_RI_USAGE_PAGE(8, 0x09), /* Button */
96 HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
97 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */
98 HID_RI_LOGICAL_MINIMUM(8, 0x00),
99 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
100 HID_RI_REPORT_COUNT(8, 0x05),
101 HID_RI_REPORT_SIZE(8, 0x01),
102 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
103 HID_RI_REPORT_COUNT(8, 0x01),
104 HID_RI_REPORT_SIZE(8, 0x03),
105 HID_RI_INPUT(8, HID_IOF_CONSTANT),
107 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
108 HID_RI_USAGE(8, 0x30), /* Usage X */
109 HID_RI_USAGE(8, 0x31), /* Usage Y */
110 HID_RI_LOGICAL_MINIMUM(8, -127),
111 HID_RI_LOGICAL_MAXIMUM(8, 127),
112 HID_RI_REPORT_COUNT(8, 0x02),
113 HID_RI_REPORT_SIZE(8, 0x08),
114 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
116 HID_RI_USAGE(8, 0x38), /* Wheel */
117 HID_RI_LOGICAL_MINIMUM(8, -127),
118 HID_RI_LOGICAL_MAXIMUM(8, 127),
119 HID_RI_REPORT_COUNT(8, 0x01),
120 HID_RI_REPORT_SIZE(8, 0x08),
121 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
123 HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
124 HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */
125 HID_RI_LOGICAL_MINIMUM(8, -127),
126 HID_RI_LOGICAL_MAXIMUM(8, 127),
127 HID_RI_REPORT_COUNT(8, 0x01),
128 HID_RI_REPORT_SIZE(8, 0x08),
129 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
131 HID_RI_END_COLLECTION(0),
132 HID_RI_END_COLLECTION(0),
136 #ifdef EXTRAKEY_ENABLE
137 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
139 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
140 HID_RI_USAGE(8, 0x80), /* System Control */
141 HID_RI_COLLECTION(8, 0x01), /* Application */
142 HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
143 HID_RI_LOGICAL_MINIMUM(16, 0x0081),
144 HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
145 HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
146 HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */
147 HID_RI_REPORT_SIZE(8, 16),
148 HID_RI_REPORT_COUNT(8, 1),
149 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
150 HID_RI_END_COLLECTION(0),
152 HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
153 HID_RI_USAGE(8, 0x01), /* Consumer Control */
154 HID_RI_COLLECTION(8, 0x01), /* Application */
155 HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
156 HID_RI_LOGICAL_MINIMUM(16, 0x0001),
157 HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
158 HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
159 HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */
160 HID_RI_REPORT_SIZE(8, 16),
161 HID_RI_REPORT_COUNT(8, 1),
162 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
163 HID_RI_END_COLLECTION(0),
168 const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
170 HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
171 HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
172 HID_RI_COLLECTION(8, 0x01), /* Application */
173 HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
174 HID_RI_LOGICAL_MINIMUM(8, 0x00),
175 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
176 HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
177 HID_RI_REPORT_SIZE(8, 0x08),
178 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
179 HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
180 HID_RI_LOGICAL_MINIMUM(8, 0x00),
181 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
182 HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
183 HID_RI_REPORT_SIZE(8, 0x08),
184 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
185 HID_RI_END_COLLECTION(0),
189 #ifdef CONSOLE_ENABLE
190 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
192 HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
193 HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
194 HID_RI_COLLECTION(8, 0x01), /* Application */
195 HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
196 HID_RI_LOGICAL_MINIMUM(8, 0x00),
197 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
198 HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
199 HID_RI_REPORT_SIZE(8, 0x08),
200 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
201 HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
202 HID_RI_LOGICAL_MINIMUM(8, 0x00),
203 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
204 HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
205 HID_RI_REPORT_SIZE(8, 0x08),
206 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
207 HID_RI_END_COLLECTION(0),
212 const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
214 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
215 HID_RI_USAGE(8, 0x06), /* Keyboard */
216 HID_RI_COLLECTION(8, 0x01), /* Application */
217 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
218 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
219 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
220 HID_RI_LOGICAL_MINIMUM(8, 0x00),
221 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
222 HID_RI_REPORT_COUNT(8, 0x08),
223 HID_RI_REPORT_SIZE(8, 0x01),
224 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
226 HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
227 HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
228 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
229 HID_RI_REPORT_COUNT(8, 0x05),
230 HID_RI_REPORT_SIZE(8, 0x01),
231 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
232 HID_RI_REPORT_COUNT(8, 0x01),
233 HID_RI_REPORT_SIZE(8, 0x03),
234 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
236 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
237 HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
238 HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
239 HID_RI_LOGICAL_MINIMUM(8, 0x00),
240 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
241 HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
242 HID_RI_REPORT_SIZE(8, 0x01),
243 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
244 HID_RI_END_COLLECTION(0),
248 /*******************************************************************************
250 ******************************************************************************/
251 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
253 .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
255 .USBSpecification = VERSION_BCD(1,1,0),
257 .Class = USB_CSCP_IADDeviceClass,
258 .SubClass = USB_CSCP_IADDeviceSubclass,
259 .Protocol = USB_CSCP_IADDeviceProtocol,
261 .Class = USB_CSCP_NoDeviceClass,
262 .SubClass = USB_CSCP_NoDeviceSubclass,
263 .Protocol = USB_CSCP_NoDeviceProtocol,
266 .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
268 /* specified in config.h */
269 .VendorID = VENDOR_ID,
270 .ProductID = PRODUCT_ID,
271 .ReleaseNumber = DEVICE_VER,
273 .ManufacturerStrIndex = 0x01,
274 .ProductStrIndex = 0x02,
275 .SerialNumStrIndex = NO_DESCRIPTOR,
277 .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
280 /*******************************************************************************
281 * Configuration Descriptors
282 ******************************************************************************/
283 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
287 .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
289 .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
290 .TotalInterfaces = TOTAL_INTERFACES,
292 .ConfigurationNumber = 1,
293 .ConfigurationStrIndex = NO_DESCRIPTOR,
295 .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
297 .MaxPowerConsumption = USB_CONFIG_POWER_MA(500)
303 .Keyboard_Interface =
305 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
307 .InterfaceNumber = KEYBOARD_INTERFACE,
308 .AlternateSetting = 0x00,
312 .Class = HID_CSCP_HIDClass,
313 .SubClass = HID_CSCP_BootSubclass,
314 .Protocol = HID_CSCP_KeyboardBootProtocol,
316 .InterfaceStrIndex = NO_DESCRIPTOR
321 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
323 .HIDSpec = VERSION_BCD(1,1,1),
325 .TotalReportDescriptors = 1,
326 .HIDReportType = HID_DTYPE_Report,
327 .HIDReportLength = sizeof(KeyboardReport)
330 .Keyboard_INEndpoint =
332 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
334 .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
335 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
336 .EndpointSize = KEYBOARD_EPSIZE,
337 .PollingIntervalMS = 0x0A
346 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
348 .InterfaceNumber = MOUSE_INTERFACE,
349 .AlternateSetting = 0x00,
353 .Class = HID_CSCP_HIDClass,
354 .SubClass = HID_CSCP_BootSubclass,
355 .Protocol = HID_CSCP_MouseBootProtocol,
357 .InterfaceStrIndex = NO_DESCRIPTOR
362 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
364 .HIDSpec = VERSION_BCD(1,1,1),
366 .TotalReportDescriptors = 1,
367 .HIDReportType = HID_DTYPE_Report,
368 .HIDReportLength = sizeof(MouseReport)
373 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
375 .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
376 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
377 .EndpointSize = MOUSE_EPSIZE,
378 .PollingIntervalMS = 0x0A
385 #ifdef EXTRAKEY_ENABLE
386 .Extrakey_Interface =
388 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
390 .InterfaceNumber = EXTRAKEY_INTERFACE,
391 .AlternateSetting = 0x00,
395 .Class = HID_CSCP_HIDClass,
396 .SubClass = HID_CSCP_NonBootSubclass,
397 .Protocol = HID_CSCP_NonBootProtocol,
399 .InterfaceStrIndex = NO_DESCRIPTOR
404 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
406 .HIDSpec = VERSION_BCD(1,1,1),
408 .TotalReportDescriptors = 1,
409 .HIDReportType = HID_DTYPE_Report,
410 .HIDReportLength = sizeof(ExtrakeyReport)
413 .Extrakey_INEndpoint =
415 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
417 .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
418 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
419 .EndpointSize = EXTRAKEY_EPSIZE,
420 .PollingIntervalMS = 0x0A
430 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
432 .InterfaceNumber = RAW_INTERFACE,
433 .AlternateSetting = 0x00,
437 .Class = HID_CSCP_HIDClass,
438 .SubClass = HID_CSCP_NonBootSubclass,
439 .Protocol = HID_CSCP_NonBootProtocol,
441 .InterfaceStrIndex = NO_DESCRIPTOR
446 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
448 .HIDSpec = VERSION_BCD(1,1,1),
450 .TotalReportDescriptors = 1,
451 .HIDReportType = HID_DTYPE_Report,
452 .HIDReportLength = sizeof(RawReport)
457 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
459 .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
460 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
461 .EndpointSize = RAW_EPSIZE,
462 .PollingIntervalMS = 0x01
467 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
469 .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
470 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
471 .EndpointSize = RAW_EPSIZE,
472 .PollingIntervalMS = 0x01
479 #ifdef CONSOLE_ENABLE
482 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
484 .InterfaceNumber = CONSOLE_INTERFACE,
485 .AlternateSetting = 0x00,
489 .Class = HID_CSCP_HIDClass,
490 .SubClass = HID_CSCP_NonBootSubclass,
491 .Protocol = HID_CSCP_NonBootProtocol,
493 .InterfaceStrIndex = NO_DESCRIPTOR
498 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
500 .HIDSpec = VERSION_BCD(1,1,1),
502 .TotalReportDescriptors = 1,
503 .HIDReportType = HID_DTYPE_Report,
504 .HIDReportLength = sizeof(ConsoleReport)
507 .Console_INEndpoint =
509 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
511 .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
512 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
513 .EndpointSize = CONSOLE_EPSIZE,
514 .PollingIntervalMS = 0x01
517 .Console_OUTEndpoint =
519 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
521 .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
522 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
523 .EndpointSize = CONSOLE_EPSIZE,
524 .PollingIntervalMS = 0x01
534 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
536 .InterfaceNumber = NKRO_INTERFACE,
537 .AlternateSetting = 0x00,
541 .Class = HID_CSCP_HIDClass,
542 .SubClass = HID_CSCP_NonBootSubclass,
543 .Protocol = HID_CSCP_NonBootProtocol,
545 .InterfaceStrIndex = NO_DESCRIPTOR
550 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
552 .HIDSpec = VERSION_BCD(1,1,1),
554 .TotalReportDescriptors = 1,
555 .HIDReportType = HID_DTYPE_Report,
556 .HIDReportLength = sizeof(NKROReport)
561 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
563 .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
564 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
565 .EndpointSize = NKRO_EPSIZE,
566 .PollingIntervalMS = 0x01
571 .Audio_ControlInterface =
573 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
575 .InterfaceNumber = AC_INTERFACE,
576 .AlternateSetting = 0,
580 .Class = AUDIO_CSCP_AudioClass,
581 .SubClass = AUDIO_CSCP_ControlSubclass,
582 .Protocol = AUDIO_CSCP_ControlProtocol,
584 .InterfaceStrIndex = NO_DESCRIPTOR
587 .Audio_ControlInterface_SPC =
589 .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
590 .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
592 .ACSpecification = VERSION_BCD(1,0,0),
593 .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
596 .InterfaceNumber = AS_INTERFACE,
599 .Audio_StreamInterface =
601 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
603 .InterfaceNumber = AS_INTERFACE,
604 .AlternateSetting = 0,
608 .Class = AUDIO_CSCP_AudioClass,
609 .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
610 .Protocol = AUDIO_CSCP_StreamingProtocol,
612 .InterfaceStrIndex = NO_DESCRIPTOR
615 .Audio_StreamInterface_SPC =
617 .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
618 .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
620 .AudioSpecification = VERSION_BCD(1,0,0),
622 .TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
623 offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
628 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
629 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
631 .JackType = MIDI_JACKTYPE_Embedded,
634 .JackStrIndex = NO_DESCRIPTOR
639 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
640 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
642 .JackType = MIDI_JACKTYPE_External,
645 .JackStrIndex = NO_DESCRIPTOR
650 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
651 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
653 .JackType = MIDI_JACKTYPE_Embedded,
657 .SourceJackID = {0x02},
658 .SourcePinID = {0x01},
660 .JackStrIndex = NO_DESCRIPTOR
665 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
666 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
668 .JackType = MIDI_JACKTYPE_External,
672 .SourceJackID = {0x01},
673 .SourcePinID = {0x01},
675 .JackStrIndex = NO_DESCRIPTOR
678 .MIDI_In_Jack_Endpoint =
682 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
684 .EndpointAddress = MIDI_STREAM_OUT_EPADDR,
685 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
686 .EndpointSize = MIDI_STREAM_EPSIZE,
687 .PollingIntervalMS = 0x05
691 .SyncEndpointNumber = 0
694 .MIDI_In_Jack_Endpoint_SPC =
696 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
697 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
699 .TotalEmbeddedJacks = 0x01,
700 .AssociatedJackID = {0x01}
703 .MIDI_Out_Jack_Endpoint =
707 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
709 .EndpointAddress = MIDI_STREAM_IN_EPADDR,
710 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
711 .EndpointSize = MIDI_STREAM_EPSIZE,
712 .PollingIntervalMS = 0x05
716 .SyncEndpointNumber = 0
719 .MIDI_Out_Jack_Endpoint_SPC =
721 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
722 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
724 .TotalEmbeddedJacks = 0x01,
725 .AssociatedJackID = {0x03}
729 #ifdef VIRTSER_ENABLE
730 .CDC_Interface_Association =
732 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
734 .FirstInterfaceIndex = CCI_INTERFACE,
735 .TotalInterfaces = 2,
737 .Class = CDC_CSCP_CDCClass,
738 .SubClass = CDC_CSCP_ACMSubclass,
739 .Protocol = CDC_CSCP_ATCommandProtocol,
741 .IADStrIndex = NO_DESCRIPTOR,
746 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
748 .InterfaceNumber = CCI_INTERFACE,
749 .AlternateSetting = 0,
753 .Class = CDC_CSCP_CDCClass,
754 .SubClass = CDC_CSCP_ACMSubclass,
755 .Protocol = CDC_CSCP_ATCommandProtocol,
757 .InterfaceStrIndex = NO_DESCRIPTOR
760 .CDC_Functional_Header =
762 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
765 .CDCSpecification = VERSION_BCD(1,1,0),
768 .CDC_Functional_ACM =
770 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
773 .Capabilities = 0x02,
776 .CDC_Functional_Union =
778 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
781 .MasterInterfaceNumber = CCI_INTERFACE,
782 .SlaveInterfaceNumber = CDI_INTERFACE,
785 .CDC_NotificationEndpoint =
787 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
789 .EndpointAddress = CDC_NOTIFICATION_EPADDR,
790 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
791 .EndpointSize = CDC_NOTIFICATION_EPSIZE,
792 .PollingIntervalMS = 0xFF
797 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
799 .InterfaceNumber = CDI_INTERFACE,
800 .AlternateSetting = 0,
804 .Class = CDC_CSCP_CDCDataClass,
805 .SubClass = CDC_CSCP_NoDataSubclass,
806 .Protocol = CDC_CSCP_NoDataProtocol,
808 .InterfaceStrIndex = NO_DESCRIPTOR
811 .CDC_DataOutEndpoint =
813 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
815 .EndpointAddress = CDC_OUT_EPADDR,
816 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
817 .EndpointSize = CDC_EPSIZE,
818 .PollingIntervalMS = 0x05
821 .CDC_DataInEndpoint =
823 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
825 .EndpointAddress = CDC_IN_EPADDR,
826 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
827 .EndpointSize = CDC_EPSIZE,
828 .PollingIntervalMS = 0x05
834 /*******************************************************************************
836 ******************************************************************************/
837 const USB_Descriptor_String_t PROGMEM LanguageString =
839 .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
841 .UnicodeString = {LANGUAGE_ID_ENG}
844 const USB_Descriptor_String_t PROGMEM ManufacturerString =
846 /* subtract 1 for null terminator */
847 .Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
849 .UnicodeString = LSTR(MANUFACTURER)
852 const USB_Descriptor_String_t PROGMEM ProductString =
854 /* subtract 1 for null terminator */
855 .Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
857 .UnicodeString = LSTR(PRODUCT)
861 /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
862 * documentation) by the application code so that the address and size of a requested descriptor can be given
863 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
864 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
867 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
868 const uint8_t wIndex,
869 const void** const DescriptorAddress)
871 const uint8_t DescriptorType = (wValue >> 8);
872 const uint8_t DescriptorIndex = (wValue & 0xFF);
874 const void* Address = NULL;
875 uint16_t Size = NO_DESCRIPTOR;
877 switch (DescriptorType)
880 Address = &DeviceDescriptor;
881 Size = sizeof(USB_Descriptor_Device_t);
883 case DTYPE_Configuration:
884 Address = &ConfigurationDescriptor;
885 Size = sizeof(USB_Descriptor_Configuration_t);
888 switch (DescriptorIndex )
891 Address = &LanguageString;
892 Size = pgm_read_byte(&LanguageString.Header.Size);
895 Address = &ManufacturerString;
896 Size = pgm_read_byte(&ManufacturerString.Header.Size);
899 Address = &ProductString;
900 Size = pgm_read_byte(&ProductString.Header.Size);
906 case KEYBOARD_INTERFACE:
907 Address = &ConfigurationDescriptor.Keyboard_HID;
908 Size = sizeof(USB_HID_Descriptor_HID_t);
911 case MOUSE_INTERFACE:
912 Address = &ConfigurationDescriptor.Mouse_HID;
913 Size = sizeof(USB_HID_Descriptor_HID_t);
916 #ifdef EXTRAKEY_ENABLE
917 case EXTRAKEY_INTERFACE:
918 Address = &ConfigurationDescriptor.Extrakey_HID;
919 Size = sizeof(USB_HID_Descriptor_HID_t);
924 Address = &ConfigurationDescriptor.Raw_HID;
925 Size = sizeof(USB_HID_Descriptor_HID_t);
928 #ifdef CONSOLE_ENABLE
929 case CONSOLE_INTERFACE:
930 Address = &ConfigurationDescriptor.Console_HID;
931 Size = sizeof(USB_HID_Descriptor_HID_t);
936 Address = &ConfigurationDescriptor.NKRO_HID;
937 Size = sizeof(USB_HID_Descriptor_HID_t);
942 case HID_DTYPE_Report:
944 case KEYBOARD_INTERFACE:
945 Address = &KeyboardReport;
946 Size = sizeof(KeyboardReport);
949 case MOUSE_INTERFACE:
950 Address = &MouseReport;
951 Size = sizeof(MouseReport);
954 #ifdef EXTRAKEY_ENABLE
955 case EXTRAKEY_INTERFACE:
956 Address = &ExtrakeyReport;
957 Size = sizeof(ExtrakeyReport);
962 Address = &RawReport;
963 Size = sizeof(RawReport);
966 #ifdef CONSOLE_ENABLE
967 case CONSOLE_INTERFACE:
968 Address = &ConsoleReport;
969 Size = sizeof(ConsoleReport);
974 Address = &NKROReport;
975 Size = sizeof(NKROReport);
982 *DescriptorAddress = Address;