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.c144
1 files changed, 64 insertions, 80 deletions
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 5feff889a..77bbbd7bd 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -15,10 +15,12 @@ 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/wdt.h>
19#include <util/delay.h>
20#include <stdint.h> 18#include <stdint.h>
19
20#include <avr/wdt.h>
21
21#include <usbdrv/usbdrv.h> 22#include <usbdrv/usbdrv.h>
23
22#include "usbconfig.h" 24#include "usbconfig.h"
23#include "host.h" 25#include "host.h"
24#include "report.h" 26#include "report.h"
@@ -26,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
26#include "vusb.h" 28#include "vusb.h"
27#include "print.h" 29#include "print.h"
28#include "debug.h" 30#include "debug.h"
31#include "wait.h"
29#include "usb_descriptor_common.h" 32#include "usb_descriptor_common.h"
30 33
31#ifdef RAW_ENABLE 34#ifdef RAW_ENABLE
@@ -56,16 +59,20 @@ enum usb_interfaces {
56#ifdef CONSOLE_ENABLE 59#ifdef CONSOLE_ENABLE
57 CONSOLE_INTERFACE = NEXT_INTERFACE, 60 CONSOLE_INTERFACE = NEXT_INTERFACE,
58#endif 61#endif
59 TOTAL_INTERFACES = NEXT_INTERFACE, 62 TOTAL_INTERFACES = NEXT_INTERFACE
60}; 63};
61 64
62#define MAX_INTERFACES 2 65#define MAX_INTERFACES 3
63 66
64#if (NEXT_INTERFACE - 1) > MAX_INTERFACES 67#if (NEXT_INTERFACE - 1) > MAX_INTERFACES
65# 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 68# 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
66#endif 69#endif
67 70
68static uint8_t vusb_keyboard_leds = 0; 71#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && CONSOLE_ENABLE
72# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
73#endif
74
75static uint8_t keyboard_led_state = 0;
69static uint8_t vusb_idle_rate = 0; 76static uint8_t vusb_idle_rate = 0;
70 77
71/* Keyboard report send buffer */ 78/* Keyboard report send buffer */
@@ -74,13 +81,7 @@ static report_keyboard_t kbuf[KBUF_SIZE];
74static uint8_t kbuf_head = 0; 81static uint8_t kbuf_head = 0;
75static uint8_t kbuf_tail = 0; 82static uint8_t kbuf_tail = 0;
76 83
77typedef struct { 84static report_keyboard_t keyboard_report_sent;
78 uint8_t modifier;
79 uint8_t reserved;
80 uint8_t keycode[6];
81} keyboard_report_t;
82
83static keyboard_report_t keyboard_report; // sent to PC
84 85
85#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10 86#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10
86 87
@@ -92,19 +93,13 @@ void vusb_transfer_keyboard(void) {
92 usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); 93 usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
93 kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE; 94 kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
94 if (debug_keyboard) { 95 if (debug_keyboard) {
95 print("V-USB: kbuf["); 96 dprintf("V-USB: kbuf[%d->%d](%02X)\n", kbuf_tail, kbuf_head, (kbuf_head < kbuf_tail) ? (KBUF_SIZE - kbuf_tail + kbuf_head) : (kbuf_head - kbuf_tail));
96 pdec(kbuf_tail);
97 print("->");
98 pdec(kbuf_head);
99 print("](");
100 phex((kbuf_head < kbuf_tail) ? (KBUF_SIZE - kbuf_tail + kbuf_head) : (kbuf_head - kbuf_tail));
101 print(")\n");
102 } 97 }
103 } 98 }
104 break; 99 break;
105 } 100 }
106 usbPoll(); 101 usbPoll();
107 _delay_ms(1); 102 wait_ms(1);
108 } 103 }
109} 104}
110 105
@@ -125,16 +120,16 @@ void raw_hid_send(uint8_t *data, uint8_t length) {
125 120
126 uint8_t *temp = data; 121 uint8_t *temp = data;
127 for (uint8_t i = 0; i < 4; i++) { 122 for (uint8_t i = 0; i < 4; i++) {
128 while (!usbInterruptIsReady3()) { 123 while (!usbInterruptIsReady4()) {
129 usbPoll(); 124 usbPoll();
130 } 125 }
131 usbSetInterrupt3(temp, 8); 126 usbSetInterrupt4(temp, 8);
132 temp += 8; 127 temp += 8;
133 } 128 }
134 while (!usbInterruptIsReady3()) { 129 while (!usbInterruptIsReady4()) {
135 usbPoll(); 130 usbPoll();
136 } 131 }
137 usbSetInterrupt3(0, 0); 132 usbSetInterrupt4(0, 0);
138} 133}
139 134
140__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) { 135__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
@@ -218,7 +213,7 @@ static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_sy
218 213
219host_driver_t *vusb_driver(void) { return &driver; } 214host_driver_t *vusb_driver(void) { return &driver; }
220 215
221static uint8_t keyboard_leds(void) { return vusb_keyboard_leds; } 216static uint8_t keyboard_leds(void) { return keyboard_led_state; }
222 217
223static void send_keyboard(report_keyboard_t *report) { 218static void send_keyboard(report_keyboard_t *report) {
224 uint8_t next = (kbuf_head + 1) % KBUF_SIZE; 219 uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
@@ -226,12 +221,13 @@ static void send_keyboard(report_keyboard_t *report) {
226 kbuf[kbuf_head] = *report; 221 kbuf[kbuf_head] = *report;
227 kbuf_head = next; 222 kbuf_head = next;
228 } else { 223 } else {
229 debug("kbuf: full\n"); 224 dprint("kbuf: full\n");
230 } 225 }
231 226
232 // NOTE: send key strokes of Macro 227 // NOTE: send key strokes of Macro
233 usbPoll(); 228 usbPoll();
234 vusb_transfer_keyboard(); 229 vusb_transfer_keyboard();
230 keyboard_report_sent = *report;
235} 231}
236 232
237typedef struct { 233typedef struct {
@@ -288,36 +284,35 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
288 284
289 if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) { /* class request type */ 285 if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) { /* class request type */
290 if (rq->bRequest == USBRQ_HID_GET_REPORT) { 286 if (rq->bRequest == USBRQ_HID_GET_REPORT) {
291 debug("GET_REPORT:"); 287 dprint("GET_REPORT:");
292 /* we only have one report type, so don't look at wValue */ 288 if (rq->wIndex.word == KEYBOARD_INTERFACE) {
293 usbMsgPtr = (usbMsgPtr_t)&keyboard_report; 289 usbMsgPtr = (usbMsgPtr_t)&keyboard_report_sent;
294 return sizeof(keyboard_report); 290 return sizeof(keyboard_report_sent);
291 }
295 } else if (rq->bRequest == USBRQ_HID_GET_IDLE) { 292 } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
296 debug("GET_IDLE: "); 293 dprint("GET_IDLE:");
297 // debug_hex(vusb_idle_rate);
298 usbMsgPtr = (usbMsgPtr_t)&vusb_idle_rate; 294 usbMsgPtr = (usbMsgPtr_t)&vusb_idle_rate;
299 return 1; 295 return 1;
300 } else if (rq->bRequest == USBRQ_HID_SET_IDLE) { 296 } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
301 vusb_idle_rate = rq->wValue.bytes[1]; 297 vusb_idle_rate = rq->wValue.bytes[1];
302 debug("SET_IDLE: "); 298 dprintf("SET_IDLE: %02X", vusb_idle_rate);
303 debug_hex(vusb_idle_rate);
304 } else if (rq->bRequest == USBRQ_HID_SET_REPORT) { 299 } else if (rq->bRequest == USBRQ_HID_SET_REPORT) {
305 debug("SET_REPORT: "); 300 dprint("SET_REPORT:");
306 // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard) 301 // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard)
307 if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { 302 if (rq->wValue.word == 0x0200 && rq->wIndex.word == KEYBOARD_INTERFACE) {
308 debug("SET_LED: "); 303 dprint("SET_LED:");
309 last_req.kind = SET_LED; 304 last_req.kind = SET_LED;
310 last_req.len = rq->wLength.word; 305 last_req.len = rq->wLength.word;
311 } 306 }
312 return USB_NO_MSG; // to get data in usbFunctionWrite 307 return USB_NO_MSG; // to get data in usbFunctionWrite
313 } else { 308 } else {
314 debug("UNKNOWN:"); 309 dprint("UNKNOWN:");
315 } 310 }
316 } else { 311 } else {
317 debug("VENDOR:"); 312 dprint("VENDOR:");
318 /* no vendor specific requests implemented */ 313 /* no vendor specific requests implemented */
319 } 314 }
320 debug("\n"); 315 dprint("\n");
321 return 0; /* default for not implemented requests: return no data back to host */ 316 return 0; /* default for not implemented requests: return no data back to host */
322} 317}
323 318
@@ -327,10 +322,8 @@ uchar usbFunctionWrite(uchar *data, uchar len) {
327 } 322 }
328 switch (last_req.kind) { 323 switch (last_req.kind) {
329 case SET_LED: 324 case SET_LED:
330 debug("SET_LED: "); 325 dprintf("SET_LED: %02X\n", data[0]);
331 debug_hex(data[0]); 326 keyboard_led_state = data[0];
332 debug("\n");
333 vusb_keyboard_leds = data[0];
334 last_req.len = 0; 327 last_req.len = 0;
335 return 1; 328 return 1;
336 break; 329 break;
@@ -346,13 +339,13 @@ void usbFunctionWriteOut(uchar *data, uchar len) {
346#ifdef RAW_ENABLE 339#ifdef RAW_ENABLE
347 // Data from host must be divided every 8bytes 340 // Data from host must be divided every 8bytes
348 if (len != 8) { 341 if (len != 8) {
349 debug("RAW: invalid length"); 342 dprint("RAW: invalid length\n");
350 raw_output_received_bytes = 0; 343 raw_output_received_bytes = 0;
351 return; 344 return;
352 } 345 }
353 346
354 if (raw_output_received_bytes + len > RAW_BUFFER_SIZE) { 347 if (raw_output_received_bytes + len > RAW_BUFFER_SIZE) {
355 debug("RAW: buffer full"); 348 dprint("RAW: buffer full\n");
356 raw_output_received_bytes = 0; 349 raw_output_received_bytes = 0;
357 } else { 350 } else {
358 for (uint8_t i = 0; i < 8; i++) { 351 for (uint8_t i = 0; i < 8; i++) {
@@ -408,29 +401,6 @@ const PROGMEM uchar keyboard_hid_report[] = {
408 0xC0 // End Collection 401 0xC0 // End Collection
409}; 402};
410 403
411#ifdef RAW_ENABLE
412const PROGMEM uchar raw_hid_report[] = {
413 0x06, RAW_USAGE_PAGE_LO, RAW_USAGE_PAGE_HI, // Usage Page (Vendor Defined)
414 0x09, RAW_USAGE_ID, // Usage (Vendor Defined)
415 0xA1, 0x01, // Collection (Application)
416 // Data to host
417 0x09, 0x62, // Usage (Vendor Defined)
418 0x15, 0x00, // Logical Minimum (0)
419 0x26, 0xFF, 0x00, // Logical Maximum (255)
420 0x95, RAW_BUFFER_SIZE, // Report Count
421 0x75, 0x08, // Report Size (8)
422 0x81, 0x02, // Input (Data, Variable, Absolute)
423 // Data from host
424 0x09, 0x63, // Usage (Vendor Defined)
425 0x15, 0x00, // Logical Minimum (0)
426 0x26, 0xFF, 0x00, // Logical Maximum (255)
427 0x95, RAW_BUFFER_SIZE, // Report Count
428 0x75, 0x08, // Report Size (8)
429 0x91, 0x02, // Output (Data, Variable, Absolute)
430 0xC0 // End Collection
431};
432#endif
433
434#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) 404#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
435const PROGMEM uchar mouse_extra_hid_report[] = { 405const PROGMEM uchar mouse_extra_hid_report[] = {
436# ifdef MOUSE_ENABLE 406# ifdef MOUSE_ENABLE
@@ -515,6 +485,29 @@ const PROGMEM uchar mouse_extra_hid_report[] = {
515}; 485};
516#endif 486#endif
517 487
488#ifdef RAW_ENABLE
489const PROGMEM uchar raw_hid_report[] = {
490 0x06, RAW_USAGE_PAGE_LO, RAW_USAGE_PAGE_HI, // Usage Page (Vendor Defined)
491 0x09, RAW_USAGE_ID, // Usage (Vendor Defined)
492 0xA1, 0x01, // Collection (Application)
493 // Data to host
494 0x09, 0x62, // Usage (Vendor Defined)
495 0x15, 0x00, // Logical Minimum (0)
496 0x26, 0xFF, 0x00, // Logical Maximum (255)
497 0x95, RAW_BUFFER_SIZE, // Report Count
498 0x75, 0x08, // Report Size (8)
499 0x81, 0x02, // Input (Data, Variable, Absolute)
500 // Data from host
501 0x09, 0x63, // Usage (Vendor Defined)
502 0x15, 0x00, // Logical Minimum (0)
503 0x26, 0xFF, 0x00, // Logical Maximum (255)
504 0x95, RAW_BUFFER_SIZE, // Report Count
505 0x75, 0x08, // Report Size (8)
506 0x91, 0x02, // Output (Data, Variable, Absolute)
507 0xC0 // End Collection
508};
509#endif
510
518#if defined(CONSOLE_ENABLE) 511#if defined(CONSOLE_ENABLE)
519const PROGMEM uchar console_hid_report[] = { 512const PROGMEM uchar console_hid_report[] = {
520 0x06, 0x31, 0xFF, // Usage Page (Vendor Defined - PJRC Teensy compatible) 513 0x06, 0x31, 0xFF, // Usage Page (Vendor Defined - PJRC Teensy compatible)
@@ -694,7 +687,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
694 .bLength = sizeof(usbEndpointDescriptor_t), 687 .bLength = sizeof(usbEndpointDescriptor_t),
695 .bDescriptorType = USBDESCR_ENDPOINT 688 .bDescriptorType = USBDESCR_ENDPOINT
696 }, 689 },
697 .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER), 690 .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP4_NUMBER),
698 .bmAttributes = 0x03, 691 .bmAttributes = 0x03,
699 .wMaxPacketSize = RAW_EPSIZE, 692 .wMaxPacketSize = RAW_EPSIZE,
700 .bInterval = USB_POLLING_INTERVAL_MS 693 .bInterval = USB_POLLING_INTERVAL_MS
@@ -704,7 +697,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
704 .bLength = sizeof(usbEndpointDescriptor_t), 697 .bLength = sizeof(usbEndpointDescriptor_t),
705 .bDescriptorType = USBDESCR_ENDPOINT 698 .bDescriptorType = USBDESCR_ENDPOINT
706 }, 699 },
707 .bEndpointAddress = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP3_NUMBER), 700 .bEndpointAddress = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP4_NUMBER),
708 .bmAttributes = 0x03, 701 .bmAttributes = 0x03,
709 .wMaxPacketSize = RAW_EPSIZE, 702 .wMaxPacketSize = RAW_EPSIZE,
710 .bInterval = USB_POLLING_INTERVAL_MS 703 .bInterval = USB_POLLING_INTERVAL_MS
@@ -805,14 +798,6 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
805USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { 798USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
806 usbMsgLen_t len = 0; 799 usbMsgLen_t len = 0;
807 800
808 /*
809 debug("usbFunctionDescriptor: ");
810 debug_hex(rq->bmRequestType); debug(" ");
811 debug_hex(rq->bRequest); debug(" ");
812 debug_hex16(rq->wValue.word); debug(" ");
813 debug_hex16(rq->wIndex.word); debug(" ");
814 debug_hex16(rq->wLength.word); debug("\n");
815 */
816 switch (rq->wValue.bytes[1]) { 801 switch (rq->wValue.bytes[1]) {
817 case USBDESCR_DEVICE: 802 case USBDESCR_DEVICE:
818 usbMsgPtr = (usbMsgPtr_t)&usbDeviceDescriptor; 803 usbMsgPtr = (usbMsgPtr_t)&usbDeviceDescriptor;
@@ -896,6 +881,5 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
896 } 881 }
897 break; 882 break;
898 } 883 }
899 // debug("desc len: "); debug_hex(len); debug("\n");
900 return len; 884 return len;
901} 885}