|
@@ -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
|
|
|
|
- sleep_led_enable();
|
|
|
|
-#endif /* SLEEP_LED_ENABLE */
|
|
|
|
|
|
+ usb_event_queue_enqueue(USB_EVENT_SUSPEND);
|
|
/* 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();
|
|
|
|
-#ifdef SLEEP_LED_ENABLE
|
|
|
|
- sleep_led_disable();
|
|
|
|
- // NOTE: converters may not accept this
|
|
|
|
- led_set(host_keyboard_leds());
|
|
|
|
-#endif /* SLEEP_LED_ENABLE */
|
|
|
|
|
|
+ usb_event_queue_enqueue(USB_EVENT_WAKEUP);
|
|
return;
|
|
return;
|
|
|
|
|
|
case USB_EVENT_STALLED:
|
|
case USB_EVENT_STALLED:
|