aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/common.mk21
-rw-r--r--tmk_core/common/host.c22
-rw-r--r--tmk_core/common/report.c21
-rw-r--r--tmk_core/common/report.h46
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c5
-rw-r--r--tmk_core/protocol/chibios/usb_main.c176
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
-rw-r--r--tmk_core/protocol/lufa/lufa.c92
-rw-r--r--tmk_core/protocol/usb_descriptor.c213
-rw-r--r--tmk_core/protocol/usb_descriptor.h170
10 files changed, 397 insertions, 380 deletions
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 8eac1734f..063115acb 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -82,15 +82,31 @@ else
82 TMK_COMMON_SRC += $(COMMON_DIR)/magic.c 82 TMK_COMMON_SRC += $(COMMON_DIR)/magic.c
83endif 83endif
84 84
85SHARED_EP_ENABLE = no
86MOUSE_SHARED_EP ?= yes
87ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes)
88 TMK_COMMON_DEFS += -DKEYBOARD_SHARED_EP
89 SHARED_EP_ENABLE = yes
90 # With the current usb_descriptor.c code,
91 # you can't share kbd without sharing mouse;
92 # that would be a very unexpected use case anyway
93 MOUSE_SHARED_EP = yes
94endif
85 95
86ifeq ($(strip $(MOUSEKEY_ENABLE)), yes) 96ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
87 TMK_COMMON_SRC += $(COMMON_DIR)/mousekey.c 97 TMK_COMMON_SRC += $(COMMON_DIR)/mousekey.c
88 TMK_COMMON_DEFS += -DMOUSEKEY_ENABLE 98 TMK_COMMON_DEFS += -DMOUSEKEY_ENABLE
89 TMK_COMMON_DEFS += -DMOUSE_ENABLE 99 TMK_COMMON_DEFS += -DMOUSE_ENABLE
100
101 ifeq ($(strip $(MOUSE_SHARED_EP)), yes)
102 TMK_COMMON_DEFS += -DMOUSE_SHARED_EP
103 SHARED_EP_ENABLE = yes
104 endif
90endif 105endif
91 106
92ifeq ($(strip $(EXTRAKEY_ENABLE)), yes) 107ifeq ($(strip $(EXTRAKEY_ENABLE)), yes)
93 TMK_COMMON_DEFS += -DEXTRAKEY_ENABLE 108 TMK_COMMON_DEFS += -DEXTRAKEY_ENABLE
109 SHARED_EP_ENABLE = yes
94endif 110endif
95 111
96ifeq ($(strip $(RAW_ENABLE)), yes) 112ifeq ($(strip $(RAW_ENABLE)), yes)
@@ -111,6 +127,7 @@ endif
111 127
112ifeq ($(strip $(NKRO_ENABLE)), yes) 128ifeq ($(strip $(NKRO_ENABLE)), yes)
113 TMK_COMMON_DEFS += -DNKRO_ENABLE 129 TMK_COMMON_DEFS += -DNKRO_ENABLE
130 SHARED_EP_ENABLE = yes
114endif 131endif
115 132
116ifeq ($(strip $(USB_6KRO_ENABLE)), yes) 133ifeq ($(strip $(USB_6KRO_ENABLE)), yes)
@@ -182,6 +199,10 @@ ifeq ($(strip $(KEYMAP_SECTION_ENABLE)), yes)
182 endif 199 endif
183endif 200endif
184 201
202ifeq ($(strip $(SHARED_EP_ENABLE)), yes)
203 TMK_COMMON_DEFS += -DSHARED_EP_ENABLE
204endif
205
185# Bootloader address 206# Bootloader address
186ifdef STM32_BOOTLOADER_ADDRESS 207ifdef STM32_BOOTLOADER_ADDRESS
187 TMK_COMMON_DEFS += -DSTM32_BOOTLOADER_ADDRESS=$(STM32_BOOTLOADER_ADDRESS) 208 TMK_COMMON_DEFS += -DSTM32_BOOTLOADER_ADDRESS=$(STM32_BOOTLOADER_ADDRESS)
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
index e12b62216..f5d041699 100644
--- a/tmk_core/common/host.c
+++ b/tmk_core/common/host.c
@@ -22,6 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
22#include "util.h" 22#include "util.h"
23#include "debug.h" 23#include "debug.h"
24 24
25#ifdef NKRO_ENABLE
26 #include "keycode_config.h"
27 extern keymap_config_t keymap_config;
28#endif
29
25static host_driver_t *driver; 30static host_driver_t *driver;
26static uint16_t last_system_report = 0; 31static uint16_t last_system_report = 0;
27static uint16_t last_consumer_report = 0; 32static uint16_t last_consumer_report = 0;
@@ -46,6 +51,20 @@ uint8_t host_keyboard_leds(void)
46void host_keyboard_send(report_keyboard_t *report) 51void host_keyboard_send(report_keyboard_t *report)
47{ 52{
48 if (!driver) return; 53 if (!driver) return;
54#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
55 if (keyboard_protocol && keymap_config.nkro) {
56 /* The callers of this function assume that report->mods is where mods go in.
57 * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
58 */
59 report->nkro.mods = report->mods;
60 report->nkro.report_id = REPORT_ID_NKRO;
61 } else
62#endif
63 {
64#ifdef KEYBOARD_SHARED_EP
65 report->report_id = REPORT_ID_KEYBOARD;
66#endif
67 }
49 (*driver->send_keyboard)(report); 68 (*driver->send_keyboard)(report);
50 69
51 if (debug_keyboard) { 70 if (debug_keyboard) {
@@ -60,6 +79,9 @@ void host_keyboard_send(report_keyboard_t *report)
60void host_mouse_send(report_mouse_t *report) 79void host_mouse_send(report_mouse_t *report)
61{ 80{
62 if (!driver) return; 81 if (!driver) return;
82#ifdef MOUSE_SHARED_EP
83 report->report_id = REPORT_ID_MOUSE;
84#endif
63 (*driver->send_mouse)(report); 85 (*driver->send_mouse)(report);
64} 86}
65 87
diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c
index eb3b44312..6a06b70c6 100644
--- a/tmk_core/common/report.c
+++ b/tmk_core/common/report.c
@@ -19,6 +19,7 @@
19#include "keycode_config.h" 19#include "keycode_config.h"
20#include "debug.h" 20#include "debug.h"
21#include "util.h" 21#include "util.h"
22#include <string.h>
22 23
23/** \brief has_anykey 24/** \brief has_anykey
24 * 25 *
@@ -27,8 +28,16 @@
27uint8_t has_anykey(report_keyboard_t* keyboard_report) 28uint8_t has_anykey(report_keyboard_t* keyboard_report)
28{ 29{
29 uint8_t cnt = 0; 30 uint8_t cnt = 0;
30 for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) { 31 uint8_t *p = keyboard_report->keys;
31 if (keyboard_report->raw[i]) 32 uint8_t lp = sizeof(keyboard_report->keys);
33#ifdef NKRO_ENABLE
34 if (keyboard_protocol && keymap_config.nkro) {
35 p = keyboard_report->nkro.bits;
36 lp = sizeof(keyboard_report->nkro.bits);
37 }
38#endif
39 while (lp--) {
40 if (*p++)
32 cnt++; 41 cnt++;
33 } 42 }
34 return cnt; 43 return cnt;
@@ -237,7 +246,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
237void clear_keys_from_report(report_keyboard_t* keyboard_report) 246void clear_keys_from_report(report_keyboard_t* keyboard_report)
238{ 247{
239 // not clear mods 248 // not clear mods
240 for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) { 249#ifdef NKRO_ENABLE
241 keyboard_report->raw[i] = 0; 250 if (keyboard_protocol && keymap_config.nkro) {
251 memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
252 return;
242 } 253 }
254#endif
255 memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
243} 256}
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 167f38275..5a1a6b19c 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -23,9 +23,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23 23
24 24
25/* report id */ 25/* report id */
26#define REPORT_ID_MOUSE 1 26#define REPORT_ID_KEYBOARD 1
27#define REPORT_ID_SYSTEM 2 27#define REPORT_ID_MOUSE 2
28#define REPORT_ID_CONSUMER 3 28#define REPORT_ID_SYSTEM 3
29#define REPORT_ID_CONSUMER 4
30#define REPORT_ID_NKRO 5
29 31
30/* mouse buttons */ 32/* mouse buttons */
31#define MOUSE_BTN1 (1<<0) 33#define MOUSE_BTN1 (1<<0)
@@ -72,32 +74,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
72#define SYSTEM_WAKE_UP 0x0083 74#define SYSTEM_WAKE_UP 0x0083
73 75
74 76
77#define NKRO_SHARED_EP
75/* key report size(NKRO or boot mode) */ 78/* key report size(NKRO or boot mode) */
76#if defined(NKRO_ENABLE) 79#if defined(NKRO_ENABLE)
77 #if defined(PROTOCOL_PJRC) 80 #if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
78 #include "usb.h"
79 #define KEYBOARD_REPORT_SIZE KBD2_SIZE
80 #define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
81 #define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
82 #elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
83 #include "protocol/usb_descriptor.h" 81 #include "protocol/usb_descriptor.h"
84 #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE 82 #define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
85 #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
86 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
87 #elif defined(PROTOCOL_ARM_ATSAM) 83 #elif defined(PROTOCOL_ARM_ATSAM)
88 #include "protocol/arm_atsam/usb/udi_device_epsize.h" 84 #include "protocol/arm_atsam/usb/udi_device_epsize.h"
89 #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
90 #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
91 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) 85 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
86 #undef NKRO_SHARED_EP
87 #undef MOUSE_SHARED_EP
92 #else 88 #else
93 #error "NKRO not supported with this protocol" 89 #error "NKRO not supported with this protocol"
90 #endif
94#endif 91#endif
95 92
93#ifdef KEYBOARD_SHARED_EP
94# define KEYBOARD_REPORT_SIZE 9
96#else 95#else
97# define KEYBOARD_REPORT_SIZE 8 96# define KEYBOARD_REPORT_SIZE 8
98# define KEYBOARD_REPORT_KEYS 6
99#endif 97#endif
100 98
99#define KEYBOARD_REPORT_KEYS 6
100
101/* VUSB hardcodes keyboard and mouse+extrakey only */
102#if defined(PROTOCOL_VUSB)
103 #undef KEYBOARD_SHARED_EP
104 #undef MOUSE_SHARED_EP
105#endif
101 106
102#ifdef __cplusplus 107#ifdef __cplusplus
103extern "C" { 108extern "C" {
@@ -126,12 +131,18 @@ extern "C" {
126typedef union { 131typedef union {
127 uint8_t raw[KEYBOARD_REPORT_SIZE]; 132 uint8_t raw[KEYBOARD_REPORT_SIZE];
128 struct { 133 struct {
134#ifdef KEYBOARD_SHARED_EP
135 uint8_t report_id;
136#endif
129 uint8_t mods; 137 uint8_t mods;
130 uint8_t reserved; 138 uint8_t reserved;
131 uint8_t keys[KEYBOARD_REPORT_KEYS]; 139 uint8_t keys[KEYBOARD_REPORT_KEYS];
132 }; 140 };
133#ifdef NKRO_ENABLE 141#ifdef NKRO_ENABLE
134 struct { 142 struct nkro_report {
143#ifdef NKRO_SHARED_EP
144 uint8_t report_id;
145#endif
135 uint8_t mods; 146 uint8_t mods;
136 uint8_t bits[KEYBOARD_REPORT_BITS]; 147 uint8_t bits[KEYBOARD_REPORT_BITS];
137 } nkro; 148 } nkro;
@@ -139,6 +150,9 @@ typedef union {
139} __attribute__ ((packed)) report_keyboard_t; 150} __attribute__ ((packed)) report_keyboard_t;
140 151
141typedef struct { 152typedef struct {
153#ifdef MOUSE_SHARED_EP
154 uint8_t report_id;
155#endif
142 uint8_t buttons; 156 uint8_t buttons;
143 int8_t x; 157 int8_t x;
144 int8_t y; 158 int8_t y;
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
index 18f9784ae..c263ac4aa 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
@@ -54,6 +54,7 @@
54#include "udi_hid.h" 54#include "udi_hid.h"
55#include "udi_hid_kbd.h" 55#include "udi_hid_kbd.h"
56#include <string.h> 56#include <string.h>
57#include "report.h"
57 58
58//*************************************************************************** 59//***************************************************************************
59// KBD 60// KBD
@@ -430,7 +431,7 @@ UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {
430 0x05, 0x01, // Usage Page (Generic Desktop), 431 0x05, 0x01, // Usage Page (Generic Desktop),
431 0x09, 0x80, // Usage (System Control), 432 0x09, 0x80, // Usage (System Control),
432 0xA1, 0x01, // Collection (Application), 433 0xA1, 0x01, // Collection (Application),
433 0x85, 0x02, // Report ID (2) (System), 434 0x85, REPORT_ID_SYSTEM, // Report ID (2) (System),
434 0x16, 0x01, 0x00, // Logical Minimum (1), 435 0x16, 0x01, 0x00, // Logical Minimum (1),
435 0x26, 0x03, 0x00, // Logical Maximum (3), 436 0x26, 0x03, 0x00, // Logical Maximum (3),
436 0x1A, 0x81, 0x00, // Usage Minimum (81) (System Power Down), 437 0x1A, 0x81, 0x00, // Usage Minimum (81) (System Power Down),
@@ -445,7 +446,7 @@ UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {
445 0x05, 0x0C, // Usage Page (Consumer), 446 0x05, 0x0C, // Usage Page (Consumer),
446 0x09, 0x01, // Usage (Consumer Control), 447 0x09, 0x01, // Usage (Consumer Control),
447 0xA1, 0x01, // Collection (Application), 448 0xA1, 0x01, // Collection (Application),
448 0x85, 0x03, // Report ID (3) (Consumer), 449 0x85, REPORT_ID_CONSUMER, // Report ID (3) (Consumer),
449 0x16, 0x01, 0x00, // Logical Minimum (1), 450 0x16, 0x01, 0x00, // Logical Minimum (1),
450 0x26, 0x9C, 0x02, // Logical Maximum (668), 451 0x26, 0x9C, 0x02, // Logical Maximum (668),
451 0x1A, 0x01, 0x00, // Usage Minimum (1), 452 0x1A, 0x01, 0x00, // Usage Minimum (1),
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 71892c4f4..3028e7ea2 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -95,6 +95,7 @@ static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype
95 return &desc; 95 return &desc;
96} 96}
97 97
98#ifndef KEYBOARD_SHARED_EP
98/* keyboard endpoint state structure */ 99/* keyboard endpoint state structure */
99static USBInEndpointState kbd_ep_state; 100static USBInEndpointState kbd_ep_state;
100/* keyboard endpoint initialization structure (IN) */ 101/* keyboard endpoint initialization structure (IN) */
@@ -110,8 +111,9 @@ static const USBEndpointConfig kbd_ep_config = {
110 2, /* IN multiplier */ 111 2, /* IN multiplier */
111 NULL /* SETUP buffer (not a SETUP endpoint) */ 112 NULL /* SETUP buffer (not a SETUP endpoint) */
112}; 113};
114#endif
113 115
114#ifdef MOUSE_ENABLE 116#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
115/* mouse endpoint state structure */ 117/* mouse endpoint state structure */
116static USBInEndpointState mouse_ep_state; 118static USBInEndpointState mouse_ep_state;
117 119
@@ -128,45 +130,26 @@ static const USBEndpointConfig mouse_ep_config = {
128 2, /* IN multiplier */ 130 2, /* IN multiplier */
129 NULL /* SETUP buffer (not a SETUP endpoint) */ 131 NULL /* SETUP buffer (not a SETUP endpoint) */
130}; 132};
131#endif /* MOUSE_ENABLE */ 133#endif
132
133#ifdef EXTRAKEY_ENABLE
134/* extrakey endpoint state structure */
135static USBInEndpointState extra_ep_state;
136
137/* extrakey endpoint initialization structure (IN) */
138static const USBEndpointConfig extra_ep_config = {
139 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
140 NULL, /* SETUP packet notification callback */
141 extra_in_cb, /* IN notification callback */
142 NULL, /* OUT notification callback */
143 EXTRAKEY_EPSIZE, /* IN maximum packet size */
144 0, /* OUT maximum packet size */
145 &extra_ep_state, /* IN Endpoint state */
146 NULL, /* OUT endpoint state */
147 2, /* IN multiplier */
148 NULL /* SETUP buffer (not a SETUP endpoint) */
149};
150#endif /* EXTRAKEY_ENABLE */
151 134
152#ifdef NKRO_ENABLE 135#ifdef SHARED_EP_ENABLE
153/* nkro endpoint state structure */ 136/* shared endpoint state structure */
154static USBInEndpointState nkro_ep_state; 137static USBInEndpointState shared_ep_state;
155 138
156/* nkro endpoint initialization structure (IN) */ 139/* shared endpoint initialization structure (IN) */
157static const USBEndpointConfig nkro_ep_config = { 140static const USBEndpointConfig shared_ep_config = {
158 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ 141 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
159 NULL, /* SETUP packet notification callback */ 142 NULL, /* SETUP packet notification callback */
160 nkro_in_cb, /* IN notification callback */ 143 shared_in_cb, /* IN notification callback */
161 NULL, /* OUT notification callback */ 144 NULL, /* OUT notification callback */
162 NKRO_EPSIZE, /* IN maximum packet size */ 145 SHARED_EPSIZE, /* IN maximum packet size */
163 0, /* OUT maximum packet size */ 146 0, /* OUT maximum packet size */
164 &nkro_ep_state, /* IN Endpoint state */ 147 &shared_ep_state, /* IN Endpoint state */
165 NULL, /* OUT endpoint state */ 148 NULL, /* OUT endpoint state */
166 2, /* IN multiplier */ 149 2, /* IN multiplier */
167 NULL /* SETUP buffer (not a SETUP endpoint) */ 150 NULL /* SETUP buffer (not a SETUP endpoint) */
168}; 151};
169#endif /* NKRO_ENABLE */ 152#endif
170 153
171typedef struct { 154typedef struct {
172 size_t queue_capacity_in; 155 size_t queue_capacity_in;
@@ -309,16 +292,15 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
309 case USB_EVENT_CONFIGURED: 292 case USB_EVENT_CONFIGURED:
310 osalSysLockFromISR(); 293 osalSysLockFromISR();
311 /* Enable the endpoints specified into the configuration. */ 294 /* Enable the endpoints specified into the configuration. */
295#ifndef KEYBOARD_SHARED_EP
312 usbInitEndpointI(usbp, KEYBOARD_IN_EPNUM, &kbd_ep_config); 296 usbInitEndpointI(usbp, KEYBOARD_IN_EPNUM, &kbd_ep_config);
313#ifdef MOUSE_ENABLE 297#endif
298#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
314 usbInitEndpointI(usbp, MOUSE_IN_EPNUM, &mouse_ep_config); 299 usbInitEndpointI(usbp, MOUSE_IN_EPNUM, &mouse_ep_config);
315#endif /* MOUSE_ENABLE */ 300#endif
316#ifdef EXTRAKEY_ENABLE 301#ifdef SHARED_EP_ENABLE
317 usbInitEndpointI(usbp, EXTRAKEY_IN_EPNUM, &extra_ep_config); 302 usbInitEndpointI(usbp, SHARED_IN_EPNUM, &shared_ep_config);
318#endif /* EXTRAKEY_ENABLE */ 303#endif
319#ifdef NKRO_ENABLE
320 usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config);
321#endif /* NKRO_ENABLE */
322 for (int i=0;i<NUM_USB_DRIVERS;i++) { 304 for (int i=0;i<NUM_USB_DRIVERS;i++) {
323 usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config); 305 usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config);
324 usbInitEndpointI(usbp, drivers.array[i].config.bulk_out, &drivers.array[i].out_ep_config); 306 usbInitEndpointI(usbp, drivers.array[i].config.bulk_out, &drivers.array[i].out_ep_config);
@@ -389,9 +371,20 @@ static uint16_t get_hword(uint8_t *p) {
389 * Other Device Required Optional Optional Optional Optional Optional 371 * Other Device Required Optional Optional Optional Optional Optional
390 */ 372 */
391 373
374#ifdef SHARED_EP_ENABLE
375static uint8_t set_report_buf[2] __attribute__((aligned(2)));
376static void set_led_transfer_cb(USBDriver *usbp) {
377 if ((set_report_buf[0] == REPORT_ID_KEYBOARD) ||
378 (set_report_buf[0] == REPORT_ID_NKRO)) {
379 keyboard_led_stats = set_report_buf[1];
380 }
381}
382#endif
383
392/* Callback for SETUP request on the endpoint 0 (control) */ 384/* Callback for SETUP request on the endpoint 0 (control) */
393static bool usb_request_hook_cb(USBDriver *usbp) { 385static bool usb_request_hook_cb(USBDriver *usbp) {
394 const USBDescriptor *dp; 386 const USBDescriptor *dp;
387 int has_report_id;
395 388
396 /* usbp->setup fields: 389 /* usbp->setup fields:
397 * 0: bmRequestType (bitmask) 390 * 0: bmRequestType (bitmask)
@@ -409,42 +402,16 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
409 case HID_GET_REPORT: 402 case HID_GET_REPORT:
410 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */ 403 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */
411 case KEYBOARD_INTERFACE: 404 case KEYBOARD_INTERFACE:
412#ifdef NKRO_ENABLE
413 case NKRO_INTERFACE:
414#endif /* NKRO_ENABLE */
415 usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent), NULL); 405 usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent), NULL);
416 return TRUE; 406 return TRUE;
417 break; 407 break;
418 408
419#ifdef MOUSE_ENABLE 409#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
420 case MOUSE_INTERFACE: 410 case MOUSE_INTERFACE:
421 usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL); 411 usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL);
422 return TRUE; 412 return TRUE;
423 break; 413 break;
424#endif /* MOUSE_ENABLE */ 414#endif
425
426#ifdef EXTRAKEY_ENABLE
427 case EXTRAKEY_INTERFACE:
428 if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */
429 switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */
430 case REPORT_ID_SYSTEM:
431 extra_report_blank[0] = REPORT_ID_SYSTEM;
432 usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
433 return TRUE;
434 break;
435 case REPORT_ID_CONSUMER:
436 extra_report_blank[0] = REPORT_ID_CONSUMER;
437 usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
438 return TRUE;
439 break;
440 default:
441 return FALSE;
442 }
443 } else {
444 return FALSE;
445 }
446 break;
447#endif /* EXTRAKEY_ENABLE */
448 415
449 default: 416 default:
450 usbSetupTransfer(usbp, NULL, 0, NULL); 417 usbSetupTransfer(usbp, NULL, 0, NULL);
@@ -472,12 +439,25 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
472 case HID_SET_REPORT: 439 case HID_SET_REPORT:
473 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */ 440 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */
474 case KEYBOARD_INTERFACE: 441 case KEYBOARD_INTERFACE:
475#ifdef NKRO_ENABLE 442#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
476 case NKRO_INTERFACE: 443 case SHARED_INTERFACE:
477#endif /* NKRO_ENABLE */ 444#endif
478 /* keyboard_led_stats = <read byte from next OUT report> 445 /* keyboard_led_stats = <read byte from next OUT report>
479 * keyboard_led_stats needs be word (or dword), otherwise we get an exception on F0 */ 446 * keyboard_led_stats needs be word (or dword), otherwise we get an exception on F0 */
480 usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL); 447 has_report_id = 0;
448#if defined(SHARED_EP_ENABLE)
449 if (usbp->setup[4] == SHARED_INTERFACE) {
450 has_report_id = 1;
451 }
452#endif
453 if (usbp->setup[4] == KEYBOARD_INTERFACE && !keyboard_protocol) {
454 has_report_id = 0;
455 }
456 if (has_report_id) {
457 usbSetupTransfer(usbp, set_report_buf, sizeof(set_report_buf), set_led_transfer_cb);
458 } else {
459 usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL);
460 }
481 return TRUE; 461 return TRUE;
482 break; 462 break;
483 } 463 }
@@ -591,20 +571,13 @@ void init_usb_driver(USBDriver *usbp) {
591 * --------------------------------------------------------- 571 * ---------------------------------------------------------
592 */ 572 */
593/* keyboard IN callback hander (a kbd report has made it IN) */ 573/* keyboard IN callback hander (a kbd report has made it IN) */
574#ifndef KEYBOARD_SHARED_EP
594void kbd_in_cb(USBDriver *usbp, usbep_t ep) { 575void kbd_in_cb(USBDriver *usbp, usbep_t ep) {
595 /* STUB */ 576 /* STUB */
596 (void)usbp; 577 (void)usbp;
597 (void)ep; 578 (void)ep;
598} 579}
599 580#endif
600#ifdef NKRO_ENABLE
601/* nkro IN callback hander (a nkro report has made it IN) */
602void nkro_in_cb(USBDriver *usbp, usbep_t ep) {
603 /* STUB */
604 (void)usbp;
605 (void)ep;
606}
607#endif /* NKRO_ENABLE */
608 581
609/* start-of-frame handler 582/* start-of-frame handler
610 * TODO: i guess it would be better to re-implement using timers, 583 * TODO: i guess it would be better to re-implement using timers,
@@ -628,9 +601,9 @@ static void keyboard_idle_timer_cb(void *arg) {
628 } 601 }
629 602
630#ifdef NKRO_ENABLE 603#ifdef NKRO_ENABLE
631 if(!keymap_config.nkro && keyboard_idle) { 604 if(!keymap_config.nkro && keyboard_idle && keyboard_protocol) {
632#else /* NKRO_ENABLE */ 605#else /* NKRO_ENABLE */
633 if(keyboard_idle) { 606 if(keyboard_idle && keyboard_protocol) {
634#endif /* NKRO_ENABLE */ 607#endif /* NKRO_ENABLE */
635 /* TODO: are we sure we want the KBD_ENDPOINT? */ 608 /* TODO: are we sure we want the KBD_ENDPOINT? */
636 if(!usbGetTransmitStatusI(usbp, KEYBOARD_IN_EPNUM)) { 609 if(!usbGetTransmitStatusI(usbp, KEYBOARD_IN_EPNUM)) {
@@ -661,25 +634,25 @@ void send_keyboard(report_keyboard_t *report) {
661 osalSysUnlock(); 634 osalSysUnlock();
662 635
663#ifdef NKRO_ENABLE 636#ifdef NKRO_ENABLE
664 if(keymap_config.nkro) { /* NKRO protocol */ 637 if(keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */
665 /* need to wait until the previous packet has made it through */ 638 /* need to wait until the previous packet has made it through */
666 /* can rewrite this using the synchronous API, then would wait 639 /* can rewrite this using the synchronous API, then would wait
667 * until *after* the packet has been transmitted. I think 640 * until *after* the packet has been transmitted. I think
668 * this is more efficient */ 641 * this is more efficient */
669 /* busy wait, should be short and not very common */ 642 /* busy wait, should be short and not very common */
670 osalSysLock(); 643 osalSysLock();
671 if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_IN_EPNUM)) { 644 if(usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) {
672 /* Need to either suspend, or loop and call unlock/lock during 645 /* Need to either suspend, or loop and call unlock/lock during
673 * every iteration - otherwise the system will remain locked, 646 * every iteration - otherwise the system will remain locked,
674 * no interrupts served, so USB not going through as well. 647 * no interrupts served, so USB not going through as well.
675 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ 648 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
676 osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_IN_EPNUM]->in_state->thread); 649 osalThreadSuspendS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread);
677 } 650 }
678 usbStartTransmitI(&USB_DRIVER, NKRO_IN_EPNUM, (uint8_t *)report, sizeof(report_keyboard_t)); 651 usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(struct nkro_report));
679 osalSysUnlock(); 652 osalSysUnlock();
680 } else 653 } else
681#endif /* NKRO_ENABLE */ 654#endif /* NKRO_ENABLE */
682 { /* boot protocol */ 655 { /* regular protocol */
683 /* need to wait until the previous packet has made it through */ 656 /* need to wait until the previous packet has made it through */
684 /* busy wait, should be short and not very common */ 657 /* busy wait, should be short and not very common */
685 osalSysLock(); 658 osalSysLock();
@@ -690,7 +663,15 @@ void send_keyboard(report_keyboard_t *report) {
690 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ 663 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
691 osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread); 664 osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread);
692 } 665 }
693 usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, (uint8_t *)report, KEYBOARD_EPSIZE); 666 uint8_t *data, size;
667 if (keyboard_protocol) {
668 data = (uint8_t*)report;
669 size = KEYBOARD_REPORT_SIZE;
670 } else { /* boot protocol */
671 data = &report->mods;
672 size = 8;
673 }
674 usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size);
694 osalSysUnlock(); 675 osalSysUnlock();
695 } 676 }
696 keyboard_report_sent = *report; 677 keyboard_report_sent = *report;
@@ -703,11 +684,13 @@ void send_keyboard(report_keyboard_t *report) {
703 684
704#ifdef MOUSE_ENABLE 685#ifdef MOUSE_ENABLE
705 686
687#ifndef MOUSE_SHARED_EP
706/* mouse IN callback hander (a mouse report has made it IN) */ 688/* mouse IN callback hander (a mouse report has made it IN) */
707void mouse_in_cb(USBDriver *usbp, usbep_t ep) { 689void mouse_in_cb(USBDriver *usbp, usbep_t ep) {
708 (void)usbp; 690 (void)usbp;
709 (void)ep; 691 (void)ep;
710} 692}
693#endif
711 694
712void send_mouse(report_mouse_t *report) { 695void send_mouse(report_mouse_t *report) {
713 osalSysLock(); 696 osalSysLock();
@@ -737,19 +720,24 @@ void send_mouse(report_mouse_t *report) {
737#endif /* MOUSE_ENABLE */ 720#endif /* MOUSE_ENABLE */
738 721
739/* --------------------------------------------------------- 722/* ---------------------------------------------------------
740 * Extrakey functions 723 * Shared EP functions
741 * --------------------------------------------------------- 724 * ---------------------------------------------------------
742 */ 725 */
743 726#ifdef SHARED_EP_ENABLE
744#ifdef EXTRAKEY_ENABLE 727/* shared IN callback hander */
745 728void shared_in_cb(USBDriver *usbp, usbep_t ep) {
746/* extrakey IN callback hander */
747void extra_in_cb(USBDriver *usbp, usbep_t ep) {
748 /* STUB */ 729 /* STUB */
749 (void)usbp; 730 (void)usbp;
750 (void)ep; 731 (void)ep;
751} 732}
733#endif
734
735/* ---------------------------------------------------------
736 * Extrakey functions
737 * ---------------------------------------------------------
738 */
752 739
740#ifdef EXTRAKEY_ENABLE
753static void send_extra_report(uint8_t report_id, uint16_t data) { 741static void send_extra_report(uint8_t report_id, uint16_t data) {
754 osalSysLock(); 742 osalSysLock();
755 if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { 743 if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
@@ -762,7 +750,7 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
762 .usage = data 750 .usage = data
763 }; 751 };
764 752
765 usbStartTransmitI(&USB_DRIVER, EXTRAKEY_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t)); 753 usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
766 osalSysUnlock(); 754 osalSysUnlock();
767} 755}
768 756
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index 1f7eb12f8..55e8882cc 100644
--- a/tmk_core/protocol/chibios/usb_main.h
+++ b/tmk_core/protocol/chibios/usb_main.h
@@ -66,15 +66,20 @@ void mouse_in_cb(USBDriver *usbp, usbep_t ep);
66#endif /* MOUSE_ENABLE */ 66#endif /* MOUSE_ENABLE */
67 67
68/* --------------- 68/* ---------------
69 * Shared EP header
70 * ---------------
71 */
72
73/* shared IN request callback handler */
74void shared_in_cb(USBDriver *usbp, usbep_t ep);
75
76/* ---------------
69 * Extrakey header 77 * Extrakey header
70 * --------------- 78 * ---------------
71 */ 79 */
72 80
73#ifdef EXTRAKEY_ENABLE 81#ifdef EXTRAKEY_ENABLE
74 82
75/* extrakey IN request callback handler */
76void extra_in_cb(USBDriver *usbp, usbep_t ep);
77
78/* extra report structure */ 83/* extra report structure */
79typedef struct { 84typedef struct {
80 uint8_t report_id; 85 uint8_t report_id;
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 95e0b95b2..e88e6f34a 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -409,19 +409,21 @@ void EVENT_USB_Device_ConfigurationChanged(void)
409 bool ConfigSuccess = true; 409 bool ConfigSuccess = true;
410 410
411 /* Setup Keyboard HID Report Endpoints */ 411 /* Setup Keyboard HID Report Endpoints */
412#ifndef KEYBOARD_SHARED_EP
412 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, 413 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
413 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE); 414 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
415#endif
414 416
415#ifdef MOUSE_ENABLE 417#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
416 /* Setup Mouse HID Report Endpoint */ 418 /* Setup Mouse HID Report Endpoint */
417 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, 419 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
418 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE); 420 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
419#endif 421#endif
420 422
421#ifdef EXTRAKEY_ENABLE 423#ifdef SHARED_EP_ENABLE
422 /* Setup Extra HID Report Endpoint */ 424 /* Setup Shared HID Report Endpoint */
423 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, 425 ConfigSuccess &= ENDPOINT_CONFIG(SHARED_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
424 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE); 426 SHARED_EPSIZE, ENDPOINT_BANK_SINGLE);
425#endif 427#endif
426 428
427#ifdef RAW_ENABLE 429#ifdef RAW_ENABLE
@@ -442,12 +444,6 @@ void EVENT_USB_Device_ConfigurationChanged(void)
442#endif 444#endif
443#endif 445#endif
444 446
445#ifdef NKRO_ENABLE
446 /* Setup NKRO HID Report Endpoints */
447 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
448 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
449#endif
450
451#ifdef MIDI_ENABLE 447#ifdef MIDI_ENABLE
452 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE); 448 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
453 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE); 449 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
@@ -512,8 +508,8 @@ void EVENT_USB_Device_ControlRequest(void)
512 // Interface 508 // Interface
513 switch (USB_ControlRequest.wIndex) { 509 switch (USB_ControlRequest.wIndex) {
514 case KEYBOARD_INTERFACE: 510 case KEYBOARD_INTERFACE:
515#ifdef NKRO_ENABLE 511#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
516 case NKRO_INTERFACE: 512 case SHARED_INTERFACE:
517#endif 513#endif
518 Endpoint_ClearSETUP(); 514 Endpoint_ClearSETUP();
519 515
@@ -521,7 +517,17 @@ void EVENT_USB_Device_ControlRequest(void)
521 if (USB_DeviceState == DEVICE_STATE_Unattached) 517 if (USB_DeviceState == DEVICE_STATE_Unattached)
522 return; 518 return;
523 } 519 }
520#if defined(SHARED_EP_ENABLE)
521 uint8_t report_id = REPORT_ID_KEYBOARD;
522 if (keyboard_protocol) {
523 report_id = Endpoint_Read_8();
524 }
525 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
526 keyboard_led_stats = Endpoint_Read_8();
527 }
528#else
524 keyboard_led_stats = Endpoint_Read_8(); 529 keyboard_led_stats = Endpoint_Read_8();
530#endif
525 531
526 Endpoint_ClearOUT(); 532 Endpoint_ClearOUT();
527 Endpoint_ClearStatusStage(); 533 Endpoint_ClearStatusStage();
@@ -612,16 +618,20 @@ static void send_keyboard(report_keyboard_t *report)
612 #ifdef MODULE_ADAFRUIT_BLE 618 #ifdef MODULE_ADAFRUIT_BLE
613 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys)); 619 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
614 #elif MODULE_RN42 620 #elif MODULE_RN42
615 bluefruit_serial_send(0xFD); 621 bluefruit_serial_send(0xFD);
616 bluefruit_serial_send(0x09); 622 bluefruit_serial_send(0x09);
617 bluefruit_serial_send(0x01); 623 bluefruit_serial_send(0x01);
618 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) { 624 bluefruit_serial_send(report->mods);
619 bluefruit_serial_send(report->raw[i]); 625 bluefruit_serial_send(report->reserved);
620 } 626 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
627 bluefruit_serial_send(report->keys[i]);
628 }
621 #else 629 #else
622 bluefruit_serial_send(0xFD); 630 bluefruit_serial_send(0xFD);
623 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) { 631 bluefruit_serial_send(report->mods);
624 bluefruit_serial_send(report->raw[i]); 632 bluefruit_serial_send(report->reserved);
633 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
634 bluefruit_serial_send(report->keys[i]);
625 } 635 }
626 #endif 636 #endif
627 } 637 }
@@ -632,30 +642,24 @@ static void send_keyboard(report_keyboard_t *report)
632 } 642 }
633 643
634 /* Select the Keyboard Report Endpoint */ 644 /* Select the Keyboard Report Endpoint */
645 uint8_t ep = KEYBOARD_IN_EPNUM;
646 uint8_t size = KEYBOARD_REPORT_SIZE;
635#ifdef NKRO_ENABLE 647#ifdef NKRO_ENABLE
636 if (keyboard_protocol && keymap_config.nkro) { 648 if (keyboard_protocol && keymap_config.nkro) {
637 /* Report protocol - NKRO */ 649 ep = SHARED_IN_EPNUM;
638 Endpoint_SelectEndpoint(NKRO_IN_EPNUM); 650 size = sizeof(struct nkro_report);
639
640 /* Check if write ready for a polling interval around 1ms */
641 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
642 if (!Endpoint_IsReadWriteAllowed()) return;
643
644 /* Write Keyboard Report Data */
645 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
646 } 651 }
647 else
648#endif 652#endif
649 { 653 Endpoint_SelectEndpoint(ep);
650 /* Boot protocol */ 654 /* Check if write ready for a polling interval around 10ms */
651 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); 655 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
652 656 if (!Endpoint_IsReadWriteAllowed()) return;
653 /* Check if write ready for a polling interval around 10ms */
654 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
655 if (!Endpoint_IsReadWriteAllowed()) return;
656 657
657 /* Write Keyboard Report Data */ 658 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
658 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL); 659 if (!keyboard_protocol) {
660 Endpoint_Write_Stream_LE(&report->mods, 8, NULL);
661 } else {
662 Endpoint_Write_Stream_LE(report, size, NULL);
659 } 663 }
660 664
661 /* Finalize the stream transfer to send the last packet */ 665 /* Finalize the stream transfer to send the last packet */
@@ -718,6 +722,7 @@ static void send_mouse(report_mouse_t *report)
718 */ 722 */
719static void send_system(uint16_t data) 723static void send_system(uint16_t data)
720{ 724{
725#ifdef EXTRAKEY_ENABLE
721 uint8_t timeout = 255; 726 uint8_t timeout = 255;
722 727
723 if (USB_DeviceState != DEVICE_STATE_Configured) 728 if (USB_DeviceState != DEVICE_STATE_Configured)
@@ -727,7 +732,7 @@ static void send_system(uint16_t data)
727 .report_id = REPORT_ID_SYSTEM, 732 .report_id = REPORT_ID_SYSTEM,
728 .usage = data - SYSTEM_POWER_DOWN + 1 733 .usage = data - SYSTEM_POWER_DOWN + 1
729 }; 734 };
730 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); 735 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
731 736
732 /* Check if write ready for a polling interval around 10ms */ 737 /* Check if write ready for a polling interval around 10ms */
733 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); 738 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@@ -735,6 +740,7 @@ static void send_system(uint16_t data)
735 740
736 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); 741 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
737 Endpoint_ClearIN(); 742 Endpoint_ClearIN();
743#endif
738} 744}
739 745
740/** \brief Send Consumer 746/** \brief Send Consumer
@@ -743,6 +749,7 @@ static void send_system(uint16_t data)
743 */ 749 */
744static void send_consumer(uint16_t data) 750static void send_consumer(uint16_t data)
745{ 751{
752#ifdef EXTRAKEY_ENABLE
746 uint8_t timeout = 255; 753 uint8_t timeout = 255;
747 uint8_t where = where_to_send(); 754 uint8_t where = where_to_send();
748 755
@@ -786,7 +793,7 @@ static void send_consumer(uint16_t data)
786 .report_id = REPORT_ID_CONSUMER, 793 .report_id = REPORT_ID_CONSUMER,
787 .usage = data 794 .usage = data
788 }; 795 };
789 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); 796 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
790 797
791 /* Check if write ready for a polling interval around 10ms */ 798 /* Check if write ready for a polling interval around 10ms */
792 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); 799 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@@ -794,6 +801,7 @@ static void send_consumer(uint16_t data)
794 801
795 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); 802 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
796 Endpoint_ClearIN(); 803 Endpoint_ClearIN();
804#endif
797} 805}
798 806
799 807
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index cab344675..589ad23cd 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -47,11 +47,18 @@
47/******************************************************************************* 47/*******************************************************************************
48 * HID Report Descriptors 48 * HID Report Descriptors
49 ******************************************************************************/ 49 ******************************************************************************/
50const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = 50#ifdef KEYBOARD_SHARED_EP
51{ 51const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
52#define SHARED_REPORT_STARTED
53#else
54const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
55#endif
52 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ 56 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
53 HID_RI_USAGE(8, 0x06), /* Keyboard */ 57 HID_RI_USAGE(8, 0x06), /* Keyboard */
54 HID_RI_COLLECTION(8, 0x01), /* Application */ 58 HID_RI_COLLECTION(8, 0x01), /* Application */
59# ifdef KEYBOARD_SHARED_EP
60 HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
61# endif
55 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ 62 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
56 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ 63 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
57 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ 64 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
@@ -84,14 +91,25 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
84 HID_RI_REPORT_SIZE(8, 0x08), 91 HID_RI_REPORT_SIZE(8, 0x08),
85 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), 92 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
86 HID_RI_END_COLLECTION(0), 93 HID_RI_END_COLLECTION(0),
94
95#ifndef KEYBOARD_SHARED_EP
87}; 96};
97#endif
88 98
89#ifdef MOUSE_ENABLE 99#if defined(MOUSE_ENABLE)
90const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = 100
91{ 101# if !defined(MOUSE_SHARED_EP)
102const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
103# elif !defined(SHARED_REPORT_STARTED)
104const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
105#define SHARED_REPORT_STARTED
106# endif
92 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ 107 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
93 HID_RI_USAGE(8, 0x02), /* Mouse */ 108 HID_RI_USAGE(8, 0x02), /* Mouse */
94 HID_RI_COLLECTION(8, 0x01), /* Application */ 109 HID_RI_COLLECTION(8, 0x01), /* Application */
110# ifdef MOUSE_SHARED_EP
111 HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
112# endif
95 HID_RI_USAGE(8, 0x01), /* Pointer */ 113 HID_RI_USAGE(8, 0x01), /* Pointer */
96 HID_RI_COLLECTION(8, 0x00), /* Physical */ 114 HID_RI_COLLECTION(8, 0x00), /* Physical */
97 115
@@ -133,12 +151,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
133 151
134 HID_RI_END_COLLECTION(0), 152 HID_RI_END_COLLECTION(0),
135 HID_RI_END_COLLECTION(0), 153 HID_RI_END_COLLECTION(0),
154# ifndef MOUSE_SHARED_EP
136}; 155};
156# endif
137#endif 157#endif
138 158
139#ifdef EXTRAKEY_ENABLE 159#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
140const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] = 160const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
141{ 161#endif
162# ifdef EXTRAKEY_ENABLE
142 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ 163 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
143 HID_RI_USAGE(8, 0x80), /* System Control */ 164 HID_RI_USAGE(8, 0x80), /* System Control */
144 HID_RI_COLLECTION(8, 0x01), /* Application */ 165 HID_RI_COLLECTION(8, 0x01), /* Application */
@@ -164,6 +185,43 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
164 HID_RI_REPORT_COUNT(8, 1), 185 HID_RI_REPORT_COUNT(8, 1),
165 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), 186 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
166 HID_RI_END_COLLECTION(0), 187 HID_RI_END_COLLECTION(0),
188# endif
189
190# ifdef NKRO_ENABLE
191 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
192 HID_RI_USAGE(8, 0x06), /* Keyboard */
193 HID_RI_COLLECTION(8, 0x01), /* Application */
194 HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
195 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
196 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
197 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
198 HID_RI_LOGICAL_MINIMUM(8, 0x00),
199 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
200 HID_RI_REPORT_COUNT(8, 0x08),
201 HID_RI_REPORT_SIZE(8, 0x01),
202 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
203
204 HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
205 HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
206 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
207 HID_RI_REPORT_COUNT(8, 0x05),
208 HID_RI_REPORT_SIZE(8, 0x01),
209 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
210 HID_RI_REPORT_COUNT(8, 0x01),
211 HID_RI_REPORT_SIZE(8, 0x03),
212 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
213
214 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
215 HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
216 HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS*8-1),
217 HID_RI_LOGICAL_MINIMUM(8, 0x00),
218 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
219 HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS*8),
220 HID_RI_REPORT_SIZE(8, 0x01),
221 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
222 HID_RI_END_COLLECTION(0),
223# endif
224#ifdef SHARED_EP_ENABLE
167}; 225};
168#endif 226#endif
169 227
@@ -211,42 +269,6 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
211}; 269};
212#endif 270#endif
213 271
214#ifdef NKRO_ENABLE
215const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
216{
217 HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
218 HID_RI_USAGE(8, 0x06), /* Keyboard */
219 HID_RI_COLLECTION(8, 0x01), /* Application */
220 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
221 HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
222 HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
223 HID_RI_LOGICAL_MINIMUM(8, 0x00),
224 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
225 HID_RI_REPORT_COUNT(8, 0x08),
226 HID_RI_REPORT_SIZE(8, 0x01),
227 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
228
229 HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
230 HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
231 HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
232 HID_RI_REPORT_COUNT(8, 0x05),
233 HID_RI_REPORT_SIZE(8, 0x01),
234 HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
235 HID_RI_REPORT_COUNT(8, 0x01),
236 HID_RI_REPORT_SIZE(8, 0x03),
237 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
238
239 HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
240 HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
241 HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
242 HID_RI_LOGICAL_MINIMUM(8, 0x00),
243 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
244 HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
245 HID_RI_REPORT_SIZE(8, 0x01),
246 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
247 HID_RI_END_COLLECTION(0),
248};
249#endif
250 272
251/******************************************************************************* 273/*******************************************************************************
252 * Device Descriptors 274 * Device Descriptors
@@ -303,6 +325,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
303 /* 325 /*
304 * Keyboard 326 * Keyboard
305 */ 327 */
328#ifndef KEYBOARD_SHARED_EP
306 .Keyboard_Interface = 329 .Keyboard_Interface =
307 { 330 {
308 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, 331 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -339,11 +362,12 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
339 .EndpointSize = KEYBOARD_EPSIZE, 362 .EndpointSize = KEYBOARD_EPSIZE,
340 .PollingIntervalMS = 0x0A 363 .PollingIntervalMS = 0x0A
341 }, 364 },
365#endif
342 366
343 /* 367 /*
344 * Mouse 368 * Mouse
345 */ 369 */
346#ifdef MOUSE_ENABLE 370#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
347 .Mouse_Interface = 371 .Mouse_Interface =
348 { 372 {
349 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, 373 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -383,26 +407,31 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
383#endif 407#endif
384 408
385 /* 409 /*
386 * Extra 410 * Shared
387 */ 411 */
388#ifdef EXTRAKEY_ENABLE 412#ifdef SHARED_EP_ENABLE
389 .Extrakey_Interface = 413 .Shared_Interface =
390 { 414 {
391 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, 415 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
392 416
393 .InterfaceNumber = EXTRAKEY_INTERFACE, 417 .InterfaceNumber = SHARED_INTERFACE,
394 .AlternateSetting = 0x00, 418 .AlternateSetting = 0x00,
395 419
396 .TotalEndpoints = 1, 420 .TotalEndpoints = 1,
397 421
398 .Class = HID_CSCP_HIDClass, 422 .Class = HID_CSCP_HIDClass,
423# ifdef KEYBOARD_SHARED_EP
424 .SubClass = HID_CSCP_BootSubclass,
425 .Protocol = HID_CSCP_KeyboardBootProtocol,
426# else
399 .SubClass = HID_CSCP_NonBootSubclass, 427 .SubClass = HID_CSCP_NonBootSubclass,
400 .Protocol = HID_CSCP_NonBootProtocol, 428 .Protocol = HID_CSCP_NonBootProtocol,
429#endif
401 430
402 .InterfaceStrIndex = NO_DESCRIPTOR 431 .InterfaceStrIndex = NO_DESCRIPTOR
403 }, 432 },
404 433
405 .Extrakey_HID = 434 .Shared_HID =
406 { 435 {
407 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, 436 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
408 437
@@ -410,16 +439,16 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
410 .CountryCode = 0x00, 439 .CountryCode = 0x00,
411 .TotalReportDescriptors = 1, 440 .TotalReportDescriptors = 1,
412 .HIDReportType = HID_DTYPE_Report, 441 .HIDReportType = HID_DTYPE_Report,
413 .HIDReportLength = sizeof(ExtrakeyReport) 442 .HIDReportLength = sizeof(SharedReport)
414 }, 443 },
415 444
416 .Extrakey_INEndpoint = 445 .Shared_INEndpoint =
417 { 446 {
418 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, 447 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
419 448
420 .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM), 449 .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
421 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), 450 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
422 .EndpointSize = EXTRAKEY_EPSIZE, 451 .EndpointSize = SHARED_EPSIZE,
423 .PollingIntervalMS = 0x0A 452 .PollingIntervalMS = 0x0A
424 }, 453 },
425#endif 454#endif
@@ -528,48 +557,6 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
528 }, 557 },
529#endif 558#endif
530 559
531 /*
532 * NKRO
533 */
534#ifdef NKRO_ENABLE
535 .NKRO_Interface =
536 {
537 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
538
539 .InterfaceNumber = NKRO_INTERFACE,
540 .AlternateSetting = 0x00,
541
542 .TotalEndpoints = 1,
543
544 .Class = HID_CSCP_HIDClass,
545 .SubClass = HID_CSCP_NonBootSubclass,
546 .Protocol = HID_CSCP_NonBootProtocol,
547
548 .InterfaceStrIndex = NO_DESCRIPTOR
549 },
550
551 .NKRO_HID =
552 {
553 .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
554
555 .HIDSpec = VERSION_BCD(1,1,1),
556 .CountryCode = 0x00,
557 .TotalReportDescriptors = 1,
558 .HIDReportType = HID_DTYPE_Report,
559 .HIDReportLength = sizeof(NKROReport)
560 },
561
562 .NKRO_INEndpoint =
563 {
564 .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
565
566 .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
567 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
568 .EndpointSize = NKRO_EPSIZE,
569 .PollingIntervalMS = 0x01
570 },
571#endif
572
573#ifdef MIDI_ENABLE 560#ifdef MIDI_ENABLE
574 .Audio_Interface_Association = 561 .Audio_Interface_Association =
575 { 562 {
@@ -936,19 +923,21 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
936 break; 923 break;
937 case HID_DTYPE_HID: 924 case HID_DTYPE_HID:
938 switch (wIndex) { 925 switch (wIndex) {
926#ifndef KEYBOARD_SHARED_EP
939 case KEYBOARD_INTERFACE: 927 case KEYBOARD_INTERFACE:
940 Address = &ConfigurationDescriptor.Keyboard_HID; 928 Address = &ConfigurationDescriptor.Keyboard_HID;
941 Size = sizeof(USB_HID_Descriptor_HID_t); 929 Size = sizeof(USB_HID_Descriptor_HID_t);
942 break; 930 break;
943#ifdef MOUSE_ENABLE 931#endif
932#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
944 case MOUSE_INTERFACE: 933 case MOUSE_INTERFACE:
945 Address = &ConfigurationDescriptor.Mouse_HID; 934 Address = &ConfigurationDescriptor.Mouse_HID;
946 Size = sizeof(USB_HID_Descriptor_HID_t); 935 Size = sizeof(USB_HID_Descriptor_HID_t);
947 break; 936 break;
948#endif 937#endif
949#ifdef EXTRAKEY_ENABLE 938#ifdef SHARED_EP_ENABLE
950 case EXTRAKEY_INTERFACE: 939 case SHARED_INTERFACE:
951 Address = &ConfigurationDescriptor.Extrakey_HID; 940 Address = &ConfigurationDescriptor.Shared_HID;
952 Size = sizeof(USB_HID_Descriptor_HID_t); 941 Size = sizeof(USB_HID_Descriptor_HID_t);
953 break; 942 break;
954#endif 943#endif
@@ -964,30 +953,26 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
964 Size = sizeof(USB_HID_Descriptor_HID_t); 953 Size = sizeof(USB_HID_Descriptor_HID_t);
965 break; 954 break;
966#endif 955#endif
967#ifdef NKRO_ENABLE
968 case NKRO_INTERFACE:
969 Address = &ConfigurationDescriptor.NKRO_HID;
970 Size = sizeof(USB_HID_Descriptor_HID_t);
971 break;
972#endif
973 } 956 }
974 break; 957 break;
975 case HID_DTYPE_Report: 958 case HID_DTYPE_Report:
976 switch (wIndex) { 959 switch (wIndex) {
960#ifndef KEYBOARD_SHARED_EP
977 case KEYBOARD_INTERFACE: 961 case KEYBOARD_INTERFACE:
978 Address = &KeyboardReport; 962 Address = &KeyboardReport;
979 Size = sizeof(KeyboardReport); 963 Size = sizeof(KeyboardReport);
980 break; 964 break;
981#ifdef MOUSE_ENABLE 965#endif
966#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
982 case MOUSE_INTERFACE: 967 case MOUSE_INTERFACE:
983 Address = &MouseReport; 968 Address = &MouseReport;
984 Size = sizeof(MouseReport); 969 Size = sizeof(MouseReport);
985 break; 970 break;
986#endif 971#endif
987#ifdef EXTRAKEY_ENABLE 972#ifdef SHARED_EP_ENABLE
988 case EXTRAKEY_INTERFACE: 973 case SHARED_INTERFACE:
989 Address = &ExtrakeyReport; 974 Address = &SharedReport;
990 Size = sizeof(ExtrakeyReport); 975 Size = sizeof(SharedReport);
991 break; 976 break;
992#endif 977#endif
993#ifdef RAW_ENABLE 978#ifdef RAW_ENABLE
@@ -1002,12 +987,6 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
1002 Size = sizeof(ConsoleReport); 987 Size = sizeof(ConsoleReport);
1003 break; 988 break;
1004#endif 989#endif
1005#ifdef NKRO_ENABLE
1006 case NKRO_INTERFACE:
1007 Address = &NKROReport;
1008 Size = sizeof(NKROReport);
1009 break;
1010#endif
1011 } 990 }
1012 break; 991 break;
1013 } 992 }
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
index 586d07df6..3ca0c00b3 100644
--- a/tmk_core/protocol/usb_descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -53,26 +53,27 @@ typedef struct
53{ 53{
54 USB_Descriptor_Configuration_Header_t Config; 54 USB_Descriptor_Configuration_Header_t Config;
55 55
56#ifndef KEYBOARD_SHARED_EP
56 // Keyboard HID Interface 57 // Keyboard HID Interface
57 USB_Descriptor_Interface_t Keyboard_Interface; 58 USB_Descriptor_Interface_t Keyboard_Interface;
58 USB_HID_Descriptor_HID_t Keyboard_HID; 59 USB_HID_Descriptor_HID_t Keyboard_HID;
59 USB_Descriptor_Endpoint_t Keyboard_INEndpoint; 60 USB_Descriptor_Endpoint_t Keyboard_INEndpoint;
61#endif
60 62
61#ifdef MOUSE_ENABLE 63#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
62 // Mouse HID Interface 64 // Mouse HID Interface
63 USB_Descriptor_Interface_t Mouse_Interface; 65 USB_Descriptor_Interface_t Mouse_Interface;
64 USB_HID_Descriptor_HID_t Mouse_HID; 66 USB_HID_Descriptor_HID_t Mouse_HID;
65 USB_Descriptor_Endpoint_t Mouse_INEndpoint; 67 USB_Descriptor_Endpoint_t Mouse_INEndpoint;
66#endif 68#endif
67 69
68#ifdef EXTRAKEY_ENABLE 70#if defined(SHARED_EP_ENABLE)
69 // Extrakey HID Interface 71 USB_Descriptor_Interface_t Shared_Interface;
70 USB_Descriptor_Interface_t Extrakey_Interface; 72 USB_HID_Descriptor_HID_t Shared_HID;
71 USB_HID_Descriptor_HID_t Extrakey_HID; 73 USB_Descriptor_Endpoint_t Shared_INEndpoint;
72 USB_Descriptor_Endpoint_t Extrakey_INEndpoint;
73#endif 74#endif
74 75
75#ifdef RAW_ENABLE 76#if defined(RAW_ENABLE)
76 // Raw HID Interface 77 // Raw HID Interface
77 USB_Descriptor_Interface_t Raw_Interface; 78 USB_Descriptor_Interface_t Raw_Interface;
78 USB_HID_Descriptor_HID_t Raw_HID; 79 USB_HID_Descriptor_HID_t Raw_HID;
@@ -88,13 +89,6 @@ typedef struct
88 USB_Descriptor_Endpoint_t Console_OUTEndpoint; 89 USB_Descriptor_Endpoint_t Console_OUTEndpoint;
89#endif 90#endif
90 91
91#ifdef NKRO_ENABLE
92 // NKRO HID Interface
93 USB_Descriptor_Interface_t NKRO_Interface;
94 USB_HID_Descriptor_HID_t NKRO_HID;
95 USB_Descriptor_Endpoint_t NKRO_INEndpoint;
96#endif
97
98#ifdef MIDI_ENABLE 92#ifdef MIDI_ENABLE
99 USB_Descriptor_Interface_Association_t Audio_Interface_Association; 93 USB_Descriptor_Interface_Association_t Audio_Interface_Association;
100 // MIDI Audio Control Interface 94 // MIDI Audio Control Interface
@@ -133,133 +127,105 @@ typedef struct
133 127
134 128
135/* index of interface */ 129/* index of interface */
136#define KEYBOARD_INTERFACE 0 130enum usb_interfaces {
137 131#if !defined(KEYBOARD_SHARED_EP)
132 KEYBOARD_INTERFACE,
133#else
134# define KEYBOARD_INTERFACE SHARED_INTERFACE
135#endif
138// It is important that the Raw HID interface is at a constant 136// It is important that the Raw HID interface is at a constant
139// interface number, to support Linux/OSX platforms and chrome.hid 137// interface number, to support Linux/OSX platforms and chrome.hid
140// If Raw HID is enabled, let it be always 1. 138// If Raw HID is enabled, let it be always 1.
141#ifdef RAW_ENABLE 139#if defined(RAW_ENABLE)
142# define RAW_INTERFACE (KEYBOARD_INTERFACE + 1) 140 RAW_INTERFACE,
143#else
144# define RAW_INTERFACE KEYBOARD_INTERFACE
145#endif 141#endif
146 142#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
147#ifdef MOUSE_ENABLE 143 MOUSE_INTERFACE,
148# define MOUSE_INTERFACE (RAW_INTERFACE + 1)
149#else
150# define MOUSE_INTERFACE RAW_INTERFACE
151#endif 144#endif
152 145#if defined(SHARED_EP_ENABLE)
153#ifdef EXTRAKEY_ENABLE 146 SHARED_INTERFACE,
154# define EXTRAKEY_INTERFACE (MOUSE_INTERFACE + 1)
155#else
156# define EXTRAKEY_INTERFACE MOUSE_INTERFACE
157#endif 147#endif
158 148#if defined(CONSOLE_ENABLE)
159#ifdef CONSOLE_ENABLE 149 CONSOLE_INTERFACE,
160# define CONSOLE_INTERFACE (EXTRAKEY_INTERFACE + 1)
161#else
162# define CONSOLE_INTERFACE EXTRAKEY_INTERFACE
163#endif
164
165#ifdef NKRO_ENABLE
166# define NKRO_INTERFACE (CONSOLE_INTERFACE + 1)
167#else
168# define NKRO_INTERFACE CONSOLE_INTERFACE
169#endif 150#endif
170 151#if defined(MIDI_ENABLE)
171#ifdef MIDI_ENABLE 152 AC_INTERFACE,
172# define AC_INTERFACE (NKRO_INTERFACE + 1) 153 AS_INTERFACE,
173# define AS_INTERFACE (NKRO_INTERFACE + 2)
174#else
175# define AS_INTERFACE NKRO_INTERFACE
176#endif 154#endif
177 155#if defined(VIRTSER_ENABLE)
178#ifdef VIRTSER_ENABLE 156 CCI_INTERFACE,
179# define CCI_INTERFACE (AS_INTERFACE + 1) 157 CDI_INTERFACE,
180# define CDI_INTERFACE (AS_INTERFACE + 2)
181#else
182# define CDI_INTERFACE AS_INTERFACE
183#endif 158#endif
159 TOTAL_INTERFACES
160};
184 161
185/* nubmer of interfaces */ 162#define NEXT_EPNUM __COUNTER__
186#define TOTAL_INTERFACES (CDI_INTERFACE + 1)
187
188 163
189// Endopoint number and size 164enum usb_endpoints {
190#define KEYBOARD_IN_EPNUM 1 165 __unused_epnum__ = NEXT_EPNUM, /* EP numbering starts at 1 */
191 166#if !defined(KEYBOARD_SHARED_EP)
192#ifdef MOUSE_ENABLE 167 KEYBOARD_IN_EPNUM = NEXT_EPNUM,
193# define MOUSE_IN_EPNUM (KEYBOARD_IN_EPNUM + 1)
194#else 168#else
195# define MOUSE_IN_EPNUM KEYBOARD_IN_EPNUM 169# define KEYBOARD_IN_EPNUM SHARED_IN_EPNUM
196#endif 170#endif
197 171#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
198#ifdef EXTRAKEY_ENABLE 172 MOUSE_IN_EPNUM = NEXT_EPNUM,
199# define EXTRAKEY_IN_EPNUM (MOUSE_IN_EPNUM + 1)
200#else 173#else
201# define EXTRAKEY_IN_EPNUM MOUSE_IN_EPNUM 174# define MOUSE_IN_EPNUM SHARED_IN_EPNUM
202#endif 175#endif
203 176#if defined(RAW_ENABLE)
204#ifdef RAW_ENABLE 177 RAW_IN_EPNUM = NEXT_EPNUM,
205# define RAW_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1) 178 RAW_OUT_EPNUM = NEXT_EPNUM,
206# define RAW_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 2)
207#else
208# define RAW_OUT_EPNUM EXTRAKEY_IN_EPNUM
209#endif 179#endif
210 180#if defined(SHARED_EP_ENABLE)
211#ifdef CONSOLE_ENABLE 181 SHARED_IN_EPNUM = NEXT_EPNUM,
212# define CONSOLE_IN_EPNUM (RAW_OUT_EPNUM + 1) 182#endif
183#if defined(CONSOLE_ENABLE)
184 CONSOLE_IN_EPNUM = NEXT_EPNUM,
213#ifdef PROTOCOL_CHIBIOS 185#ifdef PROTOCOL_CHIBIOS
214// ChibiOS has enough memory and descriptor to actually enable the endpoint 186// ChibiOS has enough memory and descriptor to actually enable the endpoint
215// It could use the same endpoint numbers, as that's supported by ChibiOS 187// It could use the same endpoint numbers, as that's supported by ChibiOS
216// But the QMK code currently assumes that the endpoint numbers are different 188// But the QMK code currently assumes that the endpoint numbers are different
217# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 2) 189 CONSOLE_OUT_EPNUM = NEXT_EPNUM,
218#else 190#else
219# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 1) 191#define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
220#endif 192#endif
221#else
222# define CONSOLE_OUT_EPNUM RAW_OUT_EPNUM
223#endif 193#endif
224
225#ifdef NKRO_ENABLE
226# define NKRO_IN_EPNUM (CONSOLE_OUT_EPNUM + 1)
227#else
228# define NKRO_IN_EPNUM CONSOLE_OUT_EPNUM
229#endif
230
231#ifdef MIDI_ENABLE 194#ifdef MIDI_ENABLE
232# define MIDI_STREAM_IN_EPNUM (NKRO_IN_EPNUM + 1) 195 MIDI_STREAM_IN_EPNUM = NEXT_EPNUM,
233// # define MIDI_STREAM_OUT_EPNUM (NKRO_IN_EPNUM + 1) 196 MIDI_STREAM_OUT_EPNUM = NEXT_EPNUM,
234# define MIDI_STREAM_OUT_EPNUM (NKRO_IN_EPNUM + 2)
235# define MIDI_STREAM_IN_EPADDR (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM) 197# define MIDI_STREAM_IN_EPADDR (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM)
236# define MIDI_STREAM_OUT_EPADDR (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM) 198# define MIDI_STREAM_OUT_EPADDR (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM)
237#else
238# define MIDI_STREAM_OUT_EPNUM NKRO_IN_EPNUM
239#endif 199#endif
240
241#ifdef VIRTSER_ENABLE 200#ifdef VIRTSER_ENABLE
242# define CDC_NOTIFICATION_EPNUM (MIDI_STREAM_OUT_EPNUM + 1) 201 CDC_NOTIFICATION_EPNUM = NEXT_EPNUM,
243# define CDC_IN_EPNUM (MIDI_STREAM_OUT_EPNUM + 2) 202 CDC_IN_EPNUM = NEXT_EPNUM,
244# define CDC_OUT_EPNUM (MIDI_STREAM_OUT_EPNUM + 3) 203 CDC_OUT_EPNUM = NEXT_EPNUM,
245# define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM) 204# define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM)
246# define CDC_IN_EPADDR (ENDPOINT_DIR_IN | CDC_IN_EPNUM) 205# define CDC_IN_EPADDR (ENDPOINT_DIR_IN | CDC_IN_EPNUM)
247# define CDC_OUT_EPADDR (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM) 206# define CDC_OUT_EPADDR (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM)
248#else
249# define CDC_OUT_EPNUM MIDI_STREAM_OUT_EPNUM
250#endif 207#endif
208};
209
210#if defined(PROTOCOL_LUFA)
211/* LUFA tells us total endpoints including control */
212#define MAX_ENDPOINTS (ENDPOINT_TOTAL_ENDPOINTS - 1)
213#elif defined(PROTOCOL_CHIBIOS)
214/* ChibiOS gives us number of available user endpoints, not control */
215#define MAX_ENDPOINTS USB_MAX_ENDPOINTS
216#endif
217/* TODO - ARM_ATSAM */
218
251 219
252#if (defined(PROTOCOL_LUFA) && CDC_OUT_EPNUM > (ENDPOINT_TOTAL_ENDPOINTS - 1)) || \ 220#if (NEXT_EPNUM - 1) > MAX_ENDPOINTS
253 (defined(PROTOCOL_CHIBIOS) && CDC_OUT_EPNUM > USB_MAX_ENDPOINTS) 221# error There are not enough available endpoints to support all functions. Remove some in the rules.mk file. (MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL, STENO)
254# error "There are not enough available endpoints to support all functions. Remove some in the rules.mk file.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL, STENO)"
255#endif 222#endif
256 223
257#define KEYBOARD_EPSIZE 8 224#define KEYBOARD_EPSIZE 8
225#define SHARED_EPSIZE 32
258#define MOUSE_EPSIZE 8 226#define MOUSE_EPSIZE 8
259#define EXTRAKEY_EPSIZE 8
260#define RAW_EPSIZE 32 227#define RAW_EPSIZE 32
261#define CONSOLE_EPSIZE 32 228#define CONSOLE_EPSIZE 32
262#define NKRO_EPSIZE 32
263#define MIDI_STREAM_EPSIZE 64 229#define MIDI_STREAM_EPSIZE 64
264#define CDC_NOTIFICATION_EPSIZE 8 230#define CDC_NOTIFICATION_EPSIZE 8
265#define CDC_EPSIZE 16 231#define CDC_EPSIZE 16