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 }