]> git.gir.st - tmk_keyboard.git/blob - keyboard/lufa/descriptor.c
Add LUFA mouse feature and fix mouse report.
[tmk_keyboard.git] / keyboard / lufa / descriptor.c
1 /*
2 * Copyright 2012 Jun Wako <wakojun@gmail.com>
3 * This file is based on:
4 * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
5 * LUFA-120219/Demos/Device/Lowlevel/GenericHID
6 */
7
8 /*
9 LUFA Library
10 Copyright (C) Dean Camera, 2012.
11
12 dean [at] fourwalledcubicle [dot] com
13 www.lufa-lib.org
14 */
15
16 /*
17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
19
20 Permission to use, copy, modify, distribute, and sell this
21 software and its documentation for any purpose is hereby granted
22 without fee, provided that the above copyright notice appear in
23 all copies and that both that the copyright notice and this
24 permission notice and warranty disclaimer appear in supporting
25 documentation, and that the name of the author not be used in
26 advertising or publicity pertaining to distribution of the
27 software without specific, written prior permission.
28
29 The author disclaim all warranties with regard to this
30 software, including all implied warranties of merchantability
31 and fitness. In no event shall the author be liable for any
32 special, indirect or consequential damages or any damages
33 whatsoever resulting from loss of use, data or profits, whether
34 in an action of contract, negligence or other tortious action,
35 arising out of or in connection with the use or performance of
36 this software.
37 */
38
39 #include "util.h"
40 #include "descriptor.h"
41
42
43 /*******************************************************************************
44 * HID Report Descriptors
45 ******************************************************************************/
46 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
47 {
48 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
49 HID_RI_USAGE(8, 0x06), /* Keyboard */
50 HID_RI_COLLECTION(8, 0x01), /* Application */
51 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
52 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
53 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
54 HID_RI_LOGICAL_MINIMUM(8, 0x00),
55 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
56 HID_RI_REPORT_SIZE(8, 0x01),
57 HID_RI_REPORT_COUNT(8, 0x08),
58 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
59 HID_RI_REPORT_COUNT(8, 0x01),
60 HID_RI_REPORT_SIZE(8, 0x08),
61 HID_RI_INPUT(8, HID_IOF_CONSTANT),
62 HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
63 HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
64 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
65 HID_RI_REPORT_COUNT(8, 0x05),
66 HID_RI_REPORT_SIZE(8, 0x01),
67 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
68 HID_RI_REPORT_COUNT(8, 0x01),
69 HID_RI_REPORT_SIZE(8, 0x03),
70 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
71 HID_RI_LOGICAL_MINIMUM(8, 0x00),
72 HID_RI_LOGICAL_MAXIMUM(8, 0x65),
73 HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
74 HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
75 HID_RI_USAGE_MAXIMUM(8, 0x65), /* Keyboard Application */
76 HID_RI_REPORT_COUNT(8, 0x06),
77 HID_RI_REPORT_SIZE(8, 0x08),
78 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
79 HID_RI_END_COLLECTION(0),
80 };
81
82 const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
83 {
84 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
85 HID_RI_USAGE(8, 0x02), /* Mouse */
86 HID_RI_COLLECTION(8, 0x01), /* Application */
87 HID_RI_USAGE(8, 0x01), /* Pointer */
88 HID_RI_COLLECTION(8, 0x00), /* Physical */
89 HID_RI_USAGE_PAGE(8, 0x09), /* Button */
90 HID_RI_USAGE_MINIMUM(8, 0x01),
91 HID_RI_USAGE_MAXIMUM(8, 0x03),
92 HID_RI_LOGICAL_MINIMUM(8, 0x00),
93 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
94 HID_RI_REPORT_COUNT(8, 0x03),
95 HID_RI_REPORT_SIZE(8, 0x01),
96 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
97 HID_RI_REPORT_COUNT(8, 0x01),
98 HID_RI_REPORT_SIZE(8, 0x05),
99 HID_RI_INPUT(8, HID_IOF_CONSTANT),
100 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
101 HID_RI_USAGE(8, 0x30), /* Usage X */
102 HID_RI_USAGE(8, 0x31), /* Usage Y */
103 HID_RI_LOGICAL_MINIMUM(8, -1),
104 HID_RI_LOGICAL_MAXIMUM(8, 1),
105 HID_RI_PHYSICAL_MINIMUM(8, -1),
106 HID_RI_PHYSICAL_MAXIMUM(8, 1),
107 HID_RI_REPORT_COUNT(8, 0x02),
108 HID_RI_REPORT_SIZE(8, 0x08),
109 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
110 HID_RI_END_COLLECTION(0),
111 HID_RI_END_COLLECTION(0),
112 };
113
114 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
115 {
116 HID_RI_USAGE_PAGE(16, 0xFF00), /* Vendor Page 0 */
117 HID_RI_USAGE(8, 0x01), /* Vendor Usage 1 */
118 HID_RI_COLLECTION(8, 0x01), /* Vendor Usage 1 */
119 HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */
120 HID_RI_LOGICAL_MINIMUM(8, 0x00),
121 HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
122 HID_RI_REPORT_SIZE(8, 0x08),
123 HID_RI_REPORT_COUNT(8, GENERIC_REPORT_SIZE),
124 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
125 HID_RI_USAGE(8, 0x03), /* Vendor Usage 3 */
126 HID_RI_LOGICAL_MINIMUM(8, 0x00),
127 HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
128 HID_RI_REPORT_SIZE(8, 0x08),
129 HID_RI_REPORT_COUNT(8, GENERIC_REPORT_SIZE),
130 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
131 HID_RI_END_COLLECTION(0),
132 };
133
134
135 /*******************************************************************************
136 * Device Descriptors
137 ******************************************************************************/
138 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
139 {
140 .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
141
142 .USBSpecification = VERSION_BCD(01.10),
143 .Class = USB_CSCP_NoDeviceClass,
144 .SubClass = USB_CSCP_NoDeviceSubclass,
145 .Protocol = USB_CSCP_NoDeviceProtocol,
146
147 .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
148
149 .VendorID = VENDOR_ID,
150 .ProductID = PRODUCT_ID,
151 .ReleaseNumber = DEVICE_VER,
152
153 .ManufacturerStrIndex = 0x01,
154 .ProductStrIndex = 0x02,
155 .SerialNumStrIndex = NO_DESCRIPTOR,
156
157 .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
158 };
159
160 /*******************************************************************************
161 * Configuration Descriptors
162 ******************************************************************************/
163 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
164 {
165 .Config =
166 {
167 .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
168
169 .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
170 .TotalInterfaces = 3,
171
172 .ConfigurationNumber = 1,
173 .ConfigurationStrIndex = NO_DESCRIPTOR,
174
175 .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
176
177 .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
178 },
179
180 /*
181 * Keyboard
182 */
183 .Keyboard_Interface =
184 {
185 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
186
187 .InterfaceNumber = KEYBOARD_INTERFACE,
188 .AlternateSetting = 0x00,
189
190 .TotalEndpoints = 1,
191
192 .Class = HID_CSCP_HIDClass,
193 .SubClass = HID_CSCP_BootSubclass,
194 .Protocol = HID_CSCP_KeyboardBootProtocol,
195
196 .InterfaceStrIndex = NO_DESCRIPTOR
197 },
198
199 .Keyboard_HID =
200 {
201 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
202
203 .HIDSpec = VERSION_BCD(01.11),
204 .CountryCode = 0x00,
205 .TotalReportDescriptors = 1,
206 .HIDReportType = HID_DTYPE_Report,
207 .HIDReportLength = sizeof(KeyboardReport)
208 },
209
210 .Keyboard_INEndpoint =
211 {
212 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
213
214 .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
215 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
216 .EndpointSize = HID_EPSIZE,
217 .PollingIntervalMS = 0x01
218 },
219
220 /*
221 * Mouse
222 */
223 .Mouse_Interface =
224 {
225 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
226
227 .InterfaceNumber = MOUSE_INTERFACE,
228 .AlternateSetting = 0x00,
229
230 .TotalEndpoints = 1,
231
232 .Class = HID_CSCP_HIDClass,
233 .SubClass = HID_CSCP_BootSubclass,
234 .Protocol = HID_CSCP_MouseBootProtocol,
235
236 .InterfaceStrIndex = NO_DESCRIPTOR
237 },
238
239 .Mouse_HID =
240 {
241 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
242
243 .HIDSpec = VERSION_BCD(01.11),
244 .CountryCode = 0x00,
245 .TotalReportDescriptors = 1,
246 .HIDReportType = HID_DTYPE_Report,
247 .HIDReportLength = sizeof(MouseReport)
248 },
249
250 .Mouse_INEndpoint =
251 {
252 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
253
254 .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
255 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
256 .EndpointSize = HID_EPSIZE,
257 .PollingIntervalMS = 0x01
258 },
259
260 /*
261 * Console
262 */
263 .Console_Interface =
264 {
265 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
266
267 .InterfaceNumber = GENERIC_INTERFACE,
268 .AlternateSetting = 0x00,
269
270 .TotalEndpoints = 2,
271
272 .Class = HID_CSCP_HIDClass,
273 .SubClass = HID_CSCP_NonBootSubclass,
274 .Protocol = HID_CSCP_NonBootProtocol,
275
276 .InterfaceStrIndex = NO_DESCRIPTOR
277 },
278
279 .Console_HID =
280 {
281 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
282
283 .HIDSpec = VERSION_BCD(01.11),
284 .CountryCode = 0x00,
285 .TotalReportDescriptors = 1,
286 .HIDReportType = HID_DTYPE_Report,
287 .HIDReportLength = sizeof(ConsoleReport)
288 },
289
290 .Console_INEndpoint =
291 {
292 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
293
294 .EndpointAddress = (ENDPOINT_DIR_IN | GENERIC_IN_EPNUM),
295 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
296 .EndpointSize = GENERIC_EPSIZE,
297 .PollingIntervalMS = 0x01
298 },
299
300 .Console_OUTEndpoint =
301 {
302 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
303
304 .EndpointAddress = (ENDPOINT_DIR_OUT | GENERIC_OUT_EPNUM),
305 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
306 .EndpointSize = GENERIC_EPSIZE,
307 .PollingIntervalMS = 0x01
308 }
309 };
310
311
312 /*******************************************************************************
313 * String Descriptors
314 ******************************************************************************/
315 const USB_Descriptor_String_t PROGMEM LanguageString =
316 {
317 .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
318
319 .UnicodeString = {LANGUAGE_ID_ENG}
320 };
321
322 const USB_Descriptor_String_t PROGMEM ManufacturerString =
323 {
324 .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
325
326 .UnicodeString = LSTR(MANUFACTURER)
327 };
328
329 const USB_Descriptor_String_t PROGMEM ProductString =
330 {
331 .Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String},
332
333 .UnicodeString = LSTR(PRODUCT)
334 };
335
336
337 /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
338 * documentation) by the application code so that the address and size of a requested descriptor can be given
339 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
340 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
341 * USB host.
342 */
343 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
344 const uint8_t wIndex,
345 const void** const DescriptorAddress)
346 {
347 const uint8_t DescriptorType = (wValue >> 8);
348 const uint8_t DescriptorIndex = (wValue & 0xFF);
349
350 const void* Address = NULL;
351 uint16_t Size = NO_DESCRIPTOR;
352
353 switch (DescriptorType)
354 {
355 case DTYPE_Device:
356 Address = &DeviceDescriptor;
357 Size = sizeof(USB_Descriptor_Device_t);
358 break;
359 case DTYPE_Configuration:
360 Address = &ConfigurationDescriptor;
361 Size = sizeof(USB_Descriptor_Configuration_t);
362 break;
363 case DTYPE_String:
364 switch (DescriptorIndex )
365 {
366 case 0x00:
367 Address = &LanguageString;
368 Size = pgm_read_byte(&LanguageString.Header.Size);
369 break;
370 case 0x01:
371 Address = &ManufacturerString;
372 Size = pgm_read_byte(&ManufacturerString.Header.Size);
373 break;
374 case 0x02:
375 Address = &ProductString;
376 Size = pgm_read_byte(&ProductString.Header.Size);
377 break;
378 }
379 break;
380 case HID_DTYPE_HID:
381 switch (wIndex) {
382 case KEYBOARD_INTERFACE:
383 Address = &ConfigurationDescriptor.Keyboard_HID;
384 Size = sizeof(USB_HID_Descriptor_HID_t);
385 break;
386 case MOUSE_INTERFACE:
387 Address = &ConfigurationDescriptor.Mouse_HID;
388 Size = sizeof(USB_HID_Descriptor_HID_t);
389 break;
390 case GENERIC_INTERFACE:
391 Address = &ConfigurationDescriptor.Console_HID;
392 Size = sizeof(USB_HID_Descriptor_HID_t);
393 break;
394 }
395 break;
396 case HID_DTYPE_Report:
397 switch (wIndex) {
398 case KEYBOARD_INTERFACE:
399 Address = &KeyboardReport;
400 Size = sizeof(KeyboardReport);
401 break;
402 case MOUSE_INTERFACE:
403 Address = &MouseReport;
404 Size = sizeof(MouseReport);
405 break;
406 case GENERIC_INTERFACE:
407 Address = &ConsoleReport;
408 Size = sizeof(ConsoleReport);
409 break;
410 }
411 break;
412 }
413
414 *DescriptorAddress = Address;
415 return Size;
416 }
Imprint / Impressum