Просмотр исходного кода

ChibiOS: add support for HID Programmable Buttons (#15787)

* ChibiOS: add support for HID Programmable Buttons

Fixes #15596

* Enable SHARED_ENDPOINT when PROGRAMMABLE_BUTTON is enabled

The Programmable Button driver expects the shared EP to be enabled.
So enforce this invariant.
Thomas Weißschuh 3 лет назад
Родитель
Сommit
f1cd2a5a89
3 измененных файлов с 36 добавлено и 1 удалено
  1. 5 0
      tmk_core/protocol.mk
  2. 2 1
      tmk_core/protocol/chibios/chibios.c
  3. 29 0
      tmk_core/protocol/chibios/usb_main.c

+ 5 - 0
tmk_core/protocol.mk

@@ -28,6 +28,11 @@ ifeq ($(strip $(EXTRAKEY_ENABLE)), yes)
     SHARED_EP_ENABLE = yes
 endif
 
+ifeq ($(strip $(PROGRAMMABLE_BUTTON_ENABLE)), yes)
+    TMK_COMMON_DEFS += -DPROGRAMMABLE_BUTTON_ENABLE
+    SHARED_EP_ENABLE = yes
+endif
+
 ifeq ($(strip $(RAW_ENABLE)), yes)
     TMK_COMMON_DEFS += -DRAW_ENABLE
 endif

+ 2 - 1
tmk_core/protocol/chibios/chibios.c

@@ -60,10 +60,11 @@ void    send_keyboard(report_keyboard_t *report);
 void    send_mouse(report_mouse_t *report);
 void    send_system(uint16_t data);
 void    send_consumer(uint16_t data);
+void    send_programmable_button(uint32_t data);
 void    send_digitizer(report_digitizer_t *report);
 
 /* host struct */
-host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
+host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer, send_programmable_button};
 
 #ifdef VIRTSER_ENABLE
 void virtser_task(void);

+ 29 - 0
tmk_core/protocol/chibios/usb_main.c

@@ -975,6 +975,35 @@ void send_consumer(uint16_t data) {
 #endif
 }
 
+void send_programmable_button(uint32_t data) {
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+    osalSysLock();
+    if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
+        osalSysUnlock();
+        return;
+    }
+
+    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 */
+        if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
+            osalSysUnlock();
+            return;
+        }
+    }
+    static report_programmable_button_t report = {
+        .report_id = REPORT_ID_PROGRAMMABLE_BUTTON,
+    };
+
+    report.usage = data;
+
+    usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)&report, sizeof(report));
+    osalSysUnlock();
+#endif
+}
+
 void send_digitizer(report_digitizer_t *report) {
 #ifdef DIGITIZER_ENABLE
 #    ifdef DIGITIZER_SHARED_EP