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 | ||