Merge pull request #919 from jackhumbert/hf/robot_test_layout
[jackhill/qmk/firmware.git] / tmk_core / protocol / lufa / descriptor.c
CommitLineData
3969ec09 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
effa5914 39#include "util.h"
3d81d522 40#include "report.h"
effa5914 41#include "descriptor.h"
3969ec09 42
43
44/*******************************************************************************
45 * HID Report Descriptors
46 ******************************************************************************/
47const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
48{
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),
3969ec09 57 HID_RI_REPORT_COUNT(8, 0x08),
f2ebac10 58 HID_RI_REPORT_SIZE(8, 0x01),
3969ec09 59 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
daa4a423 60
3969ec09 61 HID_RI_REPORT_COUNT(8, 0x01),
62 HID_RI_REPORT_SIZE(8, 0x08),
daa4a423 63 HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */
64
3969ec09 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),
daa4a423 74
3969ec09 75 HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
76 HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
f2ebac10 77 HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
78 HID_RI_LOGICAL_MINIMUM(8, 0x00),
6b8b332f 79 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
3969ec09 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),
84};
85
e075361b 86#ifdef MOUSE_ENABLE
3969ec09 87const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
88{
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 */
3d81d522 94
3969ec09 95 HID_RI_USAGE_PAGE(8, 0x09), /* Button */
3d81d522 96 HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
97 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */
3969ec09 98 HID_RI_LOGICAL_MINIMUM(8, 0x00),
99 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
3d81d522 100 HID_RI_REPORT_COUNT(8, 0x05),
3969ec09 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),
3d81d522 104 HID_RI_REPORT_SIZE(8, 0x03),
3969ec09 105 HID_RI_INPUT(8, HID_IOF_CONSTANT),
3d81d522 106
3969ec09 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 */
3d81d522 110 HID_RI_LOGICAL_MINIMUM(8, -127),
111 HID_RI_LOGICAL_MAXIMUM(8, 127),
3969ec09 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),
3d81d522 115
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),
122
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),
130
3969ec09 131 HID_RI_END_COLLECTION(0),
132 HID_RI_END_COLLECTION(0),
133};
e075361b 134#endif
3969ec09 135
f2ebac10 136#ifdef EXTRAKEY_ENABLE
e075361b 137const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
3d81d522 138{
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),
d48a4cf1 143 HID_RI_LOGICAL_MINIMUM(16, 0x0081),
3d81d522 144 HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
d48a4cf1 145 HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
3d81d522 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),
151
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),
ab89bfce 156 HID_RI_LOGICAL_MINIMUM(16, 0x0001),
3d81d522 157 HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
ab89bfce 158 HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
3d81d522 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),
164};
f2ebac10 165#endif
166
e075361b 167#ifdef CONSOLE_ENABLE
168const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
169{
170 HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
171 HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
172 HID_RI_COLLECTION(8, 0x01), /* Application */
173 HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
174 HID_RI_LOGICAL_MINIMUM(8, 0x00),
649b33d7 175 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
e075361b 176 HID_RI_REPORT_COUNT(8, CONSOLE_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, 0x76), /* Vendor Usage 0x76 */
180 HID_RI_LOGICAL_MINIMUM(8, 0x00),
649b33d7 181 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
e075361b 182 HID_RI_REPORT_COUNT(8, CONSOLE_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),
186};
187#endif
188
f2ebac10 189#ifdef NKRO_ENABLE
190const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
191{
192 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
193 HID_RI_USAGE(8, 0x06), /* Keyboard */
194 HID_RI_COLLECTION(8, 0x01), /* Application */
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 */
daa4a423 216 HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
f2ebac10 217 HID_RI_LOGICAL_MINIMUM(8, 0x00),
218 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
daa4a423 219 HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
f2ebac10 220 HID_RI_REPORT_SIZE(8, 0x01),
daa4a423 221 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
222 HID_RI_END_COLLECTION(0),
f2ebac10 223};
224#endif
3969ec09 225
226/*******************************************************************************
227 * Device Descriptors
228 ******************************************************************************/
229const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
230{
231 .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
232
fc3a20c5 233 .USBSpecification = VERSION_BCD(1,1,0),
80d10bef
JG
234#if VIRTSER_ENABLE
235 .Class = USB_CSCP_IADDeviceClass,
236 .SubClass = USB_CSCP_IADDeviceSubclass,
237 .Protocol = USB_CSCP_IADDeviceProtocol,
238#else
3969ec09 239 .Class = USB_CSCP_NoDeviceClass,
240 .SubClass = USB_CSCP_NoDeviceSubclass,
241 .Protocol = USB_CSCP_NoDeviceProtocol,
80d10bef 242#endif
3969ec09 243
3c5add5f 244 .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
3969ec09 245
1348663a 246 /* specified in config.h */
effa5914 247 .VendorID = VENDOR_ID,
248 .ProductID = PRODUCT_ID,
249 .ReleaseNumber = DEVICE_VER,
3969ec09 250
251 .ManufacturerStrIndex = 0x01,
252 .ProductStrIndex = 0x02,
253 .SerialNumStrIndex = NO_DESCRIPTOR,
254
3c5add5f 255 .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
3969ec09 256};
257
258/*******************************************************************************
259 * Configuration Descriptors
260 ******************************************************************************/
261const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
262{
263 .Config =
264 {
265 .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
266
267 .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
3d81d522 268 .TotalInterfaces = TOTAL_INTERFACES,
3969ec09 269
270 .ConfigurationNumber = 1,
271 .ConfigurationStrIndex = NO_DESCRIPTOR,
272
effa5914 273 .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
3969ec09 274
c966e798 275 .MaxPowerConsumption = USB_CONFIG_POWER_MA(500)
3969ec09 276 },
277
3d81d522 278 /*
279 * Keyboard
280 */
a9a3610d 281 .Keyboard_Interface =
3969ec09 282 {
283 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
284
effa5914 285 .InterfaceNumber = KEYBOARD_INTERFACE,
3969ec09 286 .AlternateSetting = 0x00,
287
effa5914 288 .TotalEndpoints = 1,
3969ec09 289
290 .Class = HID_CSCP_HIDClass,
291 .SubClass = HID_CSCP_BootSubclass,
292 .Protocol = HID_CSCP_KeyboardBootProtocol,
293
294 .InterfaceStrIndex = NO_DESCRIPTOR
295 },
296
a9a3610d 297 .Keyboard_HID =
3969ec09 298 {
299 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
300
fc3a20c5 301 .HIDSpec = VERSION_BCD(1,1,1),
3969ec09 302 .CountryCode = 0x00,
303 .TotalReportDescriptors = 1,
304 .HIDReportType = HID_DTYPE_Report,
305 .HIDReportLength = sizeof(KeyboardReport)
306 },
307
a9a3610d 308 .Keyboard_INEndpoint =
3969ec09 309 {
310 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
311
312 .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
313 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
3d81d522 314 .EndpointSize = KEYBOARD_EPSIZE,
c6902681 315 .PollingIntervalMS = 0x0A
3969ec09 316 },
317
3969ec09 318 /*
319 * Mouse
320 */
f2ebac10 321#ifdef MOUSE_ENABLE
a9a3610d 322 .Mouse_Interface =
3969ec09 323 {
324 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
325
effa5914 326 .InterfaceNumber = MOUSE_INTERFACE,
3969ec09 327 .AlternateSetting = 0x00,
328
329 .TotalEndpoints = 1,
330
331 .Class = HID_CSCP_HIDClass,
332 .SubClass = HID_CSCP_BootSubclass,
333 .Protocol = HID_CSCP_MouseBootProtocol,
334
335 .InterfaceStrIndex = NO_DESCRIPTOR
336 },
337
a9a3610d 338 .Mouse_HID =
3969ec09 339 {
340 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
341
fc3a20c5 342 .HIDSpec = VERSION_BCD(1,1,1),
3969ec09 343 .CountryCode = 0x00,
344 .TotalReportDescriptors = 1,
345 .HIDReportType = HID_DTYPE_Report,
346 .HIDReportLength = sizeof(MouseReport)
347 },
348
a9a3610d 349 .Mouse_INEndpoint =
3969ec09 350 {
351 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
352
353 .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
354 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
3d81d522 355 .EndpointSize = MOUSE_EPSIZE,
a5d4a1f3 356 .PollingIntervalMS = 0x0A
3969ec09 357 },
f2ebac10 358#endif
3969ec09 359
360 /*
e075361b 361 * Extra
3969ec09 362 */
e075361b 363#ifdef EXTRAKEY_ENABLE
364 .Extrakey_Interface =
3969ec09 365 {
366 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
367
e075361b 368 .InterfaceNumber = EXTRAKEY_INTERFACE,
3969ec09 369 .AlternateSetting = 0x00,
370
e075361b 371 .TotalEndpoints = 1,
3969ec09 372
373 .Class = HID_CSCP_HIDClass,
374 .SubClass = HID_CSCP_NonBootSubclass,
375 .Protocol = HID_CSCP_NonBootProtocol,
376
377 .InterfaceStrIndex = NO_DESCRIPTOR
378 },
379
e075361b 380 .Extrakey_HID =
3969ec09 381 {
382 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
383
fc3a20c5 384 .HIDSpec = VERSION_BCD(1,1,1),
3969ec09 385 .CountryCode = 0x00,
386 .TotalReportDescriptors = 1,
387 .HIDReportType = HID_DTYPE_Report,
e075361b 388 .HIDReportLength = sizeof(ExtrakeyReport)
3969ec09 389 },
390
e075361b 391 .Extrakey_INEndpoint =
3969ec09 392 {
393 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
394
e075361b 395 .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
3969ec09 396 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
e075361b 397 .EndpointSize = EXTRAKEY_EPSIZE,
a5d4a1f3 398 .PollingIntervalMS = 0x0A
3d81d522 399 },
e075361b 400#endif
3d81d522 401
402 /*
e075361b 403 * Console
3d81d522 404 */
e075361b 405#ifdef CONSOLE_ENABLE
406 .Console_Interface =
3d81d522 407 {
408 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
409
e075361b 410 .InterfaceNumber = CONSOLE_INTERFACE,
3d81d522 411 .AlternateSetting = 0x00,
412
e075361b 413 .TotalEndpoints = 2,
3d81d522 414
415 .Class = HID_CSCP_HIDClass,
416 .SubClass = HID_CSCP_NonBootSubclass,
417 .Protocol = HID_CSCP_NonBootProtocol,
418
419 .InterfaceStrIndex = NO_DESCRIPTOR
420 },
421
e075361b 422 .Console_HID =
3d81d522 423 {
424 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
425
fc3a20c5 426 .HIDSpec = VERSION_BCD(1,1,1),
3d81d522 427 .CountryCode = 0x00,
428 .TotalReportDescriptors = 1,
429 .HIDReportType = HID_DTYPE_Report,
e075361b 430 .HIDReportLength = sizeof(ConsoleReport)
3d81d522 431 },
432
e075361b 433 .Console_INEndpoint =
3d81d522 434 {
435 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
436
e075361b 437 .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
3969ec09 438 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
e075361b 439 .EndpointSize = CONSOLE_EPSIZE,
440 .PollingIntervalMS = 0x01
441 },
442
443 .Console_OUTEndpoint =
444 {
445 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
446
447 .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
448 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
449 .EndpointSize = CONSOLE_EPSIZE,
3969ec09 450 .PollingIntervalMS = 0x01
3d81d522 451 },
f2ebac10 452#endif
daa4a423 453
454 /*
455 * NKRO
456 */
457#ifdef NKRO_ENABLE
458 .NKRO_Interface =
459 {
460 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
461
462 .InterfaceNumber = NKRO_INTERFACE,
463 .AlternateSetting = 0x00,
464
465 .TotalEndpoints = 1,
466
467 .Class = HID_CSCP_HIDClass,
468 .SubClass = HID_CSCP_NonBootSubclass,
469 .Protocol = HID_CSCP_NonBootProtocol,
470
471 .InterfaceStrIndex = NO_DESCRIPTOR
472 },
473
474 .NKRO_HID =
475 {
476 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
477
fc3a20c5 478 .HIDSpec = VERSION_BCD(1,1,1),
daa4a423 479 .CountryCode = 0x00,
480 .TotalReportDescriptors = 1,
481 .HIDReportType = HID_DTYPE_Report,
482 .HIDReportLength = sizeof(NKROReport)
483 },
484
485 .NKRO_INEndpoint =
486 {
487 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
488
489 .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
490 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
491 .EndpointSize = NKRO_EPSIZE,
492 .PollingIntervalMS = 0x01
493 },
494#endif
e528087e 495
04885a3b 496#ifdef MIDI_ENABLE
e528087e
JH
497 .Audio_ControlInterface =
498 {
499 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
500
cda23c75 501 .InterfaceNumber = AC_INTERFACE,
e528087e
JH
502 .AlternateSetting = 0,
503
504 .TotalEndpoints = 0,
505
506 .Class = AUDIO_CSCP_AudioClass,
507 .SubClass = AUDIO_CSCP_ControlSubclass,
508 .Protocol = AUDIO_CSCP_ControlProtocol,
509
510 .InterfaceStrIndex = NO_DESCRIPTOR
511 },
512
513 .Audio_ControlInterface_SPC =
514 {
515 .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
516 .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
517
04885a3b 518 .ACSpecification = VERSION_BCD(1,0,0),
e528087e
JH
519 .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
520
521 .InCollection = 1,
cda23c75 522 .InterfaceNumber = AS_INTERFACE,
e528087e
JH
523 },
524
525 .Audio_StreamInterface =
526 {
527 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
528
cda23c75 529 .InterfaceNumber = AS_INTERFACE,
e528087e
JH
530 .AlternateSetting = 0,
531
532 .TotalEndpoints = 2,
533
534 .Class = AUDIO_CSCP_AudioClass,
535 .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
536 .Protocol = AUDIO_CSCP_StreamingProtocol,
537
538 .InterfaceStrIndex = NO_DESCRIPTOR
539 },
540
541 .Audio_StreamInterface_SPC =
542 {
543 .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
544 .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
545
04885a3b 546 .AudioSpecification = VERSION_BCD(1,0,0),
e528087e
JH
547
548 .TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
549 offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
550 },
551
552 .MIDI_In_Jack_Emb =
553 {
554 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
555 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
556
557 .JackType = MIDI_JACKTYPE_Embedded,
558 .JackID = 0x01,
559
560 .JackStrIndex = NO_DESCRIPTOR
561 },
562
563 .MIDI_In_Jack_Ext =
564 {
565 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
566 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
567
568 .JackType = MIDI_JACKTYPE_External,
569 .JackID = 0x02,
570
571 .JackStrIndex = NO_DESCRIPTOR
572 },
573
574 .MIDI_Out_Jack_Emb =
575 {
576 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
577 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
578
579 .JackType = MIDI_JACKTYPE_Embedded,
580 .JackID = 0x03,
581
582 .NumberOfPins = 1,
583 .SourceJackID = {0x02},
584 .SourcePinID = {0x01},
585
586 .JackStrIndex = NO_DESCRIPTOR
587 },
588
589 .MIDI_Out_Jack_Ext =
590 {
591 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
592 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
593
594 .JackType = MIDI_JACKTYPE_External,
595 .JackID = 0x04,
596
597 .NumberOfPins = 1,
598 .SourceJackID = {0x01},
599 .SourcePinID = {0x01},
600
601 .JackStrIndex = NO_DESCRIPTOR
602 },
603
604 .MIDI_In_Jack_Endpoint =
605 {
606 .Endpoint =
607 {
608 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
609
cda23c75 610 .EndpointAddress = MIDI_STREAM_OUT_EPADDR,
e528087e
JH
611 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
612 .EndpointSize = MIDI_STREAM_EPSIZE,
04885a3b 613 .PollingIntervalMS = 0x05
e528087e
JH
614 },
615
616 .Refresh = 0,
617 .SyncEndpointNumber = 0
618 },
619
620 .MIDI_In_Jack_Endpoint_SPC =
621 {
622 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
623 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
624
625 .TotalEmbeddedJacks = 0x01,
626 .AssociatedJackID = {0x01}
627 },
628
629 .MIDI_Out_Jack_Endpoint =
630 {
631 .Endpoint =
632 {
633 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
634
cda23c75 635 .EndpointAddress = MIDI_STREAM_IN_EPADDR,
e528087e
JH
636 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
637 .EndpointSize = MIDI_STREAM_EPSIZE,
04885a3b 638 .PollingIntervalMS = 0x05
e528087e
JH
639 },
640
641 .Refresh = 0,
642 .SyncEndpointNumber = 0
643 },
644
645 .MIDI_Out_Jack_Endpoint_SPC =
646 {
647 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
648 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
649
650 .TotalEmbeddedJacks = 0x01,
651 .AssociatedJackID = {0x03}
80d10bef
JG
652 },
653#endif
654
655#ifdef VIRTSER_ENABLE
656 .CDC_Interface_Association =
657 {
658 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
659
660 .FirstInterfaceIndex = CCI_INTERFACE,
661 .TotalInterfaces = 2,
662
663 .Class = CDC_CSCP_CDCClass,
664 .SubClass = CDC_CSCP_ACMSubclass,
665 .Protocol = CDC_CSCP_ATCommandProtocol,
666
667 .IADStrIndex = NO_DESCRIPTOR,
668 },
669
670 .CDC_CCI_Interface =
671 {
672 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
673
674 .InterfaceNumber = CCI_INTERFACE,
675 .AlternateSetting = 0,
676
677 .TotalEndpoints = 1,
678
679 .Class = CDC_CSCP_CDCClass,
680 .SubClass = CDC_CSCP_ACMSubclass,
681 .Protocol = CDC_CSCP_ATCommandProtocol,
682
683 .InterfaceStrIndex = NO_DESCRIPTOR
684 },
685
686 .CDC_Functional_Header =
687 {
688 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
689 .Subtype = 0x00,
690
691 .CDCSpecification = VERSION_BCD(1,1,0),
692 },
693
694 .CDC_Functional_ACM =
695 {
696 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
697 .Subtype = 0x02,
698
699 .Capabilities = 0x02,
700 },
701
702 .CDC_Functional_Union =
703 {
704 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
705 .Subtype = 0x06,
706
707 .MasterInterfaceNumber = CCI_INTERFACE,
708 .SlaveInterfaceNumber = CDI_INTERFACE,
709 },
710
711 .CDC_NotificationEndpoint =
712 {
713 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
714
715 .EndpointAddress = CDC_NOTIFICATION_EPADDR,
716 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
717 .EndpointSize = CDC_NOTIFICATION_EPSIZE,
718 .PollingIntervalMS = 0xFF
719 },
720
721 .CDC_DCI_Interface =
722 {
723 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
724
725 .InterfaceNumber = CDI_INTERFACE,
726 .AlternateSetting = 0,
727
728 .TotalEndpoints = 2,
729
730 .Class = CDC_CSCP_CDCDataClass,
731 .SubClass = CDC_CSCP_NoDataSubclass,
732 .Protocol = CDC_CSCP_NoDataProtocol,
733
734 .InterfaceStrIndex = NO_DESCRIPTOR
735 },
736
737 .CDC_DataOutEndpoint =
738 {
739 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
740
741 .EndpointAddress = CDC_OUT_EPADDR,
742 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
743 .EndpointSize = CDC_EPSIZE,
744 .PollingIntervalMS = 0x05
745 },
746
747 .CDC_DataInEndpoint =
748 {
749 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
750
751 .EndpointAddress = CDC_IN_EPADDR,
752 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
753 .EndpointSize = CDC_EPSIZE,
754 .PollingIntervalMS = 0x05
755 },
04885a3b 756#endif
80d10bef 757
3969ec09 758};
759
760
761/*******************************************************************************
762 * String Descriptors
763 ******************************************************************************/
764const USB_Descriptor_String_t PROGMEM LanguageString =
765{
766 .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
767
768 .UnicodeString = {LANGUAGE_ID_ENG}
769};
770
771const USB_Descriptor_String_t PROGMEM ManufacturerString =
772{
1348663a 773 /* subtract 1 for null terminator */
774 .Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
3969ec09 775
effa5914 776 .UnicodeString = LSTR(MANUFACTURER)
3969ec09 777};
778
779const USB_Descriptor_String_t PROGMEM ProductString =
780{
1348663a 781 /* subtract 1 for null terminator */
782 .Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
3969ec09 783
effa5914 784 .UnicodeString = LSTR(PRODUCT)
3969ec09 785};
786
787
788/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
789 * documentation) by the application code so that the address and size of a requested descriptor can be given
790 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
791 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
792 * USB host.
793 */
794uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
795 const uint8_t wIndex,
796 const void** const DescriptorAddress)
797{
798 const uint8_t DescriptorType = (wValue >> 8);
799 const uint8_t DescriptorIndex = (wValue & 0xFF);
800
801 const void* Address = NULL;
802 uint16_t Size = NO_DESCRIPTOR;
803
804 switch (DescriptorType)
805 {
806 case DTYPE_Device:
807 Address = &DeviceDescriptor;
808 Size = sizeof(USB_Descriptor_Device_t);
809 break;
810 case DTYPE_Configuration:
811 Address = &ConfigurationDescriptor;
812 Size = sizeof(USB_Descriptor_Configuration_t);
813 break;
814 case DTYPE_String:
815 switch (DescriptorIndex )
816 {
817 case 0x00:
818 Address = &LanguageString;
819 Size = pgm_read_byte(&LanguageString.Header.Size);
820 break;
821 case 0x01:
822 Address = &ManufacturerString;
823 Size = pgm_read_byte(&ManufacturerString.Header.Size);
824 break;
825 case 0x02:
826 Address = &ProductString;
827 Size = pgm_read_byte(&ProductString.Header.Size);
828 break;
829 }
830 break;
831 case HID_DTYPE_HID:
832 switch (wIndex) {
effa5914 833 case KEYBOARD_INTERFACE:
a9a3610d 834 Address = &ConfigurationDescriptor.Keyboard_HID;
3969ec09 835 Size = sizeof(USB_HID_Descriptor_HID_t);
836 break;
f2ebac10 837#ifdef MOUSE_ENABLE
effa5914 838 case MOUSE_INTERFACE:
a9a3610d 839 Address = &ConfigurationDescriptor.Mouse_HID;
3969ec09 840 Size = sizeof(USB_HID_Descriptor_HID_t);
841 break;
f2ebac10 842#endif
e075361b 843#ifdef EXTRAKEY_ENABLE
844 case EXTRAKEY_INTERFACE:
845 Address = &ConfigurationDescriptor.Extrakey_HID;
3969ec09 846 Size = sizeof(USB_HID_Descriptor_HID_t);
847 break;
e075361b 848#endif
849#ifdef CONSOLE_ENABLE
850 case CONSOLE_INTERFACE:
851 Address = &ConfigurationDescriptor.Console_HID;
3d81d522 852 Size = sizeof(USB_HID_Descriptor_HID_t);
853 break;
daa4a423 854#endif
855#ifdef NKRO_ENABLE
856 case NKRO_INTERFACE:
857 Address = &ConfigurationDescriptor.NKRO_HID;
858 Size = sizeof(USB_HID_Descriptor_HID_t);
859 break;
f2ebac10 860#endif
3969ec09 861 }
862 break;
863 case HID_DTYPE_Report:
864 switch (wIndex) {
effa5914 865 case KEYBOARD_INTERFACE:
3969ec09 866 Address = &KeyboardReport;
867 Size = sizeof(KeyboardReport);
868 break;
f2ebac10 869#ifdef MOUSE_ENABLE
effa5914 870 case MOUSE_INTERFACE:
3969ec09 871 Address = &MouseReport;
872 Size = sizeof(MouseReport);
873 break;
f2ebac10 874#endif
e075361b 875#ifdef EXTRAKEY_ENABLE
876 case EXTRAKEY_INTERFACE:
877 Address = &ExtrakeyReport;
878 Size = sizeof(ExtrakeyReport);
879 break;
880#endif
881#ifdef CONSOLE_ENABLE
3d81d522 882 case CONSOLE_INTERFACE:
a9a3610d 883 Address = &ConsoleReport;
884 Size = sizeof(ConsoleReport);
3969ec09 885 break;
daa4a423 886#endif
887#ifdef NKRO_ENABLE
888 case NKRO_INTERFACE:
889 Address = &NKROReport;
890 Size = sizeof(NKROReport);
891 break;
f2ebac10 892#endif
3969ec09 893 }
894 break;
895 }
896
897 *DescriptorAddress = Address;
898 return Size;
899}