aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorTakuya Urakawa <urkwtky@gmail.com>2020-03-31 05:15:05 +0900
committerGitHub <noreply@github.com>2020-03-30 21:15:05 +0100
commit89a675d57c14b3980ba73198b692d6fb5a62f105 (patch)
tree0bbc4da65471d0a489746ab8c359da2a42774225 /tmk_core
parentb892a1429d753d83d179fea26a2c7b84edab840d (diff)
downloadqmk_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.c7
-rw-r--r--tmk_core/protocol/vusb/vusb.c157
-rw-r--r--tmk_core/protocol/vusb/vusb.h11
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
31static uint8_t vusb_keyboard_leds = 0; 39static uint8_t vusb_keyboard_leds = 0;
32static uint8_t vusb_idle_rate = 0; 40static 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
89static uint8_t raw_output_buffer[RAW_BUFFER_SIZE];
90static uint8_t raw_output_received_bytes = 0;
91
92void 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
119void 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 *------------------------------------------------------------------*/
77static uint8_t keyboard_leds(void); 131static 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
263void 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)
414const 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
105host_driver_t *vusb_driver(void); 112host_driver_t *vusb_driver(void);
106void vusb_transfer_keyboard(void); 113void vusb_transfer_keyboard(void);
114
115#if defined(RAW_ENABLE)
116void raw_hid_task(void);
117#endif