Browse Source

Separate 6KRO and NKRO report structs (#22267)

Ryan 2 years ago
parent
commit
0c160e1fba

+ 1 - 1
keyboards/annepro2/annepro2_ble.c

@@ -31,7 +31,7 @@ static void ap2_ble_swtich_ble_driver(void);
 
 /* -------------------- Static Local Variables ------------------------------ */
 static host_driver_t ap2_ble_driver = {
-    ap2_ble_leds, ap2_ble_keyboard, ap2_ble_mouse, ap2_ble_extra
+    ap2_ble_leds, ap2_ble_keyboard, NULL, ap2_ble_mouse, ap2_ble_extra
 };
 
 static uint8_t ble_mcu_wakeup[11] = {0x7b, 0x12, 0x53, 0x00, 0x03, 0x00, 0x01, 0x7d, 0x02, 0x01, 0x02};

+ 1 - 2
keyboards/horrortroll/lemon40/info.json

@@ -19,8 +19,7 @@
             "knight": true,
             "christmas": true,
             "static_gradient": true,
-            "alternating": true,
-            "twinkle": true
+            "alternating": true
         }
     },
     "ws2812": {

+ 0 - 1
keyboards/kbdfans/kbd67/rev1/info.json

@@ -38,7 +38,6 @@
       "knight": true,
       "christmas": true,
       "static_gradient": true,
-      "rgb_test": true,
       "alternating": true,
       "twinkle": true
     }

+ 1 - 1
quantum/action.c

@@ -925,7 +925,7 @@ __attribute__((weak)) void register_code(uint8_t code) {
         // Force a new key press if the key is already pressed
         // without this, keys with the same keycode, but different
         // modifiers will be reported incorrectly, see issue #1708
-        if (is_key_pressed(keyboard_report, code)) {
+        if (is_key_pressed(code)) {
             del_key(code);
             send_keyboard_report();
         }

+ 45 - 12
quantum/action_util.c

@@ -35,6 +35,9 @@ static uint8_t suppressed_mods    = 0;
 // TODO: pointer variable is not needed
 // report_keyboard_t keyboard_report = {};
 report_keyboard_t *keyboard_report = &(report_keyboard_t){};
+#ifdef NKRO_ENABLE
+report_nkro_t *nkro_report = &(report_nkro_t){};
+#endif
 
 extern inline void add_key(uint8_t key);
 extern inline void del_key(uint8_t key);
@@ -252,13 +255,8 @@ bool is_oneshot_enabled(void) {
 
 #endif
 
-/** \brief Send keyboard report
- *
- * FIXME: needs doc
- */
-void send_keyboard_report(void) {
-    keyboard_report->mods = real_mods;
-    keyboard_report->mods |= weak_mods;
+static uint8_t get_mods_for_report(void) {
+    uint8_t mods = real_mods | weak_mods;
 
 #ifndef NO_ACTION_ONESHOT
     if (oneshot_mods) {
@@ -268,20 +266,25 @@ void send_keyboard_report(void) {
             clear_oneshot_mods();
         }
 #    endif
-        keyboard_report->mods |= oneshot_mods;
-        if (has_anykey(keyboard_report)) {
+        mods |= oneshot_mods;
+        if (has_anykey()) {
             clear_oneshot_mods();
         }
     }
-
 #endif
 
 #ifdef KEY_OVERRIDE_ENABLE
     // These need to be last to be able to properly control key overrides
-    keyboard_report->mods &= ~suppressed_mods;
-    keyboard_report->mods |= weak_override_mods;
+    mods &= ~suppressed_mods;
+    mods |= weak_override_mods;
 #endif
 
+    return mods;
+}
+
+void send_6kro_report(void) {
+    keyboard_report->mods = get_mods_for_report();
+
 #ifdef PROTOCOL_VUSB
     host_keyboard_send(keyboard_report);
 #else
@@ -295,6 +298,36 @@ void send_keyboard_report(void) {
 #endif
 }
 
+#ifdef NKRO_ENABLE
+void send_nkro_report(void) {
+    nkro_report->mods = get_mods_for_report();
+
+    static report_nkro_t last_report;
+
+    /* Only send the report if there are changes to propagate to the host. */
+    if (memcmp(nkro_report, &last_report, sizeof(report_nkro_t)) != 0) {
+        memcpy(&last_report, nkro_report, sizeof(report_nkro_t));
+        host_nkro_send(nkro_report);
+    }
+}
+#endif
+
+/** \brief Send keyboard report
+ *
+ * FIXME: needs doc
+ */
+void send_keyboard_report(void) {
+#ifdef NKRO_ENABLE
+    if (keyboard_protocol && keymap_config.nkro) {
+        send_nkro_report();
+    } else {
+        send_6kro_report();
+    }
+#else
+    send_6kro_report();
+#endif
+}
+
 /** \brief Get mods
  *
  * FIXME: needs doc

+ 6 - 3
quantum/action_util.h

@@ -26,20 +26,23 @@ extern "C" {
 #endif
 
 extern report_keyboard_t *keyboard_report;
+#ifdef NKRO_ENABLE
+extern report_nkro_t *nkro_report;
+#endif
 
 void send_keyboard_report(void);
 
 /* key */
 inline void add_key(uint8_t key) {
-    add_key_to_report(keyboard_report, key);
+    add_key_to_report(key);
 }
 
 inline void del_key(uint8_t key) {
-    del_key_from_report(keyboard_report, key);
+    del_key_from_report(key);
 }
 
 inline void clear_keys(void) {
-    clear_keys_from_report(keyboard_report);
+    clear_keys_from_report();
 }
 
 /* modifier */

+ 2 - 2
tests/test_common/keyboard_report_util.cpp

@@ -95,12 +95,12 @@ std::ostream& operator<<(std::ostream& os, const report_keyboard_t& report) {
 }
 
 KeyboardReportMatcher::KeyboardReportMatcher(const std::vector<uint8_t>& keys) {
-    memset(m_report.raw, 0, sizeof(m_report.raw));
+    memset(&m_report, 0, sizeof(report_keyboard_t));
     for (auto k : keys) {
         if (IS_MODIFIER_KEYCODE(k)) {
             m_report.mods |= MOD_BIT(k);
         } else {
-            add_key_to_report(&m_report, k);
+            add_key_byte(&m_report, k);
         }
     }
 }

+ 5 - 1
tests/test_common/test_driver.cpp

@@ -31,7 +31,7 @@ uint8_t hex_digit_to_keycode(uint8_t digit) {
 }
 } // namespace
 
-TestDriver::TestDriver() : m_driver{&TestDriver::keyboard_leds, &TestDriver::send_keyboard, &TestDriver::send_mouse, &TestDriver::send_extra} {
+TestDriver::TestDriver() : m_driver{&TestDriver::keyboard_leds, &TestDriver::send_keyboard, &TestDriver::send_nkro, &TestDriver::send_mouse, &TestDriver::send_extra} {
     host_set_driver(&m_driver);
     m_this = this;
 }
@@ -49,6 +49,10 @@ void TestDriver::send_keyboard(report_keyboard_t* report) {
     m_this->send_keyboard_mock(*report);
 }
 
+void TestDriver::send_nkro(report_nkro_t* report) {
+    m_this->send_nkro_mock(*report);
+}
+
 void TestDriver::send_mouse(report_mouse_t* report) {
     m_this->send_mouse_mock(*report);
 }

+ 2 - 0
tests/test_common/test_driver.hpp

@@ -32,12 +32,14 @@ class TestDriver {
     }
 
     MOCK_METHOD1(send_keyboard_mock, void(report_keyboard_t&));
+    MOCK_METHOD1(send_nkro_mock, void(report_nkro_t&));
     MOCK_METHOD1(send_mouse_mock, void(report_mouse_t&));
     MOCK_METHOD1(send_extra_mock, void(report_extra_t&));
 
    private:
     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      m_driver;

+ 1 - 3
tmk_core/protocol.mk

@@ -46,9 +46,7 @@ else
 endif
 
 ifeq ($(strip $(NKRO_ENABLE)), yes)
-    ifeq ($(PROTOCOL), VUSB)
-        $(info NKRO is not currently supported on V-USB, and has been disabled.)
-    else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
+    ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
         $(info NKRO is not currently supported with Bluetooth, and has been disabled.)
     else
         OPT_DEFS += -DNKRO_ENABLE

+ 30 - 29
tmk_core/protocol/arm_atsam/main_arm_atsam.c

@@ -36,6 +36,7 @@ uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; // Saved USB state from ha
 void    main_subtasks(void);
 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);
 
@@ -43,7 +44,7 @@ void    send_extra(report_extra_t *report);
 void deferred_exec_task(void);
 #endif // DEFERRED_EXEC_ENABLE
 
-host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra};
+host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
 
 uint8_t led_states;
 
@@ -59,41 +60,41 @@ uint8_t keyboard_leds(void) {
 void send_keyboard(report_keyboard_t *report) {
     uint32_t irqflags;
 
-#ifdef NKRO_ENABLE
-    if (!keymap_config.nkro) {
-#endif // NKRO_ENABLE
-        while (udi_hid_kbd_b_report_trans_ongoing) {
-            main_subtasks();
-        } // Run other tasks while waiting for USB to be free
+    while (udi_hid_kbd_b_report_trans_ongoing) {
+        main_subtasks();
+    } // Run other tasks while waiting for USB to be free
 
-        irqflags = __get_PRIMASK();
-        __disable_irq();
-        __DMB();
+    irqflags = __get_PRIMASK();
+    __disable_irq();
+    __DMB();
 
-        memcpy(udi_hid_kbd_report, report->raw, UDI_HID_KBD_REPORT_SIZE);
-        udi_hid_kbd_b_report_valid = 1;
-        udi_hid_kbd_send_report();
+    memcpy(udi_hid_kbd_report, report, UDI_HID_KBD_REPORT_SIZE);
+    udi_hid_kbd_b_report_valid = 1;
+    udi_hid_kbd_send_report();
 
-        __DMB();
-        __set_PRIMASK(irqflags);
+    __DMB();
+    __set_PRIMASK(irqflags);
+}
+
+void send_nkro(report_nkro_t *report) {
 #ifdef NKRO_ENABLE
-    } else {
-        while (udi_hid_nkro_b_report_trans_ongoing) {
-            main_subtasks();
-        } // Run other tasks while waiting for USB to be free
+    uint32_t irqflags;
 
-        irqflags = __get_PRIMASK();
-        __disable_irq();
-        __DMB();
+    while (udi_hid_nkro_b_report_trans_ongoing) {
+        main_subtasks();
+    } // Run other tasks while waiting for USB to be free
 
-        memcpy(udi_hid_nkro_report, report->raw, UDI_HID_NKRO_REPORT_SIZE);
-        udi_hid_nkro_b_report_valid = 1;
-        udi_hid_nkro_send_report();
+    irqflags = __get_PRIMASK();
+    __disable_irq();
+    __DMB();
 
-        __DMB();
-        __set_PRIMASK(irqflags);
-    }
-#endif // NKRO_ENABLE
+    memcpy(udi_hid_nkro_report, report, UDI_HID_NKRO_REPORT_SIZE);
+    udi_hid_nkro_b_report_valid = 1;
+    udi_hid_nkro_send_report();
+
+    __DMB();
+    __set_PRIMASK(irqflags);
+#endif
 }
 
 void send_mouse(report_mouse_t *report) {

+ 2 - 1
tmk_core/protocol/chibios/chibios.c

@@ -59,11 +59,12 @@
 /* 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);
 
 /* host struct */
-host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra};
+host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
 
 #ifdef VIRTSER_ENABLE
 void virtser_task(void);

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

@@ -71,7 +71,7 @@ static virtual_timer_t keyboard_idle_timer;
 
 static void keyboard_idle_timer_cb(struct ch_virtual_timer *, void *arg);
 
-report_keyboard_t keyboard_report_sent = {{0}};
+report_keyboard_t keyboard_report_sent = {0};
 report_mouse_t    mouse_report_sent    = {0};
 
 union {
@@ -883,26 +883,22 @@ void send_report(uint8_t endpoint, void *report, size_t size) {
 /* prepare and start sending a report IN
  * not callable from ISR or locked state */
 void send_keyboard(report_keyboard_t *report) {
-    uint8_t ep   = KEYBOARD_IN_EPNUM;
-    size_t  size = KEYBOARD_REPORT_SIZE;
-
     /* If we're in Boot Protocol, don't send any report ID or other funky fields */
     if (!keyboard_protocol) {
-        send_report(ep, &report->mods, 8);
+        send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
     } else {
-#ifdef NKRO_ENABLE
-        if (keymap_config.nkro) {
-            ep   = SHARED_IN_EPNUM;
-            size = sizeof(struct nkro_report);
-        }
-#endif
-
-        send_report(ep, report, size);
+        send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
     }
 
     keyboard_report_sent = *report;
 }
 
+void send_nkro(report_nkro_t *report) {
+#ifdef NKRO_ENABLE
+    send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t));
+#endif
+}
+
 /* ---------------------------------------------------------
  *                     Mouse functions
  * ---------------------------------------------------------

+ 18 - 15
tmk_core/protocol/host.c

@@ -81,26 +81,29 @@ void host_keyboard_send(report_keyboard_t *report) {
 #endif
 
     if (!driver) return;
-#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
-    if (keyboard_protocol && keymap_config.nkro) {
-        /* The callers of this function assume that report->mods is where mods go in.
-         * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
-         */
-        report->nkro.mods      = report->mods;
-        report->nkro.report_id = REPORT_ID_NKRO;
-    } else
-#endif
-    {
 #ifdef KEYBOARD_SHARED_EP
-        report->report_id = REPORT_ID_KEYBOARD;
+    report->report_id = REPORT_ID_KEYBOARD;
 #endif
-    }
     (*driver->send_keyboard)(report);
 
     if (debug_keyboard) {
-        dprint("keyboard_report: ");
-        for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
-            dprintf("%02X ", report->raw[i]);
+        dprintf("keyboard_report: %02X | ", report->mods);
+        for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+            dprintf("%02X ", report->keys[i]);
+        }
+        dprint("\n");
+    }
+}
+
+void host_nkro_send(report_nkro_t *report) {
+    if (!driver) return;
+    report->report_id = REPORT_ID_NKRO;
+    (*driver->send_nkro)(report);
+
+    if (debug_keyboard) {
+        dprintf("nkro_report: %02X | ", report->mods);
+        for (uint8_t i = 0; i < NKRO_REPORT_BITS; i++) {
+            dprintf("%02X ", report->bits[i]);
         }
         dprint("\n");
     }

+ 1 - 0
tmk_core/protocol/host.h

@@ -38,6 +38,7 @@ host_driver_t *host_get_driver(void);
 uint8_t host_keyboard_leds(void);
 led_t   host_keyboard_led_state(void);
 void    host_keyboard_send(report_keyboard_t *report);
+void    host_nkro_send(report_nkro_t *report);
 void    host_mouse_send(report_mouse_t *report);
 void    host_system_send(uint16_t usage);
 void    host_consumer_send(uint16_t usage);

+ 1 - 0
tmk_core/protocol/host_driver.h

@@ -26,6 +26,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 typedef struct {
     uint8_t (*keyboard_leds)(void);
     void (*send_keyboard)(report_keyboard_t *);
+    void (*send_nkro)(report_nkro_t *);
     void (*send_mouse)(report_mouse_t *);
     void (*send_extra)(report_extra_t *);
 } host_driver_t;

+ 14 - 20
tmk_core/protocol/lufa/lufa.c

@@ -55,12 +55,6 @@
 #include "usb_device_state.h"
 #include <util/atomic.h>
 
-#ifdef NKRO_ENABLE
-#    include "keycode_config.h"
-
-extern keymap_config_t keymap_config;
-#endif
-
 #ifdef VIRTSER_ENABLE
 #    include "virtser.h"
 #endif
@@ -83,9 +77,10 @@ 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_mouse, send_extra};
+host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
 
 void send_report(uint8_t endpoint, void *report, size_t size) {
     uint8_t timeout = 255;
@@ -559,27 +554,26 @@ static uint8_t keyboard_leds(void) {
  * FIXME: Needs doc
  */
 static void send_keyboard(report_keyboard_t *report) {
-    /* Select the Keyboard Report Endpoint */
-    uint8_t ep   = KEYBOARD_IN_EPNUM;
-    uint8_t size = KEYBOARD_REPORT_SIZE;
-
     /* If we're in Boot Protocol, don't send any report ID or other funky fields */
     if (!keyboard_protocol) {
-        send_report(ep, &report->mods, 8);
+        send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
     } else {
-#ifdef NKRO_ENABLE
-        if (keymap_config.nkro) {
-            ep   = SHARED_IN_EPNUM;
-            size = sizeof(struct nkro_report);
-        }
-#endif
-
-        send_report(ep, report, size);
+        send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
     }
 
     keyboard_report_sent = *report;
 }
 
+/** \brief Send NKRO
+ *
+ * FIXME: Needs doc
+ */
+static void send_nkro(report_nkro_t *report) {
+#ifdef NKRO_ENABLE
+    send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t));
+#endif
+}
+
 /** \brief Send Mouse
  *
  * FIXME: Needs doc

+ 19 - 18
tmk_core/protocol/report.c

@@ -15,6 +15,7 @@
  */
 
 #include "report.h"
+#include "action_util.h"
 #include "host.h"
 #include "keycode_config.h"
 #include "debug.h"
@@ -35,14 +36,14 @@ static int8_t cb_count = 0;
  *
  * FIXME: Needs doc
  */
-uint8_t has_anykey(report_keyboard_t* keyboard_report) {
+uint8_t has_anykey(void) {
     uint8_t  cnt = 0;
     uint8_t* p   = keyboard_report->keys;
     uint8_t  lp  = sizeof(keyboard_report->keys);
 #ifdef NKRO_ENABLE
     if (keyboard_protocol && keymap_config.nkro) {
-        p  = keyboard_report->nkro.bits;
-        lp = sizeof(keyboard_report->nkro.bits);
+        p  = nkro_report->bits;
+        lp = sizeof(nkro_report->bits);
     }
 #endif
     while (lp--) {
@@ -55,13 +56,13 @@ uint8_t has_anykey(report_keyboard_t* keyboard_report) {
  *
  * FIXME: Needs doc
  */
-uint8_t get_first_key(report_keyboard_t* keyboard_report) {
+uint8_t get_first_key(void) {
 #ifdef NKRO_ENABLE
     if (keyboard_protocol && keymap_config.nkro) {
         uint8_t i = 0;
-        for (; i < NKRO_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
+        for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
             ;
-        return i << 3 | biton(keyboard_report->nkro.bits[i]);
+        return i << 3 | biton(nkro_report->bits[i]);
     }
 #endif
 #ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
@@ -83,14 +84,14 @@ uint8_t get_first_key(report_keyboard_t* keyboard_report) {
  * Returns true if the keyboard_report reports that the key is pressed, otherwise false
  * Note: The function doesn't support modifers currently, and it returns false for KC_NO
  */
-bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) {
+bool is_key_pressed(uint8_t key) {
     if (key == KC_NO) {
         return false;
     }
 #ifdef NKRO_ENABLE
     if (keyboard_protocol && keymap_config.nkro) {
         if ((key >> 3) < NKRO_REPORT_BITS) {
-            return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7);
+            return nkro_report->bits[key >> 3] & 1 << (key & 7);
         } else {
             return false;
         }
@@ -215,9 +216,9 @@ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
  *
  * FIXME: Needs doc
  */
-void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
+void add_key_bit(report_nkro_t* nkro_report, uint8_t code) {
     if ((code >> 3) < NKRO_REPORT_BITS) {
-        keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7);
+        nkro_report->bits[code >> 3] |= 1 << (code & 7);
     } else {
         dprintf("add_key_bit: can't add: %02X\n", code);
     }
@@ -227,9 +228,9 @@ void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
  *
  * FIXME: Needs doc
  */
-void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
+void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
     if ((code >> 3) < NKRO_REPORT_BITS) {
-        keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7));
+        nkro_report->bits[code >> 3] &= ~(1 << (code & 7));
     } else {
         dprintf("del_key_bit: can't del: %02X\n", code);
     }
@@ -240,10 +241,10 @@ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
  *
  * FIXME: Needs doc
  */
-void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
+void add_key_to_report(uint8_t key) {
 #ifdef NKRO_ENABLE
     if (keyboard_protocol && keymap_config.nkro) {
-        add_key_bit(keyboard_report, key);
+        add_key_bit(nkro_report, key);
         return;
     }
 #endif
@@ -254,10 +255,10 @@ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
  *
  * FIXME: Needs doc
  */
-void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
+void del_key_from_report(uint8_t key) {
 #ifdef NKRO_ENABLE
     if (keyboard_protocol && keymap_config.nkro) {
-        del_key_bit(keyboard_report, key);
+        del_key_bit(nkro_report, key);
         return;
     }
 #endif
@@ -268,11 +269,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
  *
  * FIXME: Needs doc
  */
-void clear_keys_from_report(report_keyboard_t* keyboard_report) {
+void clear_keys_from_report(void) {
     // not clear mods
 #ifdef NKRO_ENABLE
     if (keyboard_protocol && keymap_config.nkro) {
-        memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
+        memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
         return;
     }
 #endif

+ 20 - 40
tmk_core/protocol/report.h

@@ -125,21 +125,7 @@ enum desktop_usages {
 
 // clang-format on
 
-#define NKRO_SHARED_EP
-/* key report size(NKRO or boot mode) */
-#if defined(NKRO_ENABLE)
-#    if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
-#        include "protocol/usb_descriptor.h"
-#        define NKRO_REPORT_BITS (SHARED_EPSIZE - 2)
-#    elif defined(PROTOCOL_ARM_ATSAM)
-#        include "protocol/arm_atsam/usb/udi_device_epsize.h"
-#        define NKRO_REPORT_BITS (NKRO_EPSIZE - 1)
-#        undef NKRO_SHARED_EP
-#        undef MOUSE_SHARED_EP
-#    else
-#        error "NKRO not supported with this protocol"
-#    endif
-#endif
+#define NKRO_REPORT_BITS 30
 
 #ifdef KEYBOARD_SHARED_EP
 #    define KEYBOARD_REPORT_SIZE 9
@@ -173,27 +159,21 @@ extern "C" {
  * desc |Lcontrol|Lshift  |Lalt    |Lgui    |Rcontrol|Rshift  |Ralt    |Rgui
  *
  */
-typedef union {
-    uint8_t raw[KEYBOARD_REPORT_SIZE];
-    struct {
+typedef struct {
 #ifdef KEYBOARD_SHARED_EP
-        uint8_t report_id;
-#endif
-        uint8_t mods;
-        uint8_t reserved;
-        uint8_t keys[KEYBOARD_REPORT_KEYS];
-    };
-#ifdef NKRO_ENABLE
-    struct nkro_report {
-#    ifdef NKRO_SHARED_EP
-        uint8_t report_id;
-#    endif
-        uint8_t mods;
-        uint8_t bits[NKRO_REPORT_BITS];
-    } nkro;
+    uint8_t report_id;
 #endif
+    uint8_t mods;
+    uint8_t reserved;
+    uint8_t keys[KEYBOARD_REPORT_KEYS];
 } PACKED report_keyboard_t;
 
+typedef struct {
+    uint8_t report_id;
+    uint8_t mods;
+    uint8_t bits[NKRO_REPORT_BITS];
+} PACKED report_nkro_t;
+
 typedef struct {
     uint8_t  report_id;
     uint16_t usage;
@@ -330,20 +310,20 @@ static inline uint16_t KEYCODE2CONSUMER(uint8_t key) {
     }
 }
 
-uint8_t has_anykey(report_keyboard_t* keyboard_report);
-uint8_t get_first_key(report_keyboard_t* keyboard_report);
-bool    is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key);
+uint8_t has_anykey(void);
+uint8_t get_first_key(void);
+bool    is_key_pressed(uint8_t key);
 
 void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
 void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
 #ifdef NKRO_ENABLE
-void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
-void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
+void add_key_bit(report_nkro_t* nkro_report, uint8_t code);
+void del_key_bit(report_nkro_t* nkro_report, uint8_t code);
 #endif
 
-void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key);
-void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key);
-void clear_keys_from_report(report_keyboard_t* keyboard_report);
+void add_key_to_report(uint8_t key);
+void del_key_from_report(uint8_t key);
+void clear_keys_from_report(void);
 
 #ifdef MOUSE_ENABLE
 bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report);

+ 7 - 1
tmk_core/protocol/vusb/vusb.c

@@ -91,6 +91,7 @@ enum usb_interfaces {
 
 static uint8_t keyboard_led_state = 0;
 static uint8_t vusb_idle_rate     = 0;
+uint8_t        keyboard_protocol  = 1;
 
 /* Keyboard report send buffer */
 #define KBUF_SIZE 16
@@ -231,10 +232,11 @@ void console_task(void) {
  *------------------------------------------------------------------*/
 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 host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_extra};
+static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
 
 host_driver_t *vusb_driver(void) {
     return &driver;
@@ -259,6 +261,10 @@ static void send_keyboard(report_keyboard_t *report) {
     keyboard_report_sent = *report;
 }
 
+static void send_nkro(report_nkro_t *report) {
+    // TODO: Implement NKRO
+}
+
 #ifndef KEYBOARD_SHARED_EP
 #    define usbInterruptIsReadyShared usbInterruptIsReady3
 #    define usbSetInterruptShared usbSetInterrupt3