diff options
Diffstat (limited to 'tmk_core/protocol/vusb/vusb.c')
| -rw-r--r-- | tmk_core/protocol/vusb/vusb.c | 213 |
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 | |||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | along 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 | */ | ||
| 44 | enum 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 | ||
| 39 | static uint8_t vusb_keyboard_leds = 0; | 64 | static 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 | |||
| 157 | int8_t sendchar(uint8_t c) { | ||
| 158 | rbuf_enqueue(c); | ||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | static 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 | |||
| 175 | void 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) | ||
| 515 | const 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 | } |
