Commit | Line | Data |
---|---|---|
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 | ******************************************************************************/ | |
47 | const 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 | 87 | const 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 | 137 | const 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 |
168 | const 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 |
190 | const 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 | ******************************************************************************/ | |
229 | const 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), |
3969ec09 | 234 | .Class = USB_CSCP_NoDeviceClass, |
235 | .SubClass = USB_CSCP_NoDeviceSubclass, | |
236 | .Protocol = USB_CSCP_NoDeviceProtocol, | |
237 | ||
3c5add5f | 238 | .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, |
3969ec09 | 239 | |
1348663a | 240 | /* specified in config.h */ |
effa5914 | 241 | .VendorID = VENDOR_ID, |
242 | .ProductID = PRODUCT_ID, | |
243 | .ReleaseNumber = DEVICE_VER, | |
3969ec09 | 244 | |
245 | .ManufacturerStrIndex = 0x01, | |
246 | .ProductStrIndex = 0x02, | |
247 | .SerialNumStrIndex = NO_DESCRIPTOR, | |
248 | ||
3c5add5f | 249 | .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS |
3969ec09 | 250 | }; |
251 | ||
252 | /******************************************************************************* | |
253 | * Configuration Descriptors | |
254 | ******************************************************************************/ | |
255 | const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = | |
256 | { | |
257 | .Config = | |
258 | { | |
259 | .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | |
260 | ||
261 | .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | |
3d81d522 | 262 | .TotalInterfaces = TOTAL_INTERFACES, |
3969ec09 | 263 | |
264 | .ConfigurationNumber = 1, | |
265 | .ConfigurationStrIndex = NO_DESCRIPTOR, | |
266 | ||
effa5914 | 267 | .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP), |
3969ec09 | 268 | |
c966e798 | 269 | .MaxPowerConsumption = USB_CONFIG_POWER_MA(500) |
3969ec09 | 270 | }, |
271 | ||
3d81d522 | 272 | /* |
273 | * Keyboard | |
274 | */ | |
a9a3610d | 275 | .Keyboard_Interface = |
3969ec09 | 276 | { |
277 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
278 | ||
effa5914 | 279 | .InterfaceNumber = KEYBOARD_INTERFACE, |
3969ec09 | 280 | .AlternateSetting = 0x00, |
281 | ||
effa5914 | 282 | .TotalEndpoints = 1, |
3969ec09 | 283 | |
284 | .Class = HID_CSCP_HIDClass, | |
285 | .SubClass = HID_CSCP_BootSubclass, | |
286 | .Protocol = HID_CSCP_KeyboardBootProtocol, | |
287 | ||
288 | .InterfaceStrIndex = NO_DESCRIPTOR | |
289 | }, | |
290 | ||
a9a3610d | 291 | .Keyboard_HID = |
3969ec09 | 292 | { |
293 | .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, | |
294 | ||
fc3a20c5 | 295 | .HIDSpec = VERSION_BCD(1,1,1), |
3969ec09 | 296 | .CountryCode = 0x00, |
297 | .TotalReportDescriptors = 1, | |
298 | .HIDReportType = HID_DTYPE_Report, | |
299 | .HIDReportLength = sizeof(KeyboardReport) | |
300 | }, | |
301 | ||
a9a3610d | 302 | .Keyboard_INEndpoint = |
3969ec09 | 303 | { |
304 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
305 | ||
306 | .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM), | |
307 | .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |
3d81d522 | 308 | .EndpointSize = KEYBOARD_EPSIZE, |
c6902681 | 309 | .PollingIntervalMS = 0x0A |
3969ec09 | 310 | }, |
311 | ||
3969ec09 | 312 | /* |
313 | * Mouse | |
314 | */ | |
f2ebac10 | 315 | #ifdef MOUSE_ENABLE |
a9a3610d | 316 | .Mouse_Interface = |
3969ec09 | 317 | { |
318 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
319 | ||
effa5914 | 320 | .InterfaceNumber = MOUSE_INTERFACE, |
3969ec09 | 321 | .AlternateSetting = 0x00, |
322 | ||
323 | .TotalEndpoints = 1, | |
324 | ||
325 | .Class = HID_CSCP_HIDClass, | |
326 | .SubClass = HID_CSCP_BootSubclass, | |
327 | .Protocol = HID_CSCP_MouseBootProtocol, | |
328 | ||
329 | .InterfaceStrIndex = NO_DESCRIPTOR | |
330 | }, | |
331 | ||
a9a3610d | 332 | .Mouse_HID = |
3969ec09 | 333 | { |
334 | .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, | |
335 | ||
fc3a20c5 | 336 | .HIDSpec = VERSION_BCD(1,1,1), |
3969ec09 | 337 | .CountryCode = 0x00, |
338 | .TotalReportDescriptors = 1, | |
339 | .HIDReportType = HID_DTYPE_Report, | |
340 | .HIDReportLength = sizeof(MouseReport) | |
341 | }, | |
342 | ||
a9a3610d | 343 | .Mouse_INEndpoint = |
3969ec09 | 344 | { |
345 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
346 | ||
347 | .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM), | |
348 | .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |
3d81d522 | 349 | .EndpointSize = MOUSE_EPSIZE, |
a5d4a1f3 | 350 | .PollingIntervalMS = 0x0A |
3969ec09 | 351 | }, |
f2ebac10 | 352 | #endif |
3969ec09 | 353 | |
354 | /* | |
e075361b | 355 | * Extra |
3969ec09 | 356 | */ |
e075361b | 357 | #ifdef EXTRAKEY_ENABLE |
358 | .Extrakey_Interface = | |
3969ec09 | 359 | { |
360 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
361 | ||
e075361b | 362 | .InterfaceNumber = EXTRAKEY_INTERFACE, |
3969ec09 | 363 | .AlternateSetting = 0x00, |
364 | ||
e075361b | 365 | .TotalEndpoints = 1, |
3969ec09 | 366 | |
367 | .Class = HID_CSCP_HIDClass, | |
368 | .SubClass = HID_CSCP_NonBootSubclass, | |
369 | .Protocol = HID_CSCP_NonBootProtocol, | |
370 | ||
371 | .InterfaceStrIndex = NO_DESCRIPTOR | |
372 | }, | |
373 | ||
e075361b | 374 | .Extrakey_HID = |
3969ec09 | 375 | { |
376 | .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, | |
377 | ||
fc3a20c5 | 378 | .HIDSpec = VERSION_BCD(1,1,1), |
3969ec09 | 379 | .CountryCode = 0x00, |
380 | .TotalReportDescriptors = 1, | |
381 | .HIDReportType = HID_DTYPE_Report, | |
e075361b | 382 | .HIDReportLength = sizeof(ExtrakeyReport) |
3969ec09 | 383 | }, |
384 | ||
e075361b | 385 | .Extrakey_INEndpoint = |
3969ec09 | 386 | { |
387 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
388 | ||
e075361b | 389 | .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM), |
3969ec09 | 390 | .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), |
e075361b | 391 | .EndpointSize = EXTRAKEY_EPSIZE, |
a5d4a1f3 | 392 | .PollingIntervalMS = 0x0A |
3d81d522 | 393 | }, |
e075361b | 394 | #endif |
3d81d522 | 395 | |
396 | /* | |
e075361b | 397 | * Console |
3d81d522 | 398 | */ |
e075361b | 399 | #ifdef CONSOLE_ENABLE |
400 | .Console_Interface = | |
3d81d522 | 401 | { |
402 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
403 | ||
e075361b | 404 | .InterfaceNumber = CONSOLE_INTERFACE, |
3d81d522 | 405 | .AlternateSetting = 0x00, |
406 | ||
e075361b | 407 | .TotalEndpoints = 2, |
3d81d522 | 408 | |
409 | .Class = HID_CSCP_HIDClass, | |
410 | .SubClass = HID_CSCP_NonBootSubclass, | |
411 | .Protocol = HID_CSCP_NonBootProtocol, | |
412 | ||
413 | .InterfaceStrIndex = NO_DESCRIPTOR | |
414 | }, | |
415 | ||
e075361b | 416 | .Console_HID = |
3d81d522 | 417 | { |
418 | .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, | |
419 | ||
fc3a20c5 | 420 | .HIDSpec = VERSION_BCD(1,1,1), |
3d81d522 | 421 | .CountryCode = 0x00, |
422 | .TotalReportDescriptors = 1, | |
423 | .HIDReportType = HID_DTYPE_Report, | |
e075361b | 424 | .HIDReportLength = sizeof(ConsoleReport) |
3d81d522 | 425 | }, |
426 | ||
e075361b | 427 | .Console_INEndpoint = |
3d81d522 | 428 | { |
429 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
430 | ||
e075361b | 431 | .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM), |
3969ec09 | 432 | .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), |
e075361b | 433 | .EndpointSize = CONSOLE_EPSIZE, |
434 | .PollingIntervalMS = 0x01 | |
435 | }, | |
436 | ||
437 | .Console_OUTEndpoint = | |
438 | { | |
439 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
440 | ||
441 | .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM), | |
442 | .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |
443 | .EndpointSize = CONSOLE_EPSIZE, | |
3969ec09 | 444 | .PollingIntervalMS = 0x01 |
3d81d522 | 445 | }, |
f2ebac10 | 446 | #endif |
daa4a423 | 447 | |
448 | /* | |
449 | * NKRO | |
450 | */ | |
451 | #ifdef NKRO_ENABLE | |
452 | .NKRO_Interface = | |
453 | { | |
454 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
455 | ||
456 | .InterfaceNumber = NKRO_INTERFACE, | |
457 | .AlternateSetting = 0x00, | |
458 | ||
459 | .TotalEndpoints = 1, | |
460 | ||
461 | .Class = HID_CSCP_HIDClass, | |
462 | .SubClass = HID_CSCP_NonBootSubclass, | |
463 | .Protocol = HID_CSCP_NonBootProtocol, | |
464 | ||
465 | .InterfaceStrIndex = NO_DESCRIPTOR | |
466 | }, | |
467 | ||
468 | .NKRO_HID = | |
469 | { | |
470 | .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, | |
471 | ||
fc3a20c5 | 472 | .HIDSpec = VERSION_BCD(1,1,1), |
daa4a423 | 473 | .CountryCode = 0x00, |
474 | .TotalReportDescriptors = 1, | |
475 | .HIDReportType = HID_DTYPE_Report, | |
476 | .HIDReportLength = sizeof(NKROReport) | |
477 | }, | |
478 | ||
479 | .NKRO_INEndpoint = | |
480 | { | |
481 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
482 | ||
483 | .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM), | |
484 | .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |
485 | .EndpointSize = NKRO_EPSIZE, | |
486 | .PollingIntervalMS = 0x01 | |
487 | }, | |
488 | #endif | |
e528087e | 489 | |
04885a3b | 490 | #ifdef MIDI_ENABLE |
e528087e JH |
491 | .Audio_ControlInterface = |
492 | { | |
493 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
494 | ||
cda23c75 | 495 | .InterfaceNumber = AC_INTERFACE, |
e528087e JH |
496 | .AlternateSetting = 0, |
497 | ||
498 | .TotalEndpoints = 0, | |
499 | ||
500 | .Class = AUDIO_CSCP_AudioClass, | |
501 | .SubClass = AUDIO_CSCP_ControlSubclass, | |
502 | .Protocol = AUDIO_CSCP_ControlProtocol, | |
503 | ||
504 | .InterfaceStrIndex = NO_DESCRIPTOR | |
505 | }, | |
506 | ||
507 | .Audio_ControlInterface_SPC = | |
508 | { | |
509 | .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface}, | |
510 | .Subtype = AUDIO_DSUBTYPE_CSInterface_Header, | |
511 | ||
04885a3b | 512 | .ACSpecification = VERSION_BCD(1,0,0), |
e528087e JH |
513 | .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t), |
514 | ||
515 | .InCollection = 1, | |
cda23c75 | 516 | .InterfaceNumber = AS_INTERFACE, |
e528087e JH |
517 | }, |
518 | ||
519 | .Audio_StreamInterface = | |
520 | { | |
521 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
522 | ||
cda23c75 | 523 | .InterfaceNumber = AS_INTERFACE, |
e528087e JH |
524 | .AlternateSetting = 0, |
525 | ||
526 | .TotalEndpoints = 2, | |
527 | ||
528 | .Class = AUDIO_CSCP_AudioClass, | |
529 | .SubClass = AUDIO_CSCP_MIDIStreamingSubclass, | |
530 | .Protocol = AUDIO_CSCP_StreamingProtocol, | |
531 | ||
532 | .InterfaceStrIndex = NO_DESCRIPTOR | |
533 | }, | |
534 | ||
535 | .Audio_StreamInterface_SPC = | |
536 | { | |
537 | .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface}, | |
538 | .Subtype = AUDIO_DSUBTYPE_CSInterface_General, | |
539 | ||
04885a3b | 540 | .AudioSpecification = VERSION_BCD(1,0,0), |
e528087e JH |
541 | |
542 | .TotalLength = (sizeof(USB_Descriptor_Configuration_t) - | |
543 | offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)) | |
544 | }, | |
545 | ||
546 | .MIDI_In_Jack_Emb = | |
547 | { | |
548 | .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface}, | |
549 | .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, | |
550 | ||
551 | .JackType = MIDI_JACKTYPE_Embedded, | |
552 | .JackID = 0x01, | |
553 | ||
554 | .JackStrIndex = NO_DESCRIPTOR | |
555 | }, | |
556 | ||
557 | .MIDI_In_Jack_Ext = | |
558 | { | |
559 | .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface}, | |
560 | .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, | |
561 | ||
562 | .JackType = MIDI_JACKTYPE_External, | |
563 | .JackID = 0x02, | |
564 | ||
565 | .JackStrIndex = NO_DESCRIPTOR | |
566 | }, | |
567 | ||
568 | .MIDI_Out_Jack_Emb = | |
569 | { | |
570 | .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface}, | |
571 | .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, | |
572 | ||
573 | .JackType = MIDI_JACKTYPE_Embedded, | |
574 | .JackID = 0x03, | |
575 | ||
576 | .NumberOfPins = 1, | |
577 | .SourceJackID = {0x02}, | |
578 | .SourcePinID = {0x01}, | |
579 | ||
580 | .JackStrIndex = NO_DESCRIPTOR | |
581 | }, | |
582 | ||
583 | .MIDI_Out_Jack_Ext = | |
584 | { | |
585 | .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface}, | |
586 | .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, | |
587 | ||
588 | .JackType = MIDI_JACKTYPE_External, | |
589 | .JackID = 0x04, | |
590 | ||
591 | .NumberOfPins = 1, | |
592 | .SourceJackID = {0x01}, | |
593 | .SourcePinID = {0x01}, | |
594 | ||
595 | .JackStrIndex = NO_DESCRIPTOR | |
596 | }, | |
597 | ||
598 | .MIDI_In_Jack_Endpoint = | |
599 | { | |
600 | .Endpoint = | |
601 | { | |
602 | .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, | |
603 | ||
cda23c75 | 604 | .EndpointAddress = MIDI_STREAM_OUT_EPADDR, |
e528087e JH |
605 | .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), |
606 | .EndpointSize = MIDI_STREAM_EPSIZE, | |
04885a3b | 607 | .PollingIntervalMS = 0x05 |
e528087e JH |
608 | }, |
609 | ||
610 | .Refresh = 0, | |
611 | .SyncEndpointNumber = 0 | |
612 | }, | |
613 | ||
614 | .MIDI_In_Jack_Endpoint_SPC = | |
615 | { | |
616 | .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint}, | |
617 | .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, | |
618 | ||
619 | .TotalEmbeddedJacks = 0x01, | |
620 | .AssociatedJackID = {0x01} | |
621 | }, | |
622 | ||
623 | .MIDI_Out_Jack_Endpoint = | |
624 | { | |
625 | .Endpoint = | |
626 | { | |
627 | .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, | |
628 | ||
cda23c75 | 629 | .EndpointAddress = MIDI_STREAM_IN_EPADDR, |
e528087e JH |
630 | .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), |
631 | .EndpointSize = MIDI_STREAM_EPSIZE, | |
04885a3b | 632 | .PollingIntervalMS = 0x05 |
e528087e JH |
633 | }, |
634 | ||
635 | .Refresh = 0, | |
636 | .SyncEndpointNumber = 0 | |
637 | }, | |
638 | ||
639 | .MIDI_Out_Jack_Endpoint_SPC = | |
640 | { | |
641 | .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint}, | |
642 | .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, | |
643 | ||
644 | .TotalEmbeddedJacks = 0x01, | |
645 | .AssociatedJackID = {0x03} | |
646 | } | |
04885a3b | 647 | #endif |
3969ec09 | 648 | }; |
649 | ||
650 | ||
651 | /******************************************************************************* | |
652 | * String Descriptors | |
653 | ******************************************************************************/ | |
654 | const USB_Descriptor_String_t PROGMEM LanguageString = | |
655 | { | |
656 | .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, | |
657 | ||
658 | .UnicodeString = {LANGUAGE_ID_ENG} | |
659 | }; | |
660 | ||
661 | const USB_Descriptor_String_t PROGMEM ManufacturerString = | |
662 | { | |
1348663a | 663 | /* subtract 1 for null terminator */ |
664 | .Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String}, | |
3969ec09 | 665 | |
effa5914 | 666 | .UnicodeString = LSTR(MANUFACTURER) |
3969ec09 | 667 | }; |
668 | ||
669 | const USB_Descriptor_String_t PROGMEM ProductString = | |
670 | { | |
1348663a | 671 | /* subtract 1 for null terminator */ |
672 | .Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String}, | |
3969ec09 | 673 | |
effa5914 | 674 | .UnicodeString = LSTR(PRODUCT) |
3969ec09 | 675 | }; |
676 | ||
677 | ||
678 | /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | |
679 | * documentation) by the application code so that the address and size of a requested descriptor can be given | |
680 | * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | |
681 | * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | |
682 | * USB host. | |
683 | */ | |
684 | uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |
685 | const uint8_t wIndex, | |
686 | const void** const DescriptorAddress) | |
687 | { | |
688 | const uint8_t DescriptorType = (wValue >> 8); | |
689 | const uint8_t DescriptorIndex = (wValue & 0xFF); | |
690 | ||
691 | const void* Address = NULL; | |
692 | uint16_t Size = NO_DESCRIPTOR; | |
693 | ||
694 | switch (DescriptorType) | |
695 | { | |
696 | case DTYPE_Device: | |
697 | Address = &DeviceDescriptor; | |
698 | Size = sizeof(USB_Descriptor_Device_t); | |
699 | break; | |
700 | case DTYPE_Configuration: | |
701 | Address = &ConfigurationDescriptor; | |
702 | Size = sizeof(USB_Descriptor_Configuration_t); | |
703 | break; | |
704 | case DTYPE_String: | |
705 | switch (DescriptorIndex ) | |
706 | { | |
707 | case 0x00: | |
708 | Address = &LanguageString; | |
709 | Size = pgm_read_byte(&LanguageString.Header.Size); | |
710 | break; | |
711 | case 0x01: | |
712 | Address = &ManufacturerString; | |
713 | Size = pgm_read_byte(&ManufacturerString.Header.Size); | |
714 | break; | |
715 | case 0x02: | |
716 | Address = &ProductString; | |
717 | Size = pgm_read_byte(&ProductString.Header.Size); | |
718 | break; | |
719 | } | |
720 | break; | |
721 | case HID_DTYPE_HID: | |
722 | switch (wIndex) { | |
effa5914 | 723 | case KEYBOARD_INTERFACE: |
a9a3610d | 724 | Address = &ConfigurationDescriptor.Keyboard_HID; |
3969ec09 | 725 | Size = sizeof(USB_HID_Descriptor_HID_t); |
726 | break; | |
f2ebac10 | 727 | #ifdef MOUSE_ENABLE |
effa5914 | 728 | case MOUSE_INTERFACE: |
a9a3610d | 729 | Address = &ConfigurationDescriptor.Mouse_HID; |
3969ec09 | 730 | Size = sizeof(USB_HID_Descriptor_HID_t); |
731 | break; | |
f2ebac10 | 732 | #endif |
e075361b | 733 | #ifdef EXTRAKEY_ENABLE |
734 | case EXTRAKEY_INTERFACE: | |
735 | Address = &ConfigurationDescriptor.Extrakey_HID; | |
3969ec09 | 736 | Size = sizeof(USB_HID_Descriptor_HID_t); |
737 | break; | |
e075361b | 738 | #endif |
739 | #ifdef CONSOLE_ENABLE | |
740 | case CONSOLE_INTERFACE: | |
741 | Address = &ConfigurationDescriptor.Console_HID; | |
3d81d522 | 742 | Size = sizeof(USB_HID_Descriptor_HID_t); |
743 | break; | |
daa4a423 | 744 | #endif |
745 | #ifdef NKRO_ENABLE | |
746 | case NKRO_INTERFACE: | |
747 | Address = &ConfigurationDescriptor.NKRO_HID; | |
748 | Size = sizeof(USB_HID_Descriptor_HID_t); | |
749 | break; | |
f2ebac10 | 750 | #endif |
3969ec09 | 751 | } |
752 | break; | |
753 | case HID_DTYPE_Report: | |
754 | switch (wIndex) { | |
effa5914 | 755 | case KEYBOARD_INTERFACE: |
3969ec09 | 756 | Address = &KeyboardReport; |
757 | Size = sizeof(KeyboardReport); | |
758 | break; | |
f2ebac10 | 759 | #ifdef MOUSE_ENABLE |
effa5914 | 760 | case MOUSE_INTERFACE: |
3969ec09 | 761 | Address = &MouseReport; |
762 | Size = sizeof(MouseReport); | |
763 | break; | |
f2ebac10 | 764 | #endif |
e075361b | 765 | #ifdef EXTRAKEY_ENABLE |
766 | case EXTRAKEY_INTERFACE: | |
767 | Address = &ExtrakeyReport; | |
768 | Size = sizeof(ExtrakeyReport); | |
769 | break; | |
770 | #endif | |
771 | #ifdef CONSOLE_ENABLE | |
3d81d522 | 772 | case CONSOLE_INTERFACE: |
a9a3610d | 773 | Address = &ConsoleReport; |
774 | Size = sizeof(ConsoleReport); | |
3969ec09 | 775 | break; |
daa4a423 | 776 | #endif |
777 | #ifdef NKRO_ENABLE | |
778 | case NKRO_INTERFACE: | |
779 | Address = &NKROReport; | |
780 | Size = sizeof(NKROReport); | |
781 | break; | |
f2ebac10 | 782 | #endif |
3969ec09 | 783 | } |
784 | break; | |
785 | } | |
786 | ||
787 | *DescriptorAddress = Address; | |
788 | return Size; | |
789 | } |