Merge upstream QMK Firmware at '0.12.52~1'

This commit is contained in:
Drashna Jael're
2021-06-29 12:23:03 -07:00
415 changed files with 18692 additions and 7301 deletions

View File

@@ -167,6 +167,7 @@ int main(void) {
keyboard_setup();
/* Init USB */
usb_event_queue_init();
init_usb_driver(&USB_DRIVER);
#ifdef MIDI_ENABLE
@@ -225,6 +226,8 @@ int main(void) {
/* Main loop */
while (true) {
usb_event_queue_task();
#if !defined(NO_USB_STARTUP_CHECK)
if (USB_DRIVER.state == USB_SUSPENDED) {
print("[s]");

View File

@@ -27,6 +27,7 @@
#include <ch.h>
#include <hal.h>
#include <string.h>
#include "usb_main.h"
@@ -50,6 +51,7 @@ extern keymap_config_t keymap_config;
#ifdef WEBUSB_ENABLE
# include "webusb.h"
#endif
#ifdef JOYSTICK_ENABLE
# include "joystick.h"
#endif
@@ -168,6 +170,7 @@ static const USBEndpointConfig shared_ep_config = {
};
#endif
#ifdef WEBUSB_ENABLE
/** Microsoft OS 2.0 Descriptor. This is used by Windows to select the USB driver for the device.
*
@@ -397,6 +400,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
* TODO: maybe disable some things when connection is lost? */
static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
@@ -431,9 +497,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
osalSysUnlockFromISR();
return;
case USB_EVENT_SUSPEND:
#ifdef SLEEP_LED_ENABLE
sleep_led_enable();
#endif /* SLEEP_LED_ENABLE */
usb_event_queue_enqueue(USB_EVENT_SUSPEND);
/* Falls into.*/
case USB_EVENT_UNCONFIGURED:
/* Falls into.*/
@@ -454,12 +518,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
qmkusbWakeupHookI(&drivers.array[i].driver);
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;
case USB_EVENT_STALLED:
@@ -575,7 +634,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
if (!keymap_config.nkro && keyboard_idle) {
#else /* NKRO_ENABLE */
if (keyboard_idle) {
#endif /* NKRO_ENABLE */
#endif /* NKRO_ENABLE */
/* arm the idle timer if boot protocol & idle */
osalSysLockFromISR();
chVTSetI(&keyboard_idle_timer, 4 * TIME_MS2I(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
@@ -867,7 +926,7 @@ void send_mouse(report_mouse_t *report) {
}
#else /* MOUSE_ENABLE */
void send_mouse(report_mouse_t *report) { (void)report; }
void send_mouse(report_mouse_t *report) { (void)report; }
#endif /* MOUSE_ENABLE */
/* ---------------------------------------------------------
@@ -923,9 +982,32 @@ void send_consumer(uint16_t data) {
#ifdef CONSOLE_ENABLE
int8_t sendchar(uint8_t c) {
// The previous implmentation had timeouts, but I think it's better to just slow down
// and make sure that everything is transferred, rather than dropping stuff
return chnWrite(&drivers.console_driver.driver, &c, 1);
static bool timed_out = false;
/* The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
*
* When a 5ms timeout write has timed out, hid_listen is most likely not running, or not
* listening to this keyboard, so we go into the timed_out state. In this state we assume
* that hid_listen is most likely not gonna be connected to us any time soon, so it would
* be wasteful to write follow-up characters with a 5ms timeout, it would all add up and
* unncecessarily slow down the firmware. However instead of just dropping the characters,
* we write them with a TIME_IMMEDIATE timeout, which is a zero timeout,
* and this will succeed only if hid_listen gets connected again. When a write with
* TIME_IMMEDIATE timeout succeeds, we know that hid_listen is listening to us again, and
* we can go back to the timed_out = false state, and following writes will be executed
* with a 5ms timeout. The reason we don't just send all characters with the TIME_IMMEDIATE
* timeout is that this could cause bytes to be lost even if hid_listen is running, if there
* is a lot of data being sent over the console.
*
* This logic will work correctly as long as hid_listen is able to receive at least 200
* bytes per second. On a heavily overloaded machine that's so overloaded that it's
* unusable, and constantly swapping, hid_listen might have trouble receiving 200 bytes per
* second, so some bytes might be lost on the console.
*/
const sysinterval_t timeout = timed_out ? TIME_IMMEDIATE : TIME_MS2I(5);
const size_t result = chnWriteTimeout(&drivers.console_driver.driver, &c, 1, timeout);
timed_out = (result == 0);
return result;
}
// Just a dummy function for now, this could be exposed as a weak function
@@ -946,15 +1028,8 @@ void console_task(void) {
} while (size > 0);
}
#else /* CONSOLE_ENABLE */
int8_t sendchar(uint8_t c) {
(void)c;
return 0;
}
#endif /* CONSOLE_ENABLE */
void _putchar(char character) { sendchar(character); }
#ifdef RAW_ENABLE
void raw_hid_send(uint8_t *data, uint8_t length) {
// TODO: implement variable size packet

View File

@@ -37,6 +37,17 @@ void init_usb_driver(USBDriver *usbp);
/* Restart the USB driver and bus */
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
* ---------------