summaryrefslogtreecommitdiffstats
path: root/tmk_core/protocol/usb_descriptor.c
diff options
context:
space:
mode:
authorJames Laird-Wah <james@laird-wah.net>2018-11-16 07:22:05 +0100
committerDrashna Jaelre <drashna@live.com>2018-11-16 07:22:05 +0100
commit39bd760faf2666e91d6dc5b199f02fa3206c6acd (patch)
tree12db265881a0d358bb0e186689a7b20a81c37bc6 /tmk_core/protocol/usb_descriptor.c
parent46cf8cc9b33a3c8bdbb0ce7df7f48f28e4d979a5 (diff)
downloadqmk_firmware-39bd760faf2666e91d6dc5b199f02fa3206c6acd.tar.gz
qmk_firmware-39bd760faf2666e91d6dc5b199f02fa3206c6acd.tar.xz
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/usb_descriptor.c')
-rw-r--r--tmk_core/protocol/usb_descriptor.c213
1 files changed, 96 insertions, 117 deletions
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 @@
/*******************************************************************************
* 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;
}