summaryrefslogtreecommitdiff
path: root/tmk_core
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
parent1a68feb842ebcc6a7d1aef7cd7f83865cc18fab1 (diff)
Add Support for USB programmable buttons (#12950)
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/common/chibios/suspend.c4
-rw-r--r--tmk_core/common/host.c15
-rw-r--r--tmk_core/common/host.h2
-rw-r--r--tmk_core/common/host_driver.h1
-rw-r--r--tmk_core/common/report.h6
-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
8 files changed, 103 insertions, 13 deletions
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c
index 991fe6e08b..9310a99920 100644
--- a/tmk_core/common/chibios/suspend.c
+++ b/tmk_core/common/chibios/suspend.c
@@ -7,6 +7,7 @@
#include "action.h"
#include "action_util.h"
#include "mousekey.h"
+#include "programmable_button.h"
#include "host.h"
#include "suspend.h"
#include "led.h"
@@ -79,6 +80,9 @@ void suspend_wakeup_init(void) {
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
#endif /* MOUSEKEY_ENABLE */
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+ programmable_button_clear();
+#endif /* PROGRAMMABLE_BUTTON_ENABLE */
#ifdef EXTRAKEY_ENABLE
host_system_send(0);
host_consumer_send(0);
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
index f0c396b189..56d4bb0847 100644
--- a/tmk_core/common/host.c
+++ b/tmk_core/common/host.c
@@ -30,8 +30,9 @@ extern keymap_config_t keymap_config;
#endif
static host_driver_t *driver;
-static uint16_t last_system_report = 0;
-static uint16_t last_consumer_report = 0;
+static uint16_t last_system_report = 0;
+static uint16_t last_consumer_report = 0;
+static uint32_t last_programmable_button_report = 0;
void host_set_driver(host_driver_t *d) { driver = d; }
@@ -122,6 +123,16 @@ void host_digitizer_send(digitizer_t *digitizer) {
__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
+void host_programmable_button_send(uint32_t report) {
+ if (report == last_programmable_button_report) return;
+ last_programmable_button_report = report;
+
+ if (!driver) return;
+ (*driver->send_programmable_button)(report);
+}
+
uint16_t host_last_system_report(void) { return last_system_report; }
uint16_t host_last_consumer_report(void) { return last_consumer_report; }
+
+uint32_t host_last_programmable_button_report(void) { return last_programmable_button_report; }
diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h
index 2cffef6e15..6b15f0d0c1 100644
--- a/tmk_core/common/host.h
+++ b/tmk_core/common/host.h
@@ -47,9 +47,11 @@ void host_keyboard_send(report_keyboard_t *report);
void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
+void host_programmable_button_send(uint32_t data);
uint16_t host_last_system_report(void);
uint16_t host_last_consumer_report(void);
+uint32_t host_last_programmable_button_report(void);
#ifdef __cplusplus
}
diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h
index 2aebca043d..affd0dcb34 100644
--- a/tmk_core/common/host_driver.h
+++ b/tmk_core/common/host_driver.h
@@ -29,6 +29,7 @@ typedef struct {
void (*send_mouse)(report_mouse_t *);
void (*send_system)(uint16_t);
void (*send_consumer)(uint16_t);
+ void (*send_programmable_button)(uint32_t);
} host_driver_t;
void send_digitizer(report_digitizer_t *report); \ No newline at end of file
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index f2223e8063..1adc892f3b 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -29,6 +29,7 @@ enum hid_report_ids {
REPORT_ID_MOUSE,
REPORT_ID_SYSTEM,
REPORT_ID_CONSUMER,
+ REPORT_ID_PROGRAMMABLE_BUTTON,
REPORT_ID_NKRO,
REPORT_ID_JOYSTICK,
REPORT_ID_DIGITIZER
@@ -196,6 +197,11 @@ typedef struct {
} __attribute__((packed)) report_extra_t;
typedef struct {
+ uint8_t report_id;
+ uint32_t usage;
+} __attribute__((packed)) report_programmable_button_t;
+
+typedef struct {
#ifdef MOUSE_SHARED_EP
uint8_t report_id;
#endif
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