Make USB polling rate configurable with a define (#6668)
[jackhill/qmk/firmware.git] / tmk_core / protocol / usb_descriptor.c
CommitLineData
9303b42e 1/*
3969ec09 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/*
ac167268 9 LUFA Library
10 Copyright (C) Dean Camera, 2012.
3969ec09 11
ac167268 12 dean [at] fourwalledcubicle [dot] com
13 www.lufa-lib.org
3969ec09 14*/
15
16/*
ac167268 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.
3969ec09 37*/
38
effa5914 39#include "util.h"
3d81d522 40#include "report.h"
53ff8a31 41#include "usb_descriptor.h"
3969ec09 42
ac167268 43/*
44 * HID report descriptors
45 */
39bd760f
JLW
46#ifdef KEYBOARD_SHARED_EP
47const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
b624f32f 48# define SHARED_REPORT_STARTED
39bd760f
JLW
49#else
50const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
51#endif
b624f32f 52 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
53 HID_RI_USAGE(8, 0x06), // Keyboard
54 HID_RI_COLLECTION(8, 0x01), // Application
ac167268 55#ifdef KEYBOARD_SHARED_EP
b624f32f 56 HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
ac167268 57#endif
b624f32f 58 // Modifiers (8 bits)
59 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
60 HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control
61 HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI
62 HID_RI_LOGICAL_MINIMUM(8, 0x00),
63 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
64 HID_RI_REPORT_COUNT(8, 0x08),
65 HID_RI_REPORT_SIZE(8, 0x01),
66 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
67 // Reserved (1 byte)
68 HID_RI_REPORT_COUNT(8, 0x01),
69 HID_RI_REPORT_SIZE(8, 0x08),
70 HID_RI_INPUT(8, HID_IOF_CONSTANT),
71 // Keycodes (6 bytes)
72 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
73 HID_RI_USAGE_MINIMUM(8, 0x00),
74 HID_RI_USAGE_MAXIMUM(8, 0xFF),
75 HID_RI_LOGICAL_MINIMUM(8, 0x00),
76 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
77 HID_RI_REPORT_COUNT(8, 0x06),
78 HID_RI_REPORT_SIZE(8, 0x08),
79 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
80
81 // Status LEDs (5 bits)
82 HID_RI_USAGE_PAGE(8, 0x08), // LED
83 HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
84 HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
85 HID_RI_REPORT_COUNT(8, 0x05),
86 HID_RI_REPORT_SIZE(8, 0x01),
87 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
88 // LED padding (3 bits)
89 HID_RI_REPORT_COUNT(8, 0x01),
90 HID_RI_REPORT_SIZE(8, 0x03),
91 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
3969ec09 92 HID_RI_END_COLLECTION(0),
39bd760f 93#ifndef KEYBOARD_SHARED_EP
3969ec09 94};
39bd760f 95#endif
3969ec09 96
ac167268 97#ifdef MOUSE_ENABLE
b624f32f 98# ifndef MOUSE_SHARED_EP
39bd760f 99const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
b624f32f 100# elif !defined(SHARED_REPORT_STARTED)
39bd760f 101const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
b624f32f 102# define SHARED_REPORT_STARTED
103# endif
104 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
105 HID_RI_USAGE(8, 0x02), // Mouse
106 HID_RI_COLLECTION(8, 0x01), // Application
107# ifdef MOUSE_SHARED_EP
108 HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
109# endif
110 HID_RI_USAGE(8, 0x01), // Pointer
111 HID_RI_COLLECTION(8, 0x00), // Physical
112 // Buttons (5 bits)
113 HID_RI_USAGE_PAGE(8, 0x09), // Button
114 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
115 HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5
116 HID_RI_LOGICAL_MINIMUM(8, 0x00),
117 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
118 HID_RI_REPORT_COUNT(8, 0x05),
119 HID_RI_REPORT_SIZE(8, 0x01),
120 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
121 // Button padding (3 bits)
122 HID_RI_REPORT_COUNT(8, 0x01),
123 HID_RI_REPORT_SIZE(8, 0x03),
124 HID_RI_INPUT(8, HID_IOF_CONSTANT),
125
126 // X/Y position (2 bytes)
127 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
128 HID_RI_USAGE(8, 0x30), // X
129 HID_RI_USAGE(8, 0x31), // Y
130 HID_RI_LOGICAL_MINIMUM(8, -127),
131 HID_RI_LOGICAL_MAXIMUM(8, 127),
132 HID_RI_REPORT_COUNT(8, 0x02),
133 HID_RI_REPORT_SIZE(8, 0x08),
134 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
135
136 // Vertical wheel (1 byte)
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 // Horizontal wheel (1 byte)
144 HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
145 HID_RI_USAGE(16, 0x0238), // AC Pan
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),
3969ec09 151 HID_RI_END_COLLECTION(0),
b624f32f 152 HID_RI_END_COLLECTION(0),
153# ifndef MOUSE_SHARED_EP
3969ec09 154};
b624f32f 155# endif
e075361b 156#endif
3969ec09 157
39bd760f
JLW
158#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
159const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
160#endif
ac167268 161
162#ifdef EXTRAKEY_ENABLE
b624f32f 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_USAGE_MINIMUM(16, 0x0081), // System Power Down
168 HID_RI_USAGE_MAXIMUM(16, 0x0083), // System Wake Up
169 HID_RI_LOGICAL_MINIMUM(16, 0x0001),
170 HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
171 HID_RI_REPORT_COUNT(8, 1),
172 HID_RI_REPORT_SIZE(8, 16),
173 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
3d81d522 174 HID_RI_END_COLLECTION(0),
175
b624f32f 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_USAGE_MINIMUM(16, 0x0001), // Consumer Control
181 HID_RI_USAGE_MAXIMUM(16, 0x029C), // AC Distribute Vertically
182 HID_RI_LOGICAL_MINIMUM(16, 0x0001),
183 HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
184 HID_RI_REPORT_COUNT(8, 1),
185 HID_RI_REPORT_SIZE(8, 16),
186 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
3d81d522 187 HID_RI_END_COLLECTION(0),
ac167268 188#endif
39bd760f 189
ac167268 190#ifdef NKRO_ENABLE
b624f32f 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 // Modifiers (8 bits)
196 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
197 HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control
198 HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI
199 HID_RI_LOGICAL_MINIMUM(8, 0x00),
200 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
201 HID_RI_REPORT_COUNT(8, 0x08),
202 HID_RI_REPORT_SIZE(8, 0x01),
203 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
204 // Keycodes
205 HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
206 HID_RI_USAGE_MINIMUM(8, 0x00),
207 HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS * 8 - 1),
208 HID_RI_LOGICAL_MINIMUM(8, 0x00),
209 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
210 HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS * 8),
211 HID_RI_REPORT_SIZE(8, 0x01),
212 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
213
214 // Status LEDs (5 bits)
215 HID_RI_USAGE_PAGE(8, 0x08), // LED
216 HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
217 HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
218 HID_RI_REPORT_COUNT(8, 0x05),
219 HID_RI_REPORT_SIZE(8, 0x01),
220 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
221 // LED padding (3 bits)
222 HID_RI_REPORT_COUNT(8, 0x01),
223 HID_RI_REPORT_SIZE(8, 0x03),
224 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
39bd760f 225 HID_RI_END_COLLECTION(0),
ac167268 226#endif
39bd760f 227#ifdef SHARED_EP_ENABLE
3d81d522 228};
f2ebac10 229#endif
230
fe001d46 231#ifdef RAW_ENABLE
ac167268 232const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = {
b624f32f 233 HID_RI_USAGE_PAGE(16, 0xFF60), // Vendor Defined
234 HID_RI_USAGE(8, 0x61), // Vendor Defined
235 HID_RI_COLLECTION(8, 0x01), // Application
236 // Data to host
237 HID_RI_USAGE(8, 0x62), // Vendor Defined
238 HID_RI_LOGICAL_MINIMUM(8, 0x00),
239 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
240 HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
241 HID_RI_REPORT_SIZE(8, 0x08),
242 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
243 // Data from host
244 HID_RI_USAGE(8, 0x63), // Vendor Defined
245 HID_RI_LOGICAL_MINIMUM(8, 0x00),
246 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
247 HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
248 HID_RI_REPORT_SIZE(8, 0x08),
249 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
fe001d46
W
250 HID_RI_END_COLLECTION(0),
251};
252#endif
253
e075361b 254#ifdef CONSOLE_ENABLE
ac167268 255const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
b624f32f 256 HID_RI_USAGE_PAGE(16, 0xFF31), // Vendor Defined (PJRC Teensy compatible)
257 HID_RI_USAGE(8, 0x74), // Vendor Defined (PJRC Teensy compatible)
258 HID_RI_COLLECTION(8, 0x01), // Application
259 // Data to host
260 HID_RI_USAGE(8, 0x75), // Vendor Defined
261 HID_RI_LOGICAL_MINIMUM(8, 0x00),
262 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
263 HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
264 HID_RI_REPORT_SIZE(8, 0x08),
265 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
266 // Data from host
267 HID_RI_USAGE(8, 0x76), // Vendor Defined
268 HID_RI_LOGICAL_MINIMUM(8, 0x00),
269 HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
270 HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
271 HID_RI_REPORT_SIZE(8, 0x08),
272 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
e075361b 273 HID_RI_END_COLLECTION(0),
274};
275#endif
276
ac167268 277/*
278 * Device descriptor
279 */
b624f32f 280const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
281 .USBSpecification = VERSION_BCD(1, 1, 0),
80d10bef 282#if VIRTSER_ENABLE
b624f32f 283 .Class = USB_CSCP_IADDeviceClass,
284 .SubClass = USB_CSCP_IADDeviceSubclass,
285 .Protocol = USB_CSCP_IADDeviceProtocol,
80d10bef 286#else
b624f32f 287 .Class = USB_CSCP_NoDeviceClass,
288 .SubClass = USB_CSCP_NoDeviceSubclass,
289 .Protocol = USB_CSCP_NoDeviceProtocol,
80d10bef 290#endif
b624f32f 291 .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
292 // Specified in config.h
293 .VendorID = VENDOR_ID,
294 .ProductID = PRODUCT_ID,
295 .ReleaseNumber = DEVICE_VER,
296 .ManufacturerStrIndex = 0x01,
297 .ProductStrIndex = 0x02,
298 .SerialNumStrIndex = 0x03,
299 .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS};
3969ec09 300
ac167268 301#ifndef USB_MAX_POWER_CONSUMPTION
b624f32f 302# define USB_MAX_POWER_CONSUMPTION 500
ac167268 303#endif
3969ec09 304
7ffed073 305#ifndef USB_POLLING_INTERVAL_MS
306# define USB_POLLING_INTERVAL_MS 10
307#endif
308
ac167268 309/*
310 * Configuration descriptors
311 */
b624f32f 312const USB_Descriptor_Configuration_t PROGMEM
313 ConfigurationDescriptor =
314 {
315 .Config = {.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalInterfaces = TOTAL_INTERFACES, .ConfigurationNumber = 1, .ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP), .MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)},
3969ec09 316
ac167268 317#ifndef KEYBOARD_SHARED_EP
b624f32f 318 /*
319 * Keyboard
320 */
321 .Keyboard_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
322 .InterfaceNumber = KEYBOARD_INTERFACE,
323 .AlternateSetting = 0x00,
324 .TotalEndpoints = 1,
325 .Class = HID_CSCP_HIDClass,
326 .SubClass = HID_CSCP_BootSubclass,
327 .Protocol = HID_CSCP_KeyboardBootProtocol,
328
329 .InterfaceStrIndex = NO_DESCRIPTOR},
330 .Keyboard_HID = {.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .HIDSpec = VERSION_BCD(1, 1, 1), .CountryCode = 0x00, .TotalReportDescriptors = 1, .HIDReportType = HID_DTYPE_Report, .HIDReportLength = sizeof(KeyboardReport)},
7ffed073 331 .Keyboard_INEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = KEYBOARD_EPSIZE, .PollingIntervalMS = USB_POLLING_INTERVAL_MS},
39bd760f 332#endif
3969ec09 333
ac167268 334#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
b624f32f 335 /*
336 * Mouse
337 */
338 .Mouse_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .InterfaceNumber = MOUSE_INTERFACE, .AlternateSetting = 0x00, .TotalEndpoints = 1, .Class = HID_CSCP_HIDClass, .SubClass = HID_CSCP_BootSubclass, .Protocol = HID_CSCP_MouseBootProtocol, .InterfaceStrIndex = NO_DESCRIPTOR},
339 .Mouse_HID = {.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .HIDSpec = VERSION_BCD(1, 1, 1), .CountryCode = 0x00, .TotalReportDescriptors = 1, .HIDReportType = HID_DTYPE_Report, .HIDReportLength = sizeof(MouseReport)},
7ffed073 340 .Mouse_INEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = MOUSE_EPSIZE, .PollingIntervalMS = USB_POLLING_INTERVAL_MS},
f2ebac10 341#endif
3969ec09 342
ac167268 343#ifdef SHARED_EP_ENABLE
b624f32f 344 /*
345 * Shared
346 */
347 .Shared_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
348 .InterfaceNumber = SHARED_INTERFACE,
349 .AlternateSetting = 0x00,
350 .TotalEndpoints = 1,
351 .Class = HID_CSCP_HIDClass,
352# ifdef KEYBOARD_SHARED_EP
353 .SubClass = HID_CSCP_BootSubclass,
354 .Protocol = HID_CSCP_KeyboardBootProtocol,
355# else
356 .SubClass = HID_CSCP_NonBootSubclass,
357 .Protocol = HID_CSCP_NonBootProtocol,
358# endif
359 .InterfaceStrIndex = NO_DESCRIPTOR},
360 .Shared_HID = {.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .HIDSpec = VERSION_BCD(1, 1, 1), .CountryCode = 0x00, .TotalReportDescriptors = 1, .HIDReportType = HID_DTYPE_Report, .HIDReportLength = sizeof(SharedReport)},
7ffed073 361 .Shared_INEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = SHARED_EPSIZE, .PollingIntervalMS = USB_POLLING_INTERVAL_MS},
ac167268 362#endif
3969ec09 363
ac167268 364#ifdef RAW_ENABLE
b624f32f 365 /*
366 * Raw HID
367 */
368 .Raw_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .InterfaceNumber = RAW_INTERFACE, .AlternateSetting = 0x00, .TotalEndpoints = 2, .Class = HID_CSCP_HIDClass, .SubClass = HID_CSCP_NonBootSubclass, .Protocol = HID_CSCP_NonBootProtocol, .InterfaceStrIndex = NO_DESCRIPTOR},
369 .Raw_HID = {.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .HIDSpec = VERSION_BCD(1, 1, 1), .CountryCode = 0x00, .TotalReportDescriptors = 1, .HIDReportType = HID_DTYPE_Report, .HIDReportLength = sizeof(RawReport)},
370 .Raw_INEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = RAW_EPSIZE, .PollingIntervalMS = 0x01},
371 .Raw_OUTEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = RAW_EPSIZE, .PollingIntervalMS = 0x01},
e075361b 372#endif
3d81d522 373
ac167268 374#ifdef CONSOLE_ENABLE
b624f32f 375 /*
376 * Console
377 */
378 .Console_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .InterfaceNumber = CONSOLE_INTERFACE, .AlternateSetting = 0x00, .TotalEndpoints = 2, .Class = HID_CSCP_HIDClass, .SubClass = HID_CSCP_NonBootSubclass, .Protocol = HID_CSCP_NonBootProtocol, .InterfaceStrIndex = NO_DESCRIPTOR},
379 .Console_HID = {.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .HIDSpec = VERSION_BCD(1, 1, 1), .CountryCode = 0x00, .TotalReportDescriptors = 1, .HIDReportType = HID_DTYPE_Report, .HIDReportLength = sizeof(ConsoleReport)},
380 .Console_INEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = CONSOLE_EPSIZE, .PollingIntervalMS = 0x01},
381 .Console_OUTEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = CONSOLE_EPSIZE, .PollingIntervalMS = 0x01},
f2ebac10 382#endif
daa4a423 383
04885a3b 384#ifdef MIDI_ENABLE
b624f32f 385 /*
386 * MIDI
387 */
388 .Audio_Interface_Association =
389 {
390 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
391 .FirstInterfaceIndex = AC_INTERFACE,
392 .TotalInterfaces = 2,
393 .Class = AUDIO_CSCP_AudioClass,
394 .SubClass = AUDIO_CSCP_ControlSubclass,
395 .Protocol = AUDIO_CSCP_ControlProtocol,
396 .IADStrIndex = NO_DESCRIPTOR,
397 },
398 .Audio_ControlInterface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
399
400 .InterfaceNumber = AC_INTERFACE,
401 .AlternateSetting = 0,
402 .TotalEndpoints = 0,
403 .Class = AUDIO_CSCP_AudioClass,
404 .SubClass = AUDIO_CSCP_ControlSubclass,
405 .Protocol = AUDIO_CSCP_ControlProtocol,
406 .InterfaceStrIndex = NO_DESCRIPTOR},
407 .Audio_ControlInterface_SPC =
408 {
409 .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = AUDIO_DTYPE_CSInterface},
410 .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
411 .ACSpecification = VERSION_BCD(1, 0, 0),
412 .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
413 .InCollection = 1,
414 .InterfaceNumber = AS_INTERFACE,
415 },
416 .Audio_StreamInterface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
417
418 .InterfaceNumber = AS_INTERFACE,
419 .AlternateSetting = 0,
420 .TotalEndpoints = 2,
421 .Class = AUDIO_CSCP_AudioClass,
422 .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
423 .Protocol = AUDIO_CSCP_StreamingProtocol,
424 .InterfaceStrIndex = NO_DESCRIPTOR},
425 .Audio_StreamInterface_SPC = {.Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = AUDIO_DTYPE_CSInterface}, .Subtype = AUDIO_DSUBTYPE_CSInterface_General, .AudioSpecification = VERSION_BCD(1, 0, 0), .TotalLength = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC) + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t) - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)},
426 .MIDI_In_Jack_Emb = {.Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = AUDIO_DTYPE_CSInterface}, .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, .JackType = MIDI_JACKTYPE_Embedded, .JackID = 0x01, .JackStrIndex = NO_DESCRIPTOR},
427 .MIDI_In_Jack_Ext = {.Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = AUDIO_DTYPE_CSInterface}, .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, .JackType = MIDI_JACKTYPE_External, .JackID = 0x02, .JackStrIndex = NO_DESCRIPTOR},
428 .MIDI_Out_Jack_Emb = {.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = AUDIO_DTYPE_CSInterface}, .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, .JackType = MIDI_JACKTYPE_Embedded, .JackID = 0x03, .NumberOfPins = 1, .SourceJackID = {0x02}, .SourcePinID = {0x01}, .JackStrIndex = NO_DESCRIPTOR},
429 .MIDI_Out_Jack_Ext = {.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = AUDIO_DTYPE_CSInterface}, .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, .JackType = MIDI_JACKTYPE_External, .JackID = 0x04, .NumberOfPins = 1, .SourceJackID = {0x01}, .SourcePinID = {0x01}, .JackStrIndex = NO_DESCRIPTOR},
430 .MIDI_In_Jack_Endpoint = {.Endpoint = {.Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .EndpointAddress = MIDI_STREAM_OUT_EPADDR, .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = MIDI_STREAM_EPSIZE, .PollingIntervalMS = 0x05},
431
432 .Refresh = 0,
433 .SyncEndpointNumber = 0},
434 .MIDI_In_Jack_Endpoint_SPC = {.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = AUDIO_DSUBTYPE_CSEndpoint_General}, .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, .TotalEmbeddedJacks = 0x01, .AssociatedJackID = {0x01}},
435 .MIDI_Out_Jack_Endpoint = {.Endpoint = {.Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .EndpointAddress = MIDI_STREAM_IN_EPADDR, .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = MIDI_STREAM_EPSIZE, .PollingIntervalMS = 0x05},
436
437 .Refresh = 0,
438 .SyncEndpointNumber = 0},
439 .MIDI_Out_Jack_Endpoint_SPC = {.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = AUDIO_DTYPE_CSEndpoint}, .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, .TotalEmbeddedJacks = 0x01, .AssociatedJackID = {0x03}},
80d10bef
JG
440#endif
441
442#ifdef VIRTSER_ENABLE
b624f32f 443 /*
444 * Virtual Serial
445 */
446 .CDC_Interface_Association =
447 {
448 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
449 .FirstInterfaceIndex = CCI_INTERFACE,
450 .TotalInterfaces = 2,
451 .Class = CDC_CSCP_CDCClass,
452 .SubClass = CDC_CSCP_ACMSubclass,
453 .Protocol = CDC_CSCP_ATCommandProtocol,
454 .IADStrIndex = NO_DESCRIPTOR,
455 },
456 .CDC_CCI_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .InterfaceNumber = CCI_INTERFACE, .AlternateSetting = 0, .TotalEndpoints = 1, .Class = CDC_CSCP_CDCClass, .SubClass = CDC_CSCP_ACMSubclass, .Protocol = CDC_CSCP_ATCommandProtocol, .InterfaceStrIndex = NO_DESCRIPTOR},
457 .CDC_Functional_Header =
458 {
459 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = CDC_DTYPE_CSInterface},
460 .Subtype = 0x00,
461 .CDCSpecification = VERSION_BCD(1, 1, 0),
462 },
463 .CDC_Functional_ACM =
464 {
465 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = CDC_DTYPE_CSInterface},
466 .Subtype = 0x02,
467 .Capabilities = 0x02,
468 },
469 .CDC_Functional_Union =
470 {
471 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = CDC_DTYPE_CSInterface},
472 .Subtype = 0x06,
473 .MasterInterfaceNumber = CCI_INTERFACE,
474 .SlaveInterfaceNumber = CDI_INTERFACE,
475 },
476 .CDC_NotificationEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = CDC_NOTIFICATION_EPADDR, .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = CDC_NOTIFICATION_EPSIZE, .PollingIntervalMS = 0xFF},
477 .CDC_DCI_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .InterfaceNumber = CDI_INTERFACE, .AlternateSetting = 0, .TotalEndpoints = 2, .Class = CDC_CSCP_CDCDataClass, .SubClass = CDC_CSCP_NoDataSubclass, .Protocol = CDC_CSCP_NoDataProtocol, .InterfaceStrIndex = NO_DESCRIPTOR},
478 .CDC_DataOutEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = CDC_OUT_EPADDR, .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = CDC_EPSIZE, .PollingIntervalMS = 0x05},
479 .CDC_DataInEndpoint = {.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointAddress = CDC_IN_EPADDR, .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = CDC_EPSIZE, .PollingIntervalMS = 0x05},
04885a3b 480#endif
3969ec09 481};
482
ac167268 483/*
484 * String descriptors
485 */
b624f32f 486const USB_Descriptor_String_t PROGMEM LanguageString = {.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .UnicodeString = {LANGUAGE_ID_ENG}};
3969ec09 487
b624f32f 488const USB_Descriptor_String_t PROGMEM ManufacturerString = {.Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1), // Subtract 1 for null terminator
489 .Type = DTYPE_String},
490 .UnicodeString = LSTR(MANUFACTURER)};
3969ec09 491
b624f32f 492const USB_Descriptor_String_t PROGMEM ProductString = {.Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1), // Subtract 1 for null terminator
493 .Type = DTYPE_String},
494 .UnicodeString = LSTR(PRODUCT)};
3969ec09 495
f5a9758c 496#ifndef SERIAL_NUMBER
b624f32f 497# define SERIAL_NUMBER 0
f5a9758c
JH
498#endif
499
b624f32f 500const USB_Descriptor_String_t PROGMEM SerialNumberString = {.Header = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), // Subtract 1 for null terminator
501 .Type = DTYPE_String},
502 .UnicodeString = LSTR(SERIAL_NUMBER)};
f5a9758c 503
ac167268 504/**
505 * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
506 * documentation) by the application code so that the address and size of a requested descriptor can be given
507 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
508 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
509 * USB host.
3969ec09 510 */
ac167268 511uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress) {
512 const uint8_t DescriptorType = (wValue >> 8);
513 const uint8_t DescriptorIndex = (wValue & 0xFF);
514 const void* Address = NULL;
515 uint16_t Size = NO_DESCRIPTOR;
516
517 switch (DescriptorType) {
3969ec09 518 case DTYPE_Device:
519 Address = &DeviceDescriptor;
520 Size = sizeof(USB_Descriptor_Device_t);
ac167268 521
3969ec09 522 break;
523 case DTYPE_Configuration:
524 Address = &ConfigurationDescriptor;
525 Size = sizeof(USB_Descriptor_Configuration_t);
ac167268 526
3969ec09 527 break;
528 case DTYPE_String:
ac167268 529 switch (DescriptorIndex) {
3969ec09 530 case 0x00:
531 Address = &LanguageString;
532 Size = pgm_read_byte(&LanguageString.Header.Size);
ac167268 533
3969ec09 534 break;
535 case 0x01:
536 Address = &ManufacturerString;
537 Size = pgm_read_byte(&ManufacturerString.Header.Size);
ac167268 538
3969ec09 539 break;
540 case 0x02:
541 Address = &ProductString;
542 Size = pgm_read_byte(&ProductString.Header.Size);
ac167268 543
3969ec09 544 break;
f5a9758c
JH
545 case 0x03:
546 Address = &SerialNumberString;
547 Size = pgm_read_byte(&SerialNumberString.Header.Size);
ac167268 548
f5a9758c 549 break;
3969ec09 550 }
ac167268 551
3969ec09 552 break;
553 case HID_DTYPE_HID:
554 switch (wIndex) {
39bd760f 555#ifndef KEYBOARD_SHARED_EP
ac167268 556 case KEYBOARD_INTERFACE:
557 Address = &ConfigurationDescriptor.Keyboard_HID;
558 Size = sizeof(USB_HID_Descriptor_HID_t);
559 break;
39bd760f 560#endif
ac167268 561
39bd760f 562#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
ac167268 563 case MOUSE_INTERFACE:
564 Address = &ConfigurationDescriptor.Mouse_HID;
565 Size = sizeof(USB_HID_Descriptor_HID_t);
566
567 break;
f2ebac10 568#endif
ac167268 569
39bd760f 570#ifdef SHARED_EP_ENABLE
ac167268 571 case SHARED_INTERFACE:
572 Address = &ConfigurationDescriptor.Shared_HID;
573 Size = sizeof(USB_HID_Descriptor_HID_t);
574
575 break;
e075361b 576#endif
ac167268 577
fe001d46 578#ifdef RAW_ENABLE
ac167268 579 case RAW_INTERFACE:
580 Address = &ConfigurationDescriptor.Raw_HID;
581 Size = sizeof(USB_HID_Descriptor_HID_t);
582
583 break;
fe001d46 584#endif
ac167268 585
e075361b 586#ifdef CONSOLE_ENABLE
ac167268 587 case CONSOLE_INTERFACE:
588 Address = &ConfigurationDescriptor.Console_HID;
589 Size = sizeof(USB_HID_Descriptor_HID_t);
590
591 break;
f2ebac10 592#endif
3969ec09 593 }
ac167268 594
3969ec09 595 break;
596 case HID_DTYPE_Report:
597 switch (wIndex) {
39bd760f 598#ifndef KEYBOARD_SHARED_EP
ac167268 599 case KEYBOARD_INTERFACE:
600 Address = &KeyboardReport;
601 Size = sizeof(KeyboardReport);
602
603 break;
39bd760f 604#endif
ac167268 605
39bd760f 606#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
ac167268 607 case MOUSE_INTERFACE:
608 Address = &MouseReport;
609 Size = sizeof(MouseReport);
610
611 break;
f2ebac10 612#endif
ac167268 613
39bd760f 614#ifdef SHARED_EP_ENABLE
ac167268 615 case SHARED_INTERFACE:
616 Address = &SharedReport;
617 Size = sizeof(SharedReport);
618
619 break;
e075361b 620#endif
ac167268 621
fe001d46 622#ifdef RAW_ENABLE
ac167268 623 case RAW_INTERFACE:
624 Address = &RawReport;
625 Size = sizeof(RawReport);
626
627 break;
fe001d46 628#endif
ac167268 629
e075361b 630#ifdef CONSOLE_ENABLE
ac167268 631 case CONSOLE_INTERFACE:
632 Address = &ConsoleReport;
633 Size = sizeof(ConsoleReport);
634
635 break;
f2ebac10 636#endif
3969ec09 637 }
ac167268 638
3969ec09 639 break;
640 }
641
642 *DescriptorAddress = Address;
ac167268 643
3969ec09 644 return Size;
645}