aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol/vusb/vusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/vusb/vusb.c')
-rw-r--r--tmk_core/protocol/vusb/vusb.c213
1 files changed, 187 insertions, 26 deletions
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index c4baf5ab0..e8aed6f5d 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -15,25 +15,50 @@ 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#include <avr/eeprom.h>
19#include <avr/wdt.h> 18#include <avr/wdt.h>
19#include <util/delay.h>
20#include <stdint.h> 20#include <stdint.h>
21#include "usbdrv.h" 21#include "usbdrv.h"
22#include "usbconfig.h" 22#include "usbconfig.h"
23#include "host.h" 23#include "host.h"
24#include "report.h" 24#include "report.h"
25#include "print.h"
26#include "debug.h"
27#include "host_driver.h" 25#include "host_driver.h"
28#include "vusb.h" 26#include "vusb.h"
29#include <util/delay.h> 27#include "print.h"
28#include "debug.h"
30 29
31#ifdef RAW_ENABLE 30#ifdef RAW_ENABLE
32# include "raw_hid.h" 31# include "raw_hid.h"
33#endif 32#endif
34 33
35#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && defined(RAW_ENABLE) 34#if defined(CONSOLE_ENABLE)
36# error "Enabling Mousekeys/Extrakeys and Raw HID at the same time is not currently supported on V-USB." 35# define RBUF_SIZE 128
36# include "ring_buffer.h"
37#endif
38
39#define NEXT_INTERFACE __COUNTER__
40
41/*
42 * Interface indexes
43 */
44enum usb_interfaces {
45 KEYBOARD_INTERFACE = NEXT_INTERFACE,
46#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE))
47 MOUSE_EXTRA_INTERFACE = NEXT_INTERFACE,
48#endif
49#ifdef RAW_ENABLE
50 RAW_INTERFACE = NEXT_INTERFACE,
51#endif
52#ifdef CONSOLE_ENABLE
53 CONSOLE_INTERFACE = NEXT_INTERFACE,
54#endif
55 TOTAL_INTERFACES = NEXT_INTERFACE,
56};
57
58#define MAX_INTERFACES 2
59
60#if (NEXT_INTERFACE - 1) > MAX_INTERFACES
61# error 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
37#endif 62#endif
38 63
39static uint8_t vusb_keyboard_leds = 0; 64static uint8_t vusb_keyboard_leds = 0;
@@ -120,7 +145,60 @@ void raw_hid_task(void) {
120 raw_output_received_bytes = 0; 145 raw_output_received_bytes = 0;
121 } 146 }
122} 147}
148#endif
149
150/*------------------------------------------------------------------*
151 * Console
152 *------------------------------------------------------------------*/
153#ifdef CONSOLE_ENABLE
154# define CONSOLE_BUFFER_SIZE 32
155# define CONSOLE_EPSIZE 8
156
157int8_t sendchar(uint8_t c) {
158 rbuf_enqueue(c);
159 return 0;
160}
161
162static inline bool usbSendData3(char *data, uint8_t len) {
163 uint8_t retries = 5;
164 while (!usbInterruptIsReady3()) {
165 if (!(retries--)) {
166 return false;
167 }
168 usbPoll();
169 }
170
171 usbSetInterrupt3((unsigned char *)data, len);
172 return true;
173}
174
175void console_task(void) {
176 if (!usbConfiguration) {
177 return;
178 }
179
180 if (!rbuf_has_data()) {
181 return;
182 }
183
184 // Send in chunks of 8 padded to 32
185 char send_buf[CONSOLE_BUFFER_SIZE] = {0};
186 uint8_t send_buf_count = 0;
187 while (rbuf_has_data() && send_buf_count < CONSOLE_EPSIZE) {
188 send_buf[send_buf_count++] = rbuf_dequeue();
189 }
123 190
191 char *temp = send_buf;
192 for (uint8_t i = 0; i < 4; i++) {
193 if (!usbSendData3(temp, 8)) {
194 break;
195 }
196 temp += 8;
197 }
198
199 usbSendData3(0, 0);
200 usbPoll();
201}
124#endif 202#endif
125 203
126/*------------------------------------------------------------------* 204/*------------------------------------------------------------------*
@@ -429,7 +507,30 @@ const PROGMEM uchar raw_hid_report[] = {
429 0x95, RAW_BUFFER_SIZE, // Report Count 507 0x95, RAW_BUFFER_SIZE, // Report Count
430 0x75, 0x08, // Report Size (8) 508 0x75, 0x08, // Report Size (8)
431 0x91, 0x02, // Output (Data, Variable, Absolute) 509 0x91, 0x02, // Output (Data, Variable, Absolute)
432 0xC0, // End Collection 510 0xC0 // End Collection
511};
512#endif
513
514#if defined(CONSOLE_ENABLE)
515const PROGMEM uchar console_hid_report[] = {
516 0x06, 0x31, 0xFF, // Usage Page (Vendor Defined - PJRC Teensy compatible)
517 0x09, 0x74, // Usage (Vendor Defined - PJRC Teensy compatible)
518 0xA1, 0x01, // Collection (Application)
519 // Data to host
520 0x09, 0x75, // Usage (Vendor Defined)
521 0x15, 0x00, // Logical Minimum (0x00)
522 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
523 0x95, CONSOLE_BUFFER_SIZE, // Report Count
524 0x75, 0x08, // Report Size (8)
525 0x81, 0x02, // Input (Data, Variable, Absolute)
526 // Data from host
527 0x09, 0x76, // Usage (Vendor Defined)
528 0x15, 0x00, // Logical Minimum (0x00)
529 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
530 0x95, CONSOLE_BUFFER_SIZE, // Report Count
531 0x75, 0x08, // Report Size (8)
532 0x91, 0x02, // Output (Data)
533 0xC0 // End Collection
433}; 534};
434#endif 535#endif
435 536
@@ -511,11 +612,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
511 .bDescriptorType = USBDESCR_CONFIG 612 .bDescriptorType = USBDESCR_CONFIG
512 }, 613 },
513 .wTotalLength = sizeof(usbConfigurationDescriptor_t), 614 .wTotalLength = sizeof(usbConfigurationDescriptor_t),
514# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) || defined(RAW_ENABLE) 615 .bNumInterfaces = TOTAL_INTERFACES,
515 .bNumInterfaces = 2,
516# else
517 .bNumInterfaces = 1,
518# endif
519 .bConfigurationValue = 0x01, 616 .bConfigurationValue = 0x01,
520 .iConfiguration = 0x00, 617 .iConfiguration = 0x00,
521 .bmAttributes = (1 << 7) | USBATTR_REMOTEWAKE, 618 .bmAttributes = (1 << 7) | USBATTR_REMOTEWAKE,
@@ -530,7 +627,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
530 .bLength = sizeof(usbInterfaceDescriptor_t), 627 .bLength = sizeof(usbInterfaceDescriptor_t),
531 .bDescriptorType = USBDESCR_INTERFACE 628 .bDescriptorType = USBDESCR_INTERFACE
532 }, 629 },
533 .bInterfaceNumber = 0, 630 .bInterfaceNumber = KEYBOARD_INTERFACE,
534 .bAlternateSetting = 0x00, 631 .bAlternateSetting = 0x00,
535 .bNumEndpoints = 1, 632 .bNumEndpoints = 1,
536 .bInterfaceClass = 0x03, 633 .bInterfaceClass = 0x03,
@@ -569,7 +666,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
569 .bLength = sizeof(usbInterfaceDescriptor_t), 666 .bLength = sizeof(usbInterfaceDescriptor_t),
570 .bDescriptorType = USBDESCR_INTERFACE 667 .bDescriptorType = USBDESCR_INTERFACE
571 }, 668 },
572 .bInterfaceNumber = 1, 669 .bInterfaceNumber = MOUSE_EXTRA_INTERFACE,
573 .bAlternateSetting = 0x00, 670 .bAlternateSetting = 0x00,
574 .bNumEndpoints = 1, 671 .bNumEndpoints = 1,
575 .bInterfaceClass = 0x03, 672 .bInterfaceClass = 0x03,
@@ -597,14 +694,15 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
597 .bmAttributes = 0x03, 694 .bmAttributes = 0x03,
598 .wMaxPacketSize = 8, 695 .wMaxPacketSize = 8,
599 .bInterval = USB_POLLING_INTERVAL_MS 696 .bInterval = USB_POLLING_INTERVAL_MS
600 } 697 },
601# elif defined(RAW_ENABLE) 698# endif
699# if defined(RAW_ENABLE)
602 .rawInterface = { 700 .rawInterface = {
603 .header = { 701 .header = {
604 .bLength = sizeof(usbInterfaceDescriptor_t), 702 .bLength = sizeof(usbInterfaceDescriptor_t),
605 .bDescriptorType = USBDESCR_INTERFACE 703 .bDescriptorType = USBDESCR_INTERFACE
606 }, 704 },
607 .bInterfaceNumber = 1, 705 .bInterfaceNumber = RAW_INTERFACE,
608 .bAlternateSetting = 0x00, 706 .bAlternateSetting = 0x00,
609 .bNumEndpoints = 2, 707 .bNumEndpoints = 2,
610 .bInterfaceClass = 0x03, 708 .bInterfaceClass = 0x03,
@@ -642,7 +740,56 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
642 .bmAttributes = 0x03, 740 .bmAttributes = 0x03,
643 .wMaxPacketSize = RAW_EPSIZE, 741 .wMaxPacketSize = RAW_EPSIZE,
644 .bInterval = USB_POLLING_INTERVAL_MS 742 .bInterval = USB_POLLING_INTERVAL_MS
645 } 743 },
744# endif
745# if defined(CONSOLE_ENABLE)
746 /*
747 * Console
748 */
749 .consoleInterface = {
750 .header = {
751 .bLength = sizeof(usbInterfaceDescriptor_t),
752 .bDescriptorType = USBDESCR_INTERFACE
753 },
754 .bInterfaceNumber = CONSOLE_INTERFACE,
755 .bAlternateSetting = 0x00,
756 .bNumEndpoints = 2,
757 .bInterfaceClass = 0x03,
758 .bInterfaceSubClass = 0x00,
759 .bInterfaceProtocol = 0x00,
760 .iInterface = 0x00
761 },
762 .consoleHID = {
763 .header = {
764 .bLength = sizeof(usbHIDDescriptor_t),
765 .bDescriptorType = USBDESCR_HID
766 },
767 .bcdHID = 0x0111,
768 .bCountryCode = 0x00,
769 .bNumDescriptors = 1,
770 .bDescriptorType = USBDESCR_HID_REPORT,
771 .wDescriptorLength = sizeof(console_hid_report)
772 },
773 .consoleINEndpoint = {
774 .header = {
775 .bLength = sizeof(usbEndpointDescriptor_t),
776 .bDescriptorType = USBDESCR_ENDPOINT
777 },
778 .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
779 .bmAttributes = 0x03,
780 .wMaxPacketSize = CONSOLE_EPSIZE,
781 .bInterval = 0x01
782 },
783 .consoleOUTEndpoint = {
784 .header = {
785 .bLength = sizeof(usbEndpointDescriptor_t),
786 .bDescriptorType = USBDESCR_ENDPOINT
787 },
788 .bEndpointAddress = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP3_NUMBER),
789 .bmAttributes = 0x03,
790 .wMaxPacketSize = CONSOLE_EPSIZE,
791 .bInterval = 0x01
792 },
646# endif 793# endif
647}; 794};
648 795
@@ -690,41 +837,55 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
690 break; 837 break;
691 case USBDESCR_HID: 838 case USBDESCR_HID:
692 switch (rq->wValue.bytes[0]) { 839 switch (rq->wValue.bytes[0]) {
693 case 0: 840 case KEYBOARD_INTERFACE:
694 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.keyboardHID; 841 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.keyboardHID;
695 len = sizeof(usbHIDDescriptor_t); 842 len = sizeof(usbHIDDescriptor_t);
696 break; 843 break;
697#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) 844#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
698 case 1: 845 case MOUSE_EXTRA_INTERFACE:
699 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.mouseExtraHID; 846 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.mouseExtraHID;
700 len = sizeof(usbHIDDescriptor_t); 847 len = sizeof(usbHIDDescriptor_t);
701 break; 848 break;
702#elif defined(RAW_ENABLE) 849#endif
703 case 1: 850#if defined(RAW_ENABLE)
851 case RAW_INTERFACE:
704 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.rawHID; 852 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.rawHID;
705 len = sizeof(usbHIDDescriptor_t); 853 len = sizeof(usbHIDDescriptor_t);
706 break; 854 break;
707#endif 855#endif
856#if defined(CONSOLE_ENABLE)
857 case CONSOLE_INTERFACE:
858 usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.consoleHID;
859 len = sizeof(usbHIDDescriptor_t);
860 break;
861#endif
708 } 862 }
709 break; 863 break;
710 case USBDESCR_HID_REPORT: 864 case USBDESCR_HID_REPORT:
711 /* interface index */ 865 /* interface index */
712 switch (rq->wIndex.word) { 866 switch (rq->wIndex.word) {
713 case 0: 867 case KEYBOARD_INTERFACE:
714 usbMsgPtr = (unsigned char *)keyboard_hid_report; 868 usbMsgPtr = (unsigned char *)keyboard_hid_report;
715 len = sizeof(keyboard_hid_report); 869 len = sizeof(keyboard_hid_report);
716 break; 870 break;
717#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) 871#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
718 case 1: 872 case MOUSE_EXTRA_INTERFACE:
719 usbMsgPtr = (unsigned char *)mouse_extra_hid_report; 873 usbMsgPtr = (unsigned char *)mouse_extra_hid_report;
720 len = sizeof(mouse_extra_hid_report); 874 len = sizeof(mouse_extra_hid_report);
721 break; 875 break;
722#elif defined(RAW_ENABLE) 876#endif
723 case 1: 877#if defined(RAW_ENABLE)
878 case RAW_INTERFACE:
724 usbMsgPtr = (unsigned char *)raw_hid_report; 879 usbMsgPtr = (unsigned char *)raw_hid_report;
725 len = sizeof(raw_hid_report); 880 len = sizeof(raw_hid_report);
726 break; 881 break;
727#endif 882#endif
883#if defined(CONSOLE_ENABLE)
884 case CONSOLE_INTERFACE:
885 usbMsgPtr = (unsigned char *)console_hid_report;
886 len = sizeof(console_hid_report);
887 break;
888#endif
728 } 889 }
729 break; 890 break;
730 } 891 }