X-Git-Url: https://git.donarmstrong.com/?p=kiibohd-controller.git;a=blobdiff_plain;f=Output%2FpjrcUSB%2Farm%2Fusb_desc.c;h=70ece51ca7345bc5ab52b936fffd28b28c7f7fea;hp=0deaa82e103cec1f28a3b54e5a62e0030893659a;hb=7e68e81f4757ffff2261ab4a887d4114318aa5b6;hpb=99d4aaba847eeda2f6dde4826e8ef97370709c6a diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 0deaa82..70ece51 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2013-2014) + * Modified by Jacob Alexander (2013-2015) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -29,369 +29,720 @@ * SOFTWARE. */ -#include "usb_desc.h" - +// ----- Includes ----- -// USB Descriptors are binary data which the USB host reads to -// automatically detect a USB device's capabilities. The format -// and meaning of every field is documented in numerous USB -// standards. When working with USB descriptors, despite the -// complexity of the standards and poor writing quality in many -// of those documents, remember descriptors are nothing more -// than constant binary data that tells the USB host what the -// device can do. Computers will load drivers based on this data. -// Those drivers then communicate on the endpoints specified by -// the descriptors. +// Local Includes +#include "usb_desc.h" -// To configure a new combination of interfaces or make minor -// changes to existing configuration (eg, change the name or ID -// numbers), usually you would edit "usb_desc.h". This file -// is meant to be configured by the header, so generally it is -// only edited to add completely new USB interfaces or features. +// Generated Includes +#include -// ************************************************************** -// USB Device -// ************************************************************** +// ----- Macros ----- #define LSB(n) ((n) & 255) #define MSB(n) (((n) >> 8) & 255) + + +// ----- USB Device Descriptor ----- + // USB Device Descriptor. The USB host reads this first, to learn // what type of device is connected. static uint8_t device_descriptor[] = { - 18, // bLength - 1, // bDescriptorType - 0x00, 0x02, // bcdUSB -#ifdef DEVICE_CLASS - DEVICE_CLASS, // bDeviceClass -#else - 0, -#endif -#ifdef DEVICE_SUBCLASS - DEVICE_SUBCLASS, // bDeviceSubClass -#else - 0, -#endif -#ifdef DEVICE_PROTOCOL - DEVICE_PROTOCOL, // bDeviceProtocol -#else - 0, -#endif - EP0_SIZE, // bMaxPacketSize0 - LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor - LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct - 0x00, 0x01, // bcdDevice - 1, // iManufacturer - 2, // iProduct - 3, // iSerialNumber - 1 // bNumConfigurations + 18, // bLength + 1, // bDescriptorType + 0x00, 0x02, // bcdUSB + DEVICE_CLASS, // bDeviceClass + DEVICE_SUBCLASS, // bDeviceSubClass + DEVICE_PROTOCOL, // bDeviceProtocol + EP0_SIZE, // bMaxPacketSize0 + LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor + LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct + 0x00, 0x01, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 3, // iSerialNumber + 1 // bNumConfigurations +}; + +// USB Device Qualifier Descriptor +static uint8_t device_qualifier_descriptor[] = { + 0 // Indicate only single speed + /* Device qualifier example (used for specifying multiple USB speeds) + 10, // bLength + 6, // bDescriptorType + 0x00, 0x02, // bcdUSB + DEVICE_CLASS, // bDeviceClass + DEVICE_SUBCLASS, // bDeviceSubClass + DEVICE_PROTOCOL, // bDeviceProtocol + EP0_SIZE, // bMaxPacketSize0 + 0, // bNumOtherSpeedConfigurations + 0 // bReserved + */ }; +// USB Debug Descriptor +// XXX Not sure of exact use, lsusb requests it +static uint8_t usb_debug_descriptor[] = { + 0 +}; + +// XXX // These descriptors must NOT be "const", because the USB DMA // has trouble accessing flash memory with enough bandwidth // while the processor is executing from flash. +// XXX -// ************************************************************** -// HID Report Descriptors -// ************************************************************** +// ----- USB HID Report Descriptors ----- // Each HID interface needs a special report descriptor that tells // the meaning and format of the data. -#ifdef KEYBOARD_INTERFACE // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 static uint8_t keyboard_report_desc[] = { - 0x05, 0x01, // Usage Page (Generic Desktop), - 0x09, 0x06, // Usage (Keyboard), - 0xA1, 0x01, // Collection (Application), - 0x75, 0x01, // Report Size (1), - 0x95, 0x08, // Report Count (8), - 0x05, 0x07, // Usage Page (Key Codes), - 0x19, 0xE0, // Usage Minimum (224), - 0x29, 0xE7, // Usage Maximum (231), - 0x15, 0x00, // Logical Minimum (0), - 0x25, 0x01, // Logical Maximum (1), - 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte - 0x95, 0x08, // Report Count (8), - 0x75, 0x01, // Report Size (1), - 0x15, 0x00, // Logical Minimum (0), - 0x25, 0x01, // Logical Maximum (1), - 0x05, 0x0C, // Usage Page (Consumer), - 0x09, 0xE9, // Usage (Volume Increment), - 0x09, 0xEA, // Usage (Volume Decrement), - 0x09, 0xE2, // Usage (Mute), - 0x09, 0xCD, // Usage (Play/Pause), - 0x09, 0xB5, // Usage (Scan Next Track), - 0x09, 0xB6, // Usage (Scan Previous Track), - 0x09, 0xB7, // Usage (Stop), - 0x09, 0xB8, // Usage (Eject), - 0x81, 0x02, // Input (Data, Variable, Absolute), ;Media keys - 0x95, 0x05, // Report Count (5), - 0x75, 0x01, // Report Size (1), - 0x05, 0x08, // Usage Page (LEDs), - 0x19, 0x01, // Usage Minimum (1), - 0x29, 0x05, // Usage Maximum (5), - 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report - 0x95, 0x01, // Report Count (1), - 0x75, 0x03, // Report Size (3), - 0x91, 0x03, // Output (Constant), ;LED report padding - 0x95, 0x06, // Report Count (6), - 0x75, 0x08, // Report Size (8), - 0x15, 0x00, // Logical Minimum (0), - 0x25, 0x7F, // Logical Maximum(104), - 0x05, 0x07, // Usage Page (Key Codes), - 0x19, 0x00, // Usage Minimum (0), - 0x29, 0x7F, // Usage Maximum (104), - 0x81, 0x00, // Input (Data, Array), ;Normal keys - 0xc0 // End Collection + // Keyboard Collection + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x06, // Usage (Keyboard), + 0xA1, 0x01, // Collection (Application) - Keyboard, + + // Modifier Byte + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xE0, // Usage Minimum (224), + 0x29, 0xE7, // Usage Maximum (231), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x81, 0x02, // Input (Data, Variable, Absolute), + + // Reserved Byte + 0x75, 0x08, // Report Size (8), + 0x95, 0x01, // Report Count (1), + 0x81, 0x03, // Output (Constant), + + // LED Report + 0x75, 0x01, // Report Size (1), + 0x95, 0x05, // Report Count (5), + 0x05, 0x08, // Usage Page (LEDs), + 0x19, 0x01, // Usage Minimum (1), + 0x29, 0x05, // Usage Maximum (5), + 0x91, 0x02, // Output (Data, Variable, Absolute), + + // LED Report Padding + 0x75, 0x03, // Report Size (3), + 0x95, 0x01, // Report Count (1), + 0x91, 0x03, // Output (Constant), + + // Normal Keys + 0x75, 0x08, // Report Size (8), + 0x95, 0x06, // Report Count (6), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x7F, // Logical Maximum(104), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x00, // Usage Minimum (0), + 0x29, 0x7F, // Usage Maximum (104), + 0x81, 0x00, // Input (Data, Array), + 0xc0, // End Collection - Keyboard +}; + +// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 +static uint8_t nkro_keyboard_report_desc[] = { + // Keyboard Collection + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x06, // Usage (Keyboard), + 0xA1, 0x01, // Collection (Application) - Keyboard, + + // LED Report + 0x85, 0x01, // Report ID (1), + 0x75, 0x01, // Report Size (1), + 0x95, 0x05, // Report Count (5), + 0x05, 0x08, // Usage Page (LEDs), + 0x19, 0x01, // Usage Minimum (1), + 0x29, 0x05, // Usage Maximum (5), + 0x91, 0x02, // Output (Data, Variable, Absolute), + + // LED Report Padding + 0x75, 0x03, // Report Size (3), + 0x95, 0x01, // Report Count (1), + 0x91, 0x03, // Output (Constant), + + // Normal Keys - Using an NKRO Bitmap + // + // NOTES: + // Supports all keys defined by the spec, except 1-3 which define error events + // and 0 which is "no keys pressed" + // See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf Chapter 10 + // Or Macros/PartialMap/usb_hid.h + // + // 50 (ISO \ due to \ bug) and 156 (Clear due to Delete bug) must be excluded + // due to a Linux bug with bitmaps (not useful anyways) + // 165-175 are reserved/unused as well as 222-223 and 232-65535 + // + // Compatibility Notes: + // - Using a second endpoint for a boot mode device helps with compatibility + // - DO NOT use Padding in the descriptor for bitfields + // (Mac OSX silently fails... Windows/Linux work correctly) + // - DO NOT use Report IDs, Windows 8.1 will not update keyboard correctly (modifiers disappear) + // (all other OSs, including OSX work fine...) + // (you can use them *iff* you only have 1 per collection) + // - Mac OSX and Windows 8.1 are extremely picky about padding + // + // Packing of bitmaps are as follows: + // 4-49 : 6 bytes (0x04-0x31) ( 46 bits + 2 padding bits for 6 bytes total) + // 51-155 : 14 bytes (0x33-0x9B) (105 bits + 6 padding bits for 15 bytes total) + // 157-164 : 1 byte (0x9D-0xA4) ( 8 bits) + // 176-221 : 6 bytes (0xB0-0xDD) ( 46 bits + 2 padding bits for 6 bytes total) + // 224-231 : 1 byte (0xE0-0xE7) ( 8 bits) + + // Modifier Byte + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xE0, // Usage Minimum (224), + 0x29, 0xE7, // Usage Maximum (231), + 0x81, 0x02, // Input (Data, Variable, Absolute), + + // 4-49 (6 bytes/46 bits) - MainKeys + 0x75, 0x01, // Report Size (1), + 0x95, 0x2E, // Report Count (46), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x04, // Usage Minimum (4), + 0x29, 0x31, // Usage Maximum (49), + 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), + + // Padding (2 bits) + 0x75, 0x02, // Report Size (2), + 0x95, 0x01, // Report Count (1), + 0x81, 0x03, // Input (Constant), + + // 51-155 (14 bytes/105 bits) - SecondaryKeys + 0x75, 0x01, // Report Size (1), + 0x95, 0x69, // Report Count (105), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x33, // Usage Minimum (51), + 0x29, 0x9B, // Usage Maximum (155), + 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), + + // Padding (7 bits) + 0x75, 0x07, // Report Size (7), + 0x95, 0x01, // Report Count (1), + 0x81, 0x03, // Input (Constant), + + // 157-164 (1 byte/8 bits) - TertiaryKeys + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x9D, // Usage Minimum (157), + 0x29, 0xA4, // Usage Maximum (164), + 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), + + // 176-221 (6 bytes/46 bits) - QuartiaryKeys + 0x75, 0x01, // Report Size (1), + 0x95, 0x2E, // Report Count (46), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xB0, // Usage Minimum (176), + 0x29, 0xDD, // Usage Maximum (221), + 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), + + // Padding (2 bits) + 0x75, 0x02, // Report Size (2), + 0x95, 0x01, // Report Count (1), + 0x81, 0x03, // Input (Constant), + 0xc0, // End Collection - Keyboard +}; + +// System Control and Consumer Control +static uint8_t sys_ctrl_report_desc[] = { + // System Control Collection (8 bits) + // + // NOTES: + // Not bothering with NKRO for this table. If there's need, I can implement it. -HaaTa + // Using a 1KRO scheme + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x80, // Usage (System Control), + 0xA1, 0x01, // Collection (Application), + 0x85, 0x02, // Report ID (2), + 0x75, 0x08, // Report Size (8), + 0x95, 0x01, // Report Count (1), + 0x16, 0x81, 0x00, // Logical Minimum (129), + 0x26, 0xB7, 0x00, // Logical Maximum (183), + 0x19, 0x81, // Usage Minimum (129), + 0x29, 0xB7, // Usage Maximum (183), + 0x81, 0x00, // Input (Data, Array), + 0xc0, // End Collection - System Control + + // Consumer Control Collection - Media Keys (16 bits) + // + // NOTES: + // Not bothering with NKRO for this table. If there's a need, I can implement it. -HaaTa + // Using a 1KRO scheme + 0x05, 0x0c, // Usage Page (Consumer), + 0x09, 0x01, // Usage (Consumer Control), + 0xA1, 0x01, // Collection (Application), + 0x85, 0x03, // Report ID (3), + 0x75, 0x10, // Report Size (16), + 0x95, 0x01, // Report Count (1), + 0x16, 0x01, 0x00, // Logical Minimum (1), + 0x26, 0x9C, 0x02, // Logical Maximum (668), + 0x05, 0x0C, // Usage Page (Consumer), + 0x19, 0x01, // Usage Minimum (1), + 0x2A, 0x9C, 0x02, // Usage Maximum (668), + 0x81, 0x00, // Input (Data, Array), + 0xc0, // End Collection - Consumer Control }; -#endif -#ifdef MOUSE_INTERFACE // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension static uint8_t mouse_report_desc[] = { + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x02, // Usage (Mouse) + 0xa1, 0x01, // Collection (Application) + 0x09, 0x02, // Usage (Mouse) + 0xa1, 0x02, // Collection (Logical) + 0x09, 0x01, // Usage (Pointer) + + // Buttons (5 bits) + 0xa1, 0x00, // Collection (Physical) - Buttons + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button 1) + 0x29, 0x05, // Usage Maximum (Button 5) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x05, // Report Count (5) + 0x81, 0x02, // Input (Data,Var,Abs) + + // Padding (3 bits) + 0x75, 0x03, // Report Size (3) + 0x95, 0x01, // Report Count (1) + 0x81, 0x03, // Input (Cnst,Var,Abs) + + // Pointer (16 bits) + 0x05, 0x01, // Usage PAGE (Generic Desktop) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7f, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x95, 0x02, // Report Count (2) + 0x81, 0x06, // Input (Data,Var,Rel) + + // Vertical Wheel + // - Multiplier (2 bits) + 0xa1, 0x02, // Collection (Logical) + 0x09, 0x48, // Usage (Resolution Multiplier) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x35, 0x01, // Physical Minimum (1) + 0x45, 0x04, // Physical Maximum (4) + 0x75, 0x02, // Report Size (2) + 0x95, 0x01, // Report Count (1) + 0xa4, // Push + 0xb1, 0x02, // Feature (Data,Var,Abs) + // - Device (8 bits) + 0x09, 0x38, // Usage (Wheel) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7f, // Logical Maximum (127) + 0x35, 0x00, // Physical Minimum (0) - reset physical + 0x45, 0x00, // Physical Maximum (0) + 0x75, 0x08, // Report Size (8) + 0x81, 0x06, // Input (Data,Var,Rel) + 0xc0, // End Collection - Vertical Wheel + + // Horizontal Wheel + // - Multiplier (2 bits) + 0xa1, 0x02, // Collection (Logical) + 0x09, 0x48, // Usage (Resolution Multiplier) + 0xb4, // Pop + 0xb1, 0x02, // Feature (Data,Var,Abs) + // - Padding (4 bits) + 0x35, 0x00, // Physical Minimum (0) - reset physical + 0x45, 0x00, // Physical Maximum (0) + 0x75, 0x04, // Report Size (4) + 0xb1, 0x03, // Feature (Cnst,Var,Abs) + // - Device (8 bits) + 0x05, 0x0c, // Usage Page (Consumer Devices) + 0x0a, 0x38, 0x02, // Usage (AC Pan) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7f, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x81, 0x06, // Input (Data,Var,Rel) + 0xc0, // End Collection - Horizontal Wheel + + 0xc0, // End Collection - Buttons + 0xc0, // End Collection - Mouse Logical + 0xc0 // End Collection - Mouse Application +}; + +// Joystick Protocol, HID 1.11 spec, Apendix D, page 64-65 +static uint8_t joystick_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop) - 0x09, 0x02, // Usage (Mouse) + 0x09, 0x04, // Usage (Joystick) 0xA1, 0x01, // Collection (Application) - 0x05, 0x09, // Usage Page (Button) - 0x19, 0x01, // Usage Minimum (Button #1) - 0x29, 0x03, // Usage Maximum (Button #3) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x20, // Report Count (32) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button #1) + 0x29, 0x20, // Usage Maximum (Button #32) + 0x81, 0x02, // Input (variable,absolute) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x07, // Logical Maximum (7) + 0x35, 0x00, // Physical Minimum (0) + 0x46, 0x3B, 0x01, // Physical Maximum (315) + 0x75, 0x04, // Report Size (4) + 0x95, 0x01, // Report Count (1) + 0x65, 0x14, // Unit (20) + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x39, // Usage (Hat switch) + 0x81, 0x42, // Input (variable,absolute,null_state) + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x01, // Usage (Pointer) + 0xA1, 0x00, // Collection () 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x95, 0x03, // Report Count (3) - 0x75, 0x01, // Report Size (1) - 0x81, 0x02, // Input (Data, Variable, Absolute) - 0x95, 0x01, // Report Count (1) - 0x75, 0x05, // Report Size (5) - 0x81, 0x03, // Input (Constant) - 0x05, 0x01, // Usage Page (Generic Desktop) + 0x26, 0xFF, 0x03, // Logical Maximum (1023) + 0x75, 0x0A, // Report Size (10) + 0x95, 0x04, // Report Count (4) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x7F, // Logical Maximum (32767) - 0x75, 0x10, // Report Size (16), - 0x95, 0x02, // Report Count (2), - 0x81, 0x02, // Input (Data, Variable, Absolute) - 0x09, 0x38, // Usage (Wheel) - 0x15, 0x81, // Logical Minimum (-127) - 0x25, 0x7F, // Logical Maximum (127) - 0x75, 0x08, // Report Size (8), - 0x95, 0x01, // Report Count (1), - 0x81, 0x06, // Input (Data, Variable, Relative) + 0x09, 0x32, // Usage (Z) + 0x09, 0x35, // Usage (Rz) + 0x81, 0x02, // Input (variable,absolute) + 0xC0, // End Collection + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x03, // Logical Maximum (1023) + 0x75, 0x0A, // Report Size (10) + 0x95, 0x02, // Report Count (2) + 0x09, 0x36, // Usage (Slider) + 0x09, 0x36, // Usage (Slider) + 0x81, 0x02, // Input (variable,absolute) 0xC0 // End Collection }; -#endif -// ************************************************************** -// USB Configuration -// ************************************************************** +// ----- USB Configuration ----- // USB Configuration Descriptor. This huge descriptor tells all // of the devices capbilities. static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { - // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 - 9, // bLength; - 2, // bDescriptorType; - LSB(CONFIG_DESC_SIZE), // wTotalLength - MSB(CONFIG_DESC_SIZE), - NUM_INTERFACE, // bNumInterfaces - 1, // bConfigurationValue - 0, // iConfiguration - 0xC0, // bmAttributes - 50, // bMaxPower - -#ifdef CDC_IAD_DESCRIPTOR - // interface association descriptor, USB ECN, Table 9-Z - 8, // bLength - 11, // bDescriptorType - CDC_STATUS_INTERFACE, // bFirstInterface - 2, // bInterfaceCount - 0x02, // bFunctionClass - 0x02, // bFunctionSubClass - 0x01, // bFunctionProtocol - 4, // iFunction -#endif - -#ifdef CDC_DATA_INTERFACE - // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 - 9, // bLength - 4, // bDescriptorType - CDC_STATUS_INTERFACE, // bInterfaceNumber - 0, // bAlternateSetting - 1, // bNumEndpoints - 0x02, // bInterfaceClass - 0x02, // bInterfaceSubClass - 0x01, // bInterfaceProtocol - 0, // iInterface - // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 - 5, // bFunctionLength - 0x24, // bDescriptorType - 0x00, // bDescriptorSubtype - 0x10, 0x01, // bcdCDC - // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 - 5, // bFunctionLength - 0x24, // bDescriptorType - 0x01, // bDescriptorSubtype - 0x01, // bmCapabilities - 1, // bDataInterface - // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 - 4, // bFunctionLength - 0x24, // bDescriptorType - 0x02, // bDescriptorSubtype - 0x06, // bmCapabilities - // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 - 5, // bFunctionLength - 0x24, // bDescriptorType - 0x06, // bDescriptorSubtype - CDC_STATUS_INTERFACE, // bMasterInterface - CDC_DATA_INTERFACE, // bSlaveInterface0 - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - 7, // bLength - 5, // bDescriptorType - CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress - 0x03, // bmAttributes (0x03=intr) - CDC_ACM_SIZE, 0, // wMaxPacketSize - 64, // bInterval - // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 - 9, // bLength - 4, // bDescriptorType - CDC_DATA_INTERFACE, // bInterfaceNumber - 0, // bAlternateSetting - 2, // bNumEndpoints - 0x0A, // bInterfaceClass - 0x00, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0, // iInterface - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - 7, // bLength - 5, // bDescriptorType - CDC_RX_ENDPOINT, // bEndpointAddress - 0x02, // bmAttributes (0x02=bulk) - CDC_RX_SIZE, 0, // wMaxPacketSize - 0, // bInterval - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - 7, // bLength - 5, // bDescriptorType - CDC_TX_ENDPOINT | 0x80, // bEndpointAddress - 0x02, // bmAttributes (0x02=bulk) - CDC_TX_SIZE, 0, // wMaxPacketSize - 0, // bInterval -#endif // CDC_DATA_INTERFACE - -#ifdef KEYBOARD_INTERFACE - // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 - 9, // bLength - 4, // bDescriptorType - KEYBOARD_INTERFACE, // bInterfaceNumber - 0, // bAlternateSetting - 1, // bNumEndpoints - 0x03, // bInterfaceClass (0x03 = HID) - 0x01, // bInterfaceSubClass (0x01 = Boot) - 0x01, // bInterfaceProtocol (0x01 = Keyboard) - 0, // iInterface - // HID interface descriptor, HID 1.11 spec, section 6.2.1 - 9, // bLength - 0x21, // bDescriptorType - 0x11, 0x01, // bcdHID - 0, // bCountryCode - 1, // bNumDescriptors - 0x22, // bDescriptorType - LSB(sizeof(keyboard_report_desc)), // wDescriptorLength - MSB(sizeof(keyboard_report_desc)), - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - 7, // bLength - 5, // bDescriptorType - KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress - 0x03, // bmAttributes (0x03=intr) - KEYBOARD_SIZE, 0, // wMaxPacketSize - KEYBOARD_INTERVAL, // bInterval -#endif // KEYBOARD_INTERFACE - -#ifdef MOUSE_INTERFACE - // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 - 9, // bLength - 4, // bDescriptorType - MOUSE_INTERFACE, // bInterfaceNumber - 0, // bAlternateSetting - 1, // bNumEndpoints - 0x03, // bInterfaceClass (0x03 = HID) - 0x00, // bInterfaceSubClass (0x01 = Boot) - 0x00, // bInterfaceProtocol (0x02 = Mouse) - 0, // iInterface - // HID interface descriptor, HID 1.11 spec, section 6.2.1 - 9, // bLength - 0x21, // bDescriptorType - 0x11, 0x01, // bcdHID - 0, // bCountryCode - 1, // bNumDescriptors - 0x22, // bDescriptorType - LSB(sizeof(mouse_report_desc)), // wDescriptorLength - MSB(sizeof(mouse_report_desc)), - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 - 7, // bLength - 5, // bDescriptorType - MOUSE_ENDPOINT | 0x80, // bEndpointAddress - 0x03, // bmAttributes (0x03=intr) - MOUSE_SIZE, 0, // wMaxPacketSize - MOUSE_INTERVAL, // bInterval -#endif // MOUSE_INTERFACE +// --- Configuration --- +// - 9 bytes - + // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 + 9, // bLength; + 2, // bDescriptorType; + LSB(CONFIG_DESC_SIZE), // wTotalLength + MSB(CONFIG_DESC_SIZE), + NUM_INTERFACE, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0xA0, // bmAttributes + 250, // bMaxPower + +// --- Keyboard HID --- Boot Mode Keyboard Interface +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + KEYBOARD_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) + 0x01, // bInterfaceProtocol (0x01 = Keyboard) + KEYBOARD_INTERFACE + 4, // iInterface +// - 9 bytes - + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + KeyboardLocale_define, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(keyboard_report_desc)), // wDescriptorLength + MSB(sizeof(keyboard_report_desc)), +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + KEYBOARD_SIZE, 0, // wMaxPacketSize + KEYBOARD_INTERVAL, // bInterval + +// --- NKRO Keyboard HID --- OS Mode Keyboard Interface +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + NKRO_KEYBOARD_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) + 0x01, // bInterfaceProtocol (0x01 = Keyboard) + NKRO_KEYBOARD_INTERFACE + 4, // iInterface +// - 9 bytes - + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + KeyboardLocale_define, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(nkro_keyboard_report_desc)), // wDescriptorLength + MSB(sizeof(nkro_keyboard_report_desc)), +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + NKRO_KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + NKRO_KEYBOARD_SIZE, 0, // wMaxPacketSize + NKRO_KEYBOARD_INTERVAL, // bInterval + +// --- Serial CDC --- CDC IAD Descriptor +// - 8 bytes - + // interface association descriptor, USB ECN, Table 9-Z + 8, // bLength + 11, // bDescriptorType + CDC_STATUS_INTERFACE, // bFirstInterface + 2, // bInterfaceCount + 0x02, // bFunctionClass + 0x02, // bFunctionSubClass + 0x01, // bFunctionProtocol + CDC_STATUS_INTERFACE + 4, // iFunction + +// --- Serial CDC --- CDC Data Interface +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + CDC_STATUS_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x02, // bInterfaceClass + 0x02, // bInterfaceSubClass + 0x01, // bInterfaceProtocol + CDC_STATUS_INTERFACE + 4, // iInterface +// - 5 bytes - + // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x00, // bDescriptorSubtype + 0x10, 0x01, // bcdCDC +// - 5 bytes - + // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x01, // bDescriptorSubtype + 0x01, // bmCapabilities + CDC_DATA_INTERFACE, // bDataInterface +// - 4 bytes - + // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 + 4, // bFunctionLength + 0x24, // bDescriptorType + 0x02, // bDescriptorSubtype + 0x06, // bmCapabilities +// - 5 bytes - + // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x06, // bDescriptorSubtype + CDC_STATUS_INTERFACE, // bMasterInterface + CDC_DATA_INTERFACE, // bSlaveInterface0 +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + CDC_ACM_SIZE, 0, // wMaxPacketSize + 64, // bInterval +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + CDC_DATA_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x0A, // bInterfaceClass + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + CDC_DATA_INTERFACE + 4, // iInterface +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + CDC_RX_ENDPOINT, // bEndpointAddress + 0x02, // bmAttributes (0x02=bulk) + CDC_RX_SIZE, 0, // wMaxPacketSize + 0, // bInterval +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + CDC_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x02, // bmAttributes (0x02=bulk) + CDC_TX_SIZE, 0, // wMaxPacketSize + 0, // bInterval + +// --- Mouse Interface --- +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + MOUSE_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass (0x01 = Boot) + 0x02, // bInterfaceProtocol (0x02 = Mouse) + MOUSE_INTERFACE + 4, // iInterface +// - 9 bytes - + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(mouse_report_desc)), // wDescriptorLength + MSB(sizeof(mouse_report_desc)), +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + MOUSE_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + MOUSE_SIZE, 0, // wMaxPacketSize + MOUSE_INTERVAL, // bInterval + +// --- Joystick Interface --- +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + JOYSTICK_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + JOYSTICK_INTERFACE + 4, // iInterface +// - 9 bytes - + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(joystick_report_desc)), // wDescriptorLength + MSB(sizeof(joystick_report_desc)), +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + JOYSTICK_SIZE, 0, // wMaxPacketSize + JOYSTICK_INTERVAL, // bInterval + +// --- System/Consumer Control --- +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + SYS_CTRL_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) + 0x00, // bInterfaceProtocol (0x00 = None) + SYS_CTRL_INTERFACE + 4, // iInterface +// - 9 bytes - + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + KeyboardLocale_define, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(sys_ctrl_report_desc)), // wDescriptorLength + MSB(sizeof(sys_ctrl_report_desc)), +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + SYS_CTRL_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + SYS_CTRL_SIZE, 0, // wMaxPacketSize + SYS_CTRL_INTERVAL, // bInterval }; -// ************************************************************** -// String Descriptors -// ************************************************************** +// ----- String Descriptors ----- // The descriptors above can provide human readable strings, // referenced by index numbers. These descriptors are the // actual string data struct usb_string_descriptor_struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wString[]; + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wString[]; }; extern struct usb_string_descriptor_struct usb_string_manufacturer_name - __attribute__ ((weak, alias("usb_string_manufacturer_name_default"))); + __attribute__ ((weak, alias("usb_string_manufacturer_name_default"))); extern struct usb_string_descriptor_struct usb_string_product_name - __attribute__ ((weak, alias("usb_string_product_name_default"))); + __attribute__ ((weak, alias("usb_string_product_name_default"))); extern struct usb_string_descriptor_struct usb_string_serial_number - __attribute__ ((weak, alias("usb_string_serial_number_default"))); + __attribute__ ((weak, alias("usb_string_serial_number_default"))); struct usb_string_descriptor_struct string0 = { - 4, - 3, - {0x0409} + 4, + 3, + {0x0409} }; -struct usb_string_descriptor_struct usb_string_manufacturer_name_default = { - sizeof(STR_MANUFACTURER), - 3, - STR_MANUFACTURER -}; -struct usb_string_descriptor_struct usb_string_product_name_default = { - sizeof(STR_PRODUCT), - 3, - STR_PRODUCT -}; -struct usb_string_descriptor_struct usb_string_serial_number_default = { - sizeof(STR_SERIAL), - 3, - STR_SERIAL -}; +#define usb_string_descriptor(name, str) \ + struct usb_string_descriptor_struct name = { \ + sizeof(str), \ + 3, \ + {str} \ + } + +usb_string_descriptor( usb_string_manufacturer_name_default, STR_MANUFACTURER ); +usb_string_descriptor( usb_string_product_name_default, STR_PRODUCT ); +usb_string_descriptor( usb_string_serial_number_default, STR_SERIAL ); +usb_string_descriptor( usb_string_keyboard_name, KEYBOARD_NAME ); +usb_string_descriptor( usb_string_nkro_keyboard_name, NKRO_KEYBOARD_NAME ); +usb_string_descriptor( usb_string_cdc_status_name, CDC_STATUS_NAME ); +usb_string_descriptor( usb_string_cdc_data_name, CDC_DATA_NAME ); +usb_string_descriptor( usb_string_mouse_name, MOUSE_NAME ); +usb_string_descriptor( usb_string_joystick_name, JOYSTICK_NAME ); +usb_string_descriptor( usb_string_sys_ctrl_name, SYS_CTRL_NAME ); + -// ************************************************************** -// Descriptors List -// ************************************************************** +// ----- Descriptors List ----- // This table provides access to all the descriptor data above. @@ -399,40 +750,51 @@ const usb_descriptor_list_t usb_descriptor_list[] = { //wValue, wIndex, address, length {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, {0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, -#ifdef KEYBOARD_INTERFACE - {0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, - {0x2100, KEYBOARD_INTERFACE, config_descriptor+KEYBOARD_DESC_OFFSET, 9}, -#endif -#ifdef MOUSE_INTERFACE - {0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, - {0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_DESC_OFFSET, 9}, -#endif - {0x0300, 0x0000, (const uint8_t *)&string0, 0}, - {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, - {0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, - {0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, + {0x0600, 0x0000, device_qualifier_descriptor, sizeof(device_qualifier_descriptor)}, + {0x0A00, 0x0000, usb_debug_descriptor, sizeof(usb_debug_descriptor)}, + + {0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, + {0x2100, KEYBOARD_INTERFACE, config_descriptor + KEYBOARD_DESC_OFFSET, 9}, + + {0x2200, NKRO_KEYBOARD_INTERFACE, nkro_keyboard_report_desc, sizeof(nkro_keyboard_report_desc)}, + {0x2100, NKRO_KEYBOARD_INTERFACE, config_descriptor + NKRO_KEYBOARD_DESC_OFFSET, 9}, + + {0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, + {0x2100, MOUSE_INTERFACE, config_descriptor + MOUSE_DESC_OFFSET, 9}, + + {0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)}, + {0x2100, JOYSTICK_INTERFACE, config_descriptor + JOYSTICK_DESC_OFFSET, 9}, + + {0x2200, SYS_CTRL_INTERFACE, sys_ctrl_report_desc, sizeof(sys_ctrl_report_desc)}, + {0x2100, SYS_CTRL_INTERFACE, config_descriptor + SYS_CTRL_DESC_OFFSET, 9}, + +#define iInterfaceString(num, var) \ + {0x0300 + 4 + num, 0x409, (const uint8_t *)&var, 0 } + + {0x0300, 0x0000, (const uint8_t *)&string0, 0}, + {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, + {0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, + {0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, + iInterfaceString( KEYBOARD_INTERFACE, usb_string_keyboard_name ), + iInterfaceString( NKRO_KEYBOARD_INTERFACE, usb_string_nkro_keyboard_name ), + iInterfaceString( CDC_STATUS_INTERFACE, usb_string_cdc_status_name ), + iInterfaceString( CDC_DATA_INTERFACE, usb_string_cdc_data_name ), + iInterfaceString( MOUSE_INTERFACE, usb_string_mouse_name ), + iInterfaceString( JOYSTICK_INTERFACE, usb_string_joystick_name ), + iInterfaceString( SYS_CTRL_INTERFACE, usb_string_sys_ctrl_name ), {0, 0, NULL, 0} }; -// ************************************************************** -// Endpoint Configuration -// ************************************************************** -#if 0 +// ----- Endpoint Configuration ----- + +// See usb_desc.h for Endpoint configuration // 0x00 = not used // 0x19 = Recieve only // 0x15 = Transmit only // 0x1D = Transmit & Recieve // -const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = -{ - 0x00, 0x15, 0x19, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -#endif - - const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = { #if (defined(ENDPOINT1_CONFIG) && NUM_ENDPOINTS >= 1) @@ -512,3 +874,4 @@ const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = #endif }; +