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
10 Copyright (C) Dean Camera, 2012.
12 dean [at] fourwalledcubicle [dot] com
17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
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.
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
40 #include "descriptor.h"
43 /*******************************************************************************
44 * HID Report Descriptors
45 ******************************************************************************/
46 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
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),
82 const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
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),
114 const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
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),
135 /*******************************************************************************
137 ******************************************************************************/
138 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
140 .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
142 .USBSpecification = VERSION_BCD(01.10),
143 .Class = USB_CSCP_NoDeviceClass,
144 .SubClass = USB_CSCP_NoDeviceSubclass,
145 .Protocol = USB_CSCP_NoDeviceProtocol,
147 .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
149 .VendorID = VENDOR_ID,
150 .ProductID = PRODUCT_ID,
151 .ReleaseNumber = DEVICE_VER,
153 .ManufacturerStrIndex = 0x01,
154 .ProductStrIndex = 0x02,
155 .SerialNumStrIndex = NO_DESCRIPTOR,
157 .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
160 /*******************************************************************************
161 * Configuration Descriptors
162 ******************************************************************************/
163 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
167 .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
169 .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
170 .TotalInterfaces = 3,
172 .ConfigurationNumber = 1,
173 .ConfigurationStrIndex = NO_DESCRIPTOR,
175 .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
177 .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
183 .Keyboard_Interface =
185 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
187 .InterfaceNumber = KEYBOARD_INTERFACE,
188 .AlternateSetting = 0x00,
192 .Class = HID_CSCP_HIDClass,
193 .SubClass = HID_CSCP_BootSubclass,
194 .Protocol = HID_CSCP_KeyboardBootProtocol,
196 .InterfaceStrIndex = NO_DESCRIPTOR
201 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
203 .HIDSpec = VERSION_BCD(01.11),
205 .TotalReportDescriptors = 1,
206 .HIDReportType = HID_DTYPE_Report,
207 .HIDReportLength = sizeof(KeyboardReport)
210 .Keyboard_INEndpoint =
212 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
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
225 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
227 .InterfaceNumber = MOUSE_INTERFACE,
228 .AlternateSetting = 0x00,
232 .Class = HID_CSCP_HIDClass,
233 .SubClass = HID_CSCP_BootSubclass,
234 .Protocol = HID_CSCP_MouseBootProtocol,
236 .InterfaceStrIndex = NO_DESCRIPTOR
241 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
243 .HIDSpec = VERSION_BCD(01.11),
245 .TotalReportDescriptors = 1,
246 .HIDReportType = HID_DTYPE_Report,
247 .HIDReportLength = sizeof(MouseReport)
252 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
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
265 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
267 .InterfaceNumber = GENERIC_INTERFACE,
268 .AlternateSetting = 0x00,
272 .Class = HID_CSCP_HIDClass,
273 .SubClass = HID_CSCP_NonBootSubclass,
274 .Protocol = HID_CSCP_NonBootProtocol,
276 .InterfaceStrIndex = NO_DESCRIPTOR
281 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
283 .HIDSpec = VERSION_BCD(01.11),
285 .TotalReportDescriptors = 1,
286 .HIDReportType = HID_DTYPE_Report,
287 .HIDReportLength = sizeof(ConsoleReport)
290 .Console_INEndpoint =
292 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
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
300 .Console_OUTEndpoint =
302 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
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
312 /*******************************************************************************
314 ******************************************************************************/
315 const USB_Descriptor_String_t PROGMEM LanguageString =
317 .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
319 .UnicodeString = {LANGUAGE_ID_ENG}
322 const USB_Descriptor_String_t PROGMEM ManufacturerString =
324 .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
326 .UnicodeString = LSTR(MANUFACTURER)
329 const USB_Descriptor_String_t PROGMEM ProductString =
331 .Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String},
333 .UnicodeString = LSTR(PRODUCT)
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
343 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
344 const uint8_t wIndex,
345 const void** const DescriptorAddress)
347 const uint8_t DescriptorType = (wValue >> 8);
348 const uint8_t DescriptorIndex = (wValue & 0xFF);
350 const void* Address = NULL;
351 uint16_t Size = NO_DESCRIPTOR;
353 switch (DescriptorType)
356 Address = &DeviceDescriptor;
357 Size = sizeof(USB_Descriptor_Device_t);
359 case DTYPE_Configuration:
360 Address = &ConfigurationDescriptor;
361 Size = sizeof(USB_Descriptor_Configuration_t);
364 switch (DescriptorIndex )
367 Address = &LanguageString;
368 Size = pgm_read_byte(&LanguageString.Header.Size);
371 Address = &ManufacturerString;
372 Size = pgm_read_byte(&ManufacturerString.Header.Size);
375 Address = &ProductString;
376 Size = pgm_read_byte(&ProductString.Header.Size);
382 case KEYBOARD_INTERFACE:
383 Address = &ConfigurationDescriptor.Keyboard_HID;
384 Size = sizeof(USB_HID_Descriptor_HID_t);
386 case MOUSE_INTERFACE:
387 Address = &ConfigurationDescriptor.Mouse_HID;
388 Size = sizeof(USB_HID_Descriptor_HID_t);
390 case GENERIC_INTERFACE:
391 Address = &ConfigurationDescriptor.Console_HID;
392 Size = sizeof(USB_HID_Descriptor_HID_t);
396 case HID_DTYPE_Report:
398 case KEYBOARD_INTERFACE:
399 Address = &KeyboardReport;
400 Size = sizeof(KeyboardReport);
402 case MOUSE_INTERFACE:
403 Address = &MouseReport;
404 Size = sizeof(MouseReport);
406 case GENERIC_INTERFACE:
407 Address = &ConsoleReport;
408 Size = sizeof(ConsoleReport);
414 *DescriptorAddress = Address;