qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

vusb.c (39724B)


      1 /*
      2 Copyright 2011 Jun Wako <wakojun@gmail.com>
      3 
      4 This program is free software: you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation, either version 2 of the License, or
      7 (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17 
     18 #include <stdint.h>
     19 
     20 #include <avr/wdt.h>
     21 
     22 #include <usbdrv/usbdrv.h>
     23 
     24 #include "compiler_support.h"
     25 #include "usbconfig.h"
     26 #include "host.h"
     27 #include "report.h"
     28 #include "host_driver.h"
     29 #include "vusb.h"
     30 #include "print.h"
     31 #include "debug.h"
     32 #include "wait.h"
     33 #include "usb_descriptor_common.h"
     34 #include "usb_device_state.h"
     35 
     36 #ifdef RAW_ENABLE
     37 #    include "raw_hid.h"
     38 #endif
     39 
     40 #ifdef JOYSTICK_ENABLE
     41 #    include "joystick.h"
     42 #endif
     43 
     44 #if defined(CONSOLE_ENABLE)
     45 #    define RBUF_SIZE 128
     46 #    include "ring_buffer.h"
     47 #endif
     48 
     49 #ifdef OS_DETECTION_ENABLE
     50 #    include "os_detection.h"
     51 #endif
     52 
     53 /*
     54  * Interface indexes
     55  */
     56 enum usb_interfaces {
     57 #ifndef KEYBOARD_SHARED_EP
     58     KEYBOARD_INTERFACE,
     59 #else
     60     SHARED_INTERFACE,
     61 #    define KEYBOARD_INTERFACE SHARED_INTERFACE
     62 #endif
     63 
     64 // It is important that the Raw HID interface is at a constant
     65 // interface number, to support Linux/OSX platforms and chrome.hid
     66 // If Raw HID is enabled, let it be always 1.
     67 #ifdef RAW_ENABLE
     68     RAW_INTERFACE,
     69 #endif
     70 
     71 #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
     72     SHARED_INTERFACE,
     73 #endif
     74 
     75 #ifdef CONSOLE_ENABLE
     76     CONSOLE_INTERFACE,
     77 #endif
     78 
     79     TOTAL_INTERFACES
     80 };
     81 
     82 #define MAX_INTERFACES 3
     83 
     84 STATIC_ASSERT(TOTAL_INTERFACES <= MAX_INTERFACES, "There are not enough available interfaces to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Raw HID, Console.");
     85 
     86 #if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && CONSOLE_ENABLE
     87 #    error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
     88 #endif
     89 
     90 static report_keyboard_t keyboard_report_sent;
     91 
     92 static void send_report_fragment(uint8_t endpoint, void *data, size_t size) {
     93     for (uint8_t retries = 5; retries > 0; retries--) {
     94         switch (endpoint) {
     95             case 1:
     96                 if (usbInterruptIsReady()) {
     97                     usbSetInterrupt(data, size);
     98                     return;
     99                 }
    100                 break;
    101             case USB_CFG_EP3_NUMBER:
    102                 if (usbInterruptIsReady3()) {
    103                     usbSetInterrupt3(data, size);
    104                     return;
    105                 }
    106                 break;
    107             case USB_CFG_EP4_NUMBER:
    108                 if (usbInterruptIsReady4()) {
    109                     usbSetInterrupt4(data, size);
    110                     return;
    111                 }
    112                 break;
    113             default:
    114                 return;
    115         }
    116 
    117         usbPoll();
    118         wait_ms(5);
    119     }
    120 }
    121 
    122 static void send_report(uint8_t endpoint, void *report, size_t size) {
    123     uint8_t *temp = (uint8_t *)report;
    124 
    125     // Send as many full packets as possible
    126     for (uint8_t i = 0; i < size / 8; i++) {
    127         send_report_fragment(endpoint, temp, 8);
    128         temp += 8;
    129     }
    130 
    131     // Send any data left over
    132     uint8_t remainder = size % 8;
    133     if (remainder) {
    134         send_report_fragment(endpoint, temp, remainder);
    135     }
    136 }
    137 
    138 /*------------------------------------------------------------------*
    139  * RAW HID
    140  *------------------------------------------------------------------*/
    141 #ifdef RAW_ENABLE
    142 #    define RAW_BUFFER_SIZE 32
    143 #    define RAW_EPSIZE 8
    144 
    145 static uint8_t raw_output_buffer[RAW_BUFFER_SIZE];
    146 static uint8_t raw_output_received_bytes = 0;
    147 
    148 static void send_raw_hid(uint8_t *data, uint8_t length) {
    149     if (length != RAW_BUFFER_SIZE) {
    150         return;
    151     }
    152 
    153     send_report(4, data, 32);
    154 }
    155 
    156 void raw_hid_task(void) {
    157     usbPoll();
    158 
    159     if (!usbConfiguration || !usbInterruptIsReady4()) {
    160         return;
    161     }
    162 
    163     if (raw_output_received_bytes == RAW_BUFFER_SIZE) {
    164         raw_hid_receive(raw_output_buffer, RAW_BUFFER_SIZE);
    165         raw_output_received_bytes = 0;
    166     }
    167 }
    168 #endif
    169 
    170 /*------------------------------------------------------------------*
    171  * Console
    172  *------------------------------------------------------------------*/
    173 #ifdef CONSOLE_ENABLE
    174 #    define CONSOLE_BUFFER_SIZE 32
    175 #    define CONSOLE_EPSIZE 8
    176 
    177 int8_t sendchar(uint8_t c) {
    178     rbuf_enqueue(c);
    179     return 0;
    180 }
    181 
    182 void console_task(void) {
    183     usbPoll();
    184 
    185     if (!usbConfiguration || !usbInterruptIsReady3()) {
    186         return;
    187     }
    188 
    189     if (!rbuf_has_data()) {
    190         return;
    191     }
    192 
    193     // Send in chunks of 8 padded to 32
    194     char    send_buf[CONSOLE_BUFFER_SIZE] = {0};
    195     uint8_t send_buf_count                = 0;
    196     while (rbuf_has_data() && send_buf_count < CONSOLE_EPSIZE) {
    197         send_buf[send_buf_count++] = rbuf_dequeue();
    198     }
    199 
    200     send_report(3, send_buf, CONSOLE_BUFFER_SIZE);
    201 }
    202 #endif
    203 
    204 /*------------------------------------------------------------------*
    205  * Host driver
    206  *------------------------------------------------------------------*/
    207 static void send_keyboard(report_keyboard_t *report);
    208 static void send_nkro(report_nkro_t *report);
    209 static void send_mouse(report_mouse_t *report);
    210 static void send_extra(report_extra_t *report);
    211 #ifdef RAW_ENABLE
    212 static void send_raw_hid(uint8_t *data, uint8_t length);
    213 #endif
    214 
    215 static host_driver_t driver = {
    216     .keyboard_leds = usb_device_state_get_leds,
    217     .send_keyboard = send_keyboard,
    218     .send_nkro     = send_nkro,
    219     .send_mouse    = send_mouse,
    220     .send_extra    = send_extra,
    221 #ifdef RAW_ENABLE
    222     .send_raw_hid = send_raw_hid,
    223 #endif
    224 };
    225 
    226 host_driver_t *vusb_driver(void) {
    227     return &driver;
    228 }
    229 
    230 static void send_keyboard(report_keyboard_t *report) {
    231     if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
    232         send_report(1, &report->mods, 8);
    233     } else {
    234         send_report(1, report, sizeof(report_keyboard_t));
    235     }
    236 
    237     keyboard_report_sent = *report;
    238 }
    239 
    240 #ifndef KEYBOARD_SHARED_EP
    241 #    define MOUSE_IN_EPNUM 3
    242 #    define SHARED_IN_EPNUM 3
    243 #else
    244 #    define MOUSE_IN_EPNUM 1
    245 #    define SHARED_IN_EPNUM 1
    246 #endif
    247 
    248 static void send_nkro(report_nkro_t *report) {
    249 #ifdef NKRO_ENABLE
    250     send_report(3, report, sizeof(report_nkro_t));
    251 #endif
    252 }
    253 
    254 static void send_mouse(report_mouse_t *report) {
    255 #ifdef MOUSE_ENABLE
    256     send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t));
    257 #endif
    258 }
    259 
    260 static void send_extra(report_extra_t *report) {
    261 #ifdef EXTRAKEY_ENABLE
    262     send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t));
    263 #endif
    264 }
    265 
    266 void send_joystick(report_joystick_t *report) {
    267 #ifdef JOYSTICK_ENABLE
    268     send_report(SHARED_IN_EPNUM, report, sizeof(report_joystick_t));
    269 #endif
    270 }
    271 
    272 void send_digitizer(report_digitizer_t *report) {
    273 #ifdef DIGITIZER_ENABLE
    274     send_report(SHARED_IN_EPNUM, report, sizeof(report_digitizer_t));
    275 #endif
    276 }
    277 
    278 void send_programmable_button(report_programmable_button_t *report) {
    279 #ifdef PROGRAMMABLE_BUTTON_ENABLE
    280     send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t));
    281 #endif
    282 }
    283 
    284 /*------------------------------------------------------------------*
    285  * Request from host                                                *
    286  *------------------------------------------------------------------*/
    287 static struct {
    288     uint16_t len;
    289     enum { NONE, SET_LED } kind;
    290 } last_req;
    291 
    292 usbMsgLen_t usbFunctionSetup(uchar data[8]) {
    293     usbRequest_t *rq = (void *)data;
    294 
    295     if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) { /* class request type */
    296         switch (rq->bRequest) {
    297             case USBRQ_HID_GET_REPORT:
    298                 dprint("GET_REPORT:");
    299                 if (rq->wIndex.word == KEYBOARD_INTERFACE) {
    300                     usbMsgPtr = (usbMsgPtr_t)&keyboard_report_sent;
    301                     return sizeof(keyboard_report_sent);
    302                 }
    303                 break;
    304             case USBRQ_HID_GET_IDLE:
    305                 dprint("GET_IDLE:");
    306                 static uint8_t keyboard_idle;
    307                 keyboard_idle = usb_device_state_get_idle_rate();
    308                 usbMsgPtr     = (usbMsgPtr_t)&keyboard_idle;
    309                 return 1;
    310             case USBRQ_HID_GET_PROTOCOL:
    311                 dprint("GET_PROTOCOL:");
    312                 static uint8_t keyboard_protocol;
    313                 keyboard_protocol = usb_device_state_get_protocol();
    314                 usbMsgPtr         = (usbMsgPtr_t)&keyboard_protocol;
    315                 return 1;
    316             case USBRQ_HID_SET_REPORT:
    317                 dprint("SET_REPORT:");
    318                 // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard)
    319                 if (rq->wValue.word == 0x0200 && rq->wIndex.word == KEYBOARD_INTERFACE) {
    320                     dprint("SET_LED:");
    321                     last_req.kind = SET_LED;
    322                     last_req.len  = rq->wLength.word;
    323                 }
    324                 return USB_NO_MSG; // to get data in usbFunctionWrite
    325             case USBRQ_HID_SET_IDLE:
    326                 usb_device_state_set_idle_rate(rq->wValue.word >> 8);
    327                 dprintf("SET_IDLE: %02X", usb_device_state_get_idle_rate());
    328                 break;
    329             case USBRQ_HID_SET_PROTOCOL:
    330                 if (rq->wIndex.word == KEYBOARD_INTERFACE) {
    331                     usb_device_state_set_protocol(rq->wValue.word & 0xFF);
    332                     dprintf("SET_PROTOCOL: %02X", usb_device_state_get_protocol());
    333                 }
    334                 break;
    335             default:
    336                 dprint("UNKNOWN:");
    337                 break;
    338         }
    339     } else {
    340         dprint("VENDOR:");
    341         /* no vendor specific requests implemented */
    342     }
    343     dprint("\n");
    344     return 0; /* default for not implemented requests: return no data back to host */
    345 }
    346 
    347 uchar usbFunctionWrite(uchar *data, uchar len) {
    348     if (last_req.len == 0) {
    349         return -1;
    350     }
    351     switch (last_req.kind) {
    352         case SET_LED:
    353             usb_device_state_set_leds(data[0]);
    354             dprintf("SET_LED: %02X\n", usb_device_state_get_leds());
    355             last_req.len = 0;
    356             return 1;
    357             break;
    358         case NONE:
    359         default:
    360             return -1;
    361             break;
    362     }
    363     return 1;
    364 }
    365 
    366 void usbFunctionWriteOut(uchar *data, uchar len) {
    367 #ifdef RAW_ENABLE
    368     // Data from host must be divided every 8bytes
    369     if (len != 8) {
    370         dprint("RAW: invalid length\n");
    371         raw_output_received_bytes = 0;
    372         return;
    373     }
    374 
    375     if (raw_output_received_bytes + len > RAW_BUFFER_SIZE) {
    376         dprint("RAW: buffer full\n");
    377         raw_output_received_bytes = 0;
    378     } else {
    379         for (uint8_t i = 0; i < 8; i++) {
    380             raw_output_buffer[raw_output_received_bytes + i] = data[i];
    381         }
    382         raw_output_received_bytes += len;
    383     }
    384 #endif
    385 }
    386 
    387 /*------------------------------------------------------------------*
    388  * Descriptors                                                      *
    389  *------------------------------------------------------------------*/
    390 
    391 #ifdef KEYBOARD_SHARED_EP
    392 const PROGMEM uchar shared_hid_report[] = {
    393 #    define SHARED_REPORT_STARTED
    394 #else
    395 const PROGMEM uchar keyboard_hid_report[] = {
    396 #endif
    397     0x05, 0x01, // Usage Page (Generic Desktop)
    398     0x09, 0x06, // Usage (Keyboard)
    399     0xA1, 0x01, // Collection (Application)
    400 #ifdef KEYBOARD_SHARED_EP
    401     0x85, REPORT_ID_KEYBOARD, // Report ID
    402 #endif
    403     // Modifiers (8 bits)
    404     0x05, 0x07, //   Usage Page (Keyboard/Keypad)
    405     0x19, 0xE0, //   Usage Minimum (Keyboard Left Control)
    406     0x29, 0xE7, //   Usage Maximum (Keyboard Right GUI)
    407     0x15, 0x00, //   Logical Minimum (0)
    408     0x25, 0x01, //   Logical Maximum (1)
    409     0x95, 0x08, //   Report Count (8)
    410     0x75, 0x01, //   Report Size (1)
    411     0x81, 0x02, //   Input (Data, Variable, Absolute)
    412     // Reserved (1 byte)
    413     0x95, 0x01, //   Report Count (1)
    414     0x75, 0x08, //   Report Size (8)
    415     0x81, 0x03, //   Input (Constant)
    416     // Keycodes (6 bytes)
    417     0x05, 0x07,       //   Usage Page (Keyboard/Keypad)
    418     0x19, 0x00,       //   Usage Minimum (0)
    419     0x29, 0xFF,       //   Usage Maximum (255)
    420     0x15, 0x00,       //   Logical Minimum (0)
    421     0x26, 0xFF, 0x00, //   Logical Maximum (255)
    422     0x95, 0x06,       //   Report Count (6)
    423     0x75, 0x08,       //   Report Size (8)
    424     0x81, 0x00,       //   Input (Data, Array, Absolute)
    425 
    426     // Status LEDs (5 bits)
    427     0x05, 0x08, //   Usage Page (LED)
    428     0x19, 0x01, //   Usage Minimum (Num Lock)
    429     0x29, 0x05, //   Usage Maximum (Kana)
    430     0x15, 0x00, //   Logical Minimum (0)
    431     0x25, 0x01, //   Logical Maximum (1)
    432     0x95, 0x05, //   Report Count (5)
    433     0x75, 0x01, //   Report Size (1)
    434     0x91, 0x02, //   Output (Data, Variable, Absolute)
    435     // LED padding (3 bits)
    436     0x95, 0x01, //   Report Count (1)
    437     0x75, 0x03, //   Report Size (3)
    438     0x91, 0x03, //   Output (Constant)
    439     0xC0,       // End Collection
    440 #ifndef KEYBOARD_SHARED_EP
    441 };
    442 #endif
    443 
    444 #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
    445 const PROGMEM uchar shared_hid_report[] = {
    446 #    define SHARED_REPORT_STARTED
    447 #endif
    448 
    449 #ifdef NKRO_ENABLE
    450     // NKRO report descriptor
    451     0x05, 0x01,           // Usage Page (Generic Desktop)
    452     0x09, 0x06,           // Usage (Keyboard)
    453     0xA1, 0x01,           // Collection (Application)
    454     0x85, REPORT_ID_NKRO, //   Report ID
    455     // Modifiers (8 bits)
    456     0x05, 0x07, //   Usage Page (Keyboard/Keypad)
    457     0x19, 0xE0, //   Usage Minimum (Keyboard Left Control)
    458     0x29, 0xE7, //   Usage Maximum (Keyboard Right GUI)
    459     0x15, 0x00, //   Logical Minimum (0)
    460     0x25, 0x01, //   Logical Maximum (1)
    461     0x95, 0x08, //   Report Count (8)
    462     0x75, 0x01, //   Report Size (1)
    463     0x81, 0x02, //   Input (Data, Variable, Absolute)
    464     // Keycodes
    465     0x05, 0x07,                     //   Usage Page (Keyboard/Keypad)
    466     0x19, 0x00,                     //   Usage Minimum (0)
    467     0x29, NKRO_REPORT_BITS * 8 - 1, //   Usage Maximum
    468     0x15, 0x00,                     //   Logical Minimum (0)
    469     0x25, 0x01,                     //   Logical Maximum (1)
    470     0x95, NKRO_REPORT_BITS * 8,     //   Report Count
    471     0x75, 0x01,                     //   Report Size (1)
    472     0x81, 0x02,                     //   Input (Data, Variable, Absolute)
    473 
    474     // Status LEDs (5 bits)
    475     0x05, 0x08, //   Usage Page (LED)
    476     0x19, 0x01, //   Usage Minimum (Num Lock)
    477     0x29, 0x05, //   Usage Maximum (Kana)
    478     0x95, 0x05, //   Report Count (5)
    479     0x75, 0x01, //   Report Size (1)
    480     0x91, 0x02, //   Output (Data, Variable, Absolute)
    481     // LED padding (3 bits)
    482     0x95, 0x01, //   Report Count (1)
    483     0x75, 0x03, //   Report Size (3)
    484     0x91, 0x03, //   Output (Constant)
    485     0xC0,       // End Collection
    486 #endif
    487 
    488 #ifdef MOUSE_ENABLE
    489     // Mouse report descriptor
    490     0x05, 0x01,            // Usage Page (Generic Desktop)
    491     0x09, 0x02,            // Usage (Mouse)
    492     0xA1, 0x01,            // Collection (Application)
    493     0x85, REPORT_ID_MOUSE, //   Report ID
    494     0x09, 0x01,            //   Usage (Pointer)
    495     0xA1, 0x00,            //   Collection (Physical)
    496     // Buttons (8 bits)
    497     0x05, 0x09, //     Usage Page (Button)
    498     0x19, 0x01, //     Usage Minimum (Button 1)
    499     0x29, 0x08, //     Usage Maximum (Button 8)
    500     0x15, 0x00, //     Logical Minimum (0)
    501     0x25, 0x01, //     Logical Maximum (1)
    502     0x95, 0x08, //     Report Count (8)
    503     0x75, 0x01, //     Report Size (1)
    504     0x81, 0x02, //     Input (Data, Variable, Absolute)
    505 
    506 #    ifdef MOUSE_EXTENDED_REPORT
    507     // Boot protocol XY ignored in Report protocol
    508     0x95, 0x02, //     Report Count (2)
    509     0x75, 0x08, //     Report Size (8)
    510     0x81, 0x03, //     Input (Constant)
    511 #    endif
    512 
    513     // X/Y position (2 or 4 bytes)
    514     0x05, 0x01, //     Usage Page (Generic Desktop)
    515     0x09, 0x30, //     Usage (X)
    516     0x09, 0x31, //     Usage (Y)
    517 #    ifndef MOUSE_EXTENDED_REPORT
    518     0x15, 0x81, //     Logical Minimum (-127)
    519     0x25, 0x7F, //     Logical Maximum (127)
    520     0x95, 0x02, //     Report Count (2)
    521     0x75, 0x08, //     Report Size (8)
    522 #    else
    523     0x16, 0x01, 0x80, // Logical Minimum (-32767)
    524     0x26, 0xFF, 0x7F, // Logical Maximum (32767)
    525     0x95, 0x02,       // Report Count (2)
    526     0x75, 0x10,       // Report Size (16)
    527 #    endif
    528     0x81, 0x06, //     Input (Data, Variable, Relative)
    529 
    530 #    ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
    531     // Feature report and padding (1 byte)
    532     0xA1, 0x02,                                    //     Collection (Logical)
    533     0x09, 0x48,                                    //       Usage (Resolution Multiplier)
    534     0x95, 0x01,                                    //       Report Count (1)
    535     0x75, 0x02,                                    //       Report Size (2)
    536     0x15, 0x00,                                    //       Logical Minimum (0)
    537     0x25, 0x01,                                    //       Logical Maximum (1)
    538     0x35, 0x01,                                    //       Physical Minimum (1)
    539     0x45, POINTING_DEVICE_HIRES_SCROLL_MULTIPLIER, // Physical Maximum (POINTING_DEVICE_HIRES_SCROLL_MULTIPLIER)
    540     0x55, POINTING_DEVICE_HIRES_SCROLL_EXPONENT,   // Unit Exponent (POINTING_DEVICE_HIRES_SCROLL_EXPONENT)
    541     0xB1, 0x02,                                    //       Feature (Data, Variable, Absolute)
    542     0x35, 0x00,                                    //       Physical Minimum (0)
    543     0x45, 0x00,                                    //       Physical Maximum (0)
    544     0x75, 0x06,                                    //       Report Size (6)
    545     0xB1, 0x03,                                    //       Feature (Constant)
    546 #    endif
    547 
    548     // Vertical wheel (1 or 2 bytes)
    549     0x09, 0x38, //     Usage (Wheel)
    550 #    ifndef WHEEL_EXTENDED_REPORT
    551     0x15, 0x81, //     Logical Minimum (-127)
    552     0x25, 0x7F, //     Logical Maximum (127)
    553     0x95, 0x01, //     Report Count (1)
    554     0x75, 0x08, //     Report Size (8)
    555 #    else
    556     0x16, 0x01, 0x80, //     Logical Minimum (-32767)
    557     0x26, 0xFF, 0x7F, //     Logical Maximum (32767)
    558     0x95, 0x01,       //     Report Count (1)
    559     0x75, 0x10,       //     Report Size (16)
    560 #    endif
    561     0x81, 0x06, //     Input (Data, Variable, Relative)
    562 
    563     // Horizontal wheel (1 or 2 bytes)
    564     0x05, 0x0C,       //     Usage Page (Consumer)
    565     0x0A, 0x38, 0x02, //     Usage (AC Pan)
    566 #    ifndef WHEEL_EXTENDED_REPORT
    567     0x15, 0x81, //     Logical Minimum (-127)
    568     0x25, 0x7F, //     Logical Maximum (127)
    569     0x95, 0x01, //     Report Count (1)
    570     0x75, 0x08, //     Report Size (8)
    571 #    else
    572     0x16, 0x01, 0x80, //     Logical Minimum (-32767)
    573     0x26, 0xFF, 0x7F, //     Logical Maximum (32767)
    574     0x95, 0x01,       //     Report Count (1)
    575     0x75, 0x10,       //     Report Size (16)
    576 #    endif
    577     0x81, 0x06, //     Input (Data, Variable, Relative)
    578 
    579 #    ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
    580     0xC0, //   End Collection
    581 #    endif
    582 
    583     0xC0, //   End Collection
    584     0xC0, // End Collection
    585 #endif
    586 
    587 #ifdef EXTRAKEY_ENABLE
    588     // Extrakeys report descriptor
    589     0x05, 0x01,             // Usage Page (Generic Desktop)
    590     0x09, 0x80,             // Usage (System Control)
    591     0xA1, 0x01,             // Collection (Application)
    592     0x85, REPORT_ID_SYSTEM, //   Report ID
    593     0x19, 0x01,             //   Usage Minimum (Pointer)
    594     0x2A, 0xB7, 0x00,       //   Usage Maximum (System Display LCD Autoscale)
    595     0x15, 0x01,             //   Logical Minimum
    596     0x26, 0xB7, 0x00,       //   Logical Maximum
    597     0x95, 0x01,             //   Report Count (1)
    598     0x75, 0x10,             //   Report Size (16)
    599     0x81, 0x00,             //   Input (Data, Array, Absolute)
    600     0xC0,                   // End Collection
    601 
    602     0x05, 0x0C,               // Usage Page (Consumer)
    603     0x09, 0x01,               // Usage (Consumer Control)
    604     0xA1, 0x01,               // Collection (Application)
    605     0x85, REPORT_ID_CONSUMER, //   Report ID
    606     0x19, 0x01,               //   Usage Minimum (Consumer Control)
    607     0x2A, 0xA0, 0x02,         //   Usage Maximum (AC Desktop Show All Applications)
    608     0x15, 0x01,               //   Logical Minimum
    609     0x26, 0xA0, 0x02,         //   Logical Maximum
    610     0x95, 0x01,               //   Report Count (1)
    611     0x75, 0x10,               //   Report Size (16)
    612     0x81, 0x00,               //   Input (Data, Array, Absolute)
    613     0xC0,                     // End Collection
    614 #endif
    615 
    616 #ifdef JOYSTICK_ENABLE
    617     // Joystick report descriptor
    618     0x05, 0x01,               // Usage Page (Generic Desktop)
    619     0x09, 0x04,               // Usage (Joystick)
    620     0xA1, 0x01,               // Collection (Application)
    621     0x85, REPORT_ID_JOYSTICK, //   Report ID
    622     0xA1, 0x00,               //   Collection (Physical)
    623 #    if JOYSTICK_AXIS_COUNT > 0
    624     0x05, 0x01, //     Usage Page (Generic Desktop)
    625     0x09, 0x30, //     Usage (X)
    626 #        if JOYSTICK_AXIS_COUNT > 1
    627     0x09, 0x31, //     Usage (Y)
    628 #        endif
    629 #        if JOYSTICK_AXIS_COUNT > 2
    630     0x09, 0x32, //     Usage (Z)
    631 #        endif
    632 #        if JOYSTICK_AXIS_COUNT > 3
    633     0x09, 0x33, //     Usage (Rx)
    634 #        endif
    635 #        if JOYSTICK_AXIS_COUNT > 4
    636     0x09, 0x34, //     Usage (Ry)
    637 #        endif
    638 #        if JOYSTICK_AXIS_COUNT > 5
    639     0x09, 0x35, //     Usage (Rz)
    640 #        endif
    641 #        if JOYSTICK_AXIS_RESOLUTION == 8
    642     0x15, -JOYSTICK_MAX_VALUE, //     Logical Minimum
    643     0x25, JOYSTICK_MAX_VALUE,  //     Logical Maximum
    644     0x95, JOYSTICK_AXIS_COUNT, //     Report Count
    645     0x75, 0x08,                //     Report Size (8)
    646 #        else
    647     0x16, HID_VALUE_16(-JOYSTICK_MAX_VALUE), //     Logical Minimum
    648     0x26, HID_VALUE_16(JOYSTICK_MAX_VALUE),  //     Logical Maximum
    649     0x95, JOYSTICK_AXIS_COUNT,               //     Report Count
    650     0x75, 0x10,                              //     Report Size (16)
    651 #        endif
    652     0x81, 0x02, //     Input (Data, Variable, Absolute)
    653 #    endif
    654 
    655 #    ifdef JOYSTICK_HAS_HAT
    656     // Hat Switch (4 bits)
    657     0x09, 0x39,       //     Usage (Hat Switch)
    658     0x15, 0x00,       //     Logical Minimum (0)
    659     0x25, 0x07,       //     Logical Maximum (7)
    660     0x35, 0x00,       //     Physical Minimum (0)
    661     0x46, 0x3B, 0x01, //     Physical Maximum (315)
    662     0x65, 0x14,       //     Unit (Degree, English Rotation)
    663     0x95, 0x01,       //     Report Count (1)
    664     0x75, 0x04,       //     Report Size (4)
    665     0x81, 0x42,       //     Input (Data, Variable, Absolute, Null State)
    666     // Padding (4 bits)
    667     0x95, 0x04, //     Report Count (4)
    668     0x75, 0x01, //     Report Size (1)
    669     0x81, 0x01, //     Input (Constant)
    670 #    endif
    671 
    672 #    if JOYSTICK_BUTTON_COUNT > 0
    673     0x05, 0x09,                  //     Usage Page (Button)
    674     0x19, 0x01,                  //     Usage Minimum (Button 1)
    675     0x29, JOYSTICK_BUTTON_COUNT, //     Usage Maximum
    676     0x15, 0x00,                  //     Logical Minimum (0)
    677     0x25, 0x01,                  //     Logical Maximum (1)
    678     0x95, JOYSTICK_BUTTON_COUNT, //     Report Count
    679     0x75, 0x01,                  //     Report Size (1)
    680     0x81, 0x02,                  //     Input (Data, Variable, Absolute)
    681 
    682 #        if (JOYSTICK_BUTTON_COUNT % 8) != 0
    683     0x95, 8 - (JOYSTICK_BUTTON_COUNT % 8), //     Report Count
    684     0x75, 0x01,                            //     Report Size (1)
    685     0x81, 0x03,                            //     Input (Constant)
    686 #        endif
    687 #    endif
    688     0xC0, //   End Collection
    689     0xC0, // End Collection
    690 #endif
    691 
    692 #ifdef DIGITIZER_ENABLE
    693     // Digitizer report descriptor
    694     0x05, 0x0D,                // Usage Page (Digitizers)
    695     0x09, 0x01,                // Usage (Digitizer)
    696     0xA1, 0x01,                // Collection (Application)
    697     0x85, REPORT_ID_DIGITIZER, //   Report ID
    698     0x09, 0x20,                //   Usage (Stylus)
    699     0xA1, 0x00,                //   Collection (Physical)
    700     // In Range, Tip Switch & Barrel Switch (3 bits)
    701     0x09, 0x32, //     Usage (In Range)
    702     0x09, 0x42, //     Usage (Tip Switch)
    703     0x09, 0x44, //     Usage (Barrel Switch)
    704     0x15, 0x00, //     Logical Minimum
    705     0x25, 0x01, //     Logical Maximum
    706     0x95, 0x03, //     Report Count (3)
    707     0x75, 0x01, //     Report Size (1)
    708     0x81, 0x02, //     Input (Data, Variable, Absolute)
    709     // Padding (5 bits)
    710     0x95, 0x05, //     Report Count (5)
    711     0x81, 0x03, //     Input (Constant)
    712 
    713     // X/Y Position (4 bytes)
    714     0x05, 0x01,       //     Usage Page (Generic Desktop)
    715     0x09, 0x30,       //     Usage (X)
    716     0x09, 0x31,       //     Usage (Y)
    717     0x26, 0xFF, 0x7F, //     Logical Maximum (32767)
    718     0x95, 0x02,       //     Report Count (2)
    719     0x75, 0x10,       //     Report Size (16)
    720     0x65, 0x13,       //     Unit (Inch, English Linear)
    721     0x55, 0x0E,       //     Unit Exponent (-2)
    722     0x81, 0x02,       //     Input (Data, Variable, Absolute)
    723     0xC0,             //   End Collection
    724     0xC0,             // End Collection
    725 #endif
    726 
    727 #ifdef PROGRAMMABLE_BUTTON_ENABLE
    728     // Programmable buttons report descriptor
    729     0x05, 0x0C,                          // Usage Page (Consumer)
    730     0x09, 0x01,                          // Usage (Consumer Control)
    731     0xA1, 0x01,                          // Collection (Application)
    732     0x85, REPORT_ID_PROGRAMMABLE_BUTTON, //   Report ID
    733     0x09, 0x03,                          //   Usage (Programmable Buttons)
    734     0xA1, 0x04,                          //   Collection (Named Array)
    735     0x05, 0x09,                          //     Usage Page (Button)
    736     0x19, 0x01,                          //     Usage Minimum (Button 1)
    737     0x29, 0x20,                          //     Usage Maximum (Button 32)
    738     0x15, 0x00,                          //     Logical Minimum (0)
    739     0x25, 0x01,                          //     Logical Maximum (1)
    740     0x95, 0x20,                          //     Report Count (32)
    741     0x75, 0x01,                          //     Report Size (1)
    742     0x81, 0x02,                          //     Input (Data, Variable, Absolute)
    743     0xC0,                                //   End Collection
    744     0xC0,                                // End Collection
    745 #endif
    746 
    747 #ifdef SHARED_EP_ENABLE
    748 };
    749 #endif
    750 
    751 #ifdef RAW_ENABLE
    752 const PROGMEM uchar raw_hid_report[] = {
    753     0x06, HID_VALUE_16(RAW_USAGE_PAGE), // Usage Page (Vendor Defined)
    754     0x09, RAW_USAGE_ID,                 // Usage (Vendor Defined)
    755     0xA1, 0x01,                         // Collection (Application)
    756     // Data to host
    757     0x09, 0x62,            //   Usage (Vendor Defined)
    758     0x15, 0x00,            //   Logical Minimum (0)
    759     0x26, 0xFF, 0x00,      //   Logical Maximum (255)
    760     0x95, RAW_BUFFER_SIZE, //   Report Count
    761     0x75, 0x08,            //   Report Size (8)
    762     0x81, 0x02,            //   Input (Data, Variable, Absolute)
    763     // Data from host
    764     0x09, 0x63,            //   Usage (Vendor Defined)
    765     0x15, 0x00,            //   Logical Minimum (0)
    766     0x26, 0xFF, 0x00,      //   Logical Maximum (255)
    767     0x95, RAW_BUFFER_SIZE, //   Report Count
    768     0x75, 0x08,            //   Report Size (8)
    769     0x91, 0x02,            //   Output (Data, Variable, Absolute)
    770     0xC0                   // End Collection
    771 };
    772 #endif
    773 
    774 #if defined(CONSOLE_ENABLE)
    775 const PROGMEM uchar console_hid_report[] = {
    776     0x06, 0x31, 0xFF, // Usage Page (Vendor Defined - PJRC Teensy compatible)
    777     0x09, 0x74,       // Usage (Vendor Defined - PJRC Teensy compatible)
    778     0xA1, 0x01,       // Collection (Application)
    779     // Data to host
    780     0x09, 0x75,                //   Usage (Vendor Defined)
    781     0x15, 0x00,                //   Logical Minimum (0x00)
    782     0x26, 0xFF, 0x00,          //   Logical Maximum (0x00FF)
    783     0x95, CONSOLE_BUFFER_SIZE, //   Report Count
    784     0x75, 0x08,                //   Report Size (8)
    785     0x81, 0x02,                //   Input (Data, Variable, Absolute)
    786     0xC0                       // End Collection
    787 };
    788 #endif
    789 
    790 #ifndef USB_MAX_POWER_CONSUMPTION
    791 #    define USB_MAX_POWER_CONSUMPTION 500
    792 #endif
    793 
    794 #ifndef USB_POLLING_INTERVAL_MS
    795 #    define USB_POLLING_INTERVAL_MS 1
    796 #endif
    797 
    798 // clang-format off
    799 const PROGMEM usbStringDescriptor_t usbStringDescriptorZero = {
    800     .header = {
    801         .bLength         = 4,
    802         .bDescriptorType = USBDESCR_STRING
    803     },
    804     .bString             = {0x0409} // US English
    805 };
    806 
    807 const PROGMEM usbStringDescriptor_t usbStringDescriptorManufacturer = {
    808     .header = {
    809         .bLength         = sizeof(USBSTR(MANUFACTURER)),
    810         .bDescriptorType = USBDESCR_STRING
    811     },
    812     .bString             = USBSTR(MANUFACTURER)
    813 };
    814 
    815 const PROGMEM usbStringDescriptor_t usbStringDescriptorProduct = {
    816     .header = {
    817         .bLength         = sizeof(USBSTR(PRODUCT)),
    818         .bDescriptorType = USBDESCR_STRING
    819     },
    820     .bString             = USBSTR(PRODUCT)
    821 };
    822 
    823 #if defined(SERIAL_NUMBER)
    824 const PROGMEM usbStringDescriptor_t usbStringDescriptorSerial = {
    825     .header = {
    826         .bLength         = sizeof(USBSTR(SERIAL_NUMBER)),
    827         .bDescriptorType = USBDESCR_STRING
    828     },
    829     .bString             = USBSTR(SERIAL_NUMBER)
    830 };
    831 #endif
    832 
    833 /*
    834  * Device descriptor
    835  */
    836 const PROGMEM usbDeviceDescriptor_t usbDeviceDescriptor = {
    837     .header = {
    838         .bLength         = sizeof(usbDeviceDescriptor_t),
    839         .bDescriptorType = USBDESCR_DEVICE
    840     },
    841     .bcdUSB              = 0x0110,
    842     .bDeviceClass        = 0x00,
    843     .bDeviceSubClass     = 0x00,
    844     .bDeviceProtocol     = 0x00,
    845     .bMaxPacketSize0     = 8,
    846     .idVendor            = VENDOR_ID,
    847     .idProduct           = PRODUCT_ID,
    848     .bcdDevice           = DEVICE_VER,
    849     .iManufacturer       = 0x01,
    850     .iProduct            = 0x02,
    851 #if defined(SERIAL_NUMBER)
    852     .iSerialNumber       = 0x03,
    853 #else
    854     .iSerialNumber       = 0x00,
    855 #endif
    856     .bNumConfigurations  = 1
    857 };
    858 
    859 /*
    860  * Configuration descriptors
    861  */
    862 const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
    863     .header = {
    864         .header = {
    865             .bLength         = sizeof(usbConfigurationDescriptorHeader_t),
    866             .bDescriptorType = USBDESCR_CONFIG
    867         },
    868         .wTotalLength        = sizeof(usbConfigurationDescriptor_t),
    869         .bNumInterfaces      = TOTAL_INTERFACES,
    870         .bConfigurationValue = 0x01,
    871         .iConfiguration      = 0x00,
    872         .bmAttributes        = (1 << 7) | USBATTR_REMOTEWAKE,
    873         .bMaxPower           = USB_MAX_POWER_CONSUMPTION / 2
    874     },
    875 
    876 #    ifndef KEYBOARD_SHARED_EP
    877     /*
    878      * Keyboard
    879      */
    880     .keyboardInterface = {
    881         .header = {
    882             .bLength         = sizeof(usbInterfaceDescriptor_t),
    883             .bDescriptorType = USBDESCR_INTERFACE
    884         },
    885         .bInterfaceNumber    = KEYBOARD_INTERFACE,
    886         .bAlternateSetting   = 0x00,
    887         .bNumEndpoints       = 1,
    888         .bInterfaceClass     = 0x03,
    889         .bInterfaceSubClass  = 0x01,
    890         .bInterfaceProtocol  = 0x01,
    891         .iInterface          = 0x00
    892     },
    893     .keyboardHID = {
    894         .header = {
    895             .bLength         = sizeof(usbHIDDescriptor_t),
    896             .bDescriptorType = USBDESCR_HID
    897         },
    898         .bcdHID              = 0x0101,
    899         .bCountryCode        = 0x00,
    900         .bNumDescriptors     = 1,
    901         .bDescriptorType     = USBDESCR_HID_REPORT,
    902         .wDescriptorLength   = sizeof(keyboard_hid_report)
    903     },
    904     .keyboardINEndpoint = {
    905         .header = {
    906             .bLength         = sizeof(usbEndpointDescriptor_t),
    907             .bDescriptorType = USBDESCR_ENDPOINT
    908         },
    909         .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | 1),
    910         .bmAttributes        = 0x03,
    911         .wMaxPacketSize      = 8,
    912         .bInterval           = USB_POLLING_INTERVAL_MS
    913     },
    914 #    endif
    915 
    916 #    if defined(RAW_ENABLE)
    917     /*
    918      * RAW HID
    919      */
    920     .rawInterface = {
    921         .header = {
    922             .bLength         = sizeof(usbInterfaceDescriptor_t),
    923             .bDescriptorType = USBDESCR_INTERFACE
    924         },
    925         .bInterfaceNumber    = RAW_INTERFACE,
    926         .bAlternateSetting   = 0x00,
    927         .bNumEndpoints       = 2,
    928         .bInterfaceClass     = 0x03,
    929         .bInterfaceSubClass  = 0x00,
    930         .bInterfaceProtocol  = 0x00,
    931         .iInterface          = 0x00
    932     },
    933     .rawHID = {
    934         .header = {
    935             .bLength         = sizeof(usbHIDDescriptor_t),
    936             .bDescriptorType = USBDESCR_HID
    937         },
    938         .bcdHID              = 0x0101,
    939         .bCountryCode        = 0x00,
    940         .bNumDescriptors     = 1,
    941         .bDescriptorType     = USBDESCR_HID_REPORT,
    942         .wDescriptorLength   = sizeof(raw_hid_report)
    943     },
    944     .rawINEndpoint = {
    945         .header = {
    946             .bLength         = sizeof(usbEndpointDescriptor_t),
    947             .bDescriptorType = USBDESCR_ENDPOINT
    948         },
    949         .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP4_NUMBER),
    950         .bmAttributes        = 0x03,
    951         .wMaxPacketSize      = RAW_EPSIZE,
    952         .bInterval           = USB_POLLING_INTERVAL_MS
    953     },
    954     .rawOUTEndpoint = {
    955         .header = {
    956             .bLength         = sizeof(usbEndpointDescriptor_t),
    957             .bDescriptorType = USBDESCR_ENDPOINT
    958         },
    959         .bEndpointAddress    = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP4_NUMBER),
    960         .bmAttributes        = 0x03,
    961         .wMaxPacketSize      = RAW_EPSIZE,
    962         .bInterval           = USB_POLLING_INTERVAL_MS
    963     },
    964 #    endif
    965 
    966 #    ifdef SHARED_EP_ENABLE
    967     /*
    968      * Shared
    969      */
    970     .sharedInterface = {
    971         .header = {
    972             .bLength         = sizeof(usbInterfaceDescriptor_t),
    973             .bDescriptorType = USBDESCR_INTERFACE
    974         },
    975         .bInterfaceNumber    = SHARED_INTERFACE,
    976         .bAlternateSetting   = 0x00,
    977         .bNumEndpoints       = 1,
    978         .bInterfaceClass     = 0x03,
    979 #        ifdef KEYBOARD_SHARED_EP
    980         .bInterfaceSubClass  = 0x01,
    981         .bInterfaceProtocol  = 0x01,
    982 #        else
    983         .bInterfaceSubClass  = 0x00,
    984         .bInterfaceProtocol  = 0x00,
    985 #        endif
    986         .iInterface          = 0x00
    987     },
    988     .sharedHID = {
    989         .header = {
    990             .bLength         = sizeof(usbHIDDescriptor_t),
    991             .bDescriptorType = USBDESCR_HID
    992         },
    993         .bcdHID              = 0x0101,
    994         .bCountryCode        = 0x00,
    995         .bNumDescriptors     = 1,
    996         .bDescriptorType     = USBDESCR_HID_REPORT,
    997         .wDescriptorLength   = sizeof(shared_hid_report)
    998     },
    999     .sharedINEndpoint = {
   1000         .header = {
   1001             .bLength         = sizeof(usbEndpointDescriptor_t),
   1002             .bDescriptorType = USBDESCR_ENDPOINT
   1003         },
   1004 #        ifdef KEYBOARD_SHARED_EP
   1005         .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | 1),
   1006 #        else
   1007         .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
   1008 #        endif
   1009         .bmAttributes        = 0x03,
   1010         .wMaxPacketSize      = 8,
   1011         .bInterval           = USB_POLLING_INTERVAL_MS
   1012     },
   1013 #    endif
   1014 
   1015 #    if defined(CONSOLE_ENABLE)
   1016     /*
   1017      * Console
   1018      */
   1019     .consoleInterface = {
   1020         .header = {
   1021             .bLength         = sizeof(usbInterfaceDescriptor_t),
   1022             .bDescriptorType = USBDESCR_INTERFACE
   1023         },
   1024         .bInterfaceNumber    = CONSOLE_INTERFACE,
   1025         .bAlternateSetting   = 0x00,
   1026         .bNumEndpoints       = 2,
   1027         .bInterfaceClass     = 0x03,
   1028         .bInterfaceSubClass  = 0x00,
   1029         .bInterfaceProtocol  = 0x00,
   1030         .iInterface          = 0x00
   1031     },
   1032     .consoleHID = {
   1033         .header = {
   1034             .bLength         = sizeof(usbHIDDescriptor_t),
   1035             .bDescriptorType = USBDESCR_HID
   1036         },
   1037         .bcdHID              = 0x0111,
   1038         .bCountryCode        = 0x00,
   1039         .bNumDescriptors     = 1,
   1040         .bDescriptorType     = USBDESCR_HID_REPORT,
   1041         .wDescriptorLength   = sizeof(console_hid_report)
   1042     },
   1043     .consoleINEndpoint = {
   1044         .header = {
   1045             .bLength         = sizeof(usbEndpointDescriptor_t),
   1046             .bDescriptorType = USBDESCR_ENDPOINT
   1047         },
   1048         .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
   1049         .bmAttributes        = 0x03,
   1050         .wMaxPacketSize      = CONSOLE_EPSIZE,
   1051         .bInterval           = 0x01
   1052     },
   1053 #    endif
   1054 };
   1055 
   1056 // clang-format on
   1057 
   1058 USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
   1059     usbMsgLen_t len = 0;
   1060 
   1061     switch (rq->wValue.bytes[1]) {
   1062         case USBDESCR_DEVICE:
   1063             usbMsgPtr = (usbMsgPtr_t)&usbDeviceDescriptor;
   1064             len       = sizeof(usbDeviceDescriptor_t);
   1065             break;
   1066         case USBDESCR_CONFIG:
   1067             usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor;
   1068             len       = sizeof(usbConfigurationDescriptor_t);
   1069             break;
   1070         case USBDESCR_STRING:
   1071             switch (rq->wValue.bytes[0]) {
   1072                 case 0:
   1073                     usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorZero;
   1074                     len       = usbStringDescriptorZero.header.bLength;
   1075                     break;
   1076                 case 1: // iManufacturer
   1077                     usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorManufacturer;
   1078                     len       = usbStringDescriptorManufacturer.header.bLength;
   1079                     break;
   1080                 case 2: // iProduct
   1081                     usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorProduct;
   1082                     len       = usbStringDescriptorProduct.header.bLength;
   1083                     break;
   1084 #if defined(SERIAL_NUMBER)
   1085                 case 3: // iSerialNumber
   1086                     usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorSerial;
   1087                     len       = usbStringDescriptorSerial.header.bLength;
   1088                     break;
   1089 #endif
   1090             }
   1091 #ifdef OS_DETECTION_ENABLE
   1092             process_wlength(rq->wLength.word);
   1093 #endif
   1094             break;
   1095         case USBDESCR_HID:
   1096             switch (rq->wIndex.word) {
   1097 #ifndef KEYBOARD_SHARED_EP
   1098                 case KEYBOARD_INTERFACE:
   1099                     usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.keyboardHID;
   1100                     len       = sizeof(usbHIDDescriptor_t);
   1101                     break;
   1102 #endif
   1103 
   1104 #if defined(RAW_ENABLE)
   1105                 case RAW_INTERFACE:
   1106                     usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.rawHID;
   1107                     len       = sizeof(usbHIDDescriptor_t);
   1108                     break;
   1109 #endif
   1110 
   1111 #ifdef SHARED_EP_ENABLE
   1112                 case SHARED_INTERFACE:
   1113                     usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.sharedHID;
   1114                     len       = sizeof(usbHIDDescriptor_t);
   1115                     break;
   1116 #endif
   1117 
   1118 #if defined(CONSOLE_ENABLE)
   1119                 case CONSOLE_INTERFACE:
   1120                     usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.consoleHID;
   1121                     len       = sizeof(usbHIDDescriptor_t);
   1122                     break;
   1123 #endif
   1124             }
   1125             break;
   1126         case USBDESCR_HID_REPORT:
   1127             /* interface index */
   1128             switch (rq->wIndex.word) {
   1129 #ifndef KEYBOARD_SHARED_EP
   1130                 case KEYBOARD_INTERFACE:
   1131                     usbMsgPtr = (usbMsgPtr_t)keyboard_hid_report;
   1132                     len       = sizeof(keyboard_hid_report);
   1133                     break;
   1134 #endif
   1135 
   1136 #if defined(RAW_ENABLE)
   1137                 case RAW_INTERFACE:
   1138                     usbMsgPtr = (usbMsgPtr_t)raw_hid_report;
   1139                     len       = sizeof(raw_hid_report);
   1140                     break;
   1141 #endif
   1142 
   1143 #ifdef SHARED_EP_ENABLE
   1144                 case SHARED_INTERFACE:
   1145                     usbMsgPtr = (usbMsgPtr_t)shared_hid_report;
   1146                     len       = sizeof(shared_hid_report);
   1147                     break;
   1148 #endif
   1149 
   1150 #if defined(CONSOLE_ENABLE)
   1151                 case CONSOLE_INTERFACE:
   1152                     usbMsgPtr = (usbMsgPtr_t)console_hid_report;
   1153                     len       = sizeof(console_hid_report);
   1154                     break;
   1155 #endif
   1156             }
   1157             break;
   1158     }
   1159     return len;
   1160 }