LUFA USB descriptor cleanup (#4871)

* Fix indentation

* Fix braces

* Expand descriptor headers

* Align descriptor elements

* Nicer formatting

* Tidy up preprocessor statements

* Remove VERSION_BCD redefine - LUFA_VERSION_INTEGER is currently 0x170418

* Tidy up comments

* Tweak ordering of  HID report elements (no functional changes)

* We don't need all of these newlines

* Move default USB_MAX_POWER_CONSUMPTION closer to where it makes sense

* Ask nicely

* Add some more comments

* Change indentation back to 4 spaces

* Add changelog entry
pull/6315/head
fauxpark 5 years ago committed by skullY
parent c1fc5edd78
commit 55982667cd

@ -0,0 +1,4 @@
* LUFA USB descriptor cleanup
* Some code cleanups related to the USB HID descriptors on AVR keyboards, to make them easier to read and understand
* More information: see https://github.com/qmk/qmk_firmware/pull/4871
* No behaviour changes anticipated and no keymaps modified

@ -6,238 +6,242 @@
*/ */
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2012. Copyright (C) Dean Camera, 2012.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org www.lufa-lib.org
*/ */
/* /*
Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
#include "util.h" #include "util.h"
#include "report.h" #include "report.h"
#include "usb_descriptor.h" #include "usb_descriptor.h"
#ifndef USB_MAX_POWER_CONSUMPTION /*
#define USB_MAX_POWER_CONSUMPTION 500 * HID report descriptors
#endif */
/*******************************************************************************
* HID Report Descriptors
******************************************************************************/
#ifdef KEYBOARD_SHARED_EP #ifdef KEYBOARD_SHARED_EP
const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
#define SHARED_REPORT_STARTED #define SHARED_REPORT_STARTED
#else #else
const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
#endif #endif
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
HID_RI_USAGE(8, 0x06), /* Keyboard */ HID_RI_USAGE(8, 0x06), // Keyboard
HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_COLLECTION(8, 0x01), // Application
# ifdef KEYBOARD_SHARED_EP #ifdef KEYBOARD_SHARED_EP
HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD), HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
# endif #endif
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ // Modifiers (8 bits)
HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ 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_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, 0x08), HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
// Reserved (1 byte)
HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */ HID_RI_INPUT(8, HID_IOF_CONSTANT),
// Keycodes (6 bytes)
HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
HID_RI_USAGE_MINIMUM(8, 0x00),
HID_RI_USAGE_MAXIMUM(8, 0xFF),
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_USAGE_PAGE(8, 0x08), /* LEDs */ // Status LEDs (5 bits)
HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ HID_RI_USAGE_PAGE(8, 0x08), // LED
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_COUNT(8, 0x05),
HID_RI_REPORT_SIZE(8, 0x01), 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_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
// LED padding (3 bits)
HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03), HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_OUTPUT(8, HID_IOF_CONSTANT), 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), HID_RI_END_COLLECTION(0),
#ifndef KEYBOARD_SHARED_EP #ifndef KEYBOARD_SHARED_EP
}; };
#endif #endif
#if defined(MOUSE_ENABLE) #ifdef MOUSE_ENABLE
#ifndef MOUSE_SHARED_EP
# if !defined(MOUSE_SHARED_EP)
const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = { const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
# elif !defined(SHARED_REPORT_STARTED) #elif !defined(SHARED_REPORT_STARTED)
const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
#define SHARED_REPORT_STARTED #define SHARED_REPORT_STARTED
# endif #endif
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
HID_RI_USAGE(8, 0x02), /* Mouse */ HID_RI_USAGE(8, 0x02), // Mouse
HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_COLLECTION(8, 0x01), // Application
# ifdef MOUSE_SHARED_EP #ifdef MOUSE_SHARED_EP
HID_RI_REPORT_ID(8, REPORT_ID_MOUSE), HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
# endif #endif
HID_RI_USAGE(8, 0x01), /* Pointer */ HID_RI_USAGE(8, 0x01), // Pointer
HID_RI_COLLECTION(8, 0x00), /* Physical */ HID_RI_COLLECTION(8, 0x00), // Physical
// Buttons (5 bits)
HID_RI_USAGE_PAGE(8, 0x09), /* Button */ HID_RI_USAGE_PAGE(8, 0x09), // Button
HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */ HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */ HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_COUNT(8, 0x05),
HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
// Button padding (3 bits)
HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03), HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_INPUT(8, HID_IOF_CONSTANT),
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ // X/Y position (2 bytes)
HID_RI_USAGE(8, 0x30), /* Usage X */ HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
HID_RI_USAGE(8, 0x31), /* Usage Y */ HID_RI_USAGE(8, 0x30), // X
HID_RI_USAGE(8, 0x31), // Y
HID_RI_LOGICAL_MINIMUM(8, -127), HID_RI_LOGICAL_MINIMUM(8, -127),
HID_RI_LOGICAL_MAXIMUM(8, 127), HID_RI_LOGICAL_MAXIMUM(8, 127),
HID_RI_REPORT_COUNT(8, 0x02), HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
HID_RI_USAGE(8, 0x38), /* Wheel */ // Vertical wheel (1 byte)
HID_RI_USAGE(8, 0x38), // Wheel
HID_RI_LOGICAL_MINIMUM(8, -127), HID_RI_LOGICAL_MINIMUM(8, -127),
HID_RI_LOGICAL_MAXIMUM(8, 127), HID_RI_LOGICAL_MAXIMUM(8, 127),
HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
// Horizontal wheel (1 byte)
HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */ HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */ HID_RI_USAGE(16, 0x0238), // AC Pan
HID_RI_LOGICAL_MINIMUM(8, -127), HID_RI_LOGICAL_MINIMUM(8, -127),
HID_RI_LOGICAL_MAXIMUM(8, 127), HID_RI_LOGICAL_MAXIMUM(8, 127),
HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
HID_RI_END_COLLECTION(0), HID_RI_END_COLLECTION(0),
HID_RI_END_COLLECTION(0), HID_RI_END_COLLECTION(0),
# ifndef MOUSE_SHARED_EP #ifndef MOUSE_SHARED_EP
}; };
# endif #endif
#endif #endif
#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED) #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
#endif #endif
# ifdef EXTRAKEY_ENABLE
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ #ifdef EXTRAKEY_ENABLE
HID_RI_USAGE(8, 0x80), /* System Control */ HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_USAGE(8, 0x80), // System Control
HID_RI_COLLECTION(8, 0x01), // Application
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM), HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
HID_RI_USAGE_MINIMUM(16, 0x0081), // System Power Down
HID_RI_USAGE_MAXIMUM(16, 0x0083), // System Wake Up
HID_RI_LOGICAL_MINIMUM(16, 0x0001), HID_RI_LOGICAL_MINIMUM(16, 0x0001),
HID_RI_LOGICAL_MAXIMUM(16, 0x0003), 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_REPORT_COUNT(8, 1),
HID_RI_REPORT_SIZE(8, 16),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0), HID_RI_END_COLLECTION(0),
HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */ HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
HID_RI_USAGE(8, 0x01), /* Consumer Control */ HID_RI_USAGE(8, 0x01), // Consumer Control
HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_COLLECTION(8, 0x01), // Application
HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER), HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
HID_RI_USAGE_MINIMUM(16, 0x0001), // Consumer Control
HID_RI_USAGE_MAXIMUM(16, 0x029C), // AC Distribute Vertically
HID_RI_LOGICAL_MINIMUM(16, 0x0001), HID_RI_LOGICAL_MINIMUM(16, 0x0001),
HID_RI_LOGICAL_MAXIMUM(16, 0x029C), 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_REPORT_COUNT(8, 1),
HID_RI_REPORT_SIZE(8, 16),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0), HID_RI_END_COLLECTION(0),
# endif #endif
# ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
HID_RI_USAGE(8, 0x06), /* Keyboard */ HID_RI_USAGE(8, 0x06), // Keyboard
HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_COLLECTION(8, 0x01), // Application
HID_RI_REPORT_ID(8, REPORT_ID_NKRO), HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ // Modifiers (8 bits)
HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ 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_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, 0x08), HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
// Keycodes
HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
HID_RI_USAGE_MINIMUM(8, 0x00),
HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS * 8 - 1),
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS * 8),
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 */ // Status LEDs (5 bits)
HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ HID_RI_USAGE_PAGE(8, 0x08), // LED
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_COUNT(8, 0x05),
HID_RI_REPORT_SIZE(8, 0x01), 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_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
// LED padding (3 bits)
HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03), HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_OUTPUT(8, HID_IOF_CONSTANT), 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, KEYBOARD_REPORT_BITS*8-1),
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS*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), HID_RI_END_COLLECTION(0),
# endif #endif
#ifdef SHARED_EP_ENABLE #ifdef SHARED_EP_ENABLE
}; };
#endif #endif
#ifdef RAW_ENABLE #ifdef RAW_ENABLE
const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = {
{ HID_RI_USAGE_PAGE(16, 0xFF60), // Vendor Defined
HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */ HID_RI_USAGE(8, 0x61), // Vendor Defined
HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */ HID_RI_COLLECTION(8, 0x01), // Application
HID_RI_COLLECTION(8, 0x01), /* Application */ // Data to host
HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */ HID_RI_USAGE(8, 0x62), // Vendor Defined
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
HID_RI_REPORT_COUNT(8, RAW_EPSIZE), HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */ // Data from host
HID_RI_USAGE(8, 0x63), // Vendor Defined
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
HID_RI_REPORT_COUNT(8, RAW_EPSIZE), HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
@ -248,18 +252,19 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
#endif #endif
#ifdef CONSOLE_ENABLE #ifdef CONSOLE_ENABLE
const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
{ HID_RI_USAGE_PAGE(16, 0xFF31), // Vendor Defined (PJRC Teensy compatible)
HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */ HID_RI_USAGE(8, 0x74), // Vendor Defined (PJRC Teensy compatible)
HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */ HID_RI_COLLECTION(8, 0x01), // Application
HID_RI_COLLECTION(8, 0x01), /* Application */ // Data to host
HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */ HID_RI_USAGE(8, 0x75), // Vendor Defined
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */ // Data from host
HID_RI_USAGE(8, 0x76), // Vendor Defined
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
@ -269,15 +274,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
}; };
#endif #endif
/*
/******************************************************************************* * Device descriptor
* Device Descriptors */
******************************************************************************/ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = .Header = {
{ .Size = sizeof(USB_Descriptor_Device_t),
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Type = DTYPE_Device
},
.USBSpecification = VERSION_BCD(1,1,0), .USBSpecification = VERSION_BCD(1, 1, 0),
#if VIRTSER_ENABLE #if VIRTSER_ENABLE
.Class = USB_CSCP_IADDeviceClass, .Class = USB_CSCP_IADDeviceClass,
.SubClass = USB_CSCP_IADDeviceSubclass, .SubClass = USB_CSCP_IADDeviceSubclass,
@ -287,710 +292,698 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.SubClass = USB_CSCP_NoDeviceSubclass, .SubClass = USB_CSCP_NoDeviceSubclass,
.Protocol = USB_CSCP_NoDeviceProtocol, .Protocol = USB_CSCP_NoDeviceProtocol,
#endif #endif
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
// Specified in config.h
/* specified in config.h */
.VendorID = VENDOR_ID, .VendorID = VENDOR_ID,
.ProductID = PRODUCT_ID, .ProductID = PRODUCT_ID,
.ReleaseNumber = DEVICE_VER, .ReleaseNumber = DEVICE_VER,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = 0x03, .SerialNumStrIndex = 0x03,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/******************************************************************************* #ifndef USB_MAX_POWER_CONSUMPTION
* Configuration Descriptors #define USB_MAX_POWER_CONSUMPTION 500
******************************************************************************/ #endif
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) /*
* 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)
},
#ifndef KEYBOARD_SHARED_EP
/* /*
* Keyboard * Keyboard
*/ */
#ifndef KEYBOARD_SHARED_EP .Keyboard_Interface = {
.Keyboard_Interface = .Header = {
{ .Size = sizeof(USB_Descriptor_Interface_t),
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .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
}, },
.InterfaceNumber = KEYBOARD_INTERFACE,
.Keyboard_HID = .AlternateSetting = 0x00,
{ .TotalEndpoints = 1,
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .Class = HID_CSCP_HIDClass,
.SubClass = HID_CSCP_BootSubclass,
.HIDSpec = VERSION_BCD(1,1,1), .Protocol = HID_CSCP_KeyboardBootProtocol,
.CountryCode = 0x00,
.TotalReportDescriptors = 1, .InterfaceStrIndex = NO_DESCRIPTOR
.HIDReportType = HID_DTYPE_Report, },
.HIDReportLength = sizeof(KeyboardReport) .Keyboard_HID = {
.Header = {
.Size = sizeof(USB_HID_Descriptor_HID_t),
.Type = HID_DTYPE_HID
}, },
.HIDSpec = VERSION_BCD(1, 1, 1),
.Keyboard_INEndpoint = .CountryCode = 0x00,
{ .TotalReportDescriptors = 1,
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .HIDReportType = HID_DTYPE_Report,
.HIDReportLength = sizeof(KeyboardReport)
.EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM), },
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Keyboard_INEndpoint = {
.EndpointSize = KEYBOARD_EPSIZE, .Header = {
.PollingIntervalMS = 0x0A .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
},
#endif #endif
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
/* /*
* Mouse * Mouse
*/ */
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) .Mouse_Interface = {
.Mouse_Interface = .Header = {
{ .Size = sizeof(USB_Descriptor_Interface_t),
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .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
}, },
.InterfaceNumber = MOUSE_INTERFACE,
.Mouse_HID = .AlternateSetting = 0x00,
{ .TotalEndpoints = 1,
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .Class = HID_CSCP_HIDClass,
.SubClass = HID_CSCP_BootSubclass,
.HIDSpec = VERSION_BCD(1,1,1), .Protocol = HID_CSCP_MouseBootProtocol,
.CountryCode = 0x00, .InterfaceStrIndex = NO_DESCRIPTOR
.TotalReportDescriptors = 1, },
.HIDReportType = HID_DTYPE_Report, .Mouse_HID = {
.HIDReportLength = sizeof(MouseReport) .Header = {
.Size = sizeof(USB_HID_Descriptor_HID_t),
.Type = HID_DTYPE_HID
}, },
.HIDSpec = VERSION_BCD(1, 1, 1),
.Mouse_INEndpoint = .CountryCode = 0x00,
{ .TotalReportDescriptors = 1,
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .HIDReportType = HID_DTYPE_Report,
.HIDReportLength = sizeof(MouseReport)
.EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM), },
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Mouse_INEndpoint = {
.EndpointSize = MOUSE_EPSIZE, .Header = {
.PollingIntervalMS = 0x0A .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 #endif
#ifdef SHARED_EP_ENABLE
/* /*
* Shared * Shared
*/ */
#ifdef SHARED_EP_ENABLE .Shared_Interface = {
.Shared_Interface = .Header = {
{ .Size = sizeof(USB_Descriptor_Interface_t),
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Type = DTYPE_Interface
},
.InterfaceNumber = SHARED_INTERFACE, .InterfaceNumber = SHARED_INTERFACE,
.AlternateSetting = 0x00, .AlternateSetting = 0x00,
.TotalEndpoints = 1,
.TotalEndpoints = 1, .Class = HID_CSCP_HIDClass,
#ifdef KEYBOARD_SHARED_EP
.Class = HID_CSCP_HIDClass, .SubClass = HID_CSCP_BootSubclass,
# ifdef KEYBOARD_SHARED_EP .Protocol = HID_CSCP_KeyboardBootProtocol,
.SubClass = HID_CSCP_BootSubclass, #else
.Protocol = HID_CSCP_KeyboardBootProtocol, .SubClass = HID_CSCP_NonBootSubclass,
# else .Protocol = HID_CSCP_NonBootProtocol,
.SubClass = HID_CSCP_NonBootSubclass,
.Protocol = HID_CSCP_NonBootProtocol,
#endif #endif
.InterfaceStrIndex = NO_DESCRIPTOR
.InterfaceStrIndex = NO_DESCRIPTOR },
.Shared_HID = {
.Header = {
.Size = sizeof(USB_HID_Descriptor_HID_t),
.Type = HID_DTYPE_HID
}, },
.HIDSpec = VERSION_BCD(1, 1, 1),
.Shared_HID = .CountryCode = 0x00,
{ .TotalReportDescriptors = 1,
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .HIDReportType = HID_DTYPE_Report,
.HIDReportLength = sizeof(SharedReport)
.HIDSpec = VERSION_BCD(1,1,1), },
.CountryCode = 0x00, .Shared_INEndpoint = {
.TotalReportDescriptors = 1, .Header = {
.HIDReportType = HID_DTYPE_Report, .Size = sizeof(USB_Descriptor_Endpoint_t),
.HIDReportLength = sizeof(SharedReport) .Type = DTYPE_Endpoint
}, },
.EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = SHARED_EPSIZE,
.PollingIntervalMS = 0x0A
},
#endif
.Shared_INEndpoint = #ifdef RAW_ENABLE
{ /*
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, * Raw HID
*/
.EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM), .Raw_Interface = {
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Header = {
.EndpointSize = SHARED_EPSIZE, .Size = sizeof(USB_Descriptor_Interface_t),
.PollingIntervalMS = 0x0A .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 #endif
/* #ifdef CONSOLE_ENABLE
* 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 * Console
*/ */
#ifdef CONSOLE_ENABLE .Console_Interface = {
.Console_Interface = .Header = {
{ .Size = sizeof(USB_Descriptor_Interface_t),
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .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
}, },
.InterfaceNumber = CONSOLE_INTERFACE,
.Console_HID = .AlternateSetting = 0x00,
{ .TotalEndpoints = 2,
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, .Class = HID_CSCP_HIDClass,
.SubClass = HID_CSCP_NonBootSubclass,
.HIDSpec = VERSION_BCD(1,1,1), .Protocol = HID_CSCP_NonBootProtocol,
.CountryCode = 0x00, .InterfaceStrIndex = NO_DESCRIPTOR
.TotalReportDescriptors = 1, },
.HIDReportType = HID_DTYPE_Report, .Console_HID = {
.HIDReportLength = sizeof(ConsoleReport) .Header = {
.Size = sizeof(USB_HID_Descriptor_HID_t),
.Type = HID_DTYPE_HID
}, },
.HIDSpec = VERSION_BCD(1, 1, 1),
.Console_INEndpoint = .CountryCode = 0x00,
{ .TotalReportDescriptors = 1,
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .HIDReportType = HID_DTYPE_Report,
.HIDReportLength = sizeof(ConsoleReport)
.EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM), },
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Console_INEndpoint = {
.EndpointSize = CONSOLE_EPSIZE, .Header = {
.PollingIntervalMS = 0x01 .Size = sizeof(USB_Descriptor_Endpoint_t),
.Type = DTYPE_Endpoint
}, },
.EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
.Console_OUTEndpoint = .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
{ .EndpointSize = CONSOLE_EPSIZE,
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .PollingIntervalMS = 0x01
},
.EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM), .Console_OUTEndpoint = {
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Header = {
.EndpointSize = CONSOLE_EPSIZE, .Size = sizeof(USB_Descriptor_Endpoint_t),
.PollingIntervalMS = 0x01 .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 #endif
#ifdef MIDI_ENABLE #ifdef MIDI_ENABLE
.Audio_Interface_Association = /*
{ * MIDI
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation}, */
.Audio_Interface_Association = {
.FirstInterfaceIndex = AC_INTERFACE, .Header = {
.TotalInterfaces = 2, .Size = sizeof(USB_Descriptor_Interface_Association_t),
.Type = DTYPE_InterfaceAssociation
.Class = AUDIO_CSCP_AudioClass,
.SubClass = AUDIO_CSCP_ControlSubclass,
.Protocol = AUDIO_CSCP_ControlProtocol,
.IADStrIndex = NO_DESCRIPTOR,
}, },
.Audio_ControlInterface = .FirstInterfaceIndex = AC_INTERFACE,
{ .TotalInterfaces = 2,
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Class = AUDIO_CSCP_AudioClass,
.SubClass = AUDIO_CSCP_ControlSubclass,
.InterfaceNumber = AC_INTERFACE, .Protocol = AUDIO_CSCP_ControlProtocol,
.AlternateSetting = 0, .IADStrIndex = NO_DESCRIPTOR,
},
.TotalEndpoints = 0, .Audio_ControlInterface = {
.Header = {
.Class = AUDIO_CSCP_AudioClass, .Size = sizeof(USB_Descriptor_Interface_t),
.SubClass = AUDIO_CSCP_ControlSubclass, .Type = DTYPE_Interface
.Protocol = AUDIO_CSCP_ControlProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
}, },
.InterfaceNumber = AC_INTERFACE,
.Audio_ControlInterface_SPC = .AlternateSetting = 0,
{ .TotalEndpoints = 0,
.Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface}, .Class = AUDIO_CSCP_AudioClass,
.Subtype = AUDIO_DSUBTYPE_CSInterface_Header, .SubClass = AUDIO_CSCP_ControlSubclass,
.Protocol = AUDIO_CSCP_ControlProtocol,
.ACSpecification = VERSION_BCD(1,0,0), .InterfaceStrIndex = NO_DESCRIPTOR
.TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t), },
.Audio_ControlInterface_SPC = {
.InCollection = 1, .Header = {
.InterfaceNumber = AS_INTERFACE, .Size = sizeof(USB_Audio_Descriptor_Interface_AC_t),
.Type = DTYPE_CSInterface
}, },
.Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
.Audio_StreamInterface = .ACSpecification = VERSION_BCD(1, 0, 0),
{ .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .InCollection = 1,
.InterfaceNumber = AS_INTERFACE,
.InterfaceNumber = AS_INTERFACE, },
.AlternateSetting = 0, .Audio_StreamInterface = {
.Header = {
.TotalEndpoints = 2, .Size = sizeof(USB_Descriptor_Interface_t),
.Type = DTYPE_Interface
.Class = AUDIO_CSCP_AudioClass,
.SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
.Protocol = AUDIO_CSCP_StreamingProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
}, },
.InterfaceNumber = AS_INTERFACE,
.Audio_StreamInterface_SPC = .AlternateSetting = 0,
{ .TotalEndpoints = 2,
.Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface}, .Class = AUDIO_CSCP_AudioClass,
.Subtype = AUDIO_DSUBTYPE_CSInterface_General, .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
.Protocol = AUDIO_CSCP_StreamingProtocol,
.AudioSpecification = VERSION_BCD(1,0,0), .InterfaceStrIndex = NO_DESCRIPTOR
},
.TotalLength = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC) .Audio_StreamInterface_SPC = {
+ sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t) .Header = {
- offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC) .Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t),
.Type = DTYPE_CSInterface
}, },
.Subtype = AUDIO_DSUBTYPE_CSInterface_General,
.MIDI_In_Jack_Emb = .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)
.Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface}, },
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, .MIDI_In_Jack_Emb = {
.Header = {
.JackType = MIDI_JACKTYPE_Embedded, .Size = sizeof(USB_MIDI_Descriptor_InputJack_t),
.JackID = 0x01, .Type = DTYPE_CSInterface
.JackStrIndex = NO_DESCRIPTOR
}, },
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
.MIDI_In_Jack_Ext = .JackType = MIDI_JACKTYPE_Embedded,
{ .JackID = 0x01,
.Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface}, .JackStrIndex = NO_DESCRIPTOR
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal, },
.MIDI_In_Jack_Ext = {
.JackType = MIDI_JACKTYPE_External, .Header = {
.JackID = 0x02, .Size = sizeof(USB_MIDI_Descriptor_InputJack_t),
.Type = DTYPE_CSInterface
.JackStrIndex = NO_DESCRIPTOR
}, },
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
.MIDI_Out_Jack_Emb = .JackType = MIDI_JACKTYPE_External,
{ .JackID = 0x02,
.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface}, .JackStrIndex = NO_DESCRIPTOR
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, },
.MIDI_Out_Jack_Emb = {
.JackType = MIDI_JACKTYPE_Embedded, .Header = {
.JackID = 0x03, .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t),
.Type = DTYPE_CSInterface
.NumberOfPins = 1,
.SourceJackID = {0x02},
.SourcePinID = {0x01},
.JackStrIndex = NO_DESCRIPTOR
}, },
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
.MIDI_Out_Jack_Ext = .JackType = MIDI_JACKTYPE_Embedded,
{ .JackID = 0x03,
.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface}, .NumberOfPins = 1,
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal, .SourceJackID = {0x02},
.SourcePinID = {0x01},
.JackType = MIDI_JACKTYPE_External, .JackStrIndex = NO_DESCRIPTOR
.JackID = 0x04, },
.MIDI_Out_Jack_Ext = {
.NumberOfPins = 1, .Header = {
.SourceJackID = {0x01}, .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t),
.SourcePinID = {0x01}, .Type = DTYPE_CSInterface
.JackStrIndex = NO_DESCRIPTOR
}, },
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
.MIDI_In_Jack_Endpoint = .JackType = MIDI_JACKTYPE_External,
{ .JackID = 0x04,
.Endpoint = .NumberOfPins = 1,
{ .SourceJackID = {0x01},
.Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .SourcePinID = {0x01},
.JackStrIndex = NO_DESCRIPTOR
.EndpointAddress = MIDI_STREAM_OUT_EPADDR, },
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .MIDI_In_Jack_Endpoint = {
.EndpointSize = MIDI_STREAM_EPSIZE, .Endpoint = {
.PollingIntervalMS = 0x05 .Header = {
}, .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t),
.Type = DTYPE_Endpoint
.Refresh = 0, },
.SyncEndpointNumber = 0 .EndpointAddress = MIDI_STREAM_OUT_EPADDR,
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MIDI_STREAM_EPSIZE,
.PollingIntervalMS = 0x05
}, },
.Refresh = 0,
.MIDI_In_Jack_Endpoint_SPC = .SyncEndpointNumber = 0
{ },
.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint}, .MIDI_In_Jack_Endpoint_SPC = {
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, .Header = {
.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t),
.TotalEmbeddedJacks = 0x01, .Type = DTYPE_CSEndpoint
.AssociatedJackID = {0x01}
}, },
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
.MIDI_Out_Jack_Endpoint = .TotalEmbeddedJacks = 0x01,
{ .AssociatedJackID = {0x01}
.Endpoint = },
{ .MIDI_Out_Jack_Endpoint = {
.Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .Endpoint = {
.Header = {
.EndpointAddress = MIDI_STREAM_IN_EPADDR, .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Type = DTYPE_Endpoint
.EndpointSize = MIDI_STREAM_EPSIZE, },
.PollingIntervalMS = 0x05 .EndpointAddress = MIDI_STREAM_IN_EPADDR,
}, .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MIDI_STREAM_EPSIZE,
.Refresh = 0, .PollingIntervalMS = 0x05
.SyncEndpointNumber = 0
}, },
.Refresh = 0,
.MIDI_Out_Jack_Endpoint_SPC = .SyncEndpointNumber = 0
{ },
.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint}, .MIDI_Out_Jack_Endpoint_SPC = {
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General, .Header = {
.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t),
.TotalEmbeddedJacks = 0x01, .Type = DTYPE_CSEndpoint
.AssociatedJackID = {0x03}
}, },
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
.TotalEmbeddedJacks = 0x01,
.AssociatedJackID = {0x03}
},
#endif #endif
#ifdef VIRTSER_ENABLE #ifdef VIRTSER_ENABLE
.CDC_Interface_Association = /*
{ * Virtual Serial
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation}, */
.CDC_Interface_Association = {
.FirstInterfaceIndex = CCI_INTERFACE, .Header = {
.TotalInterfaces = 2, .Size = sizeof(USB_Descriptor_Interface_Association_t),
.Type = DTYPE_InterfaceAssociation
.Class = CDC_CSCP_CDCClass, },
.SubClass = CDC_CSCP_ACMSubclass, .FirstInterfaceIndex = CCI_INTERFACE,
.Protocol = CDC_CSCP_ATCommandProtocol, .TotalInterfaces = 2,
.Class = CDC_CSCP_CDCClass,
.IADStrIndex = NO_DESCRIPTOR, .SubClass = CDC_CSCP_ACMSubclass,
}, .Protocol = CDC_CSCP_ATCommandProtocol,
.IADStrIndex = NO_DESCRIPTOR,
.CDC_CCI_Interface = },
{ .CDC_CCI_Interface = {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {
.Size = sizeof(USB_Descriptor_Interface_t),
.InterfaceNumber = CCI_INTERFACE, .Type = DTYPE_Interface
.AlternateSetting = 0, },
.InterfaceNumber = CCI_INTERFACE,
.TotalEndpoints = 1, .AlternateSetting = 0,
.TotalEndpoints = 1,
.Class = CDC_CSCP_CDCClass, .Class = CDC_CSCP_CDCClass,
.SubClass = CDC_CSCP_ACMSubclass, .SubClass = CDC_CSCP_ACMSubclass,
.Protocol = CDC_CSCP_ATCommandProtocol, .Protocol = CDC_CSCP_ATCommandProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
.InterfaceStrIndex = NO_DESCRIPTOR },
}, .CDC_Functional_Header = {
.Header = {
.CDC_Functional_Header = .Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t),
{ .Type = DTYPE_CSInterface
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface}, },
.Subtype = 0x00, .Subtype = 0x00,
.CDCSpecification = VERSION_BCD(1, 1, 0),
.CDCSpecification = VERSION_BCD(1,1,0), },
}, .CDC_Functional_ACM = {
.Header = {
.CDC_Functional_ACM = .Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t),
{ .Type = DTYPE_CSInterface
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface}, },
.Subtype = 0x02, .Subtype = 0x02,
.Capabilities = 0x02,
.Capabilities = 0x02, },
}, .CDC_Functional_Union = {
.Header = {
.CDC_Functional_Union = .Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t),
{ .Type = DTYPE_CSInterface
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface}, },
.Subtype = 0x06, .Subtype = 0x06,
.MasterInterfaceNumber = CCI_INTERFACE,
.MasterInterfaceNumber = CCI_INTERFACE, .SlaveInterfaceNumber = CDI_INTERFACE,
.SlaveInterfaceNumber = CDI_INTERFACE, },
}, .CDC_NotificationEndpoint = {
.Header = {
.CDC_NotificationEndpoint = .Size = sizeof(USB_Descriptor_Endpoint_t),
{ .Type = DTYPE_Endpoint
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, },
.EndpointAddress = CDC_NOTIFICATION_EPADDR,
.EndpointAddress = CDC_NOTIFICATION_EPADDR, .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = CDC_NOTIFICATION_EPSIZE,
.EndpointSize = CDC_NOTIFICATION_EPSIZE, .PollingIntervalMS = 0xFF
.PollingIntervalMS = 0xFF },
}, .CDC_DCI_Interface = {
.Header = {
.CDC_DCI_Interface = .Size = sizeof(USB_Descriptor_Interface_t),
{ .Type = DTYPE_Interface
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, },
.InterfaceNumber = CDI_INTERFACE,
.InterfaceNumber = CDI_INTERFACE, .AlternateSetting = 0,
.AlternateSetting = 0, .TotalEndpoints = 2,
.Class = CDC_CSCP_CDCDataClass,
.TotalEndpoints = 2, .SubClass = CDC_CSCP_NoDataSubclass,
.Protocol = CDC_CSCP_NoDataProtocol,
.Class = CDC_CSCP_CDCDataClass, .InterfaceStrIndex = NO_DESCRIPTOR
.SubClass = CDC_CSCP_NoDataSubclass, },
.Protocol = CDC_CSCP_NoDataProtocol, .CDC_DataOutEndpoint = {
.Header = {
.InterfaceStrIndex = NO_DESCRIPTOR .Size = sizeof(USB_Descriptor_Endpoint_t),
}, .Type = DTYPE_Endpoint
},
.CDC_DataOutEndpoint = .EndpointAddress = CDC_OUT_EPADDR,
{ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointSize = CDC_EPSIZE,
.PollingIntervalMS = 0x05
.EndpointAddress = CDC_OUT_EPADDR, },
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .CDC_DataInEndpoint = {
.EndpointSize = CDC_EPSIZE, .Header = {
.PollingIntervalMS = 0x05 .Size = sizeof(USB_Descriptor_Endpoint_t),
}, .Type = DTYPE_Endpoint
},
.CDC_DataInEndpoint = .EndpointAddress = CDC_IN_EPADDR,
{ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .EndpointSize = CDC_EPSIZE,
.PollingIntervalMS = 0x05
.EndpointAddress = CDC_IN_EPADDR, },
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_EPSIZE,
.PollingIntervalMS = 0x05
},
#endif #endif
}; };
/*
/******************************************************************************* * String descriptors
* String Descriptors */
******************************************************************************/ const USB_Descriptor_String_t PROGMEM LanguageString = {
const USB_Descriptor_String_t PROGMEM LanguageString = .Header = {
{ .Size = USB_STRING_LEN(1),
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Type = DTYPE_String
},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
const USB_Descriptor_String_t PROGMEM ManufacturerString = const USB_Descriptor_String_t PROGMEM ManufacturerString = {
{ .Header = {
/* subtract 1 for null terminator */ .Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1), // Subtract 1 for null terminator
.Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String}, .Type = DTYPE_String
},
.UnicodeString = LSTR(MANUFACTURER) .UnicodeString = LSTR(MANUFACTURER)
}; };
const USB_Descriptor_String_t PROGMEM ProductString = const USB_Descriptor_String_t PROGMEM ProductString = {
{ .Header = {
/* subtract 1 for null terminator */ .Size = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1), // Subtract 1 for null terminator
.Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String}, .Type = DTYPE_String
},
.UnicodeString = LSTR(PRODUCT) .UnicodeString = LSTR(PRODUCT)
}; };
#ifndef SERIAL_NUMBER #ifndef SERIAL_NUMBER
#define SERIAL_NUMBER 0 #define SERIAL_NUMBER 0
#endif #endif
const USB_Descriptor_String_t PROGMEM SerialNumberString = const USB_Descriptor_String_t PROGMEM SerialNumberString = {
{ .Header = {
/* subtract 1 for null terminator */ .Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), // Subtract 1 for null terminator
.Header = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER))-1), .Type = DTYPE_String}, .Type = DTYPE_String
},
.UnicodeString = LSTR(SERIAL_NUMBER) .UnicodeString = LSTR(SERIAL_NUMBER)
}; };
/**
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" * 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 * 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 * 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 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t get_usb_descriptor(const uint16_t wValue, uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress) {
const uint16_t wIndex, const uint8_t DescriptorType = (wValue >> 8);
const void** const DescriptorAddress) const uint8_t DescriptorIndex = (wValue & 0xFF);
{ const void* Address = NULL;
const uint8_t DescriptorType = (wValue >> 8); uint16_t Size = NO_DESCRIPTOR;
const uint8_t DescriptorIndex = (wValue & 0xFF);
switch (DescriptorType) {
const void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType)
{
case DTYPE_Device: case DTYPE_Device:
Address = &DeviceDescriptor; Address = &DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = &ConfigurationDescriptor; Address = &ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorIndex ) switch (DescriptorIndex) {
{
case 0x00: case 0x00:
Address = &LanguageString; Address = &LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = &ManufacturerString; Address = &ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = &ProductString; Address = &ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
case 0x03: case 0x03:
Address = &SerialNumberString; Address = &SerialNumberString;
Size = pgm_read_byte(&SerialNumberString.Header.Size); Size = pgm_read_byte(&SerialNumberString.Header.Size);
break; break;
} }
break; break;
case HID_DTYPE_HID: case HID_DTYPE_HID:
switch (wIndex) { switch (wIndex) {
#ifndef KEYBOARD_SHARED_EP #ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE: case KEYBOARD_INTERFACE:
Address = &ConfigurationDescriptor.Keyboard_HID; Address = &ConfigurationDescriptor.Keyboard_HID;
Size = sizeof(USB_HID_Descriptor_HID_t); Size = sizeof(USB_HID_Descriptor_HID_t);
break; break;
#endif #endif
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE: case MOUSE_INTERFACE:
Address = &ConfigurationDescriptor.Mouse_HID; Address = &ConfigurationDescriptor.Mouse_HID;
Size = sizeof(USB_HID_Descriptor_HID_t); Size = sizeof(USB_HID_Descriptor_HID_t);
break;
break;
#endif #endif
#ifdef SHARED_EP_ENABLE #ifdef SHARED_EP_ENABLE
case SHARED_INTERFACE: case SHARED_INTERFACE:
Address = &ConfigurationDescriptor.Shared_HID; Address = &ConfigurationDescriptor.Shared_HID;
Size = sizeof(USB_HID_Descriptor_HID_t); Size = sizeof(USB_HID_Descriptor_HID_t);
break;
break;
#endif #endif
#ifdef RAW_ENABLE #ifdef RAW_ENABLE
case RAW_INTERFACE: case RAW_INTERFACE:
Address = &ConfigurationDescriptor.Raw_HID; Address = &ConfigurationDescriptor.Raw_HID;
Size = sizeof(USB_HID_Descriptor_HID_t); Size = sizeof(USB_HID_Descriptor_HID_t);
break;
break;
#endif #endif
#ifdef CONSOLE_ENABLE #ifdef CONSOLE_ENABLE
case CONSOLE_INTERFACE: case CONSOLE_INTERFACE:
Address = &ConfigurationDescriptor.Console_HID; Address = &ConfigurationDescriptor.Console_HID;
Size = sizeof(USB_HID_Descriptor_HID_t); Size = sizeof(USB_HID_Descriptor_HID_t);
break;
break;
#endif #endif
} }
break; break;
case HID_DTYPE_Report: case HID_DTYPE_Report:
switch (wIndex) { switch (wIndex) {
#ifndef KEYBOARD_SHARED_EP #ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE: case KEYBOARD_INTERFACE:
Address = &KeyboardReport; Address = &KeyboardReport;
Size = sizeof(KeyboardReport); Size = sizeof(KeyboardReport);
break;
break;
#endif #endif
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE: case MOUSE_INTERFACE:
Address = &MouseReport; Address = &MouseReport;
Size = sizeof(MouseReport); Size = sizeof(MouseReport);
break;
break;
#endif #endif
#ifdef SHARED_EP_ENABLE #ifdef SHARED_EP_ENABLE
case SHARED_INTERFACE: case SHARED_INTERFACE:
Address = &SharedReport; Address = &SharedReport;
Size = sizeof(SharedReport); Size = sizeof(SharedReport);
break;
break;
#endif #endif
#ifdef RAW_ENABLE #ifdef RAW_ENABLE
case RAW_INTERFACE: case RAW_INTERFACE:
Address = &RawReport; Address = &RawReport;
Size = sizeof(RawReport); Size = sizeof(RawReport);
break;
break;
#endif #endif
#ifdef CONSOLE_ENABLE #ifdef CONSOLE_ENABLE
case CONSOLE_INTERFACE: case CONSOLE_INTERFACE:
Address = &ConsoleReport; Address = &ConsoleReport;
Size = sizeof(ConsoleReport); Size = sizeof(ConsoleReport);
break;
break;
#endif #endif
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

@ -6,95 +6,97 @@
*/ */
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2012. Copyright (C) Dean Camera, 2012.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org www.lufa-lib.org
*/ */
/* /*
Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#ifdef PROTOCOL_CHIBIOS
#include "hal.h"
#endif
typedef struct #ifdef PROTOCOL_CHIBIOS
{ #include "hal.h"
USB_Descriptor_Configuration_Header_t Config; #endif
/*
* USB descriptor structure
*/
typedef struct {
USB_Descriptor_Configuration_Header_t Config;
#ifndef KEYBOARD_SHARED_EP #ifndef KEYBOARD_SHARED_EP
// Keyboard HID Interface // Keyboard HID Interface
USB_Descriptor_Interface_t Keyboard_Interface; USB_Descriptor_Interface_t Keyboard_Interface;
USB_HID_Descriptor_HID_t Keyboard_HID; USB_HID_Descriptor_HID_t Keyboard_HID;
USB_Descriptor_Endpoint_t Keyboard_INEndpoint; USB_Descriptor_Endpoint_t Keyboard_INEndpoint;
#endif #endif
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
// Mouse HID Interface // Mouse HID Interface
USB_Descriptor_Interface_t Mouse_Interface; USB_Descriptor_Interface_t Mouse_Interface;
USB_HID_Descriptor_HID_t Mouse_HID; USB_HID_Descriptor_HID_t Mouse_HID;
USB_Descriptor_Endpoint_t Mouse_INEndpoint; USB_Descriptor_Endpoint_t Mouse_INEndpoint;
#endif #endif
#if defined(SHARED_EP_ENABLE) #ifdef SHARED_EP_ENABLE
USB_Descriptor_Interface_t Shared_Interface; // Shared Interface
USB_HID_Descriptor_HID_t Shared_HID; USB_Descriptor_Interface_t Shared_Interface;
USB_Descriptor_Endpoint_t Shared_INEndpoint; USB_HID_Descriptor_HID_t Shared_HID;
#endif USB_Descriptor_Endpoint_t Shared_INEndpoint;
#endif
#if defined(RAW_ENABLE)
#ifdef RAW_ENABLE
// Raw HID Interface // Raw HID Interface
USB_Descriptor_Interface_t Raw_Interface; USB_Descriptor_Interface_t Raw_Interface;
USB_HID_Descriptor_HID_t Raw_HID; USB_HID_Descriptor_HID_t Raw_HID;
USB_Descriptor_Endpoint_t Raw_INEndpoint; USB_Descriptor_Endpoint_t Raw_INEndpoint;
USB_Descriptor_Endpoint_t Raw_OUTEndpoint; USB_Descriptor_Endpoint_t Raw_OUTEndpoint;
#endif #endif
#ifdef CONSOLE_ENABLE #ifdef CONSOLE_ENABLE
// Console HID Interface // Console HID Interface
USB_Descriptor_Interface_t Console_Interface; USB_Descriptor_Interface_t Console_Interface;
USB_HID_Descriptor_HID_t Console_HID; USB_HID_Descriptor_HID_t Console_HID;
USB_Descriptor_Endpoint_t Console_INEndpoint; USB_Descriptor_Endpoint_t Console_INEndpoint;
USB_Descriptor_Endpoint_t Console_OUTEndpoint; USB_Descriptor_Endpoint_t Console_OUTEndpoint;
#endif #endif
#ifdef MIDI_ENABLE #ifdef MIDI_ENABLE
USB_Descriptor_Interface_Association_t Audio_Interface_Association; USB_Descriptor_Interface_Association_t Audio_Interface_Association;
// MIDI Audio Control Interface // MIDI Audio Control Interface
USB_Descriptor_Interface_t Audio_ControlInterface; USB_Descriptor_Interface_t Audio_ControlInterface;
USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC; USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC;
// MIDI Audio Streaming Interface // MIDI Audio Streaming Interface
USB_Descriptor_Interface_t Audio_StreamInterface; USB_Descriptor_Interface_t Audio_StreamInterface;
USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC; USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC;
@ -106,141 +108,146 @@ typedef struct
USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC; USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint; USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC; USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC;
#endif #endif
#ifdef VIRTSER_ENABLE #ifdef VIRTSER_ENABLE
USB_Descriptor_Interface_Association_t CDC_Interface_Association; USB_Descriptor_Interface_Association_t CDC_Interface_Association;
// CDC Control Interface
// CDC Control Interface USB_Descriptor_Interface_t CDC_CCI_Interface;
USB_Descriptor_Interface_t CDC_CCI_Interface; USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header; USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM; USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union; USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
USB_Descriptor_Endpoint_t CDC_NotificationEndpoint; // CDC Data Interface
USB_Descriptor_Interface_t CDC_DCI_Interface;
// CDC Data Interface USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
USB_Descriptor_Interface_t CDC_DCI_Interface; USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint; #endif
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
#endif
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/*
/* index of interface */ * Interface indexes
*/
enum usb_interfaces { enum usb_interfaces {
#if !defined(KEYBOARD_SHARED_EP) #ifndef KEYBOARD_SHARED_EP
KEYBOARD_INTERFACE, KEYBOARD_INTERFACE,
#else #else
# define KEYBOARD_INTERFACE SHARED_INTERFACE #define KEYBOARD_INTERFACE SHARED_INTERFACE
#endif #endif
// It is important that the Raw HID interface is at a constant
// interface number, to support Linux/OSX platforms and chrome.hid // It is important that the Raw HID interface is at a constant
// If Raw HID is enabled, let it be always 1. // interface number, to support Linux/OSX platforms and chrome.hid
#if defined(RAW_ENABLE) // If Raw HID is enabled, let it be always 1.
#ifdef RAW_ENABLE
RAW_INTERFACE, RAW_INTERFACE,
#endif #endif
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
MOUSE_INTERFACE, MOUSE_INTERFACE,
#endif #endif
#if defined(SHARED_EP_ENABLE)
#ifdef SHARED_EP_ENABLE
SHARED_INTERFACE, SHARED_INTERFACE,
#endif #endif
#if defined(CONSOLE_ENABLE)
#ifdef CONSOLE_ENABLE
CONSOLE_INTERFACE, CONSOLE_INTERFACE,
#endif #endif
#if defined(MIDI_ENABLE)
#ifdef MIDI_ENABLE
AC_INTERFACE, AC_INTERFACE,
AS_INTERFACE, AS_INTERFACE,
#endif #endif
#if defined(VIRTSER_ENABLE)
#ifdef VIRTSER_ENABLE
CCI_INTERFACE, CCI_INTERFACE,
CDI_INTERFACE, CDI_INTERFACE,
#endif #endif
TOTAL_INTERFACES TOTAL_INTERFACES
}; };
#define NEXT_EPNUM __COUNTER__ #define NEXT_EPNUM __COUNTER__
/*
* Endpoint numbers
*/
enum usb_endpoints { enum usb_endpoints {
__unused_epnum__ = NEXT_EPNUM, /* EP numbering starts at 1 */ __unused_epnum__ = NEXT_EPNUM, // Endpoint numbering starts at 1
#if !defined(KEYBOARD_SHARED_EP)
#ifndef KEYBOARD_SHARED_EP
KEYBOARD_IN_EPNUM = NEXT_EPNUM, KEYBOARD_IN_EPNUM = NEXT_EPNUM,
#else #else
# define KEYBOARD_IN_EPNUM SHARED_IN_EPNUM #define KEYBOARD_IN_EPNUM SHARED_IN_EPNUM
#endif #endif
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
MOUSE_IN_EPNUM = NEXT_EPNUM, MOUSE_IN_EPNUM = NEXT_EPNUM,
#else #else
# define MOUSE_IN_EPNUM SHARED_IN_EPNUM #define MOUSE_IN_EPNUM SHARED_IN_EPNUM
#endif #endif
#if defined(RAW_ENABLE)
#ifdef RAW_ENABLE
RAW_IN_EPNUM = NEXT_EPNUM, RAW_IN_EPNUM = NEXT_EPNUM,
RAW_OUT_EPNUM = NEXT_EPNUM, RAW_OUT_EPNUM = NEXT_EPNUM,
#endif #endif
#if defined(SHARED_EP_ENABLE)
#ifdef SHARED_EP_ENABLE
SHARED_IN_EPNUM = NEXT_EPNUM, SHARED_IN_EPNUM = NEXT_EPNUM,
#endif #endif
#if defined(CONSOLE_ENABLE)
#ifdef CONSOLE_ENABLE
CONSOLE_IN_EPNUM = NEXT_EPNUM, CONSOLE_IN_EPNUM = NEXT_EPNUM,
#ifdef PROTOCOL_CHIBIOS
// ChibiOS has enough memory and descriptor to actually enable the endpoint #ifdef PROTOCOL_CHIBIOS
// It could use the same endpoint numbers, as that's supported by ChibiOS // ChibiOS has enough memory and descriptor to actually enable the endpoint
// But the QMK code currently assumes that the endpoint numbers are different // It could use the same endpoint numbers, as that's supported by ChibiOS
// But the QMK code currently assumes that the endpoint numbers are different
CONSOLE_OUT_EPNUM = NEXT_EPNUM, CONSOLE_OUT_EPNUM = NEXT_EPNUM,
#else #else
#define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM #define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
#endif #endif
#endif #endif
#ifdef MIDI_ENABLE
#ifdef MIDI_ENABLE
MIDI_STREAM_IN_EPNUM = NEXT_EPNUM, MIDI_STREAM_IN_EPNUM = NEXT_EPNUM,
MIDI_STREAM_OUT_EPNUM = NEXT_EPNUM, MIDI_STREAM_OUT_EPNUM = NEXT_EPNUM,
# define MIDI_STREAM_IN_EPADDR (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM) #define MIDI_STREAM_IN_EPADDR (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM)
# define MIDI_STREAM_OUT_EPADDR (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM) #define MIDI_STREAM_OUT_EPADDR (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM)
#endif #endif
#ifdef VIRTSER_ENABLE
#ifdef VIRTSER_ENABLE
CDC_NOTIFICATION_EPNUM = NEXT_EPNUM, CDC_NOTIFICATION_EPNUM = NEXT_EPNUM,
CDC_IN_EPNUM = NEXT_EPNUM, CDC_IN_EPNUM = NEXT_EPNUM,
CDC_OUT_EPNUM = NEXT_EPNUM, CDC_OUT_EPNUM = NEXT_EPNUM,
# define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM) #define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM)
# define CDC_IN_EPADDR (ENDPOINT_DIR_IN | CDC_IN_EPNUM) #define CDC_IN_EPADDR (ENDPOINT_DIR_IN | CDC_IN_EPNUM)
# define CDC_OUT_EPADDR (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM) #define CDC_OUT_EPADDR (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM)
#endif #endif
}; };
#if defined(PROTOCOL_LUFA) #ifdef PROTOCOL_LUFA
/* LUFA tells us total endpoints including control */ // LUFA tells us total endpoints including control
#define MAX_ENDPOINTS (ENDPOINT_TOTAL_ENDPOINTS - 1) #define MAX_ENDPOINTS (ENDPOINT_TOTAL_ENDPOINTS - 1)
#elif defined(PROTOCOL_CHIBIOS) #elif defined(PROTOCOL_CHIBIOS)
/* ChibiOS gives us number of available user endpoints, not control */ // ChibiOS gives us number of available user endpoints, not control
#define MAX_ENDPOINTS USB_MAX_ENDPOINTS #define MAX_ENDPOINTS USB_MAX_ENDPOINTS
#endif #endif
/* TODO - ARM_ATSAM */
// TODO - ARM_ATSAM
#if (NEXT_EPNUM - 1) > MAX_ENDPOINTS #if (NEXT_EPNUM - 1) > MAX_ENDPOINTS
# error There are not enough available endpoints to support all functions. Remove some in the rules.mk file. (MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL, STENO) #error There are not enough available endpoints to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Console, NKRO, MIDI, Serial, Steno
#endif #endif
#define KEYBOARD_EPSIZE 8 #define KEYBOARD_EPSIZE 8
#define SHARED_EPSIZE 32 #define SHARED_EPSIZE 32
#define MOUSE_EPSIZE 8 #define MOUSE_EPSIZE 8
#define RAW_EPSIZE 32 #define RAW_EPSIZE 32
#define CONSOLE_EPSIZE 32 #define CONSOLE_EPSIZE 32
#define MIDI_STREAM_EPSIZE 64 #define MIDI_STREAM_EPSIZE 64
#define CDC_NOTIFICATION_EPSIZE 8 #define CDC_NOTIFICATION_EPSIZE 8
#define CDC_EPSIZE 16 #define CDC_EPSIZE 16
uint16_t get_usb_descriptor(const uint16_t wValue, uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress);
const uint16_t wIndex,
const void** const DescriptorAddress);
/* new API */
#if LUFA_VERSION_INTEGER < 0x140302
#undef VERSION_BCD
#define VERSION_BCD(Major, Minor, Revision) \
CPU_TO_LE16( ((Major & 0xFF) << 8) | \
((Minor & 0x0F) << 4) | \
(Revision & 0x0F) )
#endif
#endif #endif

Loading…
Cancel
Save