summary refs log tree commit diff
path: root/tmk_core/protocol
diff options
context:
space:
mode:
authorThomas Weißschuh <thomas@t-8ch.de>2021-09-15 17:40:22 +0200
committerGitHub <noreply@github.com>2021-09-15 08:40:22 -0700
commit83988597f4d916a37b2b0987f393ceaa007532eb (patch)
treeba5d07ccf743cb27bee77b4d6cd2128035ce365e /tmk_core/protocol
parent1a68feb842ebcc6a7d1aef7cd7f83865cc18fab1 (diff)
Add Support for USB programmable buttons (#12950)
Diffstat (limited to 'tmk_core/protocol')
-rw-r--r--tmk_core/protocol/lufa/lufa.c33
-rw-r--r--tmk_core/protocol/usb_descriptor.c19
-rw-r--r--tmk_core/protocol/vusb/vusb.c36
3 files changed, 77 insertions, 11 deletions
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 5b56e8a03c..cb3aa693b5 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -142,7 +142,8 @@ static void    send_keyboard(report_keyboard_t *report);
 static void    send_mouse(report_mouse_t *report);
 static void    send_system(uint16_t data);
 static void    send_consumer(uint16_t data);
-host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
+static void    send_programmable_button(uint32_t data);
+host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer, send_programmable_button};
 
 #ifdef VIRTSER_ENABLE
 // clang-format off
@@ -760,27 +761,31 @@ static void send_mouse(report_mouse_t *report) {
 #endif
 }
 
-/** \brief Send Extra
- *
- * FIXME: Needs doc
- */
-#ifdef EXTRAKEY_ENABLE
-static void send_extra(uint8_t report_id, uint16_t data) {
+static void send_report(void *report, size_t size) {
     uint8_t timeout = 255;
 
     if (USB_DeviceState != DEVICE_STATE_Configured) return;
 
-    static report_extra_t r;
-    r = (report_extra_t){.report_id = report_id, .usage = data};
     Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
 
     /* Check if write ready for a polling interval around 10ms */
     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
     if (!Endpoint_IsReadWriteAllowed()) return;
 
-    Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
+    Endpoint_Write_Stream_LE(report, size, NULL);
     Endpoint_ClearIN();
 }
+
+/** \brief Send Extra
+ *
+ * FIXME: Needs doc
+ */
+#ifdef EXTRAKEY_ENABLE
+static void send_extra(uint8_t report_id, uint16_t data) {
+    static report_extra_t r;
+    r = (report_extra_t){.report_id = report_id, .usage = data};
+    send_report(&r, sizeof(r));
+}
 #endif
 
 /** \brief Send System
@@ -822,6 +827,14 @@ static void send_consumer(uint16_t data) {
 #endif
 }
 
+static void send_programmable_button(uint32_t data) {
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+    static report_programmable_button_t r;
+    r = (report_programmable_button_t){.report_id = REPORT_ID_PROGRAMMABLE_BUTTON, .usage = data};
+    send_report(&r, sizeof(r));
+#endif
+}
+
 /*******************************************************************************
  * sendchar
  ******************************************************************************/
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 099964ae56..f720eea8d9 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -237,6 +237,25 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
     HID_RI_END_COLLECTION(0),
 #endif
 
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+    HID_RI_USAGE_PAGE(8, 0x0C),            // Consumer
+    HID_RI_USAGE(8, 0x01),                 // Consumer Control
+    HID_RI_COLLECTION(8, 0x01),            // Application
+        HID_RI_REPORT_ID(8, REPORT_ID_PROGRAMMABLE_BUTTON),
+        HID_RI_USAGE(8, 0x09),             // Programmable Buttons
+        HID_RI_COLLECTION(8, 0x04),        // Named Array
+            HID_RI_USAGE_PAGE(8, 0x09),    // Button
+            HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
+            HID_RI_USAGE_MAXIMUM(8, 0x20), // Button 32
+            HID_RI_LOGICAL_MINIMUM(8, 0x01),
+            HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+            HID_RI_REPORT_COUNT(8, 32),
+            HID_RI_REPORT_SIZE(8, 1),
+            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+        HID_RI_END_COLLECTION(0),
+    HID_RI_END_COLLECTION(0),
+#endif
+
 #ifdef NKRO_ENABLE
     HID_RI_USAGE_PAGE(8, 0x01),        // Generic Desktop
     HID_RI_USAGE(8, 0x06),             // Keyboard
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 485b20c900..e4db5d0654 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -226,8 +226,9 @@ static void    send_keyboard(report_keyboard_t *report);
 static void    send_mouse(report_mouse_t *report);
 static void    send_system(uint16_t data);
 static void    send_consumer(uint16_t data);
+static void    send_programmable_button(uint32_t data);
 
-static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
+static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer, send_programmable_button};
 
 host_driver_t *vusb_driver(void) { return &driver; }
 
@@ -296,6 +297,19 @@ void send_digitizer(report_digitizer_t *report) {
 #ifdef DIGITIZER_ENABLE
     if (usbInterruptIsReadyShared()) {
         usbSetInterruptShared((void *)report, sizeof(report_digitizer_t));
+#endif
+}
+
+static void send_programmable_button(uint32_t data) {
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+    static report_programmable_button_t report = {
+        .report_id = REPORT_ID_PROGRAMMABLE_BUTTON,
+    };
+
+    report.usage = data;
+
+    if (usbInterruptIsReadyShared()) {
+        usbSetInterruptShared((void *)&report, sizeof(report));
     }
 #endif
 }
@@ -558,6 +572,26 @@ const PROGMEM uchar shared_hid_report[] = {
     0xC0               // End Collection
 #endif
 
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+    // Programmable buttons report descriptor
+    0x05, 0x0C,                           // Usage Page (Consumer)
+    0x09, 0x01,                           // Usage (Consumer Control)
+    0xA1, 0x01,                           // Collection (Application)
+    0x85, REPORT_ID_PROGRAMMABLE_BUTTON,  //   Report ID
+    0x09, 0x03,                           //   Usage (Programmable Buttons)
+    0xA1, 0x04,                           //   Collection (Named Array)
+    0x05, 0x09,                           //     Usage Page (Button)
+    0x19, 0x01,                           //     Usage Minimum (Button 1)
+    0x29, 0x20,                           //     Usage Maximum (Button 32)
+    0x15, 0x00,                           //     Logical Minimum (0)
+    0x25, 0x01,                           //     Logical Maximum (1)
+    0x95, 0x20,                           //     Report Count (32)
+    0x75, 0x01,                           //     Report Size (1)
+    0x81, 0x02,                           //     Input (Data, Variable, Absolute)
+    0xC0,                                 //   End Collection
+    0xC0                                  // End Collection
+#endif
+
 #ifdef SHARED_EP_ENABLE
 };
 #endif