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 /tmk_core | |
| parent | 0fa2e7c790c4b4fcb318479a4951bfd33fd3862f (diff) | |
| download | qmk_firmware-db11a2a1fd7a7ff9c458e8ec9e963a61a1192bf3.tar.gz qmk_firmware-db11a2a1fd7a7ff9c458e8ec9e963a61a1192bf3.zip | |
Decouple USB events from the USB interrupt handler. (#10437)
Diffstat (limited to 'tmk_core')
| -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 | */ |
