diff options
Diffstat (limited to 'quantum/os_detection.c')
-rw-r--r-- | quantum/os_detection.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/quantum/os_detection.c b/quantum/os_detection.c index 96b026e247..0dd048a8c4 100644 --- a/quantum/os_detection.c +++ b/quantum/os_detection.c @@ -34,7 +34,7 @@ static uint16_t usb_setups[STORED_USB_SETUPS]; #endif #ifndef OS_DETECTION_DEBOUNCE -# define OS_DETECTION_DEBOUNCE 200 +# define OS_DETECTION_DEBOUNCE 250 #endif // 2s should always be more than enough (otherwise, you may have other issues) @@ -59,25 +59,40 @@ struct setups_data_t setups_data = { }; static volatile os_variant_t detected_os = OS_UNSURE; -static os_variant_t reported_os = OS_UNSURE; +static volatile os_variant_t reported_os = OS_UNSURE; // we need to be able to report OS_UNSURE if that is the stable result of the guesses -static bool first_report = true; +static volatile bool first_report = true; // to react on USB state changes -static volatile enum usb_device_state current_usb_device_state = USB_DEVICE_STATE_INIT; -static enum usb_device_state reported_usb_device_state = USB_DEVICE_STATE_INIT; +static volatile struct usb_device_state current_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT}; +static volatile struct usb_device_state maxprev_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT}; // the OS detection might be unstable for a while, "debounce" it static volatile bool debouncing = false; -static volatile fast_timer_t last_time; +static volatile fast_timer_t last_time = 0; void os_detection_task(void) { - if (current_usb_device_state == USB_DEVICE_STATE_CONFIGURED) { +#ifdef OS_DETECTION_KEYBOARD_RESET + // resetting the keyboard on the USB device state change callback results in instability, so delegate that to this task + // only take action if it's been stable at least once, to avoid issues with some KVMs + if (current_usb_device_state.configure_state <= USB_DEVICE_STATE_INIT && maxprev_usb_device_state.configure_state >= USB_DEVICE_STATE_CONFIGURED) { + if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) { + soft_reset_keyboard(); + } + return; + } +#endif +#ifdef OS_DETECTION_SINGLE_REPORT + if (!first_report) { + return; + } +#endif + if (current_usb_device_state.configure_state == USB_DEVICE_STATE_CONFIGURED) { // debouncing goes for both the detected OS as well as the USB state if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) { - debouncing = false; - reported_usb_device_state = current_usb_device_state; + debouncing = false; + last_time = 0; if (detected_os != reported_os || first_report) { first_report = false; reported_os = detected_os; @@ -85,13 +100,6 @@ void os_detection_task(void) { } } } -#ifdef OS_DETECTION_KEYBOARD_RESET - // resetting the keyboard on the USB device state change callback results in instability, so delegate that to this task - // only take action if it's been stable at least once, to avoid issues with some KVMs - else if (current_usb_device_state == USB_DEVICE_STATE_INIT && reported_usb_device_state != USB_DEVICE_STATE_INIT) { - soft_reset_keyboard(); - } -#endif } __attribute__((weak)) bool process_detected_host_os_kb(os_variant_t detected_os) { @@ -155,16 +163,20 @@ os_variant_t detected_host_os(void) { void erase_wlength_data(void) { memset(&setups_data, 0, sizeof(setups_data)); - detected_os = OS_UNSURE; - reported_os = OS_UNSURE; - current_usb_device_state = USB_DEVICE_STATE_INIT; - reported_usb_device_state = USB_DEVICE_STATE_INIT; - debouncing = false; - first_report = true; + detected_os = OS_UNSURE; + reported_os = OS_UNSURE; + current_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT; + maxprev_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT; + debouncing = false; + last_time = 0; + first_report = true; } -void os_detection_notify_usb_device_state_change(enum usb_device_state usb_device_state) { +void os_detection_notify_usb_device_state_change(struct usb_device_state usb_device_state) { // treat this like any other source of instability + if (maxprev_usb_device_state.configure_state < current_usb_device_state.configure_state) { + maxprev_usb_device_state.configure_state = current_usb_device_state.configure_state; + } current_usb_device_state = usb_device_state; last_time = timer_read_fast(); debouncing = true; |