aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol')
-rw-r--r--tmk_core/protocol/vusb/vusb.c246
-rw-r--r--tmk_core/protocol/vusb/vusb.h76
2 files changed, 218 insertions, 104 deletions
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 30c970892..19df35805 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -349,134 +349,174 @@ const PROGMEM uchar mouse_extra_hid_report[] = {
349#endif 349#endif
350 350
351// clang-format off 351// clang-format off
352const PROGMEM usbStringDescriptor_t usbDescriptorStringZero = { 352const PROGMEM usbStringDescriptor_t usbStringDescriptorZero = {
353 .header = { 353 .header = {
354 .bLength = USB_STRING_LEN(1), 354 .bLength = USB_STRING_LEN(1),
355 .bDescriptorType = USBDESCR_STRING 355 .bDescriptorType = USBDESCR_STRING
356 }, 356 },
357 .bString = {0x0409} // US English 357 .bString = {0x0409} // US English
358}; 358};
359 359
360const PROGMEM usbStringDescriptor_t usbDescriptorStringManufacturer = { 360const PROGMEM usbStringDescriptor_t usbStringDescriptorManufacturer = {
361 .header = { 361 .header = {
362 .bLength = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1), 362 .bLength = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1),
363 .bDescriptorType = USBDESCR_STRING 363 .bDescriptorType = USBDESCR_STRING
364 }, 364 },
365 .bString = LSTR(MANUFACTURER) 365 .bString = LSTR(MANUFACTURER)
366}; 366};
367 367
368const PROGMEM usbStringDescriptor_t usbDescriptorStringProduct = { 368const PROGMEM usbStringDescriptor_t usbStringDescriptorProduct = {
369 .header = { 369 .header = {
370 .bLength = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1), 370 .bLength = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1),
371 .bDescriptorType = USBDESCR_STRING 371 .bDescriptorType = USBDESCR_STRING
372 }, 372 },
373 .bString = LSTR(PRODUCT) 373 .bString = LSTR(PRODUCT)
374}; 374};
375 375
376const PROGMEM usbStringDescriptor_t usbDescriptorStringSerial = { 376const PROGMEM usbStringDescriptor_t usbStringDescriptorSerial = {
377 .header = { 377 .header = {
378 .bLength = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), 378 .bLength = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1),
379 .bDescriptorType = USBDESCR_STRING 379 .bDescriptorType = USBDESCR_STRING
380 }, 380 },
381 .bString = LSTR(SERIAL_NUMBER) 381 .bString = LSTR(SERIAL_NUMBER)
382}; 382};
383// clang-format on
384 383
384#if USB_CFG_DESCR_PROPS_DEVICE
385/* 385/*
386 * Descriptor for compite device: Keyboard + Mouse 386 * Device descriptor
387 *
388 * contains: device, interface, HID and endpoint descriptors
389 */ 387 */
388const PROGMEM usbDeviceDescriptor_t usbDeviceDescriptor = {
389 .header = {
390 .bLength = sizeof(usbDeviceDescriptor_t),
391 .bDescriptorType = USBDESCR_DEVICE
392 },
393 .bcdUSB = 0x0110,
394 .bDeviceClass = USB_CFG_DEVICE_CLASS,
395 .bDeviceSubClass = USB_CFG_DEVICE_SUBCLASS,
396 .bDeviceProtocol = 0x00,
397 .bMaxPacketSize0 = 8,
398 .idVendor = VENDOR_ID,
399 .idProduct = PRODUCT_ID,
400 .bcdDevice = DEVICE_VER,
401 .iManufacturer = 0x01,
402 .iProduct = 0x02,
403 .iSerialNumber = 0x03,
404 .bNumConfigurations = 1
405};
406#endif
407
390#if USB_CFG_DESCR_PROPS_CONFIGURATION 408#if USB_CFG_DESCR_PROPS_CONFIGURATION
391const PROGMEM char usbDescriptorConfiguration[] = { 409/*
392 /* USB configuration descriptor */ 410 * Configuration descriptors
393 9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */ 411 */
394 USBDESCR_CONFIG, /* descriptor type */ 412const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
395# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) 413 .header = {
396 59, // 9 + (9 + 9 + 7) + (9 + 9 + 7) 414 .header = {
397# else 415 .bLength = sizeof(usbConfigurationDescriptorHeader_t),
398 34, // 9 + (9 + 9 + 7) 416 .bDescriptorType = USBDESCR_CONFIG
399# endif 417 },
400 0, 418 .wTotalLength = sizeof(usbConfigurationDescriptor_t),
401// 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + 9, 0,
402/* total length of data returned (including inlined descriptors) */
403# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) 419# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
404 2, /* number of interfaces in this configuration */ 420 .bNumInterfaces = 2,
405# else 421# else
406 1, 422 .bNumInterfaces = 1,
407# endif 423# endif
408 1, /* index of this configuration */ 424 .bConfigurationValue = 0x01,
409 0, /* configuration name string index */ 425 .iConfiguration = 0x00,
410# if USB_CFG_IS_SELF_POWERED 426# if USB_CFG_IS_SELF_POWERED
411 (1 << 7) | USBATTR_SELFPOWER, /* attributes */ 427 .bmAttributes = (1 << 7) | USBATTR_SELFPOWER,
412# else 428# else
413 (1 << 7), /* attributes */ 429 .bmAttributes = (1 << 7),
414# endif 430# endif
415 USB_MAX_POWER_CONSUMPTION / 2, /* max USB current in 2mA units */ 431 .bMaxPower = USB_MAX_POWER_CONSUMPTION / 2
432 },
416 433
417 /* 434 /*
418 * Keyboard interface 435 * Keyboard
419 */ 436 */
420 /* Interface descriptor */ 437 .keyboardInterface = {
421 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ 438 .header = {
422 USBDESCR_INTERFACE, /* descriptor type */ 439 .bLength = sizeof(usbInterfaceDescriptor_t),
423 0, /* index of this interface */ 440 .bDescriptorType = USBDESCR_INTERFACE
424 0, /* alternate setting for this interface */ 441 },
425 USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */ 442 .bInterfaceNumber = 0,
426 USB_CFG_INTERFACE_CLASS, USB_CFG_INTERFACE_SUBCLASS, USB_CFG_INTERFACE_PROTOCOL, 0, /* string index for interface */ 443 .bAlternateSetting = 0x00,
427 /* HID descriptor */ 444 .bNumEndpoints = USB_CFG_HAVE_INTRIN_ENDPOINT,
428 9, /* sizeof(usbDescrHID): length of descriptor in bytes */ 445 .bInterfaceClass = USB_CFG_INTERFACE_CLASS,
429 USBDESCR_HID, /* descriptor type: HID */ 446 .bInterfaceSubClass = USB_CFG_INTERFACE_SUBCLASS,
430 0x01, 0x01, /* BCD representation of HID version */ 447 .bInterfaceProtocol = USB_CFG_INTERFACE_PROTOCOL,
431 0x00, /* target country code */ 448 .iInterface = 0x00
432 0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */ 449 },
433 0x22, /* descriptor type: report */ 450 .keyboardHID = {
434 sizeof(keyboard_hid_report), 0, /* total length of report descriptor */ 451 .header = {
435/* Endpoint descriptor */ 452 .bLength = sizeof(usbHIDDescriptor_t),
436# if USB_CFG_HAVE_INTRIN_ENDPOINT /* endpoint descriptor for endpoint 1 */ 453 .bDescriptorType = USBDESCR_HID
437 7, /* sizeof(usbDescrEndpoint) */ 454 },
438 USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 455 .bcdHID = 0x0101,
439 (char)0x81, /* IN endpoint number 1 */ 456 .bCountryCode = 0x00,
440 0x03, /* attrib: Interrupt endpoint */ 457 .bNumDescriptors = 1,
441 8, 0, /* maximum packet size */ 458 .bDescriptorType = USBDESCR_HID_REPORT,
442 USB_POLLING_INTERVAL_MS, /* in ms */ 459 .wDescriptorLength = sizeof(keyboard_hid_report)
460 },
461# ifdef USB_CFG_HAVE_INTRIN_ENDPOINT
462 .keyboardINEndpoint = {
463 .header = {
464 .bLength = sizeof(usbEndpointDescriptor_t),
465 .bDescriptorType = USBDESCR_ENDPOINT
466 },
467 .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | 1),
468 .bmAttributes = 0x03,
469 .wMaxPacketSize = 8,
470 .bInterval = USB_POLLING_INTERVAL_MS
471 },
443# endif 472# endif
444 473
445# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) 474# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
446 /* 475 /*
447 * Mouse/extrakeys interface 476 * Mouse/Extrakeys
448 */ 477 */
449 /* Interface descriptor */ 478 .mouseExtraInterface = {
450 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ 479 .header = {
451 USBDESCR_INTERFACE, /* descriptor type */ 480 .bLength = sizeof(usbInterfaceDescriptor_t),
452 1, /* index of this interface */ 481 .bDescriptorType = USBDESCR_INTERFACE
453 0, /* alternate setting for this interface */ 482 },
454 USB_CFG_HAVE_INTRIN_ENDPOINT3, /* endpoints excl 0: number of endpoint descriptors to follow */ 483 .bInterfaceNumber = 1,
455 0x03, /* CLASS: HID */ 484 .bAlternateSetting = 0x00,
456 0, /* SUBCLASS: none */ 485 .bNumEndpoints = USB_CFG_HAVE_INTRIN_ENDPOINT3,
457 0, /* PROTOCOL: none */ 486 .bInterfaceClass = 0x03,
458 0, /* string index for interface */ 487 .bInterfaceSubClass = 0x00,
459 /* HID descriptor */ 488 .bInterfaceProtocol = 0x00,
460 9, /* sizeof(usbDescrHID): length of descriptor in bytes */ 489 .iInterface = 0x00
461 USBDESCR_HID, /* descriptor type: HID */ 490 },
462 0x01, 0x01, /* BCD representation of HID version */ 491 .mouseExtraHID = {
463 0x00, /* target country code */ 492 .header = {
464 0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */ 493 .bLength = sizeof(usbHIDDescriptor_t),
465 0x22, /* descriptor type: report */ 494 .bDescriptorType = USBDESCR_HID
466 sizeof(mouse_extra_hid_report), 0, /* total length of report descriptor */ 495 },
467# if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */ 496 .bcdHID = 0x0101,
468 /* Endpoint descriptor */ 497 .bCountryCode = 0x00,
469 7, /* sizeof(usbDescrEndpoint) */ 498 .bNumDescriptors = 1,
470 USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 499 .bDescriptorType = USBDESCR_HID_REPORT,
471 (char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */ 500 .wDescriptorLength = sizeof(mouse_extra_hid_report)
472 0x03, /* attrib: Interrupt endpoint */ 501 },
473 8, 0, /* maximum packet size */ 502# if USB_CFG_HAVE_INTRIN_ENDPOINT3
474 USB_POLLING_INTERVAL_MS, /* in ms */ 503 .mouseExtraINEndpoint = {
504 .header = {
505 .bLength = sizeof(usbEndpointDescriptor_t),
506 .bDescriptorType = USBDESCR_ENDPOINT
507 },
508 .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
509 .bmAttributes = 0x03,
510 .wMaxPacketSize = 8,
511 .bInterval = USB_POLLING_INTERVAL_MS
512 }
475# endif 513# endif
476# endif 514# endif
477}; 515};
478#endif 516#endif
479 517
518// clang-format on
519
480USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { 520USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
481 usbMsgLen_t len = 0; 521 usbMsgLen_t len = 0;
482 522
@@ -489,42 +529,48 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
489 debug_hex16(rq->wLength.word); debug("\n"); 529 debug_hex16(rq->wLength.word); debug("\n");
490 */ 530 */
491 switch (rq->wValue.bytes[1]) { 531 switch (rq->wValue.bytes[1]) {
532#if USB_CFG_DESCR_PROPS_DEVICE
533 case USBDESCR_DEVICE:
534 usbMsgPtr = (unsigned char *)&usbDeviceDescriptor;
535 len = sizeof(usbDeviceDescriptor_t);
536 break;
537#endif
492#if USB_CFG_DESCR_PROPS_CONFIGURATION 538#if USB_CFG_DESCR_PROPS_CONFIGURATION
493 case USBDESCR_CONFIG: 539 case USBDESCR_CONFIG:
494 usbMsgPtr = (unsigned char *)usbDescriptorConfiguration; 540 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor;
495 len = sizeof(usbDescriptorConfiguration); 541 len = sizeof(usbConfigurationDescriptor_t);
496 break; 542 break;
497#endif 543#endif
498 case USBDESCR_STRING: 544 case USBDESCR_STRING:
499 switch (rq->wValue.bytes[0]) { 545 switch (rq->wValue.bytes[0]) {
500 case 0: 546 case 0:
501 usbMsgPtr = (unsigned char *)&usbDescriptorStringZero; 547 usbMsgPtr = (unsigned char *)&usbStringDescriptorZero;
502 len = usbDescriptorStringZero.header.bLength; 548 len = usbStringDescriptorZero.header.bLength;
503 break; 549 break;
504 case 1: // iManufacturer 550 case 1: // iManufacturer
505 usbMsgPtr = (unsigned char *)&usbDescriptorStringManufacturer; 551 usbMsgPtr = (unsigned char *)&usbStringDescriptorManufacturer;
506 len = usbDescriptorStringManufacturer.header.bLength; 552 len = usbStringDescriptorManufacturer.header.bLength;
507 break; 553 break;
508 case 2: // iProduct 554 case 2: // iProduct
509 usbMsgPtr = (unsigned char *)&usbDescriptorStringProduct; 555 usbMsgPtr = (unsigned char *)&usbStringDescriptorProduct;
510 len = usbDescriptorStringProduct.header.bLength; 556 len = usbStringDescriptorProduct.header.bLength;
511 break; 557 break;
512 case 3: // iSerialNumber 558 case 3: // iSerialNumber
513 usbMsgPtr = (unsigned char *)&usbDescriptorStringSerial; 559 usbMsgPtr = (unsigned char *)&usbStringDescriptorSerial;
514 len = usbDescriptorStringSerial.header.bLength; 560 len = usbStringDescriptorSerial.header.bLength;
515 break; 561 break;
516 } 562 }
517 break; 563 break;
518 case USBDESCR_HID: 564 case USBDESCR_HID:
519 switch (rq->wValue.bytes[0]) { 565 switch (rq->wValue.bytes[0]) {
520 case 0: 566 case 0:
521 usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + 9); 567 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.keyboardHID;
522 len = 9; 568 len = sizeof(usbHIDDescriptor_t);
523 break; 569 break;
524#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) 570#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
525 case 1: 571 case 1:
526 usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + (9 + 9 + 7) + 9); 572 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.mouseExtraHID;
527 len = 9; 573 len = sizeof(usbHIDDescriptor_t);
528 break; 574 break;
529#endif 575#endif
530 } 576 }
diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h
index cee07207a..debac67d2 100644
--- a/tmk_core/protocol/vusb/vusb.h
+++ b/tmk_core/protocol/vusb/vusb.h
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#ifndef VUSB_H 18#pragma once
19#define VUSB_H
20 19
21#include "host_driver.h" 20#include "host_driver.h"
22 21
@@ -25,14 +24,83 @@ typedef struct usbDescriptorHeader {
25 uchar bDescriptorType; 24 uchar bDescriptorType;
26} __attribute__((packed)) usbDescriptorHeader_t; 25} __attribute__((packed)) usbDescriptorHeader_t;
27 26
27typedef struct usbDeviceDescriptor {
28 usbDescriptorHeader_t header;
29 unsigned bcdUSB;
30 uchar bDeviceClass;
31 uchar bDeviceSubClass;
32 uchar bDeviceProtocol;
33 uchar bMaxPacketSize0;
34 unsigned idVendor;
35 unsigned idProduct;
36 unsigned bcdDevice;
37 uchar iManufacturer;
38 uchar iProduct;
39 uchar iSerialNumber;
40 uchar bNumConfigurations;
41} __attribute__((packed)) usbDeviceDescriptor_t;
42
43typedef struct usbConfigurationDescriptorHeader {
44 usbDescriptorHeader_t header;
45 unsigned wTotalLength;
46 uchar bNumInterfaces;
47 uchar bConfigurationValue;
48 uchar iConfiguration;
49 uchar bmAttributes;
50 uchar bMaxPower;
51} __attribute__((packed)) usbConfigurationDescriptorHeader_t;
52
28typedef struct usbStringDescriptor { 53typedef struct usbStringDescriptor {
29 usbDescriptorHeader_t header; 54 usbDescriptorHeader_t header;
30 int bString[]; 55 int bString[];
31} __attribute__((packed)) usbStringDescriptor_t; 56} __attribute__((packed)) usbStringDescriptor_t;
32 57
58typedef struct usbInterfaceDescriptor {
59 usbDescriptorHeader_t header;
60 uchar bInterfaceNumber;
61 uchar bAlternateSetting;
62 uchar bNumEndpoints;
63 uchar bInterfaceClass;
64 uchar bInterfaceSubClass;
65 uchar bInterfaceProtocol;
66 uchar iInterface;
67} __attribute__((packed)) usbInterfaceDescriptor_t;
68
69typedef struct usbEndpointDescriptor {
70 usbDescriptorHeader_t header;
71 uchar bEndpointAddress;
72 uchar bmAttributes;
73 unsigned wMaxPacketSize;
74 uchar bInterval;
75} __attribute__((packed)) usbEndpointDescriptor_t;
76
77typedef struct usbHIDDescriptor {
78 usbDescriptorHeader_t header;
79 unsigned bcdHID;
80 uchar bCountryCode;
81 uchar bNumDescriptors;
82 uchar bDescriptorType;
83 unsigned wDescriptorLength;
84} __attribute__((packed)) usbHIDDescriptor_t;
85
86typedef struct usbConfigurationDescriptor {
87 usbConfigurationDescriptorHeader_t header;
88 usbInterfaceDescriptor_t keyboardInterface;
89 usbHIDDescriptor_t keyboardHID;
90#ifdef USB_CFG_HAVE_INTRIN_ENDPOINT
91 usbEndpointDescriptor_t keyboardINEndpoint;
92#endif
93
94#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
95 usbInterfaceDescriptor_t mouseExtraInterface;
96 usbHIDDescriptor_t mouseExtraHID;
97# ifdef USB_CFG_HAVE_INTRIN_ENDPOINT3
98 usbEndpointDescriptor_t mouseExtraINEndpoint;
99# endif
100#endif
101} __attribute__((packed)) usbConfigurationDescriptor_t;
102
33#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1)) 103#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1))
34 104
35host_driver_t *vusb_driver(void); 105host_driver_t *vusb_driver(void);
36void vusb_transfer_keyboard(void); 106void vusb_transfer_keyboard(void);
37
38#endif