summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2023-10-23 14:43:46 +1000
committerGitHub <noreply@github.com>2023-10-23 15:43:46 +1100
commit0c160e1fbafbf477c74e64fd8ab9a9121eb0f42a (patch)
tree7a6e361a5fe396b72029ab03d7e00abe1f19a105
parentbf6f13a2b0a185e935b8554e41317ab471a4c0ec (diff)
Separate 6KRO and NKRO report structs (#22267)
-rw-r--r--keyboards/annepro2/annepro2_ble.c2
-rw-r--r--keyboards/horrortroll/lemon40/info.json3
-rw-r--r--keyboards/kbdfans/kbd67/rev1/info.json1
-rw-r--r--quantum/action.c2
-rw-r--r--quantum/action_util.c57
-rw-r--r--quantum/action_util.h9
-rw-r--r--tests/test_common/keyboard_report_util.cpp4
-rw-r--r--tests/test_common/test_driver.cpp6
-rw-r--r--tests/test_common/test_driver.hpp2
-rw-r--r--tmk_core/protocol.mk4
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c59
-rw-r--r--tmk_core/protocol/chibios/chibios.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c22
-rw-r--r--tmk_core/protocol/host.c33
-rw-r--r--tmk_core/protocol/host.h1
-rw-r--r--tmk_core/protocol/host_driver.h1
-rw-r--r--tmk_core/protocol/lufa/lufa.c34
-rw-r--r--tmk_core/protocol/report.c37
-rw-r--r--tmk_core/protocol/report.h60
-rw-r--r--tmk_core/protocol/vusb/vusb.c8
20 files changed, 185 insertions, 163 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);
31 31
32/* -------------------- Static Local Variables ------------------------------ */ 32/* -------------------- Static Local Variables ------------------------------ */
33static host_driver_t ap2_ble_driver = { 33static host_driver_t ap2_ble_driver = {
34 ap2_ble_leds, ap2_ble_keyboard, ap2_ble_mouse, ap2_ble_extra 34 ap2_ble_leds, ap2_ble_keyboard, NULL, ap2_ble_mouse, ap2_ble_extra
35}; 35};
36 36
37static uint8_t ble_mcu_wakeup[11] = {0x7b, 0x12, 0x53, 0x00, 0x03, 0x00, 0x01, 0x7d, 0x02, 0x01, 0x02}; 37static 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 @@
19 "knight": true, 19 "knight": true,
20 "christmas": true, 20 "christmas": true,
21 "static_gradient": true, 21 "static_gradient": true,
22 "alternating": true, 22 "alternating": true
23 "twinkle": true
24 } 23 }
25 }, 24 },
26 "ws2812": { 25 "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 @@
38 "knight": true, 38 "knight": true,
39 "christmas": true, 39 "christmas": true,
40 "static_gradient": true, 40 "static_gradient": true,
41 "rgb_test": true,
42 "alternating": true, 41 "alternating": true,
43 "twinkle": true 42 "twinkle": true
44 } 43 }
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) {
925 // Force a new key press if the key is already pressed 925 // Force a new key press if the key is already pressed
926 // without this, keys with the same keycode, but different 926 // without this, keys with the same keycode, but different
927 // modifiers will be reported incorrectly, see issue #1708 927 // modifiers will be reported incorrectly, see issue #1708
928 if (is_key_pressed(keyboard_report, code)) { 928 if (is_key_pressed(code)) {
929 del_key(code); 929 del_key(code);
930 send_keyboard_report(); 930 send_keyboard_report();
931 } 931 }
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;
35// TODO: pointer variable is not needed 35// TODO: pointer variable is not needed
36// report_keyboard_t keyboard_report = {}; 36// report_keyboard_t keyboard_report = {};
37report_keyboard_t *keyboard_report = &(report_keyboard_t){}; 37report_keyboard_t *keyboard_report = &(report_keyboard_t){};
38#ifdef NKRO_ENABLE
39report_nkro_t *nkro_report = &(report_nkro_t){};
40#endif
38 41
39extern inline void add_key(uint8_t key); 42extern inline void add_key(uint8_t key);
40extern inline void del_key(uint8_t key); 43extern inline void del_key(uint8_t key);
@@ -252,13 +255,8 @@ bool is_oneshot_enabled(void) {
252 255
253#endif 256#endif
254 257
255/** \brief Send keyboard report 258static uint8_t get_mods_for_report(void) {
256 * 259 uint8_t mods = real_mods | weak_mods;
257 * FIXME: needs doc
258 */
259void send_keyboard_report(void) {
260 keyboard_report->mods = real_mods;
261 keyboard_report->mods |= weak_mods;
262 260
263#ifndef NO_ACTION_ONESHOT 261#ifndef NO_ACTION_ONESHOT
264 if (oneshot_mods) { 262 if (oneshot_mods) {
@@ -268,20 +266,25 @@ void send_keyboard_report(void) {
268 clear_oneshot_mods(); 266 clear_oneshot_mods();
269 } 267 }
270# endif 268# endif
271 keyboard_report->mods |= oneshot_mods; 269 mods |= oneshot_mods;
272 if (has_anykey(keyboard_report)) { 270 if (has_anykey()) {
273 clear_oneshot_mods(); 271 clear_oneshot_mods();
274 } 272 }
275 } 273 }
276
277#endif 274#endif
278 275
279#ifdef KEY_OVERRIDE_ENABLE 276#ifdef KEY_OVERRIDE_ENABLE
280 // These need to be last to be able to properly control key overrides 277 // These need to be last to be able to properly control key overrides
281 keyboard_report->mods &= ~suppressed_mods; 278 mods &= ~suppressed_mods;
282 keyboard_report->mods |= weak_override_mods; 279 mods |= weak_override_mods;
283#endif 280#endif
284 281
282 return mods;
283}
284
285void send_6kro_report(void) {
286 keyboard_report->mods = get_mods_for_report();
287
285#ifdef PROTOCOL_VUSB 288#ifdef PROTOCOL_VUSB
286 host_keyboard_send(keyboard_report); 289 host_keyboard_send(keyboard_report);
287#else 290#else
@@ -295,6 +298,36 @@ void send_keyboard_report(void) {
295#endif 298#endif
296} 299}
297 300
301#ifdef NKRO_ENABLE
302void send_nkro_report(void) {
303 nkro_report->mods = get_mods_for_report();
304
305 static report_nkro_t last_report;
306
307 /* Only send the report if there are changes to propagate to the host. */
308 if (memcmp(nkro_report, &last_report, sizeof(report_nkro_t)) != 0) {
309 memcpy(&last_report, nkro_report, sizeof(report_nkro_t));
310 host_nkro_send(nkro_report);
311 }
312}
313#endif
314
315/** \brief Send keyboard report
316 *
317 * FIXME: needs doc
318 */
319void send_keyboard_report(void) {
320#ifdef NKRO_ENABLE
321 if (keyboard_protocol && keymap_config.nkro) {
322 send_nkro_report();
323 } else {
324 send_6kro_report();
325 }
326#else
327 send_6kro_report();
328#endif
329}
330
298/** \brief Get mods 331/** \brief Get mods
299 * 332 *
300 * FIXME: needs doc 333 * 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" {
26#endif 26#endif
27 27
28extern report_keyboard_t *keyboard_report; 28extern report_keyboard_t *keyboard_report;
29#ifdef NKRO_ENABLE
30extern report_nkro_t *nkro_report;
31#endif
29 32
30void send_keyboard_report(void); 33void send_keyboard_report(void);
31 34
32/* key */ 35/* key */
33inline void add_key(uint8_t key) { 36inline void add_key(uint8_t key) {
34 add_key_to_report(keyboard_report, key); 37 add_key_to_report(key);
35} 38}
36 39
37inline void del_key(uint8_t key) { 40inline void del_key(uint8_t key) {
38 del_key_from_report(keyboard_report, key); 41 del_key_from_report(key);
39} 42}
40 43
41inline void clear_keys(void) { 44inline void clear_keys(void) {
42 clear_keys_from_report(keyboard_report); 45 clear_keys_from_report();
43} 46}
44 47
45/* modifier */ 48/* 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) {
95} 95}
96 96
97KeyboardReportMatcher::KeyboardReportMatcher(const std::vector<uint8_t>& keys) { 97KeyboardReportMatcher::KeyboardReportMatcher(const std::vector<uint8_t>& keys) {
98 memset(m_report.raw, 0, sizeof(m_report.raw)); 98 memset(&m_report, 0, sizeof(report_keyboard_t));
99 for (auto k : keys) { 99 for (auto k : keys) {
100 if (IS_MODIFIER_KEYCODE(k)) { 100 if (IS_MODIFIER_KEYCODE(k)) {
101 m_report.mods |= MOD_BIT(k); 101 m_report.mods |= MOD_BIT(k);
102 } else { 102 } else {
103 add_key_to_report(&m_report, k); 103 add_key_byte(&m_report, k);
104 } 104 }
105 } 105 }
106} 106}
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) {
31} 31}
32} // namespace 32} // namespace
33 33
34TestDriver::TestDriver() : m_driver{&TestDriver::keyboard_leds, &TestDriver::send_keyboard, &TestDriver::send_mouse, &TestDriver::send_extra} { 34TestDriver::TestDriver() : m_driver{&TestDriver::keyboard_leds, &TestDriver::send_keyboard, &TestDriver::send_nkro, &TestDriver::send_mouse, &TestDriver::send_extra} {
35 host_set_driver(&m_driver); 35 host_set_driver(&m_driver);
36 m_this = this; 36 m_this = this;
37} 37}
@@ -49,6 +49,10 @@ void TestDriver::send_keyboard(report_keyboard_t* report) {
49 m_this->send_keyboard_mock(*report); 49 m_this->send_keyboard_mock(*report);
50} 50}
51 51
52void TestDriver::send_nkro(report_nkro_t* report) {
53 m_this->send_nkro_mock(*report);
54}
55
52void TestDriver::send_mouse(report_mouse_t* report) { 56void TestDriver::send_mouse(report_mouse_t* report) {
53 m_this->send_mouse_mock(*report); 57 m_this->send_mouse_mock(*report);
54} 58}
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 {
32 } 32 }
33 33
34 MOCK_METHOD1(send_keyboard_mock, void(report_keyboard_t&)); 34 MOCK_METHOD1(send_keyboard_mock, void(report_keyboard_t&));
35 MOCK_METHOD1(send_nkro_mock, void(report_nkro_t&));
35 MOCK_METHOD1(send_mouse_mock, void(report_mouse_t&)); 36 MOCK_METHOD1(send_mouse_mock, void(report_mouse_t&));
36 MOCK_METHOD1(send_extra_mock, void(report_extra_t&)); 37 MOCK_METHOD1(send_extra_mock, void(report_extra_t&));
37 38
38 private: 39 private:
39 static uint8_t keyboard_leds(void); 40 static uint8_t keyboard_leds(void);
40 static void send_keyboard(report_keyboard_t* report); 41 static void send_keyboard(report_keyboard_t* report);
42 static void send_nkro(report_nkro_t* report);
41 static void send_mouse(report_mouse_t* report); 43 static void send_mouse(report_mouse_t* report);
42 static void send_extra(report_extra_t* report); 44 static void send_extra(report_extra_t* report);
43 host_driver_t m_driver; 45 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
46endif 46endif
47 47
48ifeq ($(strip $(NKRO_ENABLE)), yes) 48ifeq ($(strip $(NKRO_ENABLE)), yes)
49 ifeq ($(PROTOCOL), VUSB) 49 ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
50 $(info NKRO is not currently supported on V-USB, and has been disabled.)
51 else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
52 $(info NKRO is not currently supported with Bluetooth, and has been disabled.) 50 $(info NKRO is not currently supported with Bluetooth, and has been disabled.)
53 else 51 else
54 OPT_DEFS += -DNKRO_ENABLE 52 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
36void main_subtasks(void); 36void main_subtasks(void);
37uint8_t keyboard_leds(void); 37uint8_t keyboard_leds(void);
38void send_keyboard(report_keyboard_t *report); 38void send_keyboard(report_keyboard_t *report);
39void send_nkro(report_nkro_t *report);
39void send_mouse(report_mouse_t *report); 40void send_mouse(report_mouse_t *report);
40void send_extra(report_extra_t *report); 41void send_extra(report_extra_t *report);
41 42
@@ -43,7 +44,7 @@ void send_extra(report_extra_t *report);
43void deferred_exec_task(void); 44void deferred_exec_task(void);
44#endif // DEFERRED_EXEC_ENABLE 45#endif // DEFERRED_EXEC_ENABLE
45 46
46host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; 47host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
47 48
48uint8_t led_states; 49uint8_t led_states;
49 50
@@ -59,41 +60,41 @@ uint8_t keyboard_leds(void) {
59void send_keyboard(report_keyboard_t *report) { 60void send_keyboard(report_keyboard_t *report) {
60 uint32_t irqflags; 61 uint32_t irqflags;
61 62
62#ifdef NKRO_ENABLE 63 while (udi_hid_kbd_b_report_trans_ongoing) {
63 if (!keymap_config.nkro) { 64 main_subtasks();
64#endif // NKRO_ENABLE 65 } // Run other tasks while waiting for USB to be free
65 while (udi_hid_kbd_b_report_trans_ongoing) {
66 main_subtasks();
67 } // Run other tasks while waiting for USB to be free
68 66
69 irqflags = __get_PRIMASK(); 67 irqflags = __get_PRIMASK();
70 __disable_irq(); 68 __disable_irq();
71 __DMB(); 69 __DMB();
72 70
73 memcpy(udi_hid_kbd_report, report->raw, UDI_HID_KBD_REPORT_SIZE); 71 memcpy(udi_hid_kbd_report, report, UDI_HID_KBD_REPORT_SIZE);
74 udi_hid_kbd_b_report_valid = 1; 72 udi_hid_kbd_b_report_valid = 1;
75 udi_hid_kbd_send_report(); 73 udi_hid_kbd_send_report();
76 74
77 __DMB(); 75 __DMB();
78 __set_PRIMASK(irqflags); 76 __set_PRIMASK(irqflags);
77}
78
79void send_nkro(report_nkro_t *report) {
79#ifdef NKRO_ENABLE 80#ifdef NKRO_ENABLE
80 } else { 81 uint32_t irqflags;
81 while (udi_hid_nkro_b_report_trans_ongoing) {
82 main_subtasks();
83 } // Run other tasks while waiting for USB to be free
84 82
85 irqflags = __get_PRIMASK(); 83 while (udi_hid_nkro_b_report_trans_ongoing) {
86 __disable_irq(); 84 main_subtasks();
87 __DMB(); 85 } // Run other tasks while waiting for USB to be free
88 86
89 memcpy(udi_hid_nkro_report, report->raw, UDI_HID_NKRO_REPORT_SIZE); 87 irqflags = __get_PRIMASK();
90 udi_hid_nkro_b_report_valid = 1; 88 __disable_irq();
91 udi_hid_nkro_send_report(); 89 __DMB();
92 90
93 __DMB(); 91 memcpy(udi_hid_nkro_report, report, UDI_HID_NKRO_REPORT_SIZE);
94 __set_PRIMASK(irqflags); 92 udi_hid_nkro_b_report_valid = 1;
95 } 93 udi_hid_nkro_send_report();
96#endif // NKRO_ENABLE 94
95 __DMB();
96 __set_PRIMASK(irqflags);
97#endif
97} 98}
98 99
99void send_mouse(report_mouse_t *report) { 100void 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 @@
59/* declarations */ 59/* declarations */
60uint8_t keyboard_leds(void); 60uint8_t keyboard_leds(void);
61void send_keyboard(report_keyboard_t *report); 61void send_keyboard(report_keyboard_t *report);
62void send_nkro(report_nkro_t *report);
62void send_mouse(report_mouse_t *report); 63void send_mouse(report_mouse_t *report);
63void send_extra(report_extra_t *report); 64void send_extra(report_extra_t *report);
64 65
65/* host struct */ 66/* host struct */
66host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; 67host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
67 68
68#ifdef VIRTSER_ENABLE 69#ifdef VIRTSER_ENABLE
69void virtser_task(void); 70void 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;
71 71
72static void keyboard_idle_timer_cb(struct ch_virtual_timer *, void *arg); 72static void keyboard_idle_timer_cb(struct ch_virtual_timer *, void *arg);
73 73
74report_keyboard_t keyboard_report_sent = {{0}}; 74report_keyboard_t keyboard_report_sent = {0};
75report_mouse_t mouse_report_sent = {0}; 75report_mouse_t mouse_report_sent = {0};
76 76
77union { 77union {
@@ -883,26 +883,22 @@ void send_report(uint8_t endpoint, void *report, size_t size) {
883/* prepare and start sending a report IN 883/* prepare and start sending a report IN
884 * not callable from ISR or locked state */ 884 * not callable from ISR or locked state */
885void send_keyboard(report_keyboard_t *report) { 885void send_keyboard(report_keyboard_t *report) {
886 uint8_t ep = KEYBOARD_IN_EPNUM;
887 size_t size = KEYBOARD_REPORT_SIZE;
888
889 /* If we're in Boot Protocol, don't send any report ID or other funky fields */ 886 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
890 if (!keyboard_protocol) { 887 if (!keyboard_protocol) {
891 send_report(ep, &report->mods, 8); 888 send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
892 } else { 889 } else {
893#ifdef NKRO_ENABLE 890 send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
894 if (keymap_config.nkro) {
895 ep = SHARED_IN_EPNUM;
896 size = sizeof(struct nkro_report);
897 }
898#endif
899
900 send_report(ep, report, size);
901 } 891 }
902 892
903 keyboard_report_sent = *report; 893 keyboard_report_sent = *report;
904} 894}
905 895
896void send_nkro(report_nkro_t *report) {
897#ifdef NKRO_ENABLE
898 send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t));
899#endif
900}
901
906/* --------------------------------------------------------- 902/* ---------------------------------------------------------
907 * Mouse functions 903 * Mouse functions
908 * --------------------------------------------------------- 904 * ---------------------------------------------------------
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) {
81#endif 81#endif
82 82
83 if (!driver) return; 83 if (!driver) return;
84#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
85 if (keyboard_protocol && keymap_config.nkro) {
86 /* The callers of this function assume that report->mods is where mods go in.
87 * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
88 */
89 report->nkro.mods = report->mods;
90 report->nkro.report_id = REPORT_ID_NKRO;
91 } else
92#endif
93 {
94#ifdef KEYBOARD_SHARED_EP 84#ifdef KEYBOARD_SHARED_EP
95 report->report_id = REPORT_ID_KEYBOARD; 85 report->report_id = REPORT_ID_KEYBOARD;
96#endif 86#endif
97 }
98 (*driver->send_keyboard)(report); 87 (*driver->send_keyboard)(report);
99 88
100 if (debug_keyboard) { 89 if (debug_keyboard) {
101 dprint("keyboard_report: "); 90 dprintf("keyboard_report: %02X | ", report->mods);
102 for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { 91 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
103 dprintf("%02X ", report->raw[i]); 92 dprintf("%02X ", report->keys[i]);
93 }
94 dprint("\n");
95 }
96}
97
98void host_nkro_send(report_nkro_t *report) {
99 if (!driver) return;
100 report->report_id = REPORT_ID_NKRO;
101 (*driver->send_nkro)(report);
102
103 if (debug_keyboard) {
104 dprintf("nkro_report: %02X | ", report->mods);
105 for (uint8_t i = 0; i < NKRO_REPORT_BITS; i++) {
106 dprintf("%02X ", report->bits[i]);
104 } 107 }
105 dprint("\n"); 108 dprint("\n");
106 } 109 }
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);
38uint8_t host_keyboard_leds(void); 38uint8_t host_keyboard_leds(void);
39led_t host_keyboard_led_state(void); 39led_t host_keyboard_led_state(void);
40void host_keyboard_send(report_keyboard_t *report); 40void host_keyboard_send(report_keyboard_t *report);
41void host_nkro_send(report_nkro_t *report);
41void host_mouse_send(report_mouse_t *report); 42void host_mouse_send(report_mouse_t *report);
42void host_system_send(uint16_t usage); 43void host_system_send(uint16_t usage);
43void host_consumer_send(uint16_t usage); 44void 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 <http://www.gnu.org/licenses/>.
26typedef struct { 26typedef struct {
27 uint8_t (*keyboard_leds)(void); 27 uint8_t (*keyboard_leds)(void);
28 void (*send_keyboard)(report_keyboard_t *); 28 void (*send_keyboard)(report_keyboard_t *);
29 void (*send_nkro)(report_nkro_t *);
29 void (*send_mouse)(report_mouse_t *); 30 void (*send_mouse)(report_mouse_t *);
30 void (*send_extra)(report_extra_t *); 31 void (*send_extra)(report_extra_t *);
31} host_driver_t; 32} 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 @@
55#include "usb_device_state.h" 55#include "usb_device_state.h"
56#include <util/atomic.h> 56#include <util/atomic.h>
57 57
58#ifdef NKRO_ENABLE
59# include "keycode_config.h"
60
61extern keymap_config_t keymap_config;
62#endif
63
64#ifdef VIRTSER_ENABLE 58#ifdef VIRTSER_ENABLE
65# include "virtser.h" 59# include "virtser.h"
66#endif 60#endif
@@ -83,9 +77,10 @@ static report_keyboard_t keyboard_report_sent;
83/* Host driver */ 77/* Host driver */
84static uint8_t keyboard_leds(void); 78static uint8_t keyboard_leds(void);
85static void send_keyboard(report_keyboard_t *report); 79static void send_keyboard(report_keyboard_t *report);
80static void send_nkro(report_nkro_t *report);
86static void send_mouse(report_mouse_t *report); 81static void send_mouse(report_mouse_t *report);
87static void send_extra(report_extra_t *report); 82static void send_extra(report_extra_t *report);
88host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; 83host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
89 84
90void send_report(uint8_t endpoint, void *report, size_t size) { 85void send_report(uint8_t endpoint, void *report, size_t size) {
91 uint8_t timeout = 255; 86 uint8_t timeout = 255;
@@ -559,27 +554,26 @@ static uint8_t keyboard_leds(void) {
559 * FIXME: Needs doc 554 * FIXME: Needs doc
560 */ 555 */
561static void send_keyboard(report_keyboard_t *report) { 556static void send_keyboard(report_keyboard_t *report) {
562 /* Select the Keyboard Report Endpoint */
563 uint8_t ep = KEYBOARD_IN_EPNUM;
564 uint8_t size = KEYBOARD_REPORT_SIZE;
565
566 /* If we're in Boot Protocol, don't send any report ID or other funky fields */ 557 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
567 if (!keyboard_protocol) { 558 if (!keyboard_protocol) {
568 send_report(ep, &report->mods, 8); 559 send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
569 } else { 560 } else {
570#ifdef NKRO_ENABLE 561 send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
571 if (keymap_config.nkro) {
572 ep = SHARED_IN_EPNUM;
573 size = sizeof(struct nkro_report);
574 }
575#endif
576
577 send_report(ep, report, size);
578 } 562 }
579 563
580 keyboard_report_sent = *report; 564 keyboard_report_sent = *report;
581} 565}
582 566
567/** \brief Send NKRO
568 *
569 * FIXME: Needs doc
570 */
571static void send_nkro(report_nkro_t *report) {
572#ifdef NKRO_ENABLE
573 send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t));
574#endif
575}
576
583/** \brief Send Mouse 577/** \brief Send Mouse
584 * 578 *
585 * FIXME: Needs doc 579 * 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 @@
15 */ 15 */
16 16
17#include "report.h" 17#include "report.h"
18#include "action_util.h"
18#include "host.h" 19#include "host.h"
19#include "keycode_config.h" 20#include "keycode_config.h"
20#include "debug.h" 21#include "debug.h"
@@ -35,14 +36,14 @@ static int8_t cb_count = 0;
35 * 36 *
36 * FIXME: Needs doc 37 * FIXME: Needs doc
37 */ 38 */
38uint8_t has_anykey(report_keyboard_t* keyboard_report) { 39uint8_t has_anykey(void) {
39 uint8_t cnt = 0; 40 uint8_t cnt = 0;
40 uint8_t* p = keyboard_report->keys; 41 uint8_t* p = keyboard_report->keys;
41 uint8_t lp = sizeof(keyboard_report->keys); 42 uint8_t lp = sizeof(keyboard_report->keys);
42#ifdef NKRO_ENABLE 43#ifdef NKRO_ENABLE
43 if (keyboard_protocol && keymap_config.nkro) { 44 if (keyboard_protocol && keymap_config.nkro) {
44 p = keyboard_report->nkro.bits; 45 p = nkro_report->bits;
45 lp = sizeof(keyboard_report->nkro.bits); 46 lp = sizeof(nkro_report->bits);
46 } 47 }
47#endif 48#endif
48 while (lp--) { 49 while (lp--) {
@@ -55,13 +56,13 @@ uint8_t has_anykey(report_keyboard_t* keyboard_report) {
55 * 56 *
56 * FIXME: Needs doc 57 * FIXME: Needs doc
57 */ 58 */
58uint8_t get_first_key(report_keyboard_t* keyboard_report) { 59uint8_t get_first_key(void) {
59#ifdef NKRO_ENABLE 60#ifdef NKRO_ENABLE
60 if (keyboard_protocol && keymap_config.nkro) { 61 if (keyboard_protocol && keymap_config.nkro) {
61 uint8_t i = 0; 62 uint8_t i = 0;
62 for (; i < NKRO_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) 63 for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
63 ; 64 ;
64 return i << 3 | biton(keyboard_report->nkro.bits[i]); 65 return i << 3 | biton(nkro_report->bits[i]);
65 } 66 }
66#endif 67#endif
67#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE 68#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
@@ -83,14 +84,14 @@ uint8_t get_first_key(report_keyboard_t* keyboard_report) {
83 * Returns true if the keyboard_report reports that the key is pressed, otherwise false 84 * Returns true if the keyboard_report reports that the key is pressed, otherwise false
84 * Note: The function doesn't support modifers currently, and it returns false for KC_NO 85 * Note: The function doesn't support modifers currently, and it returns false for KC_NO
85 */ 86 */
86bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) { 87bool is_key_pressed(uint8_t key) {
87 if (key == KC_NO) { 88 if (key == KC_NO) {
88 return false; 89 return false;
89 } 90 }
90#ifdef NKRO_ENABLE 91#ifdef NKRO_ENABLE
91 if (keyboard_protocol && keymap_config.nkro) { 92 if (keyboard_protocol && keymap_config.nkro) {
92 if ((key >> 3) < NKRO_REPORT_BITS) { 93 if ((key >> 3) < NKRO_REPORT_BITS) {
93 return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7); 94 return nkro_report->bits[key >> 3] & 1 << (key & 7);
94 } else { 95 } else {
95 return false; 96 return false;
96 } 97 }
@@ -215,9 +216,9 @@ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
215 * 216 *
216 * FIXME: Needs doc 217 * FIXME: Needs doc
217 */ 218 */
218void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { 219void add_key_bit(report_nkro_t* nkro_report, uint8_t code) {
219 if ((code >> 3) < NKRO_REPORT_BITS) { 220 if ((code >> 3) < NKRO_REPORT_BITS) {
220 keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7); 221 nkro_report->bits[code >> 3] |= 1 << (code & 7);
221 } else { 222 } else {
222 dprintf("add_key_bit: can't add: %02X\n", code); 223 dprintf("add_key_bit: can't add: %02X\n", code);
223 } 224 }
@@ -227,9 +228,9 @@ void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
227 * 228 *
228 * FIXME: Needs doc 229 * FIXME: Needs doc
229 */ 230 */
230void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { 231void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
231 if ((code >> 3) < NKRO_REPORT_BITS) { 232 if ((code >> 3) < NKRO_REPORT_BITS) {
232 keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7)); 233 nkro_report->bits[code >> 3] &= ~(1 << (code & 7));
233 } else { 234 } else {
234 dprintf("del_key_bit: can't del: %02X\n", code); 235 dprintf("del_key_bit: can't del: %02X\n", code);
235 } 236 }
@@ -240,10 +241,10 @@ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
240 * 241 *
241 * FIXME: Needs doc 242 * FIXME: Needs doc
242 */ 243 */
243void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { 244void add_key_to_report(uint8_t key) {
244#ifdef NKRO_ENABLE 245#ifdef NKRO_ENABLE
245 if (keyboard_protocol && keymap_config.nkro) { 246 if (keyboard_protocol && keymap_config.nkro) {
246 add_key_bit(keyboard_report, key); 247 add_key_bit(nkro_report, key);
247 return; 248 return;
248 } 249 }
249#endif 250#endif
@@ -254,10 +255,10 @@ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
254 * 255 *
255 * FIXME: Needs doc 256 * FIXME: Needs doc
256 */ 257 */
257void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { 258void del_key_from_report(uint8_t key) {
258#ifdef NKRO_ENABLE 259#ifdef NKRO_ENABLE
259 if (keyboard_protocol && keymap_config.nkro) { 260 if (keyboard_protocol && keymap_config.nkro) {
260 del_key_bit(keyboard_report, key); 261 del_key_bit(nkro_report, key);
261 return; 262 return;
262 } 263 }
263#endif 264#endif
@@ -268,11 +269,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
268 * 269 *
269 * FIXME: Needs doc 270 * FIXME: Needs doc
270 */ 271 */
271void clear_keys_from_report(report_keyboard_t* keyboard_report) { 272void clear_keys_from_report(void) {
272 // not clear mods 273 // not clear mods
273#ifdef NKRO_ENABLE 274#ifdef NKRO_ENABLE
274 if (keyboard_protocol && keymap_config.nkro) { 275 if (keyboard_protocol && keymap_config.nkro) {
275 memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits)); 276 memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
276 return; 277 return;
277 } 278 }
278#endif 279#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 {
125 125
126// clang-format on 126// clang-format on
127 127
128#define NKRO_SHARED_EP 128#define NKRO_REPORT_BITS 30
129/* key report size(NKRO or boot mode) */
130#if defined(NKRO_ENABLE)
131# if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
132# include "protocol/usb_descriptor.h"
133# define NKRO_REPORT_BITS (SHARED_EPSIZE - 2)
134# elif defined(PROTOCOL_ARM_ATSAM)
135# include "protocol/arm_atsam/usb/udi_device_epsize.h"
136# define NKRO_REPORT_BITS (NKRO_EPSIZE - 1)
137# undef NKRO_SHARED_EP
138# undef MOUSE_SHARED_EP
139# else
140# error "NKRO not supported with this protocol"
141# endif
142#endif
143 129
144#ifdef KEYBOARD_SHARED_EP 130#ifdef KEYBOARD_SHARED_EP
145# define KEYBOARD_REPORT_SIZE 9 131# define KEYBOARD_REPORT_SIZE 9
@@ -173,28 +159,22 @@ extern "C" {
173 * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui 159 * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui
174 * 160 *
175 */ 161 */
176typedef union { 162typedef struct {
177 uint8_t raw[KEYBOARD_REPORT_SIZE];
178 struct {
179#ifdef KEYBOARD_SHARED_EP 163#ifdef KEYBOARD_SHARED_EP
180 uint8_t report_id; 164 uint8_t report_id;
181#endif
182 uint8_t mods;
183 uint8_t reserved;
184 uint8_t keys[KEYBOARD_REPORT_KEYS];
185 };
186#ifdef NKRO_ENABLE
187 struct nkro_report {
188# ifdef NKRO_SHARED_EP
189 uint8_t report_id;
190# endif
191 uint8_t mods;
192 uint8_t bits[NKRO_REPORT_BITS];
193 } nkro;
194#endif 165#endif
166 uint8_t mods;
167 uint8_t reserved;
168 uint8_t keys[KEYBOARD_REPORT_KEYS];
195} PACKED report_keyboard_t; 169} PACKED report_keyboard_t;
196 170
197typedef struct { 171typedef struct {
172 uint8_t report_id;
173 uint8_t mods;
174 uint8_t bits[NKRO_REPORT_BITS];
175} PACKED report_nkro_t;
176
177typedef struct {
198 uint8_t report_id; 178 uint8_t report_id;
199 uint16_t usage; 179 uint16_t usage;
200} PACKED report_extra_t; 180} PACKED report_extra_t;
@@ -330,20 +310,20 @@ static inline uint16_t KEYCODE2CONSUMER(uint8_t key) {
330 } 310 }
331} 311}
332 312
333uint8_t has_anykey(report_keyboard_t* keyboard_report); 313uint8_t has_anykey(void);
334uint8_t get_first_key(report_keyboard_t* keyboard_report); 314uint8_t get_first_key(void);
335bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key); 315bool is_key_pressed(uint8_t key);
336 316
337void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code); 317void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
338void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code); 318void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
339#ifdef NKRO_ENABLE 319#ifdef NKRO_ENABLE
340void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code); 320void add_key_bit(report_nkro_t* nkro_report, uint8_t code);
341void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code); 321void del_key_bit(report_nkro_t* nkro_report, uint8_t code);
342#endif 322#endif
343 323
344void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key); 324void add_key_to_report(uint8_t key);
345void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key); 325void del_key_from_report(uint8_t key);
346void clear_keys_from_report(report_keyboard_t* keyboard_report); 326void clear_keys_from_report(void);
347 327
348#ifdef MOUSE_ENABLE 328#ifdef MOUSE_ENABLE
349bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report); 329bool 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 {
91 91
92static uint8_t keyboard_led_state = 0; 92static uint8_t keyboard_led_state = 0;
93static uint8_t vusb_idle_rate = 0; 93static uint8_t vusb_idle_rate = 0;
94uint8_t keyboard_protocol = 1;
94 95
95/* Keyboard report send buffer */ 96/* Keyboard report send buffer */
96#define KBUF_SIZE 16 97#define KBUF_SIZE 16
@@ -231,10 +232,11 @@ void console_task(void) {
231 *------------------------------------------------------------------*/ 232 *------------------------------------------------------------------*/
232static uint8_t keyboard_leds(void); 233static uint8_t keyboard_leds(void);
233static void send_keyboard(report_keyboard_t *report); 234static void send_keyboard(report_keyboard_t *report);
235static void send_nkro(report_nkro_t *report);
234static void send_mouse(report_mouse_t *report); 236static void send_mouse(report_mouse_t *report);
235static void send_extra(report_extra_t *report); 237static void send_extra(report_extra_t *report);
236 238
237static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; 239static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
238 240
239host_driver_t *vusb_driver(void) { 241host_driver_t *vusb_driver(void) {
240 return &driver; 242 return &driver;
@@ -259,6 +261,10 @@ static void send_keyboard(report_keyboard_t *report) {
259 keyboard_report_sent = *report; 261 keyboard_report_sent = *report;
260} 262}
261 263
264static void send_nkro(report_nkro_t *report) {
265 // TODO: Implement NKRO
266}
267
262#ifndef KEYBOARD_SHARED_EP 268#ifndef KEYBOARD_SHARED_EP
263# define usbInterruptIsReadyShared usbInterruptIsReady3 269# define usbInterruptIsReadyShared usbInterruptIsReady3
264# define usbSetInterruptShared usbSetInterrupt3 270# define usbSetInterruptShared usbSetInterrupt3