]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - keyboard/lufa/Descriptors.c
Add sendchar with Generic HID to support debug print.
[max/tmk_keyboard.git] / keyboard / lufa / Descriptors.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 /** \file
40  *
41  *  USB Device Descriptors, for library use when in USB device mode. Descriptors are special
42  *  computer-readable structures which the host requests upon device enumeration, to determine
43  *  the device's capabilities and functions.
44  */
45
46 #include "Descriptors.h"
47
48
49 /*******************************************************************************
50  * HID Report Descriptors
51  ******************************************************************************/
52 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
53 {
54     HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
55     HID_RI_USAGE(8, 0x06), /* Keyboard */
56     HID_RI_COLLECTION(8, 0x01), /* Application */
57         HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
58         HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
59         HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
60         HID_RI_LOGICAL_MINIMUM(8, 0x00),
61         HID_RI_LOGICAL_MAXIMUM(8, 0x01),
62         HID_RI_REPORT_SIZE(8, 0x01),
63         HID_RI_REPORT_COUNT(8, 0x08),
64         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
65         HID_RI_REPORT_COUNT(8, 0x01),
66         HID_RI_REPORT_SIZE(8, 0x08),
67         HID_RI_INPUT(8, HID_IOF_CONSTANT),
68         HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
69         HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
70         HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
71         HID_RI_REPORT_COUNT(8, 0x05),
72         HID_RI_REPORT_SIZE(8, 0x01),
73         HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
74         HID_RI_REPORT_COUNT(8, 0x01),
75         HID_RI_REPORT_SIZE(8, 0x03),
76         HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
77         HID_RI_LOGICAL_MINIMUM(8, 0x00),
78         HID_RI_LOGICAL_MAXIMUM(8, 0x65),
79         HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
80         HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
81         HID_RI_USAGE_MAXIMUM(8, 0x65), /* Keyboard Application */
82         HID_RI_REPORT_COUNT(8, 0x06),
83         HID_RI_REPORT_SIZE(8, 0x08),
84         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
85     HID_RI_END_COLLECTION(0),
86 };
87
88 const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
89 {
90     HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
91     HID_RI_USAGE(8, 0x02), /* Mouse */
92     HID_RI_COLLECTION(8, 0x01), /* Application */
93         HID_RI_USAGE(8, 0x01), /* Pointer */
94         HID_RI_COLLECTION(8, 0x00), /* Physical */
95             HID_RI_USAGE_PAGE(8, 0x09), /* Button */
96             HID_RI_USAGE_MINIMUM(8, 0x01),
97             HID_RI_USAGE_MAXIMUM(8, 0x03),
98             HID_RI_LOGICAL_MINIMUM(8, 0x00),
99             HID_RI_LOGICAL_MAXIMUM(8, 0x01),
100             HID_RI_REPORT_COUNT(8, 0x03),
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),
104             HID_RI_REPORT_SIZE(8, 0x05),
105             HID_RI_INPUT(8, HID_IOF_CONSTANT),
106             HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
107             HID_RI_USAGE(8, 0x30), /* Usage X */
108             HID_RI_USAGE(8, 0x31), /* Usage Y */
109             HID_RI_LOGICAL_MINIMUM(8, -1),
110             HID_RI_LOGICAL_MAXIMUM(8, 1),
111             HID_RI_PHYSICAL_MINIMUM(8, -1),
112             HID_RI_PHYSICAL_MAXIMUM(8, 1),
113             HID_RI_REPORT_COUNT(8, 0x02),
114             HID_RI_REPORT_SIZE(8, 0x08),
115             HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
116         HID_RI_END_COLLECTION(0),
117     HID_RI_END_COLLECTION(0),
118 };
119
120 const USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
121 {
122     HID_RI_USAGE_PAGE(16, 0xFF00), /* Vendor Page 0 */
123     HID_RI_USAGE(8, 0x01), /* Vendor Usage 1 */
124     HID_RI_COLLECTION(8, 0x01), /* Vendor Usage 1 */
125         HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */
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_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
131         HID_RI_USAGE(8, 0x03), /* Vendor Usage 3 */
132         HID_RI_LOGICAL_MINIMUM(8, 0x00),
133         HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
134         HID_RI_REPORT_SIZE(8, 0x08),
135         HID_RI_REPORT_COUNT(8, GENERIC_REPORT_SIZE),
136         HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
137     HID_RI_END_COLLECTION(0),
138 };
139
140
141 /*******************************************************************************
142  * Device Descriptors
143  ******************************************************************************/
144 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
145 {
146     .Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
147
148     .USBSpecification       = VERSION_BCD(01.10),
149     .Class                  = USB_CSCP_NoDeviceClass,
150     .SubClass               = USB_CSCP_NoDeviceSubclass,
151     .Protocol               = USB_CSCP_NoDeviceProtocol,
152
153     .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
154
155     .VendorID               = 0xFEED,
156     .ProductID              = 0x204D,
157     .ReleaseNumber          = VERSION_BCD(00.02),
158
159     .ManufacturerStrIndex   = 0x01,
160     .ProductStrIndex        = 0x02,
161     .SerialNumStrIndex      = NO_DESCRIPTOR,
162
163     .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
164 };
165
166 /*******************************************************************************
167  * Configuration Descriptors
168  ******************************************************************************/
169 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
170 {
171     .Config =
172         {
173             .Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
174
175             .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
176             .TotalInterfaces        = 3,
177
178             .ConfigurationNumber    = 1,
179             .ConfigurationStrIndex  = NO_DESCRIPTOR,
180
181             .ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED), //TODO: bus powered?
182
183             .MaxPowerConsumption    = USB_CONFIG_POWER_MA(100)
184         },
185
186         /*
187          * Keyboard
188          */
189     .HID1_KeyboardInterface =
190         {
191             .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
192
193             .InterfaceNumber        = 0x00,
194             .AlternateSetting       = 0x00,
195
196             .TotalEndpoints         = 2,
197
198             .Class                  = HID_CSCP_HIDClass,
199             .SubClass               = HID_CSCP_BootSubclass,
200             .Protocol               = HID_CSCP_KeyboardBootProtocol,
201
202             .InterfaceStrIndex      = NO_DESCRIPTOR
203         },
204
205     .HID1_KeyboardHID =
206         {
207             .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
208
209             .HIDSpec                = VERSION_BCD(01.11),
210             .CountryCode            = 0x00,
211             .TotalReportDescriptors = 1,
212             .HIDReportType          = HID_DTYPE_Report,
213             .HIDReportLength        = sizeof(KeyboardReport)
214         },
215
216     .HID1_ReportINEndpoint =
217         {
218             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
219
220             .EndpointAddress        = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
221             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
222             .EndpointSize           = HID_EPSIZE,
223             .PollingIntervalMS      = 0x01
224         },
225
226     .HID1_ReportOUTEndpoint =
227         {
228             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
229
230             .EndpointAddress        = (ENDPOINT_DIR_OUT | KEYBOARD_OUT_EPNUM),
231             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
232             .EndpointSize           = HID_EPSIZE,
233             .PollingIntervalMS      = 0x01
234         },
235
236     /*
237      * Mouse
238      */
239     .HID2_MouseInterface =
240         {
241             .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
242
243             .InterfaceNumber        = 0x01,
244             .AlternateSetting       = 0x00,
245
246             .TotalEndpoints         = 1,
247
248             .Class                  = HID_CSCP_HIDClass,
249             .SubClass               = HID_CSCP_BootSubclass,
250             .Protocol               = HID_CSCP_MouseBootProtocol,
251
252             .InterfaceStrIndex      = NO_DESCRIPTOR
253         },
254
255     .HID2_MouseHID =
256         {
257             .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
258
259             .HIDSpec                = VERSION_BCD(01.11),
260             .CountryCode            = 0x00,
261             .TotalReportDescriptors = 1,
262             .HIDReportType          = HID_DTYPE_Report,
263             .HIDReportLength        = sizeof(MouseReport)
264         },
265
266     .HID2_ReportINEndpoint =
267         {
268             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
269
270             .EndpointAddress        = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
271             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
272             .EndpointSize           = HID_EPSIZE,
273             .PollingIntervalMS      = 0x01
274         },
275
276     /*
277      * Generic
278      */
279     .HID3_GenericInterface =
280         {
281             .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
282
283             .InterfaceNumber        = 0x02,
284             .AlternateSetting       = 0x00,
285
286             .TotalEndpoints         = 2,
287
288             .Class                  = HID_CSCP_HIDClass,
289             .SubClass               = HID_CSCP_NonBootSubclass,
290             .Protocol               = HID_CSCP_NonBootProtocol,
291
292             .InterfaceStrIndex      = NO_DESCRIPTOR
293         },
294
295     .HID3_GenericHID =
296         {
297             .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
298
299             .HIDSpec                = VERSION_BCD(01.11),
300             .CountryCode            = 0x00,
301             .TotalReportDescriptors = 1,
302             .HIDReportType          = HID_DTYPE_Report,
303             .HIDReportLength        = sizeof(GenericReport)
304         },
305
306     .HID3_ReportINEndpoint =
307         {
308             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
309
310             .EndpointAddress        = (ENDPOINT_DIR_IN | GENERIC_IN_EPNUM),
311             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
312             .EndpointSize           = GENERIC_EPSIZE,
313             .PollingIntervalMS      = 0x01
314         },
315
316     .HID3_ReportOUTEndpoint =
317         {
318             .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
319
320             .EndpointAddress        = (ENDPOINT_DIR_OUT | GENERIC_OUT_EPNUM),
321             .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
322             .EndpointSize           = GENERIC_EPSIZE,
323             .PollingIntervalMS      = 0x01
324         }
325 };
326
327
328 /*******************************************************************************
329  * String Descriptors
330  ******************************************************************************/
331 const USB_Descriptor_String_t PROGMEM LanguageString =
332 {
333     .Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
334
335     .UnicodeString          = {LANGUAGE_ID_ENG}
336 };
337
338 const USB_Descriptor_String_t PROGMEM ManufacturerString =
339 {
340     .Header                 = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
341
342     .UnicodeString          = L"Dean Camera"    // TODO:
343 };
344
345 const USB_Descriptor_String_t PROGMEM ProductString =
346 {
347     .Header                 = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String},
348
349     .UnicodeString          = L"LUFA Mouse and Keyboard Demo"   // TODO:
350 };
351
352
353 /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
354  *  documentation) by the application code so that the address and size of a requested descriptor can be given
355  *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
356  *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
357  *  USB host.
358  */
359 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
360                                     const uint8_t wIndex,
361                                     const void** const DescriptorAddress)
362 {
363     const uint8_t  DescriptorType   = (wValue >> 8);
364     const uint8_t  DescriptorIndex  = (wValue & 0xFF);
365
366     const void* Address = NULL;
367     uint16_t    Size    = NO_DESCRIPTOR;
368
369     switch (DescriptorType)
370     {
371         case DTYPE_Device:
372             Address = &DeviceDescriptor;
373             Size    = sizeof(USB_Descriptor_Device_t);
374             break;
375         case DTYPE_Configuration:
376             Address = &ConfigurationDescriptor;
377             Size    = sizeof(USB_Descriptor_Configuration_t);
378             break;
379         case DTYPE_String:
380             switch (DescriptorIndex )
381             {
382                 case 0x00:
383                     Address = &LanguageString;
384                     Size    = pgm_read_byte(&LanguageString.Header.Size);
385                     break;
386                 case 0x01:
387                     Address = &ManufacturerString;
388                     Size    = pgm_read_byte(&ManufacturerString.Header.Size);
389                     break;
390                 case 0x02:
391                     Address = &ProductString;
392                     Size    = pgm_read_byte(&ProductString.Header.Size);
393                     break;
394             }
395             break;
396         case HID_DTYPE_HID:
397             switch (wIndex) {
398             case 0:
399                 Address = &ConfigurationDescriptor.HID1_KeyboardHID;
400                 Size    = sizeof(USB_HID_Descriptor_HID_t);
401                 break;
402             case 1:
403                 Address = &ConfigurationDescriptor.HID2_MouseHID;
404                 Size    = sizeof(USB_HID_Descriptor_HID_t);
405                 break;
406             case 2:
407                 Address = &ConfigurationDescriptor.HID3_GenericHID;
408                 Size    = sizeof(USB_HID_Descriptor_HID_t);
409                 break;
410             }
411             break;
412         case HID_DTYPE_Report:
413             switch (wIndex) {
414             case 0:
415                 Address = &KeyboardReport;
416                 Size    = sizeof(KeyboardReport);
417                 break;
418             case 1:
419                 Address = &MouseReport;
420                 Size    = sizeof(MouseReport);
421                 break;
422             case 2:
423                 Address = &GenericReport;
424                 Size    = sizeof(GenericReport);
425                 break;
426             }
427             break;
428     }
429
430     *DescriptorAddress = Address;
431     return Size;
432 }