From 0c160e1fbafbf477c74e64fd8ab9a9121eb0f42a Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 23 Oct 2023 14:43:46 +1000 Subject: [PATCH] Separate 6KRO and NKRO report structs (#22267) --- keyboards/annepro2/annepro2_ble.c | 2 +- keyboards/horrortroll/lemon40/info.json | 3 +- keyboards/kbdfans/kbd67/rev1/info.json | 1 - quantum/action.c | 2 +- quantum/action_util.c | 57 ++++++++++++++---- quantum/action_util.h | 9 ++- tests/test_common/keyboard_report_util.cpp | 4 +- tests/test_common/test_driver.cpp | 6 +- tests/test_common/test_driver.hpp | 2 + tmk_core/protocol.mk | 4 +- tmk_core/protocol/arm_atsam/main_arm_atsam.c | 63 ++++++++++---------- tmk_core/protocol/chibios/chibios.c | 3 +- tmk_core/protocol/chibios/usb_main.c | 22 +++---- tmk_core/protocol/host.c | 33 +++++----- tmk_core/protocol/host.h | 1 + tmk_core/protocol/host_driver.h | 1 + tmk_core/protocol/lufa/lufa.c | 34 +++++------ tmk_core/protocol/report.c | 37 ++++++------ tmk_core/protocol/report.h | 60 +++++++------------ tmk_core/protocol/vusb/vusb.c | 8 ++- 20 files changed, 187 insertions(+), 165 deletions(-) diff --git a/keyboards/annepro2/annepro2_ble.c b/keyboards/annepro2/annepro2_ble.c index b04929e958..a382c61638 100644 --- a/keyboards/annepro2/annepro2_ble.c +++ b/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}; diff --git a/keyboards/horrortroll/lemon40/info.json b/keyboards/horrortroll/lemon40/info.json index 7162e2c2c7..7b0b1c394b 100644 --- a/keyboards/horrortroll/lemon40/info.json +++ b/keyboards/horrortroll/lemon40/info.json @@ -19,8 +19,7 @@ "knight": true, "christmas": true, "static_gradient": true, - "alternating": true, - "twinkle": true + "alternating": true } }, "ws2812": { diff --git a/keyboards/kbdfans/kbd67/rev1/info.json b/keyboards/kbdfans/kbd67/rev1/info.json index 9119477584..f279c5a2c9 100644 --- a/keyboards/kbdfans/kbd67/rev1/info.json +++ b/keyboards/kbdfans/kbd67/rev1/info.json @@ -38,7 +38,6 @@ "knight": true, "christmas": true, "static_gradient": true, - "rgb_test": true, "alternating": true, "twinkle": true } diff --git a/quantum/action.c b/quantum/action.c index 349250472b..29822c39e9 100644 --- a/quantum/action.c +++ b/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(); } diff --git a/quantum/action_util.c b/quantum/action_util.c index 909dea0595..52171b5050 100644 --- a/quantum/action_util.c +++ b/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 diff --git a/quantum/action_util.h b/quantum/action_util.h index 831caf3c0a..d2ecb145be 100644 --- a/quantum/action_util.h +++ b/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 */ diff --git a/tests/test_common/keyboard_report_util.cpp b/tests/test_common/keyboard_report_util.cpp index cb7f7ae735..5676483539 100644 --- a/tests/test_common/keyboard_report_util.cpp +++ b/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& 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); } } } diff --git a/tests/test_common/test_driver.cpp b/tests/test_common/test_driver.cpp index 0495da8205..d410b225f9 100644 --- a/tests/test_common/test_driver.cpp +++ b/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); } diff --git a/tests/test_common/test_driver.hpp b/tests/test_common/test_driver.hpp index d8a6885d0f..ec75d3fff2 100644 --- a/tests/test_common/test_driver.hpp +++ b/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; diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk index d159dacc55..fd5342d637 100644 --- a/tmk_core/protocol.mk +++ b/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 diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index 30817c17b6..8abcfd6090 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/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; + 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(); + + 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); +} + +void send_nkro(report_nkro_t *report) { #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 + 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_kbd_report, report->raw, UDI_HID_KBD_REPORT_SIZE); - udi_hid_kbd_b_report_valid = 1; - udi_hid_kbd_send_report(); + irqflags = __get_PRIMASK(); + __disable_irq(); + __DMB(); - __DMB(); - __set_PRIMASK(irqflags); -#ifdef NKRO_ENABLE - } else { - 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, UDI_HID_NKRO_REPORT_SIZE); + udi_hid_nkro_b_report_valid = 1; + udi_hid_nkro_send_report(); - irqflags = __get_PRIMASK(); - __disable_irq(); - __DMB(); - - memcpy(udi_hid_nkro_report, report->raw, UDI_HID_NKRO_REPORT_SIZE); - udi_hid_nkro_b_report_valid = 1; - udi_hid_nkro_send_report(); - - __DMB(); - __set_PRIMASK(irqflags); - } -#endif // NKRO_ENABLE + __DMB(); + __set_PRIMASK(irqflags); +#endif } void send_mouse(report_mouse_t *report) { diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index 4d97f1cd82..91bb252c7c 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/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); diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index b14ca30c1a..f2158fd009 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/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 * --------------------------------------------------------- diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c index 2c6654e9a6..732fbdc37d 100644 --- a/tmk_core/protocol/host.c +++ b/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"); } diff --git a/tmk_core/protocol/host.h b/tmk_core/protocol/host.h index e4fb3a74f2..959753ae02 100644 --- a/tmk_core/protocol/host.h +++ b/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); diff --git a/tmk_core/protocol/host_driver.h b/tmk_core/protocol/host_driver.h index 7dc6c3d810..8aa38b6dee 100644 --- a/tmk_core/protocol/host_driver.h +++ b/tmk_core/protocol/host_driver.h @@ -26,6 +26,7 @@ along with this program. If not, see . 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; diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index f04ca79a0c..553f69b1e4 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -55,12 +55,6 @@ #include "usb_device_state.h" #include -#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 diff --git a/tmk_core/protocol/report.c b/tmk_core/protocol/report.c index 27d267abae..0166bf654f 100644 --- a/tmk_core/protocol/report.c +++ b/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 diff --git a/tmk_core/protocol/report.h b/tmk_core/protocol/report.h index dd3cee3df0..9b612dd182 100644 --- a/tmk_core/protocol/report.h +++ b/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); diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index d74f375f66..d2c7749937 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/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