Changed to 1209 PID (#6677)
[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
ac167268 305/*
306 * Configuration descriptors
307 */
b624f32f 308const USB_Descriptor_Configuration_t PROGMEM
309 ConfigurationDescriptor =
310 {
311 .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 312
ac167268 313#ifndef KEYBOARD_SHARED_EP
b624f32f 314 /*
315 * Keyboard
316 */
317 .Keyboard_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
318 .InterfaceNumber = KEYBOARD_INTERFACE,
319 .AlternateSetting = 0x00,
320 .TotalEndpoints = 1,
321 .Class = HID_CSCP_HIDClass,
322 .SubClass = HID_CSCP_BootSubclass,
323 .Protocol = HID_CSCP_KeyboardBootProtocol,
324
325 .InterfaceStrIndex = NO_DESCRIPTOR},
326 .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)},
327 .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 = 0x0A},
39bd760f 328#endif
3969ec09 329
ac167268 330#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
b624f32f 331 /*
332 * Mouse
333 */
334 .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},
335 .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)},
336 .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 = 0x0A},
f2ebac10 337#endif
3969ec09 338
ac167268 339#ifdef SHARED_EP_ENABLE
b624f32f 340 /*
341 * Shared
342 */
343 .Shared_Interface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
344 .InterfaceNumber = SHARED_INTERFACE,
345 .AlternateSetting = 0x00,
346 .TotalEndpoints = 1,
347 .Class = HID_CSCP_HIDClass,
348# ifdef KEYBOARD_SHARED_EP
349 .SubClass = HID_CSCP_BootSubclass,
350 .Protocol = HID_CSCP_KeyboardBootProtocol,
351# else
352 .SubClass = HID_CSCP_NonBootSubclass,
353 .Protocol = HID_CSCP_NonBootProtocol,
354# endif
355 .InterfaceStrIndex = NO_DESCRIPTOR},
356 .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)},
357 .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 = 0x0A},
ac167268 358#endif
3969ec09 359
ac167268 360#ifdef RAW_ENABLE
b624f32f 361 /*
362 * Raw HID
363 */
364 .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},
365 .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)},
366 .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},
367 .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 368#endif
3d81d522 369
ac167268 370#ifdef CONSOLE_ENABLE
b624f32f 371 /*
372 * Console
373 */
374 .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},
375 .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)},
376 .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},
377 .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 378#endif
daa4a423 379
04885a3b 380#ifdef MIDI_ENABLE
b624f32f 381 /*
382 * MIDI
383 */
384 .Audio_Interface_Association =
385 {
386 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
387 .FirstInterfaceIndex = AC_INTERFACE,
388 .TotalInterfaces = 2,
389 .Class = AUDIO_CSCP_AudioClass,
390 .SubClass = AUDIO_CSCP_ControlSubclass,
391 .Protocol = AUDIO_CSCP_ControlProtocol,
392 .IADStrIndex = NO_DESCRIPTOR,
393 },
394 .Audio_ControlInterface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
395
396 .InterfaceNumber = AC_INTERFACE,
397 .AlternateSetting = 0,
398 .TotalEndpoints = 0,
399 .Class = AUDIO_CSCP_AudioClass,
400 .SubClass = AUDIO_CSCP_ControlSubclass,
401 .Protocol = AUDIO_CSCP_ControlProtocol,
402 .InterfaceStrIndex = NO_DESCRIPTOR},
403 .Audio_ControlInterface_SPC =
404 {
405 .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = AUDIO_DTYPE_CSInterface},
406 .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
407 .ACSpecification = VERSION_BCD(1, 0, 0),
408 .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
409 .InCollection = 1,
410 .InterfaceNumber = AS_INTERFACE,
411 },
412 .Audio_StreamInterface = {.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
413
414 .InterfaceNumber = AS_INTERFACE,
415 .AlternateSetting = 0,
416 .TotalEndpoints = 2,
417 .Class = AUDIO_CSCP_AudioClass,
418 .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
419 .Protocol = AUDIO_CSCP_StreamingProtocol,
420 .InterfaceStrIndex = NO_DESCRIPTOR},
421 .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)},
422 .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},
423 .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},
424 .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},
425 .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},
426 .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},
427
428 .Refresh = 0,
429 .SyncEndpointNumber = 0},
430 .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}},
431 .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},
432
433 .Refresh = 0,
434 .SyncEndpointNumber = 0},
435 .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
436#endif
437
438#ifdef VIRTSER_ENABLE
b624f32f 439 /*
440 * Virtual Serial
441 */
442 .CDC_Interface_Association =
443 {
444 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
445 .FirstInterfaceIndex = CCI_INTERFACE,
446 .TotalInterfaces = 2,
447 .Class = CDC_CSCP_CDCClass,
448 .SubClass = CDC_CSCP_ACMSubclass,
449 .Protocol = CDC_CSCP_ATCommandProtocol,
450 .IADStrIndex = NO_DESCRIPTOR,
451 },
452 .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},
453 .CDC_Functional_Header =
454 {
455 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = CDC_DTYPE_CSInterface},
456 .Subtype = 0x00,
457 .CDCSpecification = VERSION_BCD(1, 1, 0),
458 },
459 .CDC_Functional_ACM =
460 {
461 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = CDC_DTYPE_CSInterface},
462 .Subtype = 0x02,
463 .Capabilities = 0x02,
464 },
465 .CDC_Functional_Union =
466 {
467 .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = CDC_DTYPE_CSInterface},
468 .Subtype = 0x06,
469 .MasterInterfaceNumber = CCI_INTERFACE,
470 .SlaveInterfaceNumber = CDI_INTERFACE,
471 },
472 .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},
473 .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},
474 .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},
475 .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 476#endif
3969ec09 477};
478
ac167268 479/*
480 * String descriptors
481 */
b624f32f 482const USB_Descriptor_String_t PROGMEM LanguageString = {.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .UnicodeString = {LANGUAGE_ID_ENG}};
3969ec09 483
b624f32f 484const USB_Descriptor_String_t PROGMEM ManufacturerString = {.Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1), // Subtract 1 for null terminator
485 .Type = DTYPE_String},
486 .UnicodeString = LSTR(MANUFACTURER)};
3969ec09 487
b624f32f 488const USB_Descriptor_String_t PROGMEM ProductString = {.Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1), // Subtract 1 for null terminator
489 .Type = DTYPE_String},
490 .UnicodeString = LSTR(PRODUCT)};
3969ec09 491
f5a9758c 492#ifndef SERIAL_NUMBER
b624f32f 493# define SERIAL_NUMBER 0
f5a9758c
JH
494#endif
495
b624f32f 496const USB_Descriptor_String_t PROGMEM SerialNumberString = {.Header = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), // Subtract 1 for null terminator
497 .Type = DTYPE_String},
498 .UnicodeString = LSTR(SERIAL_NUMBER)};
f5a9758c 499
ac167268 500/**
501 * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
502 * documentation) by the application code so that the address and size of a requested descriptor can be given
503 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
504 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
505 * USB host.
3969ec09 506 */
ac167268 507uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress) {
508 const uint8_t DescriptorType = (wValue >> 8);
509 const uint8_t DescriptorIndex = (wValue & 0xFF);
510 const void* Address = NULL;
511 uint16_t Size = NO_DESCRIPTOR;
512
513 switch (DescriptorType) {
3969ec09 514 case DTYPE_Device:
515 Address = &DeviceDescriptor;
516 Size = sizeof(USB_Descriptor_Device_t);
ac167268 517
3969ec09 518 break;
519 case DTYPE_Configuration:
520 Address = &ConfigurationDescriptor;
521 Size = sizeof(USB_Descriptor_Configuration_t);
ac167268 522
3969ec09 523 break;
524 case DTYPE_String:
ac167268 525 switch (DescriptorIndex) {
3969ec09 526 case 0x00:
527 Address = &LanguageString;
528 Size = pgm_read_byte(&LanguageString.Header.Size);
ac167268 529
3969ec09 530 break;
531 case 0x01:
532 Address = &ManufacturerString;
533 Size = pgm_read_byte(&ManufacturerString.Header.Size);
ac167268 534
3969ec09 535 break;
536 case 0x02:
537 Address = &ProductString;
538 Size = pgm_read_byte(&ProductString.Header.Size);
ac167268 539
3969ec09 540 break;
f5a9758c
JH
541 case 0x03:
542 Address = &SerialNumberString;
543 Size = pgm_read_byte(&SerialNumberString.Header.Size);
ac167268 544
f5a9758c 545 break;
3969ec09 546 }
ac167268 547
3969ec09 548 break;
549 case HID_DTYPE_HID:
550 switch (wIndex) {
39bd760f 551#ifndef KEYBOARD_SHARED_EP
ac167268 552 case KEYBOARD_INTERFACE:
553 Address = &ConfigurationDescriptor.Keyboard_HID;
554 Size = sizeof(USB_HID_Descriptor_HID_t);
555 break;
39bd760f 556#endif
ac167268 557
39bd760f 558#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
ac167268 559 case MOUSE_INTERFACE:
560 Address = &ConfigurationDescriptor.Mouse_HID;
561 Size = sizeof(USB_HID_Descriptor_HID_t);
562
563 break;
f2ebac10 564#endif
ac167268 565
39bd760f 566#ifdef SHARED_EP_ENABLE
ac167268 567 case SHARED_INTERFACE:
568 Address = &ConfigurationDescriptor.Shared_HID;
569 Size = sizeof(USB_HID_Descriptor_HID_t);
570
571 break;
e075361b 572#endif
ac167268 573
fe001d46 574#ifdef RAW_ENABLE
ac167268 575 case RAW_INTERFACE:
576 Address = &ConfigurationDescriptor.Raw_HID;
577 Size = sizeof(USB_HID_Descriptor_HID_t);
578
579 break;
fe001d46 580#endif
ac167268 581
e075361b 582#ifdef CONSOLE_ENABLE
ac167268 583 case CONSOLE_INTERFACE:
584 Address = &ConfigurationDescriptor.Console_HID;
585 Size = sizeof(USB_HID_Descriptor_HID_t);
586
587 break;
f2ebac10 588#endif
3969ec09 589 }
ac167268 590
3969ec09 591 break;
592 case HID_DTYPE_Report:
593 switch (wIndex) {
39bd760f 594#ifndef KEYBOARD_SHARED_EP
ac167268 595 case KEYBOARD_INTERFACE:
596 Address = &KeyboardReport;
597 Size = sizeof(KeyboardReport);
598
599 break;
39bd760f 600#endif
ac167268 601
39bd760f 602#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
ac167268 603 case MOUSE_INTERFACE:
604 Address = &MouseReport;
605 Size = sizeof(MouseReport);
606
607 break;
f2ebac10 608#endif
ac167268 609
39bd760f 610#ifdef SHARED_EP_ENABLE
ac167268 611 case SHARED_INTERFACE:
612 Address = &SharedReport;
613 Size = sizeof(SharedReport);
614
615 break;
e075361b 616#endif
ac167268 617
fe001d46 618#ifdef RAW_ENABLE
ac167268 619 case RAW_INTERFACE:
620 Address = &RawReport;
621 Size = sizeof(RawReport);
622
623 break;
fe001d46 624#endif
ac167268 625
e075361b 626#ifdef CONSOLE_ENABLE
ac167268 627 case CONSOLE_INTERFACE:
628 Address = &ConsoleReport;
629 Size = sizeof(ConsoleReport);
630
631 break;
f2ebac10 632#endif
3969ec09 633 }
ac167268 634
3969ec09 635 break;
636 }
637
638 *DescriptorAddress = Address;
ac167268 639
3969ec09 640 return Size;
641}