]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/usb_descriptor.c
Remove more commented out MCUs
[qmk_firmware.git] / tmk_core / protocol / usb_descriptor.c
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
43 #ifndef USB_MAX_POWER_CONSUMPTION
44 #define USB_MAX_POWER_CONSUMPTION 500
45 #endif
46
47 /*******************************************************************************
48  * HID Report Descriptors
49  ******************************************************************************/
50 #ifdef KEYBOARD_SHARED_EP
51 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
52 #define SHARED_REPORT_STARTED
53 #else
54 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
55 #endif
56     HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
57     HID_RI_USAGE(8, 0x06), /* Keyboard */
58     HID_RI_COLLECTION(8, 0x01), /* Application */
59 #   ifdef KEYBOARD_SHARED_EP
60         HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
61 #   endif
62         HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
63         HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
64         HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
65         HID_RI_LOGICAL_MINIMUM(8, 0x00),
66         HID_RI_LOGICAL_MAXIMUM(8, 0x01),
67         HID_RI_REPORT_COUNT(8, 0x08),
68         HID_RI_REPORT_SIZE(8, 0x01),
69         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
70
71         HID_RI_REPORT_COUNT(8, 0x01),
72         HID_RI_REPORT_SIZE(8, 0x08),
73         HID_RI_INPUT(8, HID_IOF_CONSTANT),  /* reserved */
74
75         HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
76         HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
77         HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
78         HID_RI_REPORT_COUNT(8, 0x05),
79         HID_RI_REPORT_SIZE(8, 0x01),
80         HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
81         HID_RI_REPORT_COUNT(8, 0x01),
82         HID_RI_REPORT_SIZE(8, 0x03),
83         HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
84
85         HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
86         HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
87         HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
88         HID_RI_LOGICAL_MINIMUM(8, 0x00),
89         HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
90         HID_RI_REPORT_COUNT(8, 0x06),
91         HID_RI_REPORT_SIZE(8, 0x08),
92         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
93     HID_RI_END_COLLECTION(0),
94
95 #ifndef KEYBOARD_SHARED_EP
96 };
97 #endif
98
99 #if defined(MOUSE_ENABLE)
100
101 #   if !defined(MOUSE_SHARED_EP)
102 const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
103 #   elif !defined(SHARED_REPORT_STARTED)
104 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
105 #define SHARED_REPORT_STARTED
106 #   endif
107     HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
108     HID_RI_USAGE(8, 0x02), /* Mouse */
109     HID_RI_COLLECTION(8, 0x01), /* Application */
110 #   ifdef MOUSE_SHARED_EP
111         HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
112 #   endif
113         HID_RI_USAGE(8, 0x01), /* Pointer */
114         HID_RI_COLLECTION(8, 0x00), /* Physical */
115
116             HID_RI_USAGE_PAGE(8, 0x09), /* Button */
117             HID_RI_USAGE_MINIMUM(8, 0x01),  /* Button 1 */
118             HID_RI_USAGE_MAXIMUM(8, 0x05),  /* Button 5 */
119             HID_RI_LOGICAL_MINIMUM(8, 0x00),
120             HID_RI_LOGICAL_MAXIMUM(8, 0x01),
121             HID_RI_REPORT_COUNT(8, 0x05),
122             HID_RI_REPORT_SIZE(8, 0x01),
123             HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
124             HID_RI_REPORT_COUNT(8, 0x01),
125             HID_RI_REPORT_SIZE(8, 0x03),
126             HID_RI_INPUT(8, HID_IOF_CONSTANT),
127
128             HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
129             HID_RI_USAGE(8, 0x30), /* Usage X */
130             HID_RI_USAGE(8, 0x31), /* Usage Y */
131             HID_RI_LOGICAL_MINIMUM(8, -127),
132             HID_RI_LOGICAL_MAXIMUM(8, 127),
133             HID_RI_REPORT_COUNT(8, 0x02),
134             HID_RI_REPORT_SIZE(8, 0x08),
135             HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
136
137             HID_RI_USAGE(8, 0x38), /* Wheel */
138             HID_RI_LOGICAL_MINIMUM(8, -127),
139             HID_RI_LOGICAL_MAXIMUM(8, 127),
140             HID_RI_REPORT_COUNT(8, 0x01),
141             HID_RI_REPORT_SIZE(8, 0x08),
142             HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
143
144             HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
145             HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */
146             HID_RI_LOGICAL_MINIMUM(8, -127),
147             HID_RI_LOGICAL_MAXIMUM(8, 127),
148             HID_RI_REPORT_COUNT(8, 0x01),
149             HID_RI_REPORT_SIZE(8, 0x08),
150             HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
151
152         HID_RI_END_COLLECTION(0),
153     HID_RI_END_COLLECTION(0),
154 #   ifndef MOUSE_SHARED_EP
155 };
156 #   endif
157 #endif
158
159 #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
160 const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
161 #endif
162 #   ifdef EXTRAKEY_ENABLE
163     HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
164     HID_RI_USAGE(8, 0x80), /* System Control */
165     HID_RI_COLLECTION(8, 0x01), /* Application */
166         HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
167         HID_RI_LOGICAL_MINIMUM(16, 0x0001),
168         HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
169         HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
170         HID_RI_USAGE_MAXIMUM(16, 0x0083), /* System Wake Up */
171         HID_RI_REPORT_SIZE(8, 16),
172         HID_RI_REPORT_COUNT(8, 1),
173         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
174     HID_RI_END_COLLECTION(0),
175
176     HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
177     HID_RI_USAGE(8, 0x01), /* Consumer Control */
178     HID_RI_COLLECTION(8, 0x01), /* Application */
179         HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
180         HID_RI_LOGICAL_MINIMUM(16, 0x0001),
181         HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
182         HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
183         HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */
184         HID_RI_REPORT_SIZE(8, 16),
185         HID_RI_REPORT_COUNT(8, 1),
186         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
187     HID_RI_END_COLLECTION(0),
188 #   endif
189
190 #   ifdef NKRO_ENABLE
191     HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
192     HID_RI_USAGE(8, 0x06), /* Keyboard */
193     HID_RI_COLLECTION(8, 0x01), /* Application */
194         HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
195         HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
196         HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
197         HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
198         HID_RI_LOGICAL_MINIMUM(8, 0x00),
199         HID_RI_LOGICAL_MAXIMUM(8, 0x01),
200         HID_RI_REPORT_COUNT(8, 0x08),
201         HID_RI_REPORT_SIZE(8, 0x01),
202         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
203
204         HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
205         HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
206         HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
207         HID_RI_REPORT_COUNT(8, 0x05),
208         HID_RI_REPORT_SIZE(8, 0x01),
209         HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
210         HID_RI_REPORT_COUNT(8, 0x01),
211         HID_RI_REPORT_SIZE(8, 0x03),
212         HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
213
214         HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
215         HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
216         HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS*8-1),
217         HID_RI_LOGICAL_MINIMUM(8, 0x00),
218         HID_RI_LOGICAL_MAXIMUM(8, 0x01),
219         HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS*8),
220         HID_RI_REPORT_SIZE(8, 0x01),
221         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
222     HID_RI_END_COLLECTION(0),
223 #   endif
224 #ifdef SHARED_EP_ENABLE
225 };
226 #endif
227
228 #ifdef RAW_ENABLE
229 const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
230 {
231     HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
232     HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
233     HID_RI_COLLECTION(8, 0x01), /* Application */
234         HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
235         HID_RI_LOGICAL_MINIMUM(8, 0x00),
236         HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
237         HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
238         HID_RI_REPORT_SIZE(8, 0x08),
239         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
240         HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
241         HID_RI_LOGICAL_MINIMUM(8, 0x00),
242         HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
243         HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
244         HID_RI_REPORT_SIZE(8, 0x08),
245         HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
246     HID_RI_END_COLLECTION(0),
247 };
248 #endif
249
250 #ifdef CONSOLE_ENABLE
251 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
252 {
253     HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
254     HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
255     HID_RI_COLLECTION(8, 0x01), /* Application */
256         HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
257         HID_RI_LOGICAL_MINIMUM(8, 0x00),
258         HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
259         HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
260         HID_RI_REPORT_SIZE(8, 0x08),
261         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
262         HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
263         HID_RI_LOGICAL_MINIMUM(8, 0x00),
264         HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
265         HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
266         HID_RI_REPORT_SIZE(8, 0x08),
267         HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
268     HID_RI_END_COLLECTION(0),
269 };
270 #endif
271
272
273 /*******************************************************************************
274  * Device Descriptors
275  ******************************************************************************/
276 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
277 {
278     .Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
279
280     .USBSpecification       = VERSION_BCD(1,1,0),
281 #if VIRTSER_ENABLE
282     .Class                  = USB_CSCP_IADDeviceClass,
283     .SubClass               = USB_CSCP_IADDeviceSubclass,
284     .Protocol               = USB_CSCP_IADDeviceProtocol,
285 #else
286     .Class                  = USB_CSCP_NoDeviceClass,
287     .SubClass               = USB_CSCP_NoDeviceSubclass,
288     .Protocol               = USB_CSCP_NoDeviceProtocol,
289 #endif
290
291     .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
292
293     /* specified in config.h */
294     .VendorID               = VENDOR_ID,
295     .ProductID              = PRODUCT_ID,
296     .ReleaseNumber          = DEVICE_VER,
297
298     .ManufacturerStrIndex   = 0x01,
299     .ProductStrIndex        = 0x02,
300     .SerialNumStrIndex      = 0x03,
301
302     .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
303 };
304
305 /*******************************************************************************
306  * Configuration Descriptors
307  ******************************************************************************/
308 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
309 {
310     .Config =
311         {
312             .Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
313
314             .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
315             .TotalInterfaces        = TOTAL_INTERFACES,
316
317             .ConfigurationNumber    = 1,
318             .ConfigurationStrIndex  = NO_DESCRIPTOR,
319
320             .ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
321
322             .MaxPowerConsumption    = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
323         },
324
325     /*
326      * Keyboard
327      */
328 #ifndef KEYBOARD_SHARED_EP
329     .Keyboard_Interface =
330         {
331             .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
332
333             .InterfaceNumber        = KEYBOARD_INTERFACE,
334             .AlternateSetting       = 0x00,
335
336             .TotalEndpoints         = 1,
337
338             .Class                  = HID_CSCP_HIDClass,
339             .SubClass               = HID_CSCP_BootSubclass,
340             .Protocol               = HID_CSCP_KeyboardBootProtocol,
341
342             .InterfaceStrIndex      = NO_DESCRIPTOR
343         },
344
345     .Keyboard_HID =
346         {
347             .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
348
349             .HIDSpec                = VERSION_BCD(1,1,1),
350             .CountryCode            = 0x00,
351             .TotalReportDescriptors = 1,
352             .HIDReportType          = HID_DTYPE_Report,
353             .HIDReportLength        = sizeof(KeyboardReport)
354         },
355
356     .Keyboard_INEndpoint =
357         {
358             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
359
360             .EndpointAddress        = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
361             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
362             .EndpointSize           = KEYBOARD_EPSIZE,
363             .PollingIntervalMS      = 0x0A
364         },
365 #endif
366
367     /*
368      * Mouse
369      */
370 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
371     .Mouse_Interface =
372         {
373             .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
374
375             .InterfaceNumber        = MOUSE_INTERFACE,
376             .AlternateSetting       = 0x00,
377
378             .TotalEndpoints         = 1,
379
380             .Class                  = HID_CSCP_HIDClass,
381             .SubClass               = HID_CSCP_BootSubclass,
382             .Protocol               = HID_CSCP_MouseBootProtocol,
383
384             .InterfaceStrIndex      = NO_DESCRIPTOR
385         },
386
387     .Mouse_HID =
388         {
389             .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
390
391             .HIDSpec                = VERSION_BCD(1,1,1),
392             .CountryCode            = 0x00,
393             .TotalReportDescriptors = 1,
394             .HIDReportType          = HID_DTYPE_Report,
395             .HIDReportLength        = sizeof(MouseReport)
396         },
397
398     .Mouse_INEndpoint =
399         {
400             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
401
402             .EndpointAddress        = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
403             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
404             .EndpointSize           = MOUSE_EPSIZE,
405             .PollingIntervalMS      = 0x0A
406         },
407 #endif
408
409     /*
410      * Shared
411      */
412 #ifdef SHARED_EP_ENABLE
413     .Shared_Interface =
414         {
415             .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
416
417             .InterfaceNumber        = SHARED_INTERFACE,
418             .AlternateSetting       = 0x00,
419
420             .TotalEndpoints         = 1,
421
422             .Class                  = HID_CSCP_HIDClass,
423 #   ifdef KEYBOARD_SHARED_EP
424             .SubClass               = HID_CSCP_BootSubclass,
425             .Protocol               = HID_CSCP_KeyboardBootProtocol,
426 #   else
427             .SubClass               = HID_CSCP_NonBootSubclass,
428             .Protocol               = HID_CSCP_NonBootProtocol,
429 #endif
430
431             .InterfaceStrIndex      = NO_DESCRIPTOR
432         },
433
434     .Shared_HID =
435         {
436             .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
437
438             .HIDSpec                = VERSION_BCD(1,1,1),
439             .CountryCode            = 0x00,
440             .TotalReportDescriptors = 1,
441             .HIDReportType          = HID_DTYPE_Report,
442             .HIDReportLength        = sizeof(SharedReport)
443         },
444
445     .Shared_INEndpoint =
446         {
447             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
448
449             .EndpointAddress        = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
450             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
451             .EndpointSize           = SHARED_EPSIZE,
452             .PollingIntervalMS      = 0x0A
453         },
454 #endif
455
456                 /*
457              * Raw
458              */
459         #ifdef RAW_ENABLE
460             .Raw_Interface =
461                 {
462                     .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
463
464                     .InterfaceNumber        = RAW_INTERFACE,
465                     .AlternateSetting       = 0x00,
466
467                     .TotalEndpoints         = 2,
468
469                     .Class                  = HID_CSCP_HIDClass,
470                     .SubClass               = HID_CSCP_NonBootSubclass,
471                     .Protocol               = HID_CSCP_NonBootProtocol,
472
473                     .InterfaceStrIndex      = NO_DESCRIPTOR
474                 },
475
476             .Raw_HID =
477                 {
478                     .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
479
480                     .HIDSpec                = VERSION_BCD(1,1,1),
481                     .CountryCode            = 0x00,
482                     .TotalReportDescriptors = 1,
483                     .HIDReportType          = HID_DTYPE_Report,
484                     .HIDReportLength        = sizeof(RawReport)
485                 },
486
487             .Raw_INEndpoint =
488                 {
489                     .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
490
491                     .EndpointAddress        = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
492                     .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
493                     .EndpointSize           = RAW_EPSIZE,
494                     .PollingIntervalMS      = 0x01
495                 },
496
497             .Raw_OUTEndpoint =
498                 {
499                     .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
500
501                     .EndpointAddress        = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
502                     .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
503                     .EndpointSize           = RAW_EPSIZE,
504                     .PollingIntervalMS      = 0x01
505                 },
506         #endif
507
508     /*
509      * Console
510      */
511 #ifdef CONSOLE_ENABLE
512     .Console_Interface =
513         {
514             .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
515
516             .InterfaceNumber        = CONSOLE_INTERFACE,
517             .AlternateSetting       = 0x00,
518
519             .TotalEndpoints         = 2,
520
521             .Class                  = HID_CSCP_HIDClass,
522             .SubClass               = HID_CSCP_NonBootSubclass,
523             .Protocol               = HID_CSCP_NonBootProtocol,
524
525             .InterfaceStrIndex      = NO_DESCRIPTOR
526         },
527
528     .Console_HID =
529         {
530             .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
531
532             .HIDSpec                = VERSION_BCD(1,1,1),
533             .CountryCode            = 0x00,
534             .TotalReportDescriptors = 1,
535             .HIDReportType          = HID_DTYPE_Report,
536             .HIDReportLength        = sizeof(ConsoleReport)
537         },
538
539     .Console_INEndpoint =
540         {
541             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
542
543             .EndpointAddress        = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
544             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
545             .EndpointSize           = CONSOLE_EPSIZE,
546             .PollingIntervalMS      = 0x01
547         },
548
549     .Console_OUTEndpoint =
550         {
551             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
552
553             .EndpointAddress        = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
554             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
555             .EndpointSize           = CONSOLE_EPSIZE,
556             .PollingIntervalMS      = 0x01
557         },
558 #endif
559
560 #ifdef MIDI_ENABLE
561     .Audio_Interface_Association =
562         {
563             .Header                   = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
564
565             .FirstInterfaceIndex      = AC_INTERFACE,
566             .TotalInterfaces          = 2,
567
568             .Class                    = AUDIO_CSCP_AudioClass,
569             .SubClass                 = AUDIO_CSCP_ControlSubclass,
570             .Protocol                 = AUDIO_CSCP_ControlProtocol,
571
572             .IADStrIndex              = NO_DESCRIPTOR,
573         },
574     .Audio_ControlInterface =
575         {
576             .Header                   = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
577
578             .InterfaceNumber          = AC_INTERFACE,
579             .AlternateSetting         = 0,
580
581             .TotalEndpoints           = 0,
582
583             .Class                    = AUDIO_CSCP_AudioClass,
584             .SubClass                 = AUDIO_CSCP_ControlSubclass,
585             .Protocol                 = AUDIO_CSCP_ControlProtocol,
586
587             .InterfaceStrIndex        = NO_DESCRIPTOR
588         },
589
590     .Audio_ControlInterface_SPC =
591         {
592             .Header                   = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
593             .Subtype                  = AUDIO_DSUBTYPE_CSInterface_Header,
594
595             .ACSpecification          = VERSION_BCD(1,0,0),
596             .TotalLength              = sizeof(USB_Audio_Descriptor_Interface_AC_t),
597
598             .InCollection             = 1,
599             .InterfaceNumber          = AS_INTERFACE,
600         },
601
602     .Audio_StreamInterface =
603         {
604             .Header                   = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
605
606             .InterfaceNumber          = AS_INTERFACE,
607             .AlternateSetting         = 0,
608
609             .TotalEndpoints           = 2,
610
611             .Class                    = AUDIO_CSCP_AudioClass,
612             .SubClass                 = AUDIO_CSCP_MIDIStreamingSubclass,
613             .Protocol                 = AUDIO_CSCP_StreamingProtocol,
614
615             .InterfaceStrIndex        = NO_DESCRIPTOR
616         },
617
618     .Audio_StreamInterface_SPC =
619         {
620             .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
621             .Subtype                  = AUDIO_DSUBTYPE_CSInterface_General,
622
623             .AudioSpecification       = VERSION_BCD(1,0,0),
624
625             .TotalLength              = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC)
626                                         + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t)
627                                         - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)
628         },
629
630     .MIDI_In_Jack_Emb =
631         {
632             .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
633             .Subtype                  = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
634
635             .JackType                 = MIDI_JACKTYPE_Embedded,
636             .JackID                   = 0x01,
637
638             .JackStrIndex             = NO_DESCRIPTOR
639         },
640
641     .MIDI_In_Jack_Ext =
642         {
643             .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
644             .Subtype                  = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
645
646             .JackType                 = MIDI_JACKTYPE_External,
647             .JackID                   = 0x02,
648
649             .JackStrIndex             = NO_DESCRIPTOR
650         },
651
652     .MIDI_Out_Jack_Emb =
653         {
654             .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
655             .Subtype                  = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
656
657             .JackType                 = MIDI_JACKTYPE_Embedded,
658             .JackID                   = 0x03,
659
660             .NumberOfPins             = 1,
661             .SourceJackID             = {0x02},
662             .SourcePinID              = {0x01},
663
664             .JackStrIndex             = NO_DESCRIPTOR
665         },
666
667     .MIDI_Out_Jack_Ext =
668         {
669             .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
670             .Subtype                  = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
671
672             .JackType                 = MIDI_JACKTYPE_External,
673             .JackID                   = 0x04,
674
675             .NumberOfPins             = 1,
676             .SourceJackID             = {0x01},
677             .SourcePinID              = {0x01},
678
679             .JackStrIndex             = NO_DESCRIPTOR
680         },
681
682     .MIDI_In_Jack_Endpoint =
683         {
684             .Endpoint =
685                 {
686                     .Header              = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
687
688                     .EndpointAddress     = MIDI_STREAM_OUT_EPADDR,
689                     .Attributes          = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
690                     .EndpointSize        = MIDI_STREAM_EPSIZE,
691                     .PollingIntervalMS   = 0x05
692                 },
693
694             .Refresh                  = 0,
695             .SyncEndpointNumber       = 0
696         },
697
698     .MIDI_In_Jack_Endpoint_SPC =
699         {
700             .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
701             .Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
702
703             .TotalEmbeddedJacks       = 0x01,
704             .AssociatedJackID         = {0x01}
705         },
706
707     .MIDI_Out_Jack_Endpoint =
708         {
709             .Endpoint =
710                 {
711                     .Header              = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
712
713                     .EndpointAddress     = MIDI_STREAM_IN_EPADDR,
714                     .Attributes          = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
715                     .EndpointSize        = MIDI_STREAM_EPSIZE,
716                     .PollingIntervalMS   = 0x05
717                 },
718
719             .Refresh                  = 0,
720             .SyncEndpointNumber       = 0
721         },
722
723     .MIDI_Out_Jack_Endpoint_SPC =
724         {
725             .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
726             .Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
727
728             .TotalEmbeddedJacks       = 0x01,
729             .AssociatedJackID         = {0x03}
730         },
731 #endif
732
733 #ifdef VIRTSER_ENABLE
734     .CDC_Interface_Association =
735             {
736                     .Header                 = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
737
738                     .FirstInterfaceIndex    = CCI_INTERFACE,
739                     .TotalInterfaces        = 2,
740
741                     .Class                  = CDC_CSCP_CDCClass,
742                     .SubClass               = CDC_CSCP_ACMSubclass,
743                     .Protocol               = CDC_CSCP_ATCommandProtocol,
744
745                     .IADStrIndex            = NO_DESCRIPTOR,
746             },
747
748     .CDC_CCI_Interface =
749             {
750                     .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
751
752                     .InterfaceNumber        = CCI_INTERFACE,
753                     .AlternateSetting       = 0,
754
755                     .TotalEndpoints         = 1,
756
757                     .Class                  = CDC_CSCP_CDCClass,
758                     .SubClass               = CDC_CSCP_ACMSubclass,
759                     .Protocol               = CDC_CSCP_ATCommandProtocol,
760
761                     .InterfaceStrIndex      = NO_DESCRIPTOR
762             },
763
764     .CDC_Functional_Header =
765             {
766                     .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
767                     .Subtype                = 0x00,
768
769                     .CDCSpecification       = VERSION_BCD(1,1,0),
770             },
771
772     .CDC_Functional_ACM =
773             {
774                     .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
775                     .Subtype                = 0x02,
776
777                     .Capabilities           = 0x02,
778             },
779
780     .CDC_Functional_Union =
781             {
782                     .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
783                     .Subtype                = 0x06,
784
785                     .MasterInterfaceNumber  = CCI_INTERFACE,
786                     .SlaveInterfaceNumber   = CDI_INTERFACE,
787             },
788
789     .CDC_NotificationEndpoint =
790             {
791                     .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
792
793                     .EndpointAddress        = CDC_NOTIFICATION_EPADDR,
794                     .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
795                     .EndpointSize           = CDC_NOTIFICATION_EPSIZE,
796                     .PollingIntervalMS      = 0xFF
797             },
798
799     .CDC_DCI_Interface =
800             {
801                     .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
802
803                     .InterfaceNumber        = CDI_INTERFACE,
804                     .AlternateSetting       = 0,
805
806                     .TotalEndpoints         = 2,
807
808                     .Class                  = CDC_CSCP_CDCDataClass,
809                     .SubClass               = CDC_CSCP_NoDataSubclass,
810                     .Protocol               = CDC_CSCP_NoDataProtocol,
811
812                     .InterfaceStrIndex      = NO_DESCRIPTOR
813             },
814
815     .CDC_DataOutEndpoint =
816             {
817                     .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
818
819                     .EndpointAddress        = CDC_OUT_EPADDR,
820                     .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
821                     .EndpointSize           = CDC_EPSIZE,
822                     .PollingIntervalMS      = 0x05
823             },
824
825     .CDC_DataInEndpoint =
826             {
827                     .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
828
829                     .EndpointAddress        = CDC_IN_EPADDR,
830                     .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
831                     .EndpointSize           = CDC_EPSIZE,
832                     .PollingIntervalMS      = 0x05
833             },
834 #endif
835 };
836
837
838 /*******************************************************************************
839  * String Descriptors
840  ******************************************************************************/
841 const USB_Descriptor_String_t PROGMEM LanguageString =
842 {
843     .Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
844
845     .UnicodeString          = {LANGUAGE_ID_ENG}
846 };
847
848 const USB_Descriptor_String_t PROGMEM ManufacturerString =
849 {
850     /* subtract 1 for null terminator */
851     .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
852
853     .UnicodeString          = LSTR(MANUFACTURER)
854 };
855
856 const USB_Descriptor_String_t PROGMEM ProductString =
857 {
858     /* subtract 1 for null terminator */
859     .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
860
861     .UnicodeString          = LSTR(PRODUCT)
862 };
863
864 #ifndef SERIAL_NUMBER
865     #define SERIAL_NUMBER 0
866 #endif
867
868 const USB_Descriptor_String_t PROGMEM SerialNumberString =
869 {
870     /* subtract 1 for null terminator */
871     .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER))-1), .Type = DTYPE_String},
872
873     .UnicodeString          = LSTR(SERIAL_NUMBER)
874 };
875
876
877 /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
878  *  documentation) by the application code so that the address and size of a requested descriptor can be given
879  *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
880  *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
881  *  USB host.
882  */
883 uint16_t get_usb_descriptor(const uint16_t wValue,
884                             const uint16_t wIndex,
885                             const void** const DescriptorAddress)
886 {
887     const uint8_t  DescriptorType   = (wValue >> 8);
888     const uint8_t  DescriptorIndex  = (wValue & 0xFF);
889
890     const void* Address = NULL;
891     uint16_t    Size    = NO_DESCRIPTOR;
892
893     switch (DescriptorType)
894     {
895         case DTYPE_Device:
896             Address = &DeviceDescriptor;
897             Size    = sizeof(USB_Descriptor_Device_t);
898             break;
899         case DTYPE_Configuration:
900             Address = &ConfigurationDescriptor;
901             Size    = sizeof(USB_Descriptor_Configuration_t);
902             break;
903         case DTYPE_String:
904             switch (DescriptorIndex )
905             {
906                 case 0x00:
907                     Address = &LanguageString;
908                     Size    = pgm_read_byte(&LanguageString.Header.Size);
909                     break;
910                 case 0x01:
911                     Address = &ManufacturerString;
912                     Size    = pgm_read_byte(&ManufacturerString.Header.Size);
913                     break;
914                 case 0x02:
915                     Address = &ProductString;
916                     Size    = pgm_read_byte(&ProductString.Header.Size);
917                     break;
918                 case 0x03:
919                     Address = &SerialNumberString;
920                     Size    = pgm_read_byte(&SerialNumberString.Header.Size);
921                     break;
922             }
923             break;
924         case HID_DTYPE_HID:
925             switch (wIndex) {
926 #ifndef KEYBOARD_SHARED_EP
927             case KEYBOARD_INTERFACE:
928                 Address = &ConfigurationDescriptor.Keyboard_HID;
929                 Size    = sizeof(USB_HID_Descriptor_HID_t);
930                 break;
931 #endif
932 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
933             case MOUSE_INTERFACE:
934                 Address = &ConfigurationDescriptor.Mouse_HID;
935                 Size    = sizeof(USB_HID_Descriptor_HID_t);
936                 break;
937 #endif
938 #ifdef SHARED_EP_ENABLE
939             case SHARED_INTERFACE:
940                 Address = &ConfigurationDescriptor.Shared_HID;
941                 Size    = sizeof(USB_HID_Descriptor_HID_t);
942                 break;
943 #endif
944 #ifdef RAW_ENABLE
945             case RAW_INTERFACE:
946                 Address = &ConfigurationDescriptor.Raw_HID;
947                 Size    = sizeof(USB_HID_Descriptor_HID_t);
948                 break;
949 #endif
950 #ifdef CONSOLE_ENABLE
951             case CONSOLE_INTERFACE:
952                 Address = &ConfigurationDescriptor.Console_HID;
953                 Size    = sizeof(USB_HID_Descriptor_HID_t);
954                 break;
955 #endif
956             }
957             break;
958         case HID_DTYPE_Report:
959             switch (wIndex) {
960 #ifndef KEYBOARD_SHARED_EP
961             case KEYBOARD_INTERFACE:
962                 Address = &KeyboardReport;
963                 Size    = sizeof(KeyboardReport);
964                 break;
965 #endif
966 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
967             case MOUSE_INTERFACE:
968                 Address = &MouseReport;
969                 Size    = sizeof(MouseReport);
970                 break;
971 #endif
972 #ifdef SHARED_EP_ENABLE
973             case SHARED_INTERFACE:
974                 Address = &SharedReport;
975                 Size    = sizeof(SharedReport);
976                 break;
977 #endif
978 #ifdef RAW_ENABLE
979             case RAW_INTERFACE:
980                 Address = &RawReport;
981                 Size    = sizeof(RawReport);
982                 break;
983 #endif
984 #ifdef CONSOLE_ENABLE
985             case CONSOLE_INTERFACE:
986                 Address = &ConsoleReport;
987                 Size    = sizeof(ConsoleReport);
988                 break;
989 #endif
990             }
991             break;
992     }
993
994     *DescriptorAddress = Address;
995     return Size;
996 }