diff options
author | Nick Brassel <nick@tzarc.org> | 2021-02-01 08:19:00 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-01 08:19:00 +1100 |
commit | db11a2a1fd7a7ff9c458e8ec9e963a61a1192bf3 (patch) | |
tree | 982396d6fcaeb2c6aa3a8fa5580ad9c0bbcaf7fa | |
parent | 0fa2e7c790c4b4fcb318479a4951bfd33fd3862f (diff) | |
download | qmk_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.c | 3 | ||||
-rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 75 | ||||
-rw-r--r-- | tmk_core/protocol/chibios/usb_main.h | 11 |
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 | ||
373 | usbevent_t event_queue[USB_EVENT_QUEUE_SIZE]; | ||
374 | uint8_t event_queue_head; | ||
375 | uint8_t event_queue_tail; | ||
376 | |||
377 | void 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 | |||
384 | static 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 | |||
394 | static 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 | |||
403 | static inline void usb_event_suspend_handler(void) { | ||
404 | #ifdef SLEEP_LED_ENABLE | ||
405 | sleep_led_enable(); | ||
406 | #endif /* SLEEP_LED_ENABLE */ | ||
407 | } | ||
408 | |||
409 | static 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 | |||
418 | void 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? */ |
373 | static void usb_event_cb(USBDriver *usbp, usbevent_t event) { | 437 | static 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); | |||
38 | void restart_usb_driver(USBDriver *usbp); | 38 | void restart_usb_driver(USBDriver *usbp); |
39 | 39 | ||
40 | /* --------------- | 40 | /* --------------- |
41 | * USB Event queue | ||
42 | * --------------- | ||
43 | */ | ||
44 | |||
45 | /* Initialisation of the FIFO */ | ||
46 | void usb_event_queue_init(void); | ||
47 | |||
48 | /* Task to dequeue and execute any handlers for the USB events on the main thread */ | ||
49 | void usb_event_queue_task(void); | ||
50 | |||
51 | /* --------------- | ||
41 | * Keyboard header | 52 | * Keyboard header |
42 | * --------------- | 53 | * --------------- |
43 | */ | 54 | */ |