summaryrefslogtreecommitdiffstats
path: root/tmk_core/protocol/usb_descriptor.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/usb_descriptor.c')
-rw-r--r--tmk_core/protocol/usb_descriptor.c1017
1 files changed, 1017 insertions, 0 deletions
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
new file mode 100644
index 000000000..cab344675
--- /dev/null
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -0,0 +1,1017 @@
+/*
+ * Copyright 2012 Jun Wako <wakojun@gmail.com>
+ * This file is based on:
+ * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
+ * LUFA-120219/Demos/Device/Lowlevel/GenericHID
+ */
+
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+ Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#include "util.h"
+#include "report.h"
+#include "usb_descriptor.h"
+
+#ifndef USB_MAX_POWER_CONSUMPTION
+#define USB_MAX_POWER_CONSUMPTION 500
+#endif
+
+/*******************************************************************************
+ * HID Report Descriptors
+ ******************************************************************************/
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
+{
+ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+ HID_RI_USAGE(8, 0x06), /* Keyboard */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+ HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
+ HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, 0x08),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */
+
+ HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
+ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
+ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
+ HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x03),
+ HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
+
+ HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
+ HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
+ HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+ HID_RI_REPORT_COUNT(8, 0x06),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
+ HID_RI_END_COLLECTION(0),
+};
+
+#ifdef MOUSE_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
+{
+ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+ HID_RI_USAGE(8, 0x02), /* Mouse */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_USAGE(8, 0x01), /* Pointer */
+ HID_RI_COLLECTION(8, 0x00), /* Physical */
+
+ HID_RI_USAGE_PAGE(8, 0x09), /* Button */
+ HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
+ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x03),
+ HID_RI_INPUT(8, HID_IOF_CONSTANT),
+
+ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+ HID_RI_USAGE(8, 0x30), /* Usage X */
+ HID_RI_USAGE(8, 0x31), /* Usage Y */
+ HID_RI_LOGICAL_MINIMUM(8, -127),
+ HID_RI_LOGICAL_MAXIMUM(8, 127),
+ HID_RI_REPORT_COUNT(8, 0x02),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+
+ HID_RI_USAGE(8, 0x38), /* Wheel */
+ HID_RI_LOGICAL_MINIMUM(8, -127),
+ HID_RI_LOGICAL_MAXIMUM(8, 127),
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+
+ HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
+ HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */
+ HID_RI_LOGICAL_MINIMUM(8, -127),
+ HID_RI_LOGICAL_MAXIMUM(8, 127),
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+
+ HID_RI_END_COLLECTION(0),
+ HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef EXTRAKEY_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
+{
+ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+ HID_RI_USAGE(8, 0x80), /* System Control */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
+ HID_RI_LOGICAL_MINIMUM(16, 0x0001),
+ HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
+ HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
+ HID_RI_USAGE_MAXIMUM(16, 0x0083), /* System Wake Up */
+ HID_RI_REPORT_SIZE(8, 16),
+ HID_RI_REPORT_COUNT(8, 1),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
+ HID_RI_END_COLLECTION(0),
+
+ HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
+ HID_RI_USAGE(8, 0x01), /* Consumer Control */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
+ HID_RI_LOGICAL_MINIMUM(16, 0x0001),
+ HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
+ HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
+ HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */
+ HID_RI_REPORT_SIZE(8, 16),
+ HID_RI_REPORT_COUNT(8, 1),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
+ HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef RAW_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
+{
+ HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
+ HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+ HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+ HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+ HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+ HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef CONSOLE_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
+{
+ HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
+ HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+ HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+ HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+ HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+ HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef NKRO_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
+{
+ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+ HID_RI_USAGE(8, 0x06), /* Keyboard */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+ HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
+ HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, 0x08),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+
+ HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
+ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
+ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
+ HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x03),
+ HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
+
+ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+ HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
+ HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+ HID_RI_END_COLLECTION(0),
+};
+#endif
+
+/*******************************************************************************
+ * Device Descriptors
+ ******************************************************************************/
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(1,1,0),
+#if VIRTSER_ENABLE
+ .Class = USB_CSCP_IADDeviceClass,
+ .SubClass = USB_CSCP_IADDeviceSubclass,
+ .Protocol = USB_CSCP_IADDeviceProtocol,
+#else
+ .Class = USB_CSCP_NoDeviceClass,
+ .SubClass = USB_CSCP_NoDeviceSubclass,
+ .Protocol = USB_CSCP_NoDeviceProtocol,
+#endif
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ /* specified in config.h */
+ .VendorID = VENDOR_ID,
+ .ProductID = PRODUCT_ID,
+ .ReleaseNumber = DEVICE_VER,
+
+ .ManufacturerStrIndex = 0x01,
+ .ProductStrIndex = 0x02,
+ .SerialNumStrIndex = 0x03,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/*******************************************************************************
+ * Configuration Descriptors
+ ******************************************************************************/
+const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
+{
+ .Config =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+ .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+ .TotalInterfaces = TOTAL_INTERFACES,
+
+ .ConfigurationNumber = 1,
+ .ConfigurationStrIndex = NO_DESCRIPTOR,
+
+ .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
+ },
+
+ /*
+ * Keyboard
+ */
+ .Keyboard_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = KEYBOARD_INTERFACE,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 1,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_BootSubclass,
+ .Protocol = HID_CSCP_KeyboardBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Keyboard_HID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(KeyboardReport)
+ },
+
+ .Keyboard_INEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = KEYBOARD_EPSIZE,
+ .PollingIntervalMS = 0x0A
+ },
+
+ /*
+ * Mouse
+ */
+#ifdef MOUSE_ENABLE
+ .Mouse_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = MOUSE_INTERFACE,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 1,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_BootSubclass,
+ .Protocol = HID_CSCP_MouseBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Mouse_HID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(MouseReport)
+ },
+
+ .Mouse_INEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = MOUSE_EPSIZE,
+ .PollingIntervalMS = 0x0A
+ },
+#endif
+
+ /*
+ * Extra
+ */
+#ifdef EXTRAKEY_ENABLE
+ .Extrakey_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = EXTRAKEY_INTERFACE,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 1,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_NonBootSubclass,
+ .Protocol = HID_CSCP_NonBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Extrakey_HID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(ExtrakeyReport)
+ },
+
+ .Extrakey_INEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = EXTRAKEY_EPSIZE,
+ .PollingIntervalMS = 0x0A
+ },
+#endif
+
+ /*
+ * Raw
+ */
+ #ifdef RAW_ENABLE
+ .Raw_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = RAW_INTERFACE,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 2,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_NonBootSubclass,
+ .Protocol = HID_CSCP_NonBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Raw_HID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(RawReport)
+ },
+
+ .Raw_INEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = RAW_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .Raw_OUTEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = RAW_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+ #endif
+
+ /*
+ * Console
+ */
+#ifdef CONSOLE_ENABLE
+ .Console_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = CONSOLE_INTERFACE,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 2,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_NonBootSubclass,
+ .Protocol = HID_CSCP_NonBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Console_HID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(ConsoleReport)
+ },
+
+ .Console_INEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CONSOLE_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .Console_OUTEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CONSOLE_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+#endif
+
+ /*
+ * NKRO
+ */
+#ifdef NKRO_ENABLE
+ .NKRO_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = NKRO_INTERFACE,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 1,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_NonBootSubclass,
+ .Protocol = HID_CSCP_NonBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .NKRO_HID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(NKROReport)
+ },
+
+ .NKRO_INEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = NKRO_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+#endif
+
+#ifdef MIDI_ENABLE
+ .Audio_Interface_Association =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
+
+ .FirstInterfaceIndex = AC_INTERFACE,
+ .TotalInterfaces = 2,
+
+ .Class = AUDIO_CSCP_AudioClass,
+ .SubClass = AUDIO_CSCP_ControlSubclass,
+ .Protocol = AUDIO_CSCP_ControlProtocol,
+
+ .IADStrIndex = NO_DESCRIPTOR,
+ },
+ .Audio_ControlInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = AC_INTERFACE,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 0,
+
+ .Class = AUDIO_CSCP_AudioClass,
+ .SubClass = AUDIO_CSCP_ControlSubclass,
+ .Protocol = AUDIO_CSCP_ControlProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Audio_ControlInterface_SPC =
+ {
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
+
+ .ACSpecification = VERSION_BCD(1,0,0),
+ .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
+
+ .InCollection = 1,
+ .InterfaceNumber = AS_INTERFACE,
+ },
+
+ .Audio_StreamInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = AS_INTERFACE,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = AUDIO_CSCP_AudioClass,
+ .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
+ .Protocol = AUDIO_CSCP_StreamingProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Audio_StreamInterface_SPC =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
+
+ .AudioSpecification = VERSION_BCD(1,0,0),
+
+ .TotalLength = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC)
+ + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t)
+ - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)
+ },
+
+ .MIDI_In_Jack_Emb =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
+
+ .JackType = MIDI_JACKTYPE_Embedded,
+ .JackID = 0x01,
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_In_Jack_Ext =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
+
+ .JackType = MIDI_JACKTYPE_External,
+ .JackID = 0x02,
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_Out_Jack_Emb =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
+
+ .JackType = MIDI_JACKTYPE_Embedded,
+ .JackID = 0x03,
+
+ .NumberOfPins = 1,
+ .SourceJackID = {0x02},
+ .SourcePinID = {0x01},
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_Out_Jack_Ext =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
+
+ .JackType = MIDI_JACKTYPE_External,
+ .JackID = 0x04,
+
+ .NumberOfPins = 1,
+ .SourceJackID = {0x01},
+ .SourcePinID = {0x01},
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_In_Jack_Endpoint =
+ {
+ .Endpoint =
+ {
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = MIDI_STREAM_OUT_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = MIDI_STREAM_EPSIZE,
+ .PollingIntervalMS = 0x05
+ },
+
+ .Refresh = 0,
+ .SyncEndpointNumber = 0
+ },
+
+ .MIDI_In_Jack_Endpoint_SPC =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
+ .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
+
+ .TotalEmbeddedJacks = 0x01,
+ .AssociatedJackID = {0x01}
+ },
+
+ .MIDI_Out_Jack_Endpoint =
+ {
+ .Endpoint =
+ {
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = MIDI_STREAM_IN_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = MIDI_STREAM_EPSIZE,
+ .PollingIntervalMS = 0x05
+ },
+
+ .Refresh = 0,
+ .SyncEndpointNumber = 0
+ },
+
+ .MIDI_Out_Jack_Endpoint_SPC =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
+ .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
+
+ .TotalEmbeddedJacks = 0x01,
+ .AssociatedJackID = {0x03}
+ },
+#endif
+
+#ifdef VIRTSER_ENABLE
+ .CDC_Interface_Association =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
+
+ .FirstInterfaceIndex = CCI_INTERFACE,
+ .TotalInterfaces = 2,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .IADStrIndex = NO_DESCRIPTOR,
+ },
+
+ .CDC_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = CCI_INTERFACE,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x00,
+
+ .CDCSpecification = VERSION_BCD(1,1,0),
+ },
+
+ .CDC_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x02,
+
+ .Capabilities = 0x02,
+ },
+
+ .CDC_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x06,
+
+ .MasterInterfaceNumber = CCI_INTERFACE,
+ .SlaveInterfaceNumber = CDI_INTERFACE,
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = CDC_NOTIFICATION_EPADDR,
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = CDI_INTERFACE,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = CDC_OUT_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_EPSIZE,
+ .PollingIntervalMS = 0x05
+ },
+
+ .CDC_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = CDC_IN_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_EPSIZE,
+ .PollingIntervalMS = 0x05
+ },
+#endif
+};
+
+
+/*******************************************************************************
+ * String Descriptors
+ ******************************************************************************/
+const USB_Descriptor_String_t PROGMEM LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+const USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+ /* subtract 1 for null terminator */
+ .Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
+
+ .UnicodeString = LSTR(MANUFACTURER)
+};
+
+const USB_Descriptor_String_t PROGMEM ProductString =
+{
+ /* subtract 1 for null terminator */
+ .Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
+
+ .UnicodeString = LSTR(PRODUCT)
+};
+
+#ifndef SERIAL_NUMBER
+ #define SERIAL_NUMBER 0
+#endif
+
+const USB_Descriptor_String_t PROGMEM SerialNumberString =
+{
+ /* subtract 1 for null terminator */
+ .Header = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER))-1), .Type = DTYPE_String},
+
+ .UnicodeString = LSTR(SERIAL_NUMBER)
+};
+
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t get_usb_descriptor(const uint16_t wValue,
+ const uint16_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorIndex = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorIndex )
+ {
+ case 0x00:
+ Address = &LanguageString;
+ Size = pgm_read_byte(&LanguageString.Header.Size);
+ break;
+ case 0x01:
+ Address = &ManufacturerString;
+ Size = pgm_read_byte(&ManufacturerString.Header.Size);
+ break;
+ case 0x02:
+ Address = &ProductString;
+ Size = pgm_read_byte(&ProductString.Header.Size);
+ break;
+ case 0x03:
+ Address = &SerialNumberString;
+ Size = pgm_read_byte(&SerialNumberString.Header.Size);
+ break;
+ }
+ break;
+ case HID_DTYPE_HID:
+ switch (wIndex) {
+ case KEYBOARD_INTERFACE:
+ Address = &ConfigurationDescriptor.Keyboard_HID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+#ifdef MOUSE_ENABLE
+ case MOUSE_INTERFACE:
+ Address = &ConfigurationDescriptor.Mouse_HID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+#endif
+#ifdef EXTRAKEY_ENABLE
+ case EXTRAKEY_INTERFACE:
+ Address = &ConfigurationDescriptor.Extrakey_HID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+#endif
+#ifdef RAW_ENABLE
+ case RAW_INTERFACE:
+ Address = &ConfigurationDescriptor.Raw_HID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+#endif
+#ifdef CONSOLE_ENABLE
+ case CONSOLE_INTERFACE:
+ Address = &ConfigurationDescriptor.Console_HID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+#endif
+#ifdef NKRO_ENABLE
+ case NKRO_INTERFACE:
+ Address = &ConfigurationDescriptor.NKRO_HID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+#endif
+ }
+ break;
+ case HID_DTYPE_Report:
+ switch (wIndex) {
+ case KEYBOARD_INTERFACE:
+ Address = &KeyboardReport;
+ Size = sizeof(KeyboardReport);
+ break;
+#ifdef MOUSE_ENABLE
+ case MOUSE_INTERFACE:
+ Address = &MouseReport;
+ Size = sizeof(MouseReport);
+ break;
+#endif
+#ifdef EXTRAKEY_ENABLE
+ case EXTRAKEY_INTERFACE:
+ Address = &ExtrakeyReport;
+ Size = sizeof(ExtrakeyReport);
+ break;
+#endif
+#ifdef RAW_ENABLE
+ case RAW_INTERFACE:
+ Address = &RawReport;
+ Size = sizeof(RawReport);
+ break;
+#endif
+#ifdef CONSOLE_ENABLE
+ case CONSOLE_INTERFACE:
+ Address = &ConsoleReport;
+ Size = sizeof(ConsoleReport);
+ break;
+#endif
+#ifdef NKRO_ENABLE
+ case NKRO_INTERFACE:
+ Address = &NKROReport;
+ Size = sizeof(NKROReport);
+ break;
+#endif
+ }
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}