Browse Source

Merge remote-tracking branch 'origin/develop' into xap

QMK Bot 1 year ago
parent
commit
595e339f57

+ 1 - 1
drivers/haptic/solenoid.c

@@ -158,7 +158,7 @@ void solenoid_setup(void) {
 #endif
         gpio_write_pin(solenoid_pads[i], !solenoid_active_state[i]);
         gpio_set_pin_output(solenoid_pads[i]);
-        if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED)) {
+        if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED)) {
             solenoid_fire(i);
         }
     }

+ 3 - 0
keyboards/kikoslab/ellora65/keyboard.json

@@ -8,6 +8,9 @@
         "pid": "0xE88F",
         "device_version": "0.0.1"
     },
+    "build": {
+        "lto": true
+    },
     "features": {
         "bootmagic": true,
         "command": false,

+ 3 - 0
keyboards/rgbkb/pan/info.json

@@ -8,6 +8,9 @@
         "pid": "0x8C9C",
         "device_version": "0.0.2"
     },
+    "build": {
+        "lto": true
+    },
     "features": {
         "bootmagic": true,
         "encoder": true,

+ 0 - 1
keyboards/takashicompany/minidivide/keyboard.json

@@ -30,7 +30,6 @@
             "knight": true,
             "rainbow_mood": true,
             "rainbow_swirl": true,
-            "rgb_test": true,
             "snake": true,
             "static_gradient": true,
             "twinkle": true

+ 1 - 2
keyboards/work_louder/loop/info.json

@@ -51,8 +51,7 @@
             "pixel_rain": true,
             "pixel_flow": true,
             "pixel_fractal": true,
-            "typing_heatmap": true,
-            "digital_rain": true
+            "typing_heatmap": true
         },
         "driver": "ws2812",
         "max_brightness": 120,

+ 2 - 1
quantum/action_util.c

@@ -21,6 +21,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "action_layer.h"
 #include "timer.h"
 #include "keycode_config.h"
+#include "usb_device_state.h"
 #include <string.h>
 
 extern keymap_config_t keymap_config;
@@ -318,7 +319,7 @@ void send_nkro_report(void) {
  */
 void send_keyboard_report(void) {
 #ifdef NKRO_ENABLE
-    if (keyboard_protocol && keymap_config.nkro) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
         send_nkro_report();
     } else {
         send_6kro_report();

+ 3 - 2
quantum/command.c

@@ -32,6 +32,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "led.h"
 #include "command.h"
 #include "quantum.h"
+#include "usb_device_state.h"
 #include "version.h"
 
 #ifdef BACKLIGHT_ENABLE
@@ -230,8 +231,8 @@ static void print_status(void) {
         "timer_read32(): %08lX\n"
 
         , host_keyboard_leds()
-        , keyboard_protocol
-        , keyboard_idle
+        , usb_device_state_get_protocol()
+        , usb_device_state_get_idle_rate()
 #ifdef NKRO_ENABLE
         , keymap_config.nkro
 #endif

+ 1 - 1
quantum/haptic.c

@@ -36,7 +36,7 @@ extern uint8_t split_haptic_play;
 haptic_config_t haptic_config;
 
 static void update_haptic_enable_gpios(void) {
-    if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) {
+    if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
 #if defined(HAPTIC_ENABLE_PIN)
         HAPTIC_ENABLE_PIN_WRITE_ACTIVE();
 #endif

+ 13 - 13
quantum/os_detection.c

@@ -65,8 +65,8 @@ static volatile os_variant_t reported_os = OS_UNSURE;
 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_NO_INIT;
-static volatile enum usb_device_state maxprev_usb_device_state = USB_DEVICE_STATE_NO_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;
@@ -88,7 +88,7 @@ void os_detection_task(void) {
         return;
     }
 #endif
-    if (current_usb_device_state == USB_DEVICE_STATE_CONFIGURED) {
+    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;
@@ -163,19 +163,19 @@ 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_NO_INIT;
-    maxprev_usb_device_state = USB_DEVICE_STATE_NO_INIT;
-    debouncing               = false;
-    last_time                = 0;
-    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 < current_usb_device_state) {
-        maxprev_usb_device_state = current_usb_device_state;
+    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();

+ 1 - 1
quantum/os_detection.h

@@ -31,7 +31,7 @@ typedef enum {
 void         process_wlength(const uint16_t w_length);
 os_variant_t detected_host_os(void);
 void         erase_wlength_data(void);
-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);
 
 void os_detection_task(void);
 

+ 8 - 6
quantum/os_detection/tests/os_detection.cpp

@@ -253,9 +253,11 @@ TEST_F(OsDetectionTest, TestDoNotReportIfUsbUnstable) {
     EXPECT_EQ(detected_host_os(), OS_LINUX);
 }
 
+static struct usb_device_state usb_device_state_configured = {.configure_state = USB_DEVICE_STATE_CONFIGURED};
+
 TEST_F(OsDetectionTest, TestReportAfterDebounce) {
     EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX);
-    os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+    os_detection_notify_usb_device_state_change(usb_device_state_configured);
     os_detection_task();
     assert_not_reported();
 
@@ -291,7 +293,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounce) {
 
 TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
     EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
-    os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+    os_detection_notify_usb_device_state_change(usb_device_state_configured);
     os_detection_task();
     assert_not_reported();
 
@@ -318,7 +320,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
 
 TEST_F(OsDetectionTest, TestReportUnsure) {
     EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
-    os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+    os_detection_notify_usb_device_state_change(usb_device_state_configured);
     os_detection_task();
     assert_not_reported();
 
@@ -345,7 +347,7 @@ TEST_F(OsDetectionTest, TestReportUnsure) {
 
 TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
     EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
-    os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+    os_detection_notify_usb_device_state_change(usb_device_state_configured);
     os_detection_task();
     assert_not_reported();
 
@@ -356,7 +358,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
 
     // at this stage, the final result has not been reached yet
     EXPECT_EQ(check_sequence({0xFF}), OS_LINUX);
-    os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+    os_detection_notify_usb_device_state_change(usb_device_state_configured);
     advance_time(OS_DETECTION_DEBOUNCE - 1);
     os_detection_task();
     assert_not_reported();
@@ -365,7 +367,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
 
     // the remainder is processed
     EXPECT_EQ(check_sequence({0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
-    os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+    os_detection_notify_usb_device_state_change(usb_device_state_configured);
     advance_time(OS_DETECTION_DEBOUNCE - 1);
     os_detection_task();
     assert_not_reported();

+ 1 - 1
quantum/process_keycode/process_haptic.c

@@ -129,7 +129,7 @@ bool process_haptic(uint16_t keycode, keyrecord_t *record) {
         }
     }
 
-    if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) {
+    if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
         if (record->event.pressed) {
             // keypress
             if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) {

+ 5 - 6
tmk_core/protocol/chibios/chibios.c

@@ -62,14 +62,13 @@
  */
 
 /* declarations */
-uint8_t keyboard_leds(void);
-void    send_keyboard(report_keyboard_t *report);
-void    send_nkro(report_nkro_t *report);
-void    send_mouse(report_mouse_t *report);
-void    send_extra(report_extra_t *report);
+void send_keyboard(report_keyboard_t *report);
+void send_nkro(report_nkro_t *report);
+void send_mouse(report_mouse_t *report);
+void send_extra(report_extra_t *report);
 
 /* host struct */
-host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
+host_driver_t chibios_driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra};
 
 #ifdef VIRTSER_ENABLE
 void virtser_task(void);

+ 9 - 15
tmk_core/protocol/chibios/usb_main.c

@@ -58,10 +58,6 @@ extern keymap_config_t keymap_config;
 extern usb_endpoint_in_t  usb_endpoints_in[USB_ENDPOINT_IN_COUNT];
 extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT];
 
-uint8_t _Alignas(2) keyboard_idle     = 0;
-uint8_t _Alignas(2) keyboard_protocol = 1;
-uint8_t keyboard_led_state            = 0;
-
 static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size);
 static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded);
 static bool __attribute__((__unused__)) receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size);
@@ -172,6 +168,7 @@ void usb_event_queue_task(void) {
                 break;
             case USB_EVENT_RESET:
                 usb_device_state_set_reset();
+                usb_device_state_set_protocol(USB_PROTOCOL_REPORT);
                 break;
             default:
                 // Nothing to do, we don't handle it.
@@ -254,10 +251,10 @@ static void set_led_transfer_cb(USBDriver *usbp) {
     if (setup->wLength == 2) {
         uint8_t report_id = set_report_buf[0];
         if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) {
-            keyboard_led_state = set_report_buf[1];
+            usb_device_state_set_leds(set_report_buf[1]);
         }
     } else {
-        keyboard_led_state = set_report_buf[0];
+        usb_device_state_set_leds(set_report_buf[0]);
     }
 }
 
@@ -273,7 +270,9 @@ static bool usb_requests_hook_cb(USBDriver *usbp) {
                         return usb_get_report_cb(usbp);
                     case HID_REQ_GetProtocol:
                         if (setup->wIndex == KEYBOARD_INTERFACE) {
-                            usbSetupTransfer(usbp, &keyboard_protocol, sizeof(uint8_t), NULL);
+                            static uint8_t keyboard_protocol;
+                            keyboard_protocol = usb_device_state_get_protocol();
+                            usbSetupTransfer(usbp, &keyboard_protocol, sizeof(keyboard_protocol), NULL);
                             return true;
                         }
                         break;
@@ -296,12 +295,12 @@ static bool usb_requests_hook_cb(USBDriver *usbp) {
                         break;
                     case HID_REQ_SetProtocol:
                         if (setup->wIndex == KEYBOARD_INTERFACE) {
-                            keyboard_protocol = setup->wValue.word;
+                            usb_device_state_set_protocol(setup->wValue.lbyte);
                         }
                         usbSetupTransfer(usbp, NULL, 0, NULL);
                         return true;
                     case HID_REQ_SetIdle:
-                        keyboard_idle = setup->wValue.hbyte;
+                        usb_device_state_set_idle_rate(setup->wValue.hbyte);
                         return usb_set_idle_cb(usbp);
                 }
                 break;
@@ -400,11 +399,6 @@ __attribute__((weak)) void restart_usb_driver(USBDriver *usbp) {
  * ---------------------------------------------------------
  */
 
-/* LED status */
-uint8_t keyboard_leds(void) {
-    return keyboard_led_state;
-}
-
 /**
  * @brief Send a report to the host, the report is enqueued into an output
  * queue and send once the USB endpoint becomes empty.
@@ -462,7 +456,7 @@ static bool receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t
 
 void send_keyboard(report_keyboard_t *report) {
     /* If we're in Boot Protocol, don't send any report ID or other funky fields */
-    if (!keyboard_protocol) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
         send_report(USB_ENDPOINT_IN_KEYBOARD, &report->mods, 8);
     } else {
         send_report(USB_ENDPOINT_IN_KEYBOARD, report, KEYBOARD_REPORT_SIZE);

+ 0 - 3
tmk_core/protocol/host.h

@@ -27,9 +27,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 extern "C" {
 #endif
 
-extern uint8_t keyboard_idle;
-extern uint8_t keyboard_protocol;
-
 /* host driver */
 void           host_set_driver(host_driver_t *driver);
 host_driver_t *host_get_driver(void);

+ 13 - 25
tmk_core/protocol/lufa/lufa.c

@@ -76,20 +76,14 @@
 #    define USB_WAIT_FOR_ENUMERATION
 #endif
 
-uint8_t keyboard_idle = 0;
-/* 0: Boot Protocol, 1: Report Protocol(default) */
-uint8_t        keyboard_protocol  = 1;
-static uint8_t keyboard_led_state = 0;
-
 static report_keyboard_t keyboard_report_sent;
 
 /* Host driver */
-static uint8_t keyboard_leds(void);
-static void    send_keyboard(report_keyboard_t *report);
-static void    send_nkro(report_nkro_t *report);
-static void    send_mouse(report_mouse_t *report);
-static void    send_extra(report_extra_t *report);
-host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
+static void   send_keyboard(report_keyboard_t *report);
+static void   send_nkro(report_nkro_t *report);
+static void   send_mouse(report_mouse_t *report);
+static void   send_extra(report_extra_t *report);
+host_driver_t lufa_driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra};
 
 void send_report(uint8_t endpoint, void *report, size_t size) {
     uint8_t timeout = 255;
@@ -374,6 +368,7 @@ void EVENT_USB_Device_Disconnect(void) {
 void EVENT_USB_Device_Reset(void) {
     print("[R]");
     usb_device_state_set_reset();
+    usb_device_state_set_protocol(USB_PROTOCOL_REPORT);
 }
 
 /** \brief Event USB Device Connect
@@ -562,10 +557,10 @@ void EVENT_USB_Device_ControlRequest(void) {
                             uint8_t report_id = Endpoint_Read_8();
 
                             if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
-                                keyboard_led_state = Endpoint_Read_8();
+                                usb_device_state_set_leds(Endpoint_Read_8());
                             }
                         } else {
-                            keyboard_led_state = Endpoint_Read_8();
+                            usb_device_state_set_leds(Endpoint_Read_8());
                         }
 
                         Endpoint_ClearOUT();
@@ -582,7 +577,7 @@ void EVENT_USB_Device_ControlRequest(void) {
                     Endpoint_ClearSETUP();
                     while (!(Endpoint_IsINReady()))
                         ;
-                    Endpoint_Write_8(keyboard_protocol);
+                    Endpoint_Write_8(usb_device_state_get_protocol());
                     Endpoint_ClearIN();
                     Endpoint_ClearStatusStage();
                 }
@@ -595,7 +590,7 @@ void EVENT_USB_Device_ControlRequest(void) {
                     Endpoint_ClearSETUP();
                     Endpoint_ClearStatusStage();
 
-                    keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
+                    usb_device_state_set_protocol(USB_ControlRequest.wValue & 0xFF);
                     clear_keyboard();
                 }
             }
@@ -606,7 +601,7 @@ void EVENT_USB_Device_ControlRequest(void) {
                 Endpoint_ClearSETUP();
                 Endpoint_ClearStatusStage();
 
-                keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
+                usb_device_state_set_idle_rate(USB_ControlRequest.wValue >> 8);
             }
 
             break;
@@ -615,7 +610,7 @@ void EVENT_USB_Device_ControlRequest(void) {
                 Endpoint_ClearSETUP();
                 while (!(Endpoint_IsINReady()))
                     ;
-                Endpoint_Write_8(keyboard_idle);
+                Endpoint_Write_8(usb_device_state_get_idle_rate());
                 Endpoint_ClearIN();
                 Endpoint_ClearStatusStage();
             }
@@ -631,13 +626,6 @@ void EVENT_USB_Device_ControlRequest(void) {
 /*******************************************************************************
  * Host driver
  ******************************************************************************/
-/** \brief Keyboard LEDs
- *
- * FIXME: Needs doc
- */
-static uint8_t keyboard_leds(void) {
-    return keyboard_led_state;
-}
 
 /** \brief Send Keyboard
  *
@@ -645,7 +633,7 @@ static uint8_t keyboard_leds(void) {
  */
 static void send_keyboard(report_keyboard_t *report) {
     /* If we're in Boot Protocol, don't send any report ID or other funky fields */
-    if (!keyboard_protocol) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
         send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
     } else {
         send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);

+ 7 - 6
tmk_core/protocol/report.c

@@ -19,6 +19,7 @@
 #include "host.h"
 #include "keycode_config.h"
 #include "debug.h"
+#include "usb_device_state.h"
 #include "util.h"
 #include <string.h>
 
@@ -31,7 +32,7 @@ uint8_t has_anykey(void) {
     uint8_t* p   = keyboard_report->keys;
     uint8_t  lp  = sizeof(keyboard_report->keys);
 #ifdef NKRO_ENABLE
-    if (keyboard_protocol && keymap_config.nkro) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
         p  = nkro_report->bits;
         lp = sizeof(nkro_report->bits);
     }
@@ -48,7 +49,7 @@ uint8_t has_anykey(void) {
  */
 uint8_t get_first_key(void) {
 #ifdef NKRO_ENABLE
-    if (keyboard_protocol && keymap_config.nkro) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
         uint8_t i = 0;
         for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
             ;
@@ -68,7 +69,7 @@ bool is_key_pressed(uint8_t key) {
         return false;
     }
 #ifdef NKRO_ENABLE
-    if (keyboard_protocol && keymap_config.nkro) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
         if ((key >> 3) < NKRO_REPORT_BITS) {
             return nkro_report->bits[key >> 3] & 1 << (key & 7);
         } else {
@@ -150,7 +151,7 @@ void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
  */
 void add_key_to_report(uint8_t key) {
 #ifdef NKRO_ENABLE
-    if (keyboard_protocol && keymap_config.nkro) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
         add_key_bit(nkro_report, key);
         return;
     }
@@ -164,7 +165,7 @@ void add_key_to_report(uint8_t key) {
  */
 void del_key_from_report(uint8_t key) {
 #ifdef NKRO_ENABLE
-    if (keyboard_protocol && keymap_config.nkro) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
         del_key_bit(nkro_report, key);
         return;
     }
@@ -179,7 +180,7 @@ void del_key_from_report(uint8_t key) {
 void clear_keys_from_report(void) {
     // not clear mods
 #ifdef NKRO_ENABLE
-    if (keyboard_protocol && keymap_config.nkro) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
         memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
         return;
     }

+ 43 - 12
tmk_core/protocol/usb_device_state.c

@@ -24,15 +24,15 @@
 #    include "os_detection.h"
 #endif
 
-enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT;
+static struct usb_device_state usb_device_state = {.idle_rate = 0, .leds = 0, .protocol = USB_PROTOCOL_REPORT, .configure_state = USB_DEVICE_STATE_NO_INIT};
 
-__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) {
+__attribute__((weak)) void notify_usb_device_state_change_kb(struct usb_device_state usb_device_state) {
     notify_usb_device_state_change_user(usb_device_state);
 }
 
-__attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {}
+__attribute__((weak)) void notify_usb_device_state_change_user(struct usb_device_state usb_device_state) {}
 
-static void notify_usb_device_state_change(enum usb_device_state usb_device_state) {
+static void notify_usb_device_state_change(struct usb_device_state usb_device_state) {
 #if defined(HAPTIC_ENABLE) && HAPTIC_OFF_IN_LOW_POWER
     haptic_notify_usb_device_state_change();
 #endif
@@ -44,27 +44,58 @@ static void notify_usb_device_state_change(enum usb_device_state usb_device_stat
 #endif
 }
 
-void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) {
-    usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
+void usb_device_state_set_configuration(bool is_configured, uint8_t configuration_number) {
+    usb_device_state.configure_state = is_configured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
     notify_usb_device_state_change(usb_device_state);
 }
 
-void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) {
-    usb_device_state = USB_DEVICE_STATE_SUSPEND;
+void usb_device_state_set_suspend(bool is_configured, uint8_t configuration_number) {
+    usb_device_state.configure_state = USB_DEVICE_STATE_SUSPEND;
     notify_usb_device_state_change(usb_device_state);
 }
 
-void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) {
-    usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
+void usb_device_state_set_resume(bool is_configured, uint8_t configuration_number) {
+    usb_device_state.configure_state = is_configured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
     notify_usb_device_state_change(usb_device_state);
 }
 
 void usb_device_state_set_reset(void) {
-    usb_device_state = USB_DEVICE_STATE_INIT;
+    usb_device_state.configure_state = USB_DEVICE_STATE_INIT;
     notify_usb_device_state_change(usb_device_state);
 }
 
 void usb_device_state_init(void) {
-    usb_device_state = USB_DEVICE_STATE_INIT;
+    usb_device_state.configure_state = USB_DEVICE_STATE_INIT;
     notify_usb_device_state_change(usb_device_state);
 }
+
+inline usb_configure_state_t usb_device_state_get_configure_state(void) {
+    return usb_device_state.configure_state;
+}
+
+void usb_device_state_set_protocol(usb_hid_protocol_t protocol) {
+    usb_device_state.protocol = protocol == USB_PROTOCOL_BOOT ? USB_PROTOCOL_BOOT : USB_PROTOCOL_REPORT;
+    notify_usb_device_state_change(usb_device_state);
+}
+
+inline usb_hid_protocol_t usb_device_state_get_protocol() {
+    return usb_device_state.protocol;
+}
+
+void usb_device_state_set_leds(uint8_t leds) {
+    usb_device_state.leds = leds;
+    notify_usb_device_state_change(usb_device_state);
+}
+
+inline uint8_t usb_device_state_get_leds(void) {
+    return usb_device_state.leds;
+}
+
+void usb_device_state_set_idle_rate(uint8_t idle_rate) {
+    usb_device_state.idle_rate = idle_rate;
+    notify_usb_device_state_change(usb_device_state);
+}
+
+inline uint8_t usb_device_state_get_idle_rate(void) {
+    return usb_device_state.idle_rate;
+}

+ 31 - 10
tmk_core/protocol/usb_device_state.h

@@ -20,20 +20,41 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber);
-void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber);
-void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber);
-void usb_device_state_set_reset(void);
-void usb_device_state_init(void);
-
-enum usb_device_state {
+typedef enum {
     USB_DEVICE_STATE_NO_INIT    = 0, // We're in this state before calling usb_device_state_init()
     USB_DEVICE_STATE_INIT       = 1, // Can consume up to 100mA
     USB_DEVICE_STATE_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA
     USB_DEVICE_STATE_SUSPEND    = 3  // Can consume only suspend current
+} usb_configure_state_t;
+
+typedef enum {
+    USB_PROTOCOL_BOOT   = 0,
+    USB_PROTOCOL_REPORT = 1,
+} usb_hid_protocol_t;
+
+// note: we can't typedef this struct to usb_device_state_t because it would
+// conflict with the previous definition in:
+// lib/chibios-contrib/ext/nxp-middleware-usb/device/usb_device.h
+struct usb_device_state {
+    uint8_t               idle_rate;
+    uint8_t               leds;
+    usb_hid_protocol_t    protocol;
+    usb_configure_state_t configure_state;
 };
 
-extern enum usb_device_state usb_device_state;
+void                  usb_device_state_set_configuration(bool is_configured, uint8_t configuration_number);
+void                  usb_device_state_set_suspend(bool is_configured, uint8_t configuration_number);
+void                  usb_device_state_set_resume(bool is_configured, uint8_t configuration_number);
+void                  usb_device_state_set_reset(void);
+void                  usb_device_state_init(void);
+usb_configure_state_t usb_device_state_get_configure_state(void);
+void                  usb_device_state_set_protocol(usb_hid_protocol_t protocol);
+usb_hid_protocol_t    usb_device_state_get_protocol(void);
+void                  usb_device_state_set_leds(uint8_t leds);
+uint8_t               usb_device_state_get_leds(void);
+void                  usb_device_state_set_idle_rate(uint8_t idle_rate);
+uint8_t               usb_device_state_get_idle_rate(void);
+void                  usb_device_state_reset_hid_state(void);
 
-void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state);
-void notify_usb_device_state_change_user(enum usb_device_state usb_device_state);
+void notify_usb_device_state_change_kb(struct usb_device_state usb_device_state);
+void notify_usb_device_state_change_user(struct usb_device_state usb_device_state);

+ 20 - 24
tmk_core/protocol/vusb/vusb.c

@@ -30,6 +30,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "debug.h"
 #include "wait.h"
 #include "usb_descriptor_common.h"
+#include "usb_device_state.h"
 
 #ifdef RAW_ENABLE
 #    include "raw_hid.h"
@@ -94,10 +95,6 @@ _Static_assert(TOTAL_INTERFACES <= MAX_INTERFACES, "There are not enough availab
 #    error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
 #endif
 
-static uint8_t keyboard_led_state = 0;
-uint8_t        keyboard_idle      = 0;
-uint8_t        keyboard_protocol  = 1;
-
 static report_keyboard_t keyboard_report_sent;
 
 static void send_report_fragment(uint8_t endpoint, void *data, size_t size) {
@@ -295,24 +292,19 @@ void console_task(void) {
 /*------------------------------------------------------------------*
  * Host driver
  *------------------------------------------------------------------*/
-static uint8_t keyboard_leds(void);
-static void    send_keyboard(report_keyboard_t *report);
-static void    send_nkro(report_nkro_t *report);
-static void    send_mouse(report_mouse_t *report);
-static void    send_extra(report_extra_t *report);
+static void send_keyboard(report_keyboard_t *report);
+static void send_nkro(report_nkro_t *report);
+static void send_mouse(report_mouse_t *report);
+static void send_extra(report_extra_t *report);
 
-static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
+static host_driver_t driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra};
 
 host_driver_t *vusb_driver(void) {
     return &driver;
 }
 
-static uint8_t keyboard_leds(void) {
-    return keyboard_led_state;
-}
-
 static void send_keyboard(report_keyboard_t *report) {
-    if (!keyboard_protocol) {
+    if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
         send_report(1, &report->mods, 8);
     } else {
         send_report(1, report, sizeof(report_keyboard_t));
@@ -387,11 +379,15 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
                 break;
             case USBRQ_HID_GET_IDLE:
                 dprint("GET_IDLE:");
-                usbMsgPtr = (usbMsgPtr_t)&keyboard_idle;
+                static uint8_t keyboard_idle;
+                keyboard_idle = usb_device_state_get_idle_rate();
+                usbMsgPtr     = (usbMsgPtr_t)&keyboard_idle;
                 return 1;
             case USBRQ_HID_GET_PROTOCOL:
                 dprint("GET_PROTOCOL:");
-                usbMsgPtr = (usbMsgPtr_t)&keyboard_protocol;
+                static uint8_t keyboard_protocol;
+                keyboard_protocol = usb_device_state_get_protocol();
+                usbMsgPtr         = (usbMsgPtr_t)&keyboard_protocol;
                 return 1;
             case USBRQ_HID_SET_REPORT:
                 dprint("SET_REPORT:");
@@ -403,13 +399,13 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
                 }
                 return USB_NO_MSG; // to get data in usbFunctionWrite
             case USBRQ_HID_SET_IDLE:
-                keyboard_idle = (rq->wValue.word & 0xFF00) >> 8;
-                dprintf("SET_IDLE: %02X", keyboard_idle);
+                usb_device_state_set_idle_rate(rq->wValue.word >> 8);
+                dprintf("SET_IDLE: %02X", usb_device_state_get_idle_rate());
                 break;
             case USBRQ_HID_SET_PROTOCOL:
                 if (rq->wIndex.word == KEYBOARD_INTERFACE) {
-                    keyboard_protocol = rq->wValue.word & 0xFF;
-                    dprintf("SET_PROTOCOL: %02X", keyboard_protocol);
+                    usb_device_state_set_protocol(rq->wValue.word & 0xFF);
+                    dprintf("SET_PROTOCOL: %02X", usb_device_state_get_protocol());
                 }
                 break;
             default:
@@ -430,9 +426,9 @@ uchar usbFunctionWrite(uchar *data, uchar len) {
     }
     switch (last_req.kind) {
         case SET_LED:
-            dprintf("SET_LED: %02X\n", data[0]);
-            keyboard_led_state = data[0];
-            last_req.len       = 0;
+            usb_device_state_set_leds(data[0]);
+            dprintf("SET_LED: %02X\n", usb_device_state_get_leds());
+            last_req.len = 0;
             return 1;
             break;
         case NONE: