diff options
| author | Takuya Urakawa <urkwtky@gmail.com> | 2020-03-31 05:15:05 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-30 21:15:05 +0100 |
| commit | 89a675d57c14b3980ba73198b692d6fb5a62f105 (patch) | |
| tree | 0bbc4da65471d0a489746ab8c359da2a42774225 /tmk_core | |
| parent | b892a1429d753d83d179fea26a2c7b84edab840d (diff) | |
| download | qmk_firmware-89a675d57c14b3980ba73198b692d6fb5a62f105.tar.gz qmk_firmware-89a675d57c14b3980ba73198b692d6fb5a62f105.zip | |
add hid_raw feature to VUSB (#8380)
* rewrite usbhid feature on vusb
* Apply suggestions from code review
Co-Authored-By: Ryan <fauxpark@gmail.com>
* fix typo
* fix typo again
* Update tmk_core/protocol/vusb/vusb.c
Co-Authored-By: Ryan <fauxpark@gmail.com>
* clean up defines
Co-authored-by: Ryan <fauxpark@gmail.com>
Diffstat (limited to 'tmk_core')
| -rw-r--r-- | tmk_core/protocol/vusb/main.c | 7 | ||||
| -rw-r--r-- | tmk_core/protocol/vusb/vusb.c | 157 | ||||
| -rw-r--r-- | tmk_core/protocol/vusb/vusb.h | 11 |
3 files changed, 174 insertions, 1 deletions
diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c index 219989876..1ab765343 100644 --- a/tmk_core/protocol/vusb/main.c +++ b/tmk_core/protocol/vusb/main.c | |||
| @@ -108,6 +108,13 @@ int main(void) { | |||
| 108 | keyboard_task(); | 108 | keyboard_task(); |
| 109 | } | 109 | } |
| 110 | vusb_transfer_keyboard(); | 110 | vusb_transfer_keyboard(); |
| 111 | #ifdef RAW_ENABLE | ||
| 112 | usbPoll(); | ||
| 113 | |||
| 114 | if (usbConfiguration && usbInterruptIsReady3()) { | ||
| 115 | raw_hid_task(); | ||
| 116 | } | ||
| 117 | #endif | ||
| 111 | } | 118 | } |
| 112 | } | 119 | } |
| 113 | } | 120 | } |
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index 19df35805..47dc1245d 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c | |||
| @@ -28,6 +28,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 28 | #include "vusb.h" | 28 | #include "vusb.h" |
| 29 | #include <util/delay.h> | 29 | #include <util/delay.h> |
| 30 | 30 | ||
| 31 | #if defined(RAW_ENABLE) | ||
| 32 | # include "raw_hid.h" | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && defined(RAW_ENABLE) | ||
| 36 | # error "Enabling Mousekeys/Extrakeys and Raw HID at the same time is not currently supported on V-USB." | ||
| 37 | #endif | ||
| 38 | |||
| 31 | static uint8_t vusb_keyboard_leds = 0; | 39 | static uint8_t vusb_keyboard_leds = 0; |
| 32 | static uint8_t vusb_idle_rate = 0; | 40 | static uint8_t vusb_idle_rate = 0; |
| 33 | 41 | ||
| @@ -72,6 +80,52 @@ void vusb_transfer_keyboard(void) { | |||
| 72 | } | 80 | } |
| 73 | 81 | ||
| 74 | /*------------------------------------------------------------------* | 82 | /*------------------------------------------------------------------* |
| 83 | * RAW HID | ||
| 84 | *------------------------------------------------------------------*/ | ||
| 85 | #ifdef RAW_ENABLE | ||
| 86 | # define RAW_BUFFER_SIZE 32 | ||
| 87 | # define RAW_EPSIZE 8 | ||
| 88 | |||
| 89 | static uint8_t raw_output_buffer[RAW_BUFFER_SIZE]; | ||
| 90 | static uint8_t raw_output_received_bytes = 0; | ||
| 91 | |||
| 92 | void raw_hid_send(uint8_t *data, uint8_t length) { | ||
| 93 | if (length != RAW_BUFFER_SIZE) { | ||
| 94 | return; | ||
| 95 | } | ||
| 96 | |||
| 97 | uint8_t *temp = data; | ||
| 98 | for (uint8_t i = 0; i < 4; i++) { | ||
| 99 | while (!usbInterruptIsReady3()) { | ||
| 100 | usbPoll(); | ||
| 101 | } | ||
| 102 | usbSetInterrupt3(temp, 8); | ||
| 103 | temp += 8; | ||
| 104 | } | ||
| 105 | while (!usbInterruptIsReady3()) { | ||
| 106 | usbPoll(); | ||
| 107 | } | ||
| 108 | usbSetInterrupt3(0, 0); | ||
| 109 | usbPoll(); | ||
| 110 | _delay_ms(1); | ||
| 111 | } | ||
| 112 | |||
| 113 | __attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) { | ||
| 114 | // Users should #include "raw_hid.h" in their own code | ||
| 115 | // and implement this function there. Leave this as weak linkage | ||
| 116 | // so users can opt to not handle data coming in. | ||
| 117 | } | ||
| 118 | |||
| 119 | void raw_hid_task(void) { | ||
| 120 | if (raw_output_received_bytes == RAW_BUFFER_SIZE) { | ||
| 121 | raw_hid_receive(raw_output_buffer, RAW_BUFFER_SIZE); | ||
| 122 | raw_output_received_bytes = 0; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | #endif | ||
| 127 | |||
| 128 | /*------------------------------------------------------------------* | ||
| 75 | * Host driver | 129 | * Host driver |
| 76 | *------------------------------------------------------------------*/ | 130 | *------------------------------------------------------------------*/ |
| 77 | static uint8_t keyboard_leds(void); | 131 | static uint8_t keyboard_leds(void); |
| @@ -206,6 +260,27 @@ uchar usbFunctionWrite(uchar *data, uchar len) { | |||
| 206 | return 1; | 260 | return 1; |
| 207 | } | 261 | } |
| 208 | 262 | ||
| 263 | void usbFunctionWriteOut(uchar *data, uchar len) { | ||
| 264 | #ifdef RAW_ENABLE | ||
| 265 | // Data from host must be divided every 8bytes | ||
| 266 | if (len != 8) { | ||
| 267 | debug("RAW: invalid length"); | ||
| 268 | raw_output_received_bytes = 0; | ||
| 269 | return; | ||
| 270 | } | ||
| 271 | |||
| 272 | if (raw_output_received_bytes + len > RAW_BUFFER_SIZE) { | ||
| 273 | debug("RAW: buffer full"); | ||
| 274 | raw_output_received_bytes = 0; | ||
| 275 | } else { | ||
| 276 | for (uint8_t i = 0; i < 8; i++) { | ||
| 277 | raw_output_buffer[raw_output_received_bytes + i] = data[i]; | ||
| 278 | } | ||
| 279 | raw_output_received_bytes += len; | ||
| 280 | } | ||
| 281 | #endif | ||
| 282 | } | ||
| 283 | |||
| 209 | /*------------------------------------------------------------------* | 284 | /*------------------------------------------------------------------* |
| 210 | * Descriptors * | 285 | * Descriptors * |
| 211 | *------------------------------------------------------------------*/ | 286 | *------------------------------------------------------------------*/ |
| @@ -335,6 +410,29 @@ const PROGMEM uchar mouse_extra_hid_report[] = { | |||
| 335 | }; | 410 | }; |
| 336 | #endif | 411 | #endif |
| 337 | 412 | ||
| 413 | #if defined(RAW_ENABLE) | ||
| 414 | const PROGMEM uchar raw_hid_report[] = { | ||
| 415 | 0x06, 0x60, 0xFF, // Usage Page (Vendor Defined) | ||
| 416 | 0x09, 0x61, // Usage (Vendor Defined) | ||
| 417 | 0xA1, 0x01, // Collection (Application) | ||
| 418 | // Data to host | ||
| 419 | 0x09, 0x62, // Usage (Vendor Defined) | ||
| 420 | 0x15, 0x00, // Logical Minimum (0) | ||
| 421 | 0x26, 0xFF, 0x00, // Logical Maximum (255) | ||
| 422 | 0x95, RAW_BUFFER_SIZE, // Report Count | ||
| 423 | 0x75, 0x08, // Report Size (8) | ||
| 424 | 0x81, 0x02, // Input (Data, Variable, Absolute) | ||
| 425 | // Data from host | ||
| 426 | 0x09, 0x63, // Usage (Vendor Defined) | ||
| 427 | 0x15, 0x00, // Logical Minimum (0) | ||
| 428 | 0x26, 0xFF, 0x00, // Logical Maximum (255) | ||
| 429 | 0x95, RAW_BUFFER_SIZE, // Report Count | ||
| 430 | 0x75, 0x08, // Report Size (8) | ||
| 431 | 0x91, 0x02, // Output (Data, Variable, Absolute) | ||
| 432 | 0xC0, // End Collection | ||
| 433 | }; | ||
| 434 | #endif | ||
| 435 | |||
| 338 | #ifndef SERIAL_NUMBER | 436 | #ifndef SERIAL_NUMBER |
| 339 | # define SERIAL_NUMBER 0 | 437 | # define SERIAL_NUMBER 0 |
| 340 | #endif | 438 | #endif |
| @@ -416,7 +514,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = { | |||
| 416 | .bDescriptorType = USBDESCR_CONFIG | 514 | .bDescriptorType = USBDESCR_CONFIG |
| 417 | }, | 515 | }, |
| 418 | .wTotalLength = sizeof(usbConfigurationDescriptor_t), | 516 | .wTotalLength = sizeof(usbConfigurationDescriptor_t), |
| 419 | # if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) | 517 | # if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) || defined(RAW_ENABLE) |
| 420 | .bNumInterfaces = 2, | 518 | .bNumInterfaces = 2, |
| 421 | # else | 519 | # else |
| 422 | .bNumInterfaces = 1, | 520 | .bNumInterfaces = 1, |
| @@ -511,6 +609,53 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = { | |||
| 511 | .bInterval = USB_POLLING_INTERVAL_MS | 609 | .bInterval = USB_POLLING_INTERVAL_MS |
| 512 | } | 610 | } |
| 513 | # endif | 611 | # endif |
| 612 | # elif defined(RAW_ENABLE) | ||
| 613 | .rawInterface = { | ||
| 614 | .header = { | ||
| 615 | .bLength = sizeof(usbInterfaceDescriptor_t), | ||
| 616 | .bDescriptorType = USBDESCR_INTERFACE | ||
| 617 | }, | ||
| 618 | .bInterfaceNumber = 1, | ||
| 619 | .bAlternateSetting = 0x00, | ||
| 620 | .bNumEndpoints = 2, | ||
| 621 | .bInterfaceClass = 0x03, | ||
| 622 | .bInterfaceSubClass = 0x00, | ||
| 623 | .bInterfaceProtocol = 0x00, | ||
| 624 | .iInterface = 0x00 | ||
| 625 | }, | ||
| 626 | .rawHID = { | ||
| 627 | .header = { | ||
| 628 | .bLength = sizeof(usbHIDDescriptor_t), | ||
| 629 | .bDescriptorType = USBDESCR_HID | ||
| 630 | }, | ||
| 631 | .bcdHID = 0x0101, | ||
| 632 | .bCountryCode = 0x00, | ||
| 633 | .bNumDescriptors = 2, | ||
| 634 | .bDescriptorType = USBDESCR_HID_REPORT, | ||
| 635 | .wDescriptorLength = sizeof(raw_hid_report) | ||
| 636 | }, | ||
| 637 | # if USB_CFG_HAVE_INTRIN_ENDPOINT3 | ||
| 638 | .rawINEndpoint = { | ||
| 639 | .header = { | ||
| 640 | .bLength = sizeof(usbEndpointDescriptor_t), | ||
| 641 | .bDescriptorType = USBDESCR_ENDPOINT | ||
| 642 | }, | ||
| 643 | .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER), | ||
| 644 | .bmAttributes = 0x03, | ||
| 645 | .wMaxPacketSize = RAW_EPSIZE, | ||
| 646 | .bInterval = USB_POLLING_INTERVAL_MS | ||
| 647 | }, | ||
| 648 | .rawOUTEndpoint = { | ||
| 649 | .header = { | ||
| 650 | .bLength = sizeof(usbEndpointDescriptor_t), | ||
| 651 | .bDescriptorType = USBDESCR_ENDPOINT | ||
| 652 | }, | ||
| 653 | .bEndpointAddress = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP3_NUMBER), | ||
| 654 | .bmAttributes = 0x03, | ||
| 655 | .wMaxPacketSize = RAW_EPSIZE, | ||
| 656 | .bInterval = USB_POLLING_INTERVAL_MS | ||
| 657 | } | ||
| 658 | # endif | ||
| 514 | # endif | 659 | # endif |
| 515 | }; | 660 | }; |
| 516 | #endif | 661 | #endif |
| @@ -572,6 +717,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { | |||
| 572 | usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.mouseExtraHID; | 717 | usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.mouseExtraHID; |
| 573 | len = sizeof(usbHIDDescriptor_t); | 718 | len = sizeof(usbHIDDescriptor_t); |
| 574 | break; | 719 | break; |
| 720 | #elif defined(RAW_ENABLE) | ||
| 721 | case 1: | ||
| 722 | usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.rawHID; | ||
| 723 | len = sizeof(usbHIDDescriptor_t); | ||
| 724 | break; | ||
| 575 | #endif | 725 | #endif |
| 576 | } | 726 | } |
| 577 | break; | 727 | break; |
| @@ -587,6 +737,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { | |||
| 587 | usbMsgPtr = (unsigned char *)mouse_extra_hid_report; | 737 | usbMsgPtr = (unsigned char *)mouse_extra_hid_report; |
| 588 | len = sizeof(mouse_extra_hid_report); | 738 | len = sizeof(mouse_extra_hid_report); |
| 589 | break; | 739 | break; |
| 740 | #elif defined(RAW_ENABLE) | ||
| 741 | case 1: | ||
| 742 | usbMsgPtr = (unsigned char *)raw_hid_report; | ||
| 743 | len = sizeof(raw_hid_report); | ||
| 744 | break; | ||
| 590 | #endif | 745 | #endif |
| 591 | } | 746 | } |
| 592 | break; | 747 | break; |
diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h index debac67d2..6d491266d 100644 --- a/tmk_core/protocol/vusb/vusb.h +++ b/tmk_core/protocol/vusb/vusb.h | |||
| @@ -97,6 +97,13 @@ typedef struct usbConfigurationDescriptor { | |||
| 97 | # ifdef USB_CFG_HAVE_INTRIN_ENDPOINT3 | 97 | # ifdef USB_CFG_HAVE_INTRIN_ENDPOINT3 |
| 98 | usbEndpointDescriptor_t mouseExtraINEndpoint; | 98 | usbEndpointDescriptor_t mouseExtraINEndpoint; |
| 99 | # endif | 99 | # endif |
| 100 | #elif defined(RAW_ENABLE) | ||
| 101 | usbInterfaceDescriptor_t rawInterface; | ||
| 102 | usbHIDDescriptor_t rawHID; | ||
| 103 | # ifdef USB_CFG_HAVE_INTRIN_ENDPOINT3 | ||
| 104 | usbEndpointDescriptor_t rawINEndpoint; | ||
| 105 | usbEndpointDescriptor_t rawOUTEndpoint; | ||
| 106 | # endif | ||
| 100 | #endif | 107 | #endif |
| 101 | } __attribute__((packed)) usbConfigurationDescriptor_t; | 108 | } __attribute__((packed)) usbConfigurationDescriptor_t; |
| 102 | 109 | ||
| @@ -104,3 +111,7 @@ typedef struct usbConfigurationDescriptor { | |||
| 104 | 111 | ||
| 105 | host_driver_t *vusb_driver(void); | 112 | host_driver_t *vusb_driver(void); |
| 106 | void vusb_transfer_keyboard(void); | 113 | void vusb_transfer_keyboard(void); |
| 114 | |||
| 115 | #if defined(RAW_ENABLE) | ||
| 116 | void raw_hid_task(void); | ||
| 117 | #endif | ||
