]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - keyboard/lufa/descriptor.c
clean descriptor setting. Remove keyboard OUT Endpoint.
[max/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 GenericReport[] =
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     .HID0_KeyboardInterface =
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     .HID0_KeyboardHID =
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     .HID0_ReportINEndpoint =
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     .HID1_MouseInterface =
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     .HID1_MouseHID =
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     .HID1_ReportINEndpoint =
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      * Generic
262      */
263     .HID2_GenericInterface =
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     .HID2_GenericHID =
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(GenericReport)
288         },
289
290     .HID2_ReportINEndpoint =
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     .HID2_ReportOUTEndpoint =
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.HID0_KeyboardHID;
384                 Size    = sizeof(USB_HID_Descriptor_HID_t);
385                 break;
386             case MOUSE_INTERFACE:
387                 Address = &ConfigurationDescriptor.HID1_MouseHID;
388                 Size    = sizeof(USB_HID_Descriptor_HID_t);
389                 break;
390             case GENERIC_INTERFACE:
391                 Address = &ConfigurationDescriptor.HID2_GenericHID;
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 = &GenericReport;
408                 Size    = sizeof(GenericReport);
409                 break;
410             }
411             break;
412     }
413
414     *DescriptorAddress = Address;
415     return Size;
416 }