summaryrefslogtreecommitdiff
path: root/tmk_core/protocol
diff options
context:
space:
mode:
authorJames Laird-Wah <james@laird-wah.net>2018-11-16 17:22:05 +1100
committerDrashna Jaelre <drashna@live.com>2018-11-15 22:22:05 -0800
commit39bd760faf2666e91d6dc5b199f02fa3206c6acd (patch)
tree12db265881a0d358bb0e186689a7b20a81c37bc6 /tmk_core/protocol
parent46cf8cc9b33a3c8bdbb0ce7df7f48f28e4d979a5 (diff)
Use a single endpoint for HID reports (#3951)
* Unify multiple HID interfaces into one This reduces the number of USB endpoints required, which frees them up for other things. NKRO and EXTRAKEY always use the shared endpoint. By default, MOUSEKEY also uses it. This means it won't work as a Boot Procotol mouse in some BIOSes, etc. If you really think your keyboard needs to work as a mouse in your BIOS, set MOUSE_SHARED_EP = no in your rules.mk. By default, the core keyboard does not use the shared endpoint, as not all BIOSes are standards compliant and that's one place you don't want to find out your keyboard doesn't work.. If you are really confident, you can set KEYBOARD_SHARED_EP = yes to use the shared endpoint here too. * unify endpoints: ChibiOS protocol implementation * fixup: missing #ifdef EXTRAKEY_ENABLEs broke build on AVR with EXTRAKEY disabled * endpoints: restore error when too many endpoints required * lufa: wait up to 10ms to send keyboard input This avoids packets being dropped when two reports are sent in quick succession (eg. releasing a dual role key). * endpoints: fix compile on ARM_ATSAM * endpoint: ARM_ATSAM fixes No longer use wrong or unexpected endpoint IDs * endpoints: accommodate VUSB protocol V-USB has its own, understandably simple ideas about the report formats. It already blasts the mouse and extrakeys through one endpoint with report IDs. We just stay out of its way. * endpoints: document new endpoint configuration options * endpoints: respect keyboard_report->mods in NKRO The caller(s) of host_keyboard_send expect to be able to just drop modifiers in the mods field and not worry about whether NKRO is in use. This is a good thing. So we just shift it over if needs be. * endpoints: report.c: update for new keyboard_report format
Diffstat (limited to 'tmk_core/protocol')
-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
6 files changed, 307 insertions, 360 deletions
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 18f9784ae6..c263ac4aa1 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 @@
#include "udi_hid.h"
#include "udi_hid_kbd.h"
#include <string.h>
+#include "report.h"
//***************************************************************************
// KBD
@@ -430,7 +431,7 @@ UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {
0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x80, // Usage (System Control),
0xA1, 0x01, // Collection (Application),
- 0x85, 0x02, // Report ID (2) (System),
+ 0x85, REPORT_ID_SYSTEM, // Report ID (2) (System),
0x16, 0x01, 0x00, // Logical Minimum (1),
0x26, 0x03, 0x00, // Logical Maximum (3),
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 = {
0x05, 0x0C, // Usage Page (Consumer),
0x09, 0x01, // Usage (Consumer Control),
0xA1, 0x01, // Collection (Application),
- 0x85, 0x03, // Report ID (3) (Consumer),
+ 0x85, REPORT_ID_CONSUMER, // Report ID (3) (Consumer),
0x16, 0x01, 0x00, // Logical Minimum (1),
0x26, 0x9C, 0x02, // Logical Maximum (668),
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 71892c4f49..3028e7ea2a 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
return &desc;
}
+#ifndef KEYBOARD_SHARED_EP
/* keyboard endpoint state structure */
static USBInEndpointState kbd_ep_state;
/* keyboard endpoint initialization structure (IN) */
@@ -110,8 +111,9 @@ static const USBEndpointConfig kbd_ep_config = {
2, /* IN multiplier */
NULL /* SETUP buffer (not a SETUP endpoint) */
};
+#endif
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
/* mouse endpoint state structure */
static USBInEndpointState mouse_ep_state;
@@ -128,45 +130,26 @@ static const USBEndpointConfig mouse_ep_config = {
2, /* IN multiplier */
NULL /* SETUP buffer (not a SETUP endpoint) */
};
-#endif /* MOUSE_ENABLE */
-
-#ifdef EXTRAKEY_ENABLE
-/* extrakey endpoint state structure */
-static USBInEndpointState extra_ep_state;
-
-/* extrakey endpoint initialization structure (IN) */
-static const USBEndpointConfig extra_ep_config = {
- USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
- NULL, /* SETUP packet notification callback */
- extra_in_cb, /* IN notification callback */
- NULL, /* OUT notification callback */
- EXTRAKEY_EPSIZE, /* IN maximum packet size */
- 0, /* OUT maximum packet size */
- &extra_ep_state, /* IN Endpoint state */
- NULL, /* OUT endpoint state */
- 2, /* IN multiplier */
- NULL /* SETUP buffer (not a SETUP endpoint) */
-};
-#endif /* EXTRAKEY_ENABLE */
+#endif
-#ifdef NKRO_ENABLE
-/* nkro endpoint state structure */
-static USBInEndpointState nkro_ep_state;
+#ifdef SHARED_EP_ENABLE
+/* shared endpoint state structure */
+static USBInEndpointState shared_ep_state;
-/* nkro endpoint initialization structure (IN) */
-static const USBEndpointConfig nkro_ep_config = {
+/* shared endpoint initialization structure (IN) */
+static const USBEndpointConfig shared_ep_config = {
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
NULL, /* SETUP packet notification callback */
- nkro_in_cb, /* IN notification callback */
+ shared_in_cb, /* IN notification callback */
NULL, /* OUT notification callback */
- NKRO_EPSIZE, /* IN maximum packet size */
+ SHARED_EPSIZE, /* IN maximum packet size */
0, /* OUT maximum packet size */
- &nkro_ep_state, /* IN Endpoint state */
+ &shared_ep_state, /* IN Endpoint state */
NULL, /* OUT endpoint state */
2, /* IN multiplier */
NULL /* SETUP buffer (not a SETUP endpoint) */
};
-#endif /* NKRO_ENABLE */
+#endif
typedef struct {
size_t queue_capacity_in;
@@ -309,16 +292,15 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
case USB_EVENT_CONFIGURED:
osalSysLockFromISR();
/* Enable the endpoints specified into the configuration. */
+#ifndef KEYBOARD_SHARED_EP
usbInitEndpointI(usbp, KEYBOARD_IN_EPNUM, &kbd_ep_config);
-#ifdef MOUSE_ENABLE
+#endif
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
usbInitEndpointI(usbp, MOUSE_IN_EPNUM, &mouse_ep_config);
-#endif /* MOUSE_ENABLE */
-#ifdef EXTRAKEY_ENABLE
- usbInitEndpointI(usbp, EXTRAKEY_IN_EPNUM, &extra_ep_config);
-#endif /* EXTRAKEY_ENABLE */
-#ifdef NKRO_ENABLE
- usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config);
-#endif /* NKRO_ENABLE */
+#endif
+#ifdef SHARED_EP_ENABLE
+ usbInitEndpointI(usbp, SHARED_IN_EPNUM, &shared_ep_config);
+#endif
for (int i=0;i<NUM_USB_DRIVERS;i++) {
usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config);
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) {
* Other Device Required Optional Optional Optional Optional Optional
*/
+#ifdef SHARED_EP_ENABLE
+static uint8_t set_report_buf[2] __attribute__((aligned(2)));
+static void set_led_transfer_cb(USBDriver *usbp) {
+ if ((set_report_buf[0] == REPORT_ID_KEYBOARD) ||
+ (set_report_buf[0] == REPORT_ID_NKRO)) {
+ keyboard_led_stats = set_report_buf[1];
+ }
+}
+#endif
+
/* Callback for SETUP request on the endpoint 0 (control) */
static bool usb_request_hook_cb(USBDriver *usbp) {
const USBDescriptor *dp;
+ int has_report_id;
/* usbp->setup fields:
* 0: bmRequestType (bitmask)
@@ -409,42 +402,16 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
case HID_GET_REPORT:
switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */
case KEYBOARD_INTERFACE:
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
-#endif /* NKRO_ENABLE */
usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent), NULL);
return TRUE;
break;
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE:
usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL);
return TRUE;
break;
-#endif /* MOUSE_ENABLE */
-
-#ifdef EXTRAKEY_ENABLE
- case EXTRAKEY_INTERFACE:
- if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */
- switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */
- case REPORT_ID_SYSTEM:
- extra_report_blank[0] = REPORT_ID_SYSTEM;
- usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
- return TRUE;
- break;
- case REPORT_ID_CONSUMER:
- extra_report_blank[0] = REPORT_ID_CONSUMER;
- usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
- return TRUE;
- break;
- default:
- return FALSE;
- }
- } else {
- return FALSE;
- }
- break;
-#endif /* EXTRAKEY_ENABLE */
+#endif
default:
usbSetupTransfer(usbp, NULL, 0, NULL);
@@ -472,12 +439,25 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
case HID_SET_REPORT:
switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */
case KEYBOARD_INTERFACE:
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
-#endif /* NKRO_ENABLE */
+#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
+ case SHARED_INTERFACE:
+#endif
/* keyboard_led_stats = <read byte from next OUT report>
* keyboard_led_stats needs be word (or dword), otherwise we get an exception on F0 */
- usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL);
+ has_report_id = 0;
+#if defined(SHARED_EP_ENABLE)
+ if (usbp->setup[4] == SHARED_INTERFACE) {
+ has_report_id = 1;
+ }
+#endif
+ if (usbp->setup[4] == KEYBOARD_INTERFACE && !keyboard_protocol) {
+ has_report_id = 0;
+ }
+ if (has_report_id) {
+ usbSetupTransfer(usbp, set_report_buf, sizeof(set_report_buf), set_led_transfer_cb);
+ } else {
+ usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL);
+ }
return TRUE;
break;
}
@@ -591,20 +571,13 @@ void init_usb_driver(USBDriver *usbp) {
* ---------------------------------------------------------
*/
/* keyboard IN callback hander (a kbd report has made it IN) */
+#ifndef KEYBOARD_SHARED_EP
void kbd_in_cb(USBDriver *usbp, usbep_t ep) {
/* STUB */
(void)usbp;
(void)ep;
}
-
-#ifdef NKRO_ENABLE
-/* nkro IN callback hander (a nkro report has made it IN) */
-void nkro_in_cb(USBDriver *usbp, usbep_t ep) {
- /* STUB */
- (void)usbp;
- (void)ep;
-}
-#endif /* NKRO_ENABLE */
+#endif
/* start-of-frame handler
* TODO: i guess it would be better to re-implement using timers,
@@ -628,9 +601,9 @@ static void keyboard_idle_timer_cb(void *arg) {
}
#ifdef NKRO_ENABLE
- if(!keymap_config.nkro && keyboard_idle) {
+ if(!keymap_config.nkro && keyboard_idle && keyboard_protocol) {
#else /* NKRO_ENABLE */
- if(keyboard_idle) {
+ if(keyboard_idle && keyboard_protocol) {
#endif /* NKRO_ENABLE */
/* TODO: are we sure we want the KBD_ENDPOINT? */
if(!usbGetTransmitStatusI(usbp, KEYBOARD_IN_EPNUM)) {
@@ -661,25 +634,25 @@ void send_keyboard(report_keyboard_t *report) {
osalSysUnlock();
#ifdef NKRO_ENABLE
- if(keymap_config.nkro) { /* NKRO protocol */
+ if(keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */
/* need to wait until the previous packet has made it through */
/* can rewrite this using the synchronous API, then would wait
* until *after* the packet has been transmitted. I think
* this is more efficient */
/* busy wait, should be short and not very common */
osalSysLock();
- if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_IN_EPNUM)) {
+ if(usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
- osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_IN_EPNUM]->in_state->thread);
+ osalThreadSuspendS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread);
}
- usbStartTransmitI(&USB_DRIVER, NKRO_IN_EPNUM, (uint8_t *)report, sizeof(report_keyboard_t));
+ usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(struct nkro_report));
osalSysUnlock();
} else
#endif /* NKRO_ENABLE */
- { /* boot protocol */
+ { /* regular protocol */
/* need to wait until the previous packet has made it through */
/* busy wait, should be short and not very common */
osalSysLock();
@@ -690,7 +663,15 @@ void send_keyboard(report_keyboard_t *report) {
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread);
}
- usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, (uint8_t *)report, KEYBOARD_EPSIZE);
+ uint8_t *data, size;
+ if (keyboard_protocol) {
+ data = (uint8_t*)report;
+ size = KEYBOARD_REPORT_SIZE;
+ } else { /* boot protocol */
+ data = &report->mods;
+ size = 8;
+ }
+ usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size);
osalSysUnlock();
}
keyboard_report_sent = *report;
@@ -703,11 +684,13 @@ void send_keyboard(report_keyboard_t *report) {
#ifdef MOUSE_ENABLE
+#ifndef MOUSE_SHARED_EP
/* mouse IN callback hander (a mouse report has made it IN) */
void mouse_in_cb(USBDriver *usbp, usbep_t ep) {
(void)usbp;
(void)ep;
}
+#endif
void send_mouse(report_mouse_t *report) {
osalSysLock();
@@ -737,19 +720,24 @@ void send_mouse(report_mouse_t *report) {
#endif /* MOUSE_ENABLE */
/* ---------------------------------------------------------
- * Extrakey functions
+ * Shared EP functions
* ---------------------------------------------------------
*/
-
-#ifdef EXTRAKEY_ENABLE
-
-/* extrakey IN callback hander */
-void extra_in_cb(USBDriver *usbp, usbep_t ep) {
+#ifdef SHARED_EP_ENABLE
+/* shared IN callback hander */
+void shared_in_cb(USBDriver *usbp, usbep_t ep) {
/* STUB */
(void)usbp;
(void)ep;
}
+#endif
+
+/* ---------------------------------------------------------
+ * Extrakey functions
+ * ---------------------------------------------------------
+ */
+#ifdef EXTRAKEY_ENABLE
static void send_extra_report(uint8_t report_id, uint16_t data) {
osalSysLock();
if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
@@ -762,7 +750,7 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
.usage = data
};
- usbStartTransmitI(&USB_DRIVER, EXTRAKEY_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
+ usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
osalSysUnlock();
}
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index 1f7eb12f8d..55e8882cc4 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);
#endif /* MOUSE_ENABLE */
/* ---------------
+ * Shared EP header
+ * ---------------
+ */
+
+/* shared IN request callback handler */
+void shared_in_cb(USBDriver *usbp, usbep_t ep);
+
+/* ---------------
* Extrakey header
* ---------------
*/
#ifdef EXTRAKEY_ENABLE
-/* extrakey IN request callback handler */
-void extra_in_cb(USBDriver *usbp, usbep_t ep);
-
/* extra report structure */
typedef struct {
uint8_t report_id;
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 95e0b95b2f..e88e6f34aa 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)
bool ConfigSuccess = true;
/* Setup Keyboard HID Report Endpoints */
+#ifndef KEYBOARD_SHARED_EP
ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
+#endif
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
/* Setup Mouse HID Report Endpoint */
ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
-#ifdef EXTRAKEY_ENABLE
- /* Setup Extra HID Report Endpoint */
- ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
- EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
+#ifdef SHARED_EP_ENABLE
+ /* Setup Shared HID Report Endpoint */
+ ConfigSuccess &= ENDPOINT_CONFIG(SHARED_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
+ SHARED_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
#ifdef RAW_ENABLE
@@ -442,12 +444,6 @@ void EVENT_USB_Device_ConfigurationChanged(void)
#endif
#endif
-#ifdef NKRO_ENABLE
- /* Setup NKRO HID Report Endpoints */
- ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
- NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
-#endif
-
#ifdef MIDI_ENABLE
ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
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)
// Interface
switch (USB_ControlRequest.wIndex) {
case KEYBOARD_INTERFACE:
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
+#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
+ case SHARED_INTERFACE:
#endif
Endpoint_ClearSETUP();
@@ -521,7 +517,17 @@ void EVENT_USB_Device_ControlRequest(void)
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
+#if defined(SHARED_EP_ENABLE)
+ uint8_t report_id = REPORT_ID_KEYBOARD;
+ if (keyboard_protocol) {
+ report_id = Endpoint_Read_8();
+ }
+ if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
+ keyboard_led_stats = Endpoint_Read_8();
+ }
+#else
keyboard_led_stats = Endpoint_Read_8();
+#endif
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
@@ -612,16 +618,20 @@ static void send_keyboard(report_keyboard_t *report)
#ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
#elif MODULE_RN42
- bluefruit_serial_send(0xFD);
- bluefruit_serial_send(0x09);
- bluefruit_serial_send(0x01);
- for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
- bluefruit_serial_send(report->raw[i]);
- }
+ bluefruit_serial_send(0xFD);
+ bluefruit_serial_send(0x09);
+ bluefruit_serial_send(0x01);
+ bluefruit_serial_send(report->mods);
+ bluefruit_serial_send(report->reserved);
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+ bluefruit_serial_send(report->keys[i]);
+ }
#else
bluefruit_serial_send(0xFD);
- for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
- bluefruit_serial_send(report->raw[i]);
+ bluefruit_serial_send(report->mods);
+ bluefruit_serial_send(report->reserved);
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+ bluefruit_serial_send(report->keys[i]);
}
#endif
}
@@ -632,30 +642,24 @@ static void send_keyboard(report_keyboard_t *report)
}
/* Select the Keyboard Report Endpoint */
+ uint8_t ep = KEYBOARD_IN_EPNUM;
+ uint8_t size = KEYBOARD_REPORT_SIZE;
#ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) {
- /* Report protocol - NKRO */
- Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
-
- /* Check if write ready for a polling interval around 1ms */
- while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
- if (!Endpoint_IsReadWriteAllowed()) return;
-
- /* Write Keyboard Report Data */
- Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
+ ep = SHARED_IN_EPNUM;
+ size = sizeof(struct nkro_report);
}
- else
#endif
- {
- /* Boot protocol */
- Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
-
- /* Check if write ready for a polling interval around 10ms */
- while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
- if (!Endpoint_IsReadWriteAllowed()) return;
+ Endpoint_SelectEndpoint(ep);
+ /* Check if write ready for a polling interval around 10ms */
+ while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
+ if (!Endpoint_IsReadWriteAllowed()) return;
- /* Write Keyboard Report Data */
- Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
+ /* If we're in Boot Protocol, don't send any report ID or other funky fields */
+ if (!keyboard_protocol) {
+ Endpoint_Write_Stream_LE(&report->mods, 8, NULL);
+ } else {
+ Endpoint_Write_Stream_LE(report, size, NULL);
}
/* Finalize the stream transfer to send the last packet */
@@ -718,6 +722,7 @@ static void send_mouse(report_mouse_t *report)
*/
static void send_system(uint16_t data)
{
+#ifdef EXTRAKEY_ENABLE
uint8_t timeout = 255;
if (USB_DeviceState != DEVICE_STATE_Configured)
@@ -727,7 +732,7 @@ static void send_system(uint16_t data)
.report_id = REPORT_ID_SYSTEM,
.usage = data - SYSTEM_POWER_DOWN + 1
};
- Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
+ Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
/* Check if write ready for a polling interval around 10ms */
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@@ -735,6 +740,7 @@ static void send_system(uint16_t data)
Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
Endpoint_ClearIN();
+#endif
}
/** \brief Send Consumer
@@ -743,6 +749,7 @@ static void send_system(uint16_t data)
*/
static void send_consumer(uint16_t data)
{
+#ifdef EXTRAKEY_ENABLE
uint8_t timeout = 255;
uint8_t where = where_to_send();
@@ -786,7 +793,7 @@ static void send_consumer(uint16_t data)
.report_id = REPORT_ID_CONSUMER,
.usage = data
};
- Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
+ Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
/* Check if write ready for a polling interval around 10ms */
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@@ -794,6 +801,7 @@ static void send_consumer(uint16_t data)
Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
Endpoint_ClearIN();
+#endif
}
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index cab3446752..589ad23cdd 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -47,11 +47,18 @@
/*******************************************************************************
* HID Report Descriptors
******************************************************************************/
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
-{
+#ifdef KEYBOARD_SHARED_EP
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
+#define SHARED_REPORT_STARTED
+#else
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
+#endif
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x06), /* Keyboard */
HID_RI_COLLECTION(8, 0x01), /* Application */
+# ifdef KEYBOARD_SHARED_EP
+ HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
+# endif
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
@@ -84,14 +91,25 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
+
+#ifndef KEYBOARD_SHARED_EP
};
+#endif
-#ifdef MOUSE_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
-{
+#if defined(MOUSE_ENABLE)
+
+# if !defined(MOUSE_SHARED_EP)
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
+# elif !defined(SHARED_REPORT_STARTED)
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
+#define SHARED_REPORT_STARTED
+# endif
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x02), /* Mouse */
HID_RI_COLLECTION(8, 0x01), /* Application */
+# ifdef MOUSE_SHARED_EP
+ HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
+# endif
HID_RI_USAGE(8, 0x01), /* Pointer */
HID_RI_COLLECTION(8, 0x00), /* Physical */
@@ -133,12 +151,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
HID_RI_END_COLLECTION(0),
HID_RI_END_COLLECTION(0),
+# ifndef MOUSE_SHARED_EP
};
+# endif
#endif
-#ifdef EXTRAKEY_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
-{
+#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
+#endif
+# ifdef EXTRAKEY_ENABLE
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x80), /* System Control */
HID_RI_COLLECTION(8, 0x01), /* Application */
@@ -164,6 +185,43 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
HID_RI_REPORT_COUNT(8, 1),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
+# endif
+
+# ifdef NKRO_ENABLE
+ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+ HID_RI_USAGE(8, 0x06), /* Keyboard */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
+ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+ HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
+ HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, 0x08),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+
+ HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
+ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
+ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
+ HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x03),
+ HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
+
+ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+ HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
+ HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS*8-1),
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS*8),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+ HID_RI_END_COLLECTION(0),
+# endif
+#ifdef SHARED_EP_ENABLE
};
#endif
@@ -211,42 +269,6 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
};
#endif
-#ifdef NKRO_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
-{
- HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
- HID_RI_USAGE(8, 0x06), /* Keyboard */
- HID_RI_COLLECTION(8, 0x01), /* Application */
- HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
- HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
- HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
- HID_RI_LOGICAL_MINIMUM(8, 0x00),
- HID_RI_LOGICAL_MAXIMUM(8, 0x01),
- HID_RI_REPORT_COUNT(8, 0x08),
- HID_RI_REPORT_SIZE(8, 0x01),
- HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
- HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
- HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
- HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
- HID_RI_REPORT_COUNT(8, 0x05),
- HID_RI_REPORT_SIZE(8, 0x01),
- HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
- HID_RI_REPORT_COUNT(8, 0x01),
- HID_RI_REPORT_SIZE(8, 0x03),
- HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
-
- HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
- HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
- HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
- HID_RI_LOGICAL_MINIMUM(8, 0x00),
- HID_RI_LOGICAL_MAXIMUM(8, 0x01),
- HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
- HID_RI_REPORT_SIZE(8, 0x01),
- HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
- HID_RI_END_COLLECTION(0),
-};
-#endif
/*******************************************************************************
* Device Descriptors
@@ -303,6 +325,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
/*
* Keyboard
*/
+#ifndef KEYBOARD_SHARED_EP
.Keyboard_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -339,11 +362,12 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.EndpointSize = KEYBOARD_EPSIZE,
.PollingIntervalMS = 0x0A
},
+#endif
/*
* Mouse
*/
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
.Mouse_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -383,26 +407,31 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
#endif
/*
- * Extra
+ * Shared
*/
-#ifdef EXTRAKEY_ENABLE
- .Extrakey_Interface =
+#ifdef SHARED_EP_ENABLE
+ .Shared_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
- .InterfaceNumber = EXTRAKEY_INTERFACE,
+ .InterfaceNumber = SHARED_INTERFACE,
.AlternateSetting = 0x00,
.TotalEndpoints = 1,
.Class = HID_CSCP_HIDClass,
+# ifdef KEYBOARD_SHARED_EP
+ .SubClass = HID_CSCP_BootSubclass,
+ .Protocol = HID_CSCP_KeyboardBootProtocol,
+# else
.SubClass = HID_CSCP_NonBootSubclass,
.Protocol = HID_CSCP_NonBootProtocol,
+#endif
.InterfaceStrIndex = NO_DESCRIPTOR
},
- .Extrakey_HID =
+ .Shared_HID =
{
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
@@ -410,16 +439,16 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.CountryCode = 0x00,
.TotalReportDescriptors = 1,
.HIDReportType = HID_DTYPE_Report,
- .HIDReportLength = sizeof(ExtrakeyReport)
+ .HIDReportLength = sizeof(SharedReport)
},
- .Extrakey_INEndpoint =
+ .Shared_INEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
- .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
+ .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = EXTRAKEY_EPSIZE,
+ .EndpointSize = SHARED_EPSIZE,
.PollingIntervalMS = 0x0A
},
#endif
@@ -528,48 +557,6 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
},
#endif
- /*
- * NKRO
- */
-#ifdef NKRO_ENABLE
- .NKRO_Interface =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
- .InterfaceNumber = NKRO_INTERFACE,
- .AlternateSetting = 0x00,
-
- .TotalEndpoints = 1,
-
- .Class = HID_CSCP_HIDClass,
- .SubClass = HID_CSCP_NonBootSubclass,
- .Protocol = HID_CSCP_NonBootProtocol,
-
- .InterfaceStrIndex = NO_DESCRIPTOR
- },
-
- .NKRO_HID =
- {
- .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
- .HIDSpec = VERSION_BCD(1,1,1),
- .CountryCode = 0x00,
- .TotalReportDescriptors = 1,
- .HIDReportType = HID_DTYPE_Report,
- .HIDReportLength = sizeof(NKROReport)
- },
-
- .NKRO_INEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
- .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
- .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = NKRO_EPSIZE,
- .PollingIntervalMS = 0x01
- },
-#endif
-
#ifdef MIDI_ENABLE
.Audio_Interface_Association =
{
@@ -936,19 +923,21 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
break;
case HID_DTYPE_HID:
switch (wIndex) {
+#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE:
Address = &ConfigurationDescriptor.Keyboard_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
-#ifdef MOUSE_ENABLE
+#endif
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE:
Address = &ConfigurationDescriptor.Mouse_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
-#ifdef EXTRAKEY_ENABLE
- case EXTRAKEY_INTERFACE:
- Address = &ConfigurationDescriptor.Extrakey_HID;
+#ifdef SHARED_EP_ENABLE
+ case SHARED_INTERFACE:
+ Address = &ConfigurationDescriptor.Shared_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
@@ -964,30 +953,26 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
- Address = &ConfigurationDescriptor.NKRO_HID;
- Size = sizeof(USB_HID_Descriptor_HID_t);
- break;
-#endif
}
break;
case HID_DTYPE_Report:
switch (wIndex) {
+#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE:
Address = &KeyboardReport;
Size = sizeof(KeyboardReport);
break;
-#ifdef MOUSE_ENABLE
+#endif
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE:
Address = &MouseReport;
Size = sizeof(MouseReport);
break;
#endif
-#ifdef EXTRAKEY_ENABLE
- case EXTRAKEY_INTERFACE:
- Address = &ExtrakeyReport;
- Size = sizeof(ExtrakeyReport);
+#ifdef SHARED_EP_ENABLE
+ case SHARED_INTERFACE:
+ Address = &SharedReport;
+ Size = sizeof(SharedReport);
break;
#endif
#ifdef RAW_ENABLE
@@ -1002,12 +987,6 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
Size = sizeof(ConsoleReport);
break;
#endif
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
- Address = &NKROReport;
- Size = sizeof(NKROReport);
- break;
-#endif
}
break;
}
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
index 586d07df62..3ca0c00b34 100644
--- a/tmk_core/protocol/usb_descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -53,26 +53,27 @@ typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
+#ifndef KEYBOARD_SHARED_EP
// Keyboard HID Interface
USB_Descriptor_Interface_t Keyboard_Interface;
USB_HID_Descriptor_HID_t Keyboard_HID;
USB_Descriptor_Endpoint_t Keyboard_INEndpoint;
+#endif
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
// Mouse HID Interface
USB_Descriptor_Interface_t Mouse_Interface;
USB_HID_Descriptor_HID_t Mouse_HID;
USB_Descriptor_Endpoint_t Mouse_INEndpoint;
#endif
-#ifdef EXTRAKEY_ENABLE
- // Extrakey HID Interface
- USB_Descriptor_Interface_t Extrakey_Interface;
- USB_HID_Descriptor_HID_t Extrakey_HID;
- USB_Descriptor_Endpoint_t Extrakey_INEndpoint;
+#if defined(SHARED_EP_ENABLE)
+ USB_Descriptor_Interface_t Shared_Interface;
+ USB_HID_Descriptor_HID_t Shared_HID;
+ USB_Descriptor_Endpoint_t Shared_INEndpoint;
#endif
-#ifdef RAW_ENABLE
+#if defined(RAW_ENABLE)
// Raw HID Interface
USB_Descriptor_Interface_t Raw_Interface;
USB_HID_Descriptor_HID_t Raw_HID;
@@ -88,13 +89,6 @@ typedef struct
USB_Descriptor_Endpoint_t Console_OUTEndpoint;
#endif
-#ifdef NKRO_ENABLE
- // NKRO HID Interface
- USB_Descriptor_Interface_t NKRO_Interface;
- USB_HID_Descriptor_HID_t NKRO_HID;
- USB_Descriptor_Endpoint_t NKRO_INEndpoint;
-#endif
-
#ifdef MIDI_ENABLE
USB_Descriptor_Interface_Association_t Audio_Interface_Association;
// MIDI Audio Control Interface
@@ -133,133 +127,105 @@ typedef struct
/* index of interface */
-#define KEYBOARD_INTERFACE 0
-
+enum usb_interfaces {
+#if !defined(KEYBOARD_SHARED_EP)
+ KEYBOARD_INTERFACE,
+#else
+# define KEYBOARD_INTERFACE SHARED_INTERFACE
+#endif
// It is important that the Raw HID interface is at a constant
// interface number, to support Linux/OSX platforms and chrome.hid
// If Raw HID is enabled, let it be always 1.
-#ifdef RAW_ENABLE
-# define RAW_INTERFACE (KEYBOARD_INTERFACE + 1)
-#else
-# define RAW_INTERFACE KEYBOARD_INTERFACE
+#if defined(RAW_ENABLE)
+ RAW_INTERFACE,
#endif
-
-#ifdef MOUSE_ENABLE
-# define MOUSE_INTERFACE (RAW_INTERFACE + 1)
-#else
-# define MOUSE_INTERFACE RAW_INTERFACE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
+ MOUSE_INTERFACE,
#endif
-
-#ifdef EXTRAKEY_ENABLE
-# define EXTRAKEY_INTERFACE (MOUSE_INTERFACE + 1)
-#else
-# define EXTRAKEY_INTERFACE MOUSE_INTERFACE
+#if defined(SHARED_EP_ENABLE)
+ SHARED_INTERFACE,
#endif
-
-#ifdef CONSOLE_ENABLE
-# define CONSOLE_INTERFACE (EXTRAKEY_INTERFACE + 1)
-#else
-# define CONSOLE_INTERFACE EXTRAKEY_INTERFACE
-#endif
-
-#ifdef NKRO_ENABLE
-# define NKRO_INTERFACE (CONSOLE_INTERFACE + 1)
-#else
-# define NKRO_INTERFACE CONSOLE_INTERFACE
+#if defined(CONSOLE_ENABLE)
+ CONSOLE_INTERFACE,
#endif
-
-#ifdef MIDI_ENABLE
-# define AC_INTERFACE (NKRO_INTERFACE + 1)
-# define AS_INTERFACE (NKRO_INTERFACE + 2)
-#else
-# define AS_INTERFACE NKRO_INTERFACE
+#if defined(MIDI_ENABLE)
+ AC_INTERFACE,
+ AS_INTERFACE,
#endif
-
-#ifdef VIRTSER_ENABLE
-# define CCI_INTERFACE (AS_INTERFACE + 1)
-# define CDI_INTERFACE (AS_INTERFACE + 2)
-#else
-# define CDI_INTERFACE AS_INTERFACE
+#if defined(VIRTSER_ENABLE)
+ CCI_INTERFACE,
+ CDI_INTERFACE,
#endif
+ TOTAL_INTERFACES
+};
-/* nubmer of interfaces */
-#define TOTAL_INTERFACES (CDI_INTERFACE + 1)
-
+#define NEXT_EPNUM __COUNTER__
-// Endopoint number and size
-#define KEYBOARD_IN_EPNUM 1
-
-#ifdef MOUSE_ENABLE
-# define MOUSE_IN_EPNUM (KEYBOARD_IN_EPNUM + 1)
+enum usb_endpoints {
+ __unused_epnum__ = NEXT_EPNUM, /* EP numbering starts at 1 */
+#if !defined(KEYBOARD_SHARED_EP)
+ KEYBOARD_IN_EPNUM = NEXT_EPNUM,
#else
-# define MOUSE_IN_EPNUM KEYBOARD_IN_EPNUM
+# define KEYBOARD_IN_EPNUM SHARED_IN_EPNUM
#endif
-
-#ifdef EXTRAKEY_ENABLE
-# define EXTRAKEY_IN_EPNUM (MOUSE_IN_EPNUM + 1)
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
+ MOUSE_IN_EPNUM = NEXT_EPNUM,
#else
-# define EXTRAKEY_IN_EPNUM MOUSE_IN_EPNUM
+# define MOUSE_IN_EPNUM SHARED_IN_EPNUM
#endif
-
-#ifdef RAW_ENABLE
-# define RAW_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1)
-# define RAW_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 2)
-#else
-# define RAW_OUT_EPNUM EXTRAKEY_IN_EPNUM
+#if defined(RAW_ENABLE)
+ RAW_IN_EPNUM = NEXT_EPNUM,
+ RAW_OUT_EPNUM = NEXT_EPNUM,
#endif
-
-#ifdef CONSOLE_ENABLE
-# define CONSOLE_IN_EPNUM (RAW_OUT_EPNUM + 1)
+#if defined(SHARED_EP_ENABLE)
+ SHARED_IN_EPNUM = NEXT_EPNUM,
+#endif
+#if defined(CONSOLE_ENABLE)
+ CONSOLE_IN_EPNUM = NEXT_EPNUM,
#ifdef PROTOCOL_CHIBIOS
// ChibiOS has enough memory and descriptor to actually enable the endpoint
// It could use the same endpoint numbers, as that's supported by ChibiOS
// But the QMK code currently assumes that the endpoint numbers are different
-# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 2)
+ CONSOLE_OUT_EPNUM = NEXT_EPNUM,
#else
-# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 1)
+#define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
#endif
-#else
-# define CONSOLE_OUT_EPNUM RAW_OUT_EPNUM
#endif
-
-#ifdef NKRO_ENABLE
-# define NKRO_IN_EPNUM (CONSOLE_OUT_EPNUM + 1)
-#else
-# define NKRO_IN_EPNUM CONSOLE_OUT_EPNUM
-#endif
-
#ifdef MIDI_ENABLE
-# define MIDI_STREAM_IN_EPNUM (NKRO_IN_EPNUM + 1)
-// # define MIDI_STREAM_OUT_EPNUM (NKRO_IN_EPNUM + 1)
-# define MIDI_STREAM_OUT_EPNUM (NKRO_IN_EPNUM + 2)
+ MIDI_STREAM_IN_EPNUM = NEXT_EPNUM,
+ MIDI_STREAM_OUT_EPNUM = NEXT_EPNUM,
# define MIDI_STREAM_IN_EPADDR (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM)
# define MIDI_STREAM_OUT_EPADDR (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM)
-#else
-# define MIDI_STREAM_OUT_EPNUM NKRO_IN_EPNUM
#endif
-
#ifdef VIRTSER_ENABLE
-# define CDC_NOTIFICATION_EPNUM (MIDI_STREAM_OUT_EPNUM + 1)
-# define CDC_IN_EPNUM (MIDI_STREAM_OUT_EPNUM + 2)
-# define CDC_OUT_EPNUM (MIDI_STREAM_OUT_EPNUM + 3)
+ CDC_NOTIFICATION_EPNUM = NEXT_EPNUM,
+ CDC_IN_EPNUM = NEXT_EPNUM,
+ CDC_OUT_EPNUM = NEXT_EPNUM,
# define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM)
# define CDC_IN_EPADDR (ENDPOINT_DIR_IN | CDC_IN_EPNUM)
# define CDC_OUT_EPADDR (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM)
-#else
-# define CDC_OUT_EPNUM MIDI_STREAM_OUT_EPNUM
#endif
+};
+
+#if defined(PROTOCOL_LUFA)
+/* LUFA tells us total endpoints including control */
+#define MAX_ENDPOINTS (ENDPOINT_TOTAL_ENDPOINTS - 1)
+#elif defined(PROTOCOL_CHIBIOS)
+/* ChibiOS gives us number of available user endpoints, not control */
+#define MAX_ENDPOINTS USB_MAX_ENDPOINTS
+#endif
+/* TODO - ARM_ATSAM */
+
-#if (defined(PROTOCOL_LUFA) && CDC_OUT_EPNUM > (ENDPOINT_TOTAL_ENDPOINTS - 1)) || \
- (defined(PROTOCOL_CHIBIOS) && CDC_OUT_EPNUM > USB_MAX_ENDPOINTS)
-# 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)"
+#if (NEXT_EPNUM - 1) > MAX_ENDPOINTS
+# 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)
#endif
#define KEYBOARD_EPSIZE 8
+#define SHARED_EPSIZE 32
#define MOUSE_EPSIZE 8
-#define EXTRAKEY_EPSIZE 8
#define RAW_EPSIZE 32
#define CONSOLE_EPSIZE 32
-#define NKRO_EPSIZE 32
#define MIDI_STREAM_EPSIZE 64
#define CDC_NOTIFICATION_EPSIZE 8
#define CDC_EPSIZE 16