aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2021-02-01 08:19:00 +1100
committerGitHub <noreply@github.com>2021-02-01 08:19:00 +1100
commitdb11a2a1fd7a7ff9c458e8ec9e963a61a1192bf3 (patch)
tree982396d6fcaeb2c6aa3a8fa5580ad9c0bbcaf7fa
parent0fa2e7c790c4b4fcb318479a4951bfd33fd3862f (diff)
downloadqmk_firmware-db11a2a1fd7a7ff9c458e8ec9e963a61a1192bf3.tar.gz
qmk_firmware-db11a2a1fd7a7ff9c458e8ec9e963a61a1192bf3.zip
Decouple USB events from the USB interrupt handler. (#10437)
-rw-r--r--tmk_core/protocol/chibios/main.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c75
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
3 files changed, 80 insertions, 9 deletions
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index e07c181fc..63e4c99d2 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -163,6 +163,7 @@ int main(void) {
163 keyboard_setup(); 163 keyboard_setup();
164 164
165 /* Init USB */ 165 /* Init USB */
166 usb_event_queue_init();
166 init_usb_driver(&USB_DRIVER); 167 init_usb_driver(&USB_DRIVER);
167 168
168#ifdef MIDI_ENABLE 169#ifdef MIDI_ENABLE
@@ -221,6 +222,8 @@ int main(void) {
221 222
222 /* Main loop */ 223 /* Main loop */
223 while (true) { 224 while (true) {
225 usb_event_queue_task();
226
224#if !defined(NO_USB_STARTUP_CHECK) 227#if !defined(NO_USB_STARTUP_CHECK)
225 if (USB_DRIVER.state == USB_SUSPENDED) { 228 if (USB_DRIVER.state == USB_SUSPENDED) {
226 print("[s]"); 229 print("[s]");
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index ad489fb91..cb7aeb23b 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -27,6 +27,7 @@
27 27
28#include <ch.h> 28#include <ch.h>
29#include <hal.h> 29#include <hal.h>
30#include <string.h>
30 31
31#include "usb_main.h" 32#include "usb_main.h"
32 33
@@ -368,6 +369,69 @@ static usb_driver_configs_t drivers = {
368 * --------------------------------------------------------- 369 * ---------------------------------------------------------
369 */ 370 */
370 371
372#define USB_EVENT_QUEUE_SIZE 16
373usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
374uint8_t event_queue_head;
375uint8_t event_queue_tail;
376
377void usb_event_queue_init(void) {
378 // Initialise the event queue
379 memset(&event_queue, 0, sizeof(event_queue));
380 event_queue_head = 0;
381 event_queue_tail = 0;
382}
383
384static inline bool usb_event_queue_enqueue(usbevent_t event) {
385 uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
386 if (next == event_queue_tail) {
387 return false;
388 }
389 event_queue[event_queue_head] = event;
390 event_queue_head = next;
391 return true;
392}
393
394static inline bool usb_event_queue_dequeue(usbevent_t *event) {
395 if (event_queue_head == event_queue_tail) {
396 return false;
397 }
398 *event = event_queue[event_queue_tail];
399 event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
400 return true;
401}
402
403static inline void usb_event_suspend_handler(void) {
404#ifdef SLEEP_LED_ENABLE
405 sleep_led_enable();
406#endif /* SLEEP_LED_ENABLE */
407}
408
409static inline void usb_event_wakeup_handler(void) {
410 suspend_wakeup_init();
411#ifdef SLEEP_LED_ENABLE
412 sleep_led_disable();
413 // NOTE: converters may not accept this
414 led_set(host_keyboard_leds());
415#endif /* SLEEP_LED_ENABLE */
416}
417
418void usb_event_queue_task(void) {
419 usbevent_t event;
420 while (usb_event_queue_dequeue(&event)) {
421 switch (event) {
422 case USB_EVENT_SUSPEND:
423 usb_event_suspend_handler();
424 break;
425 case USB_EVENT_WAKEUP:
426 usb_event_wakeup_handler();
427 break;
428 default:
429 // Nothing to do, we don't handle it.
430 break;
431 }
432 }
433}
434
371/* Handles the USB driver global events 435/* Handles the USB driver global events
372 * TODO: maybe disable some things when connection is lost? */ 436 * TODO: maybe disable some things when connection is lost? */
373static void usb_event_cb(USBDriver *usbp, usbevent_t event) { 437static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
@@ -402,9 +466,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
402 osalSysUnlockFromISR(); 466 osalSysUnlockFromISR();
403 return; 467 return;
404 case USB_EVENT_SUSPEND: 468 case USB_EVENT_SUSPEND:
405#ifdef SLEEP_LED_ENABLE 469 usb_event_queue_enqueue(USB_EVENT_SUSPEND);
406 sleep_led_enable();
407#endif /* SLEEP_LED_ENABLE */
408 /* Falls into.*/ 470 /* Falls into.*/
409 case USB_EVENT_UNCONFIGURED: 471 case USB_EVENT_UNCONFIGURED:
410 /* Falls into.*/ 472 /* Falls into.*/
@@ -425,12 +487,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
425 qmkusbWakeupHookI(&drivers.array[i].driver); 487 qmkusbWakeupHookI(&drivers.array[i].driver);
426 chSysUnlockFromISR(); 488 chSysUnlockFromISR();
427 } 489 }
428 suspend_wakeup_init(); 490 usb_event_queue_enqueue(USB_EVENT_WAKEUP);
429#ifdef SLEEP_LED_ENABLE
430 sleep_led_disable();
431 // NOTE: converters may not accept this
432 led_set(host_keyboard_leds());
433#endif /* SLEEP_LED_ENABLE */
434 return; 491 return;
435 492
436 case USB_EVENT_STALLED: 493 case USB_EVENT_STALLED:
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index eaa08d8f7..fb33c8cd0 100644
--- a/tmk_core/protocol/chibios/usb_main.h
+++ b/tmk_core/protocol/chibios/usb_main.h
@@ -38,6 +38,17 @@ void init_usb_driver(USBDriver *usbp);
38void restart_usb_driver(USBDriver *usbp); 38void restart_usb_driver(USBDriver *usbp);
39 39
40/* --------------- 40/* ---------------
41 * USB Event queue
42 * ---------------
43 */
44
45/* Initialisation of the FIFO */
46void usb_event_queue_init(void);
47
48/* Task to dequeue and execute any handlers for the USB events on the main thread */
49void usb_event_queue_task(void);
50
51/* ---------------
41 * Keyboard header 52 * Keyboard header
42 * --------------- 53 * ---------------
43 */ 54 */