Decouple USB events from the USB interrupt handler. (#10437)
This commit is contained in:
parent
0fa2e7c790
commit
db11a2a1fd
3 changed files with 80 additions and 9 deletions
|
@ -163,6 +163,7 @@ int main(void) {
|
||||||
keyboard_setup();
|
keyboard_setup();
|
||||||
|
|
||||||
/* Init USB */
|
/* Init USB */
|
||||||
|
usb_event_queue_init();
|
||||||
init_usb_driver(&USB_DRIVER);
|
init_usb_driver(&USB_DRIVER);
|
||||||
|
|
||||||
#ifdef MIDI_ENABLE
|
#ifdef MIDI_ENABLE
|
||||||
|
@ -221,6 +222,8 @@ int main(void) {
|
||||||
|
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
while (true) {
|
while (true) {
|
||||||
|
usb_event_queue_task();
|
||||||
|
|
||||||
#if !defined(NO_USB_STARTUP_CHECK)
|
#if !defined(NO_USB_STARTUP_CHECK)
|
||||||
if (USB_DRIVER.state == USB_SUSPENDED) {
|
if (USB_DRIVER.state == USB_SUSPENDED) {
|
||||||
print("[s]");
|
print("[s]");
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <ch.h>
|
#include <ch.h>
|
||||||
#include <hal.h>
|
#include <hal.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "usb_main.h"
|
#include "usb_main.h"
|
||||||
|
|
||||||
|
@ -368,6 +369,69 @@ static usb_driver_configs_t drivers = {
|
||||||
* ---------------------------------------------------------
|
* ---------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define USB_EVENT_QUEUE_SIZE 16
|
||||||
|
usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
|
||||||
|
uint8_t event_queue_head;
|
||||||
|
uint8_t event_queue_tail;
|
||||||
|
|
||||||
|
void usb_event_queue_init(void) {
|
||||||
|
// Initialise the event queue
|
||||||
|
memset(&event_queue, 0, sizeof(event_queue));
|
||||||
|
event_queue_head = 0;
|
||||||
|
event_queue_tail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool usb_event_queue_enqueue(usbevent_t event) {
|
||||||
|
uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
|
||||||
|
if (next == event_queue_tail) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
event_queue[event_queue_head] = event;
|
||||||
|
event_queue_head = next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool usb_event_queue_dequeue(usbevent_t *event) {
|
||||||
|
if (event_queue_head == event_queue_tail) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*event = event_queue[event_queue_tail];
|
||||||
|
event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void usb_event_suspend_handler(void) {
|
||||||
|
#ifdef SLEEP_LED_ENABLE
|
||||||
|
sleep_led_enable();
|
||||||
|
#endif /* SLEEP_LED_ENABLE */
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void usb_event_wakeup_handler(void) {
|
||||||
|
suspend_wakeup_init();
|
||||||
|
#ifdef SLEEP_LED_ENABLE
|
||||||
|
sleep_led_disable();
|
||||||
|
// NOTE: converters may not accept this
|
||||||
|
led_set(host_keyboard_leds());
|
||||||
|
#endif /* SLEEP_LED_ENABLE */
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_event_queue_task(void) {
|
||||||
|
usbevent_t event;
|
||||||
|
while (usb_event_queue_dequeue(&event)) {
|
||||||
|
switch (event) {
|
||||||
|
case USB_EVENT_SUSPEND:
|
||||||
|
usb_event_suspend_handler();
|
||||||
|
break;
|
||||||
|
case USB_EVENT_WAKEUP:
|
||||||
|
usb_event_wakeup_handler();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Nothing to do, we don't handle it.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handles the USB driver global events
|
/* Handles the USB driver global events
|
||||||
* TODO: maybe disable some things when connection is lost? */
|
* TODO: maybe disable some things when connection is lost? */
|
||||||
static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||||
|
@ -402,9 +466,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
return;
|
return;
|
||||||
case USB_EVENT_SUSPEND:
|
case USB_EVENT_SUSPEND:
|
||||||
#ifdef SLEEP_LED_ENABLE
|
usb_event_queue_enqueue(USB_EVENT_SUSPEND);
|
||||||
sleep_led_enable();
|
|
||||||
#endif /* SLEEP_LED_ENABLE */
|
|
||||||
/* Falls into.*/
|
/* Falls into.*/
|
||||||
case USB_EVENT_UNCONFIGURED:
|
case USB_EVENT_UNCONFIGURED:
|
||||||
/* Falls into.*/
|
/* Falls into.*/
|
||||||
|
@ -425,12 +487,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||||
qmkusbWakeupHookI(&drivers.array[i].driver);
|
qmkusbWakeupHookI(&drivers.array[i].driver);
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
}
|
}
|
||||||
suspend_wakeup_init();
|
usb_event_queue_enqueue(USB_EVENT_WAKEUP);
|
||||||
#ifdef SLEEP_LED_ENABLE
|
|
||||||
sleep_led_disable();
|
|
||||||
// NOTE: converters may not accept this
|
|
||||||
led_set(host_keyboard_leds());
|
|
||||||
#endif /* SLEEP_LED_ENABLE */
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case USB_EVENT_STALLED:
|
case USB_EVENT_STALLED:
|
||||||
|
|
|
@ -37,6 +37,17 @@ void init_usb_driver(USBDriver *usbp);
|
||||||
/* Restart the USB driver and bus */
|
/* Restart the USB driver and bus */
|
||||||
void restart_usb_driver(USBDriver *usbp);
|
void restart_usb_driver(USBDriver *usbp);
|
||||||
|
|
||||||
|
/* ---------------
|
||||||
|
* USB Event queue
|
||||||
|
* ---------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Initialisation of the FIFO */
|
||||||
|
void usb_event_queue_init(void);
|
||||||
|
|
||||||
|
/* Task to dequeue and execute any handlers for the USB events on the main thread */
|
||||||
|
void usb_event_queue_task(void);
|
||||||
|
|
||||||
/* ---------------
|
/* ---------------
|
||||||
* Keyboard header
|
* Keyboard header
|
||||||
* ---------------
|
* ---------------
|
||||||
|
|
Loading…
Reference in a new issue