summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kerkmann <karlk90@pm.me>2024-10-18 09:57:08 +0200
committerGitHub <noreply@github.com>2024-10-18 09:57:08 +0200
commit3f9d4644126483bbd937f2be75a8878a1c986630 (patch)
tree0c91e51941b048b87c816e05f36e8a6b50753b9b
parent80f8aae3ec733cfbd6957a70f5fe436e5b92e725 (diff)
[Core] `usb_device_state`: consolidate usb state handling across implementations (#24258)
* usb_device_state: add idle_rate, led and protocol Previously all usb drivers and platform implementations (expect for our oddball atsam) tracked the same two global variables: - keyboard_protocol: to indicate if we are in report or boot protocol - keyboard_idle: for the idle_rate of the keyboard endpoint And a local variable that was exposed trough some indirection: - keyboard_led_state: for the currently set indicator leds (caps lock etc.) These have all been moved into the usb_device_state struct wich is accessible by getters and setters. This reduces code duplication and centralizes the state management across platforms and drivers. Signed-off-by: Stefan Kerkmann <karlk90@pm.me> * usb_device_state: reset protocol on reset The usb hid specification section 7.2.6 states: When initialized, all devices default to report protocol. However the host should not make any assumptions about the device’s state and should set the desired protocol whenever initializing a device. Thus on reset we should always do exactly that. Signed-off-by: Stefan Kerkmann <karlk90@pm.me> * keyboards: fix oversize warnings Signed-off-by: Stefan Kerkmann <karlk90@pm.me> --------- Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
-rw-r--r--drivers/haptic/solenoid.c2
-rw-r--r--keyboards/kikoslab/ellora65/keyboard.json3
-rw-r--r--keyboards/rgbkb/pan/info.json3
-rw-r--r--keyboards/takashicompany/minidivide/keyboard.json1
-rw-r--r--keyboards/work_louder/loop/info.json3
-rw-r--r--quantum/action_util.c3
-rw-r--r--quantum/command.c5
-rw-r--r--quantum/haptic.c2
-rw-r--r--quantum/os_detection.c26
-rw-r--r--quantum/os_detection.h2
-rw-r--r--quantum/os_detection/tests/os_detection.cpp14
-rw-r--r--quantum/process_keycode/process_haptic.c2
-rw-r--r--tmk_core/protocol/chibios/chibios.c11
-rw-r--r--tmk_core/protocol/chibios/usb_main.c24
-rw-r--r--tmk_core/protocol/host.h3
-rw-r--r--tmk_core/protocol/lufa/lufa.c38
-rw-r--r--tmk_core/protocol/report.c13
-rw-r--r--tmk_core/protocol/usb_device_state.c55
-rw-r--r--tmk_core/protocol/usb_device_state.h41
-rw-r--r--tmk_core/protocol/vusb/vusb.c44
20 files changed, 165 insertions, 130 deletions
diff --git a/drivers/haptic/solenoid.c b/drivers/haptic/solenoid.c
index 346b88bbc4..ed2a886854 100644
--- a/drivers/haptic/solenoid.c
+++ b/drivers/haptic/solenoid.c
@@ -158,7 +158,7 @@ void solenoid_setup(void) {
158#endif 158#endif
159 gpio_write_pin(solenoid_pads[i], !solenoid_active_state[i]); 159 gpio_write_pin(solenoid_pads[i], !solenoid_active_state[i]);
160 gpio_set_pin_output(solenoid_pads[i]); 160 gpio_set_pin_output(solenoid_pads[i]);
161 if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED)) { 161 if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED)) {
162 solenoid_fire(i); 162 solenoid_fire(i);
163 } 163 }
164 } 164 }
diff --git a/keyboards/kikoslab/ellora65/keyboard.json b/keyboards/kikoslab/ellora65/keyboard.json
index 9dd8404a0b..fdb60e4791 100644
--- a/keyboards/kikoslab/ellora65/keyboard.json
+++ b/keyboards/kikoslab/ellora65/keyboard.json
@@ -8,6 +8,9 @@
8 "pid": "0xE88F", 8 "pid": "0xE88F",
9 "device_version": "0.0.1" 9 "device_version": "0.0.1"
10 }, 10 },
11 "build": {
12 "lto": true
13 },
11 "features": { 14 "features": {
12 "bootmagic": true, 15 "bootmagic": true,
13 "command": false, 16 "command": false,
diff --git a/keyboards/rgbkb/pan/info.json b/keyboards/rgbkb/pan/info.json
index 0abdc7a6ec..ad56ba5e4b 100644
--- a/keyboards/rgbkb/pan/info.json
+++ b/keyboards/rgbkb/pan/info.json
@@ -8,6 +8,9 @@
8 "pid": "0x8C9C", 8 "pid": "0x8C9C",
9 "device_version": "0.0.2" 9 "device_version": "0.0.2"
10 }, 10 },
11 "build": {
12 "lto": true
13 },
11 "features": { 14 "features": {
12 "bootmagic": true, 15 "bootmagic": true,
13 "encoder": true, 16 "encoder": true,
diff --git a/keyboards/takashicompany/minidivide/keyboard.json b/keyboards/takashicompany/minidivide/keyboard.json
index 4ae089fbee..d258baa694 100644
--- a/keyboards/takashicompany/minidivide/keyboard.json
+++ b/keyboards/takashicompany/minidivide/keyboard.json
@@ -30,7 +30,6 @@
30 "knight": true, 30 "knight": true,
31 "rainbow_mood": true, 31 "rainbow_mood": true,
32 "rainbow_swirl": true, 32 "rainbow_swirl": true,
33 "rgb_test": true,
34 "snake": true, 33 "snake": true,
35 "static_gradient": true, 34 "static_gradient": true,
36 "twinkle": true 35 "twinkle": true
diff --git a/keyboards/work_louder/loop/info.json b/keyboards/work_louder/loop/info.json
index 771a31d105..70dc6cc13a 100644
--- a/keyboards/work_louder/loop/info.json
+++ b/keyboards/work_louder/loop/info.json
@@ -51,8 +51,7 @@
51 "pixel_rain": true, 51 "pixel_rain": true,
52 "pixel_flow": true, 52 "pixel_flow": true,
53 "pixel_fractal": true, 53 "pixel_fractal": true,
54 "typing_heatmap": true, 54 "typing_heatmap": true
55 "digital_rain": true
56 }, 55 },
57 "driver": "ws2812", 56 "driver": "ws2812",
58 "max_brightness": 120, 57 "max_brightness": 120,
diff --git a/quantum/action_util.c b/quantum/action_util.c
index 52171b5050..c0dc4f3822 100644
--- a/quantum/action_util.c
+++ b/quantum/action_util.c
@@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21#include "action_layer.h" 21#include "action_layer.h"
22#include "timer.h" 22#include "timer.h"
23#include "keycode_config.h" 23#include "keycode_config.h"
24#include "usb_device_state.h"
24#include <string.h> 25#include <string.h>
25 26
26extern keymap_config_t keymap_config; 27extern keymap_config_t keymap_config;
@@ -318,7 +319,7 @@ void send_nkro_report(void) {
318 */ 319 */
319void send_keyboard_report(void) { 320void send_keyboard_report(void) {
320#ifdef NKRO_ENABLE 321#ifdef NKRO_ENABLE
321 if (keyboard_protocol && keymap_config.nkro) { 322 if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
322 send_nkro_report(); 323 send_nkro_report();
323 } else { 324 } else {
324 send_6kro_report(); 325 send_6kro_report();
diff --git a/quantum/command.c b/quantum/command.c
index c188638eb4..024d96917d 100644
--- a/quantum/command.c
+++ b/quantum/command.c
@@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
32#include "led.h" 32#include "led.h"
33#include "command.h" 33#include "command.h"
34#include "quantum.h" 34#include "quantum.h"
35#include "usb_device_state.h"
35#include "version.h" 36#include "version.h"
36 37
37#ifdef BACKLIGHT_ENABLE 38#ifdef BACKLIGHT_ENABLE
@@ -230,8 +231,8 @@ static void print_status(void) {
230 "timer_read32(): %08lX\n" 231 "timer_read32(): %08lX\n"
231 232
232 , host_keyboard_leds() 233 , host_keyboard_leds()
233 , keyboard_protocol 234 , usb_device_state_get_protocol()
234 , keyboard_idle 235 , usb_device_state_get_idle_rate()
235#ifdef NKRO_ENABLE 236#ifdef NKRO_ENABLE
236 , keymap_config.nkro 237 , keymap_config.nkro
237#endif 238#endif
diff --git a/quantum/haptic.c b/quantum/haptic.c
index 6a466293a7..81bad469b3 100644
--- a/quantum/haptic.c
+++ b/quantum/haptic.c
@@ -36,7 +36,7 @@ extern uint8_t split_haptic_play;
36haptic_config_t haptic_config; 36haptic_config_t haptic_config;
37 37
38static void update_haptic_enable_gpios(void) { 38static void update_haptic_enable_gpios(void) {
39 if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) { 39 if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
40#if defined(HAPTIC_ENABLE_PIN) 40#if defined(HAPTIC_ENABLE_PIN)
41 HAPTIC_ENABLE_PIN_WRITE_ACTIVE(); 41 HAPTIC_ENABLE_PIN_WRITE_ACTIVE();
42#endif 42#endif
diff --git a/quantum/os_detection.c b/quantum/os_detection.c
index 99ffe1927a..4196b3ec8a 100644
--- a/quantum/os_detection.c
+++ b/quantum/os_detection.c
@@ -65,8 +65,8 @@ static volatile os_variant_t reported_os = OS_UNSURE;
65static volatile bool first_report = true; 65static volatile bool first_report = true;
66 66
67// to react on USB state changes 67// to react on USB state changes
68static volatile enum usb_device_state current_usb_device_state = USB_DEVICE_STATE_NO_INIT; 68static volatile struct usb_device_state current_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT};
69static volatile enum usb_device_state maxprev_usb_device_state = USB_DEVICE_STATE_NO_INIT; 69static volatile struct usb_device_state maxprev_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT};
70 70
71// the OS detection might be unstable for a while, "debounce" it 71// the OS detection might be unstable for a while, "debounce" it
72static volatile bool debouncing = false; 72static volatile bool debouncing = false;
@@ -88,7 +88,7 @@ void os_detection_task(void) {
88 return; 88 return;
89 } 89 }
90#endif 90#endif
91 if (current_usb_device_state == USB_DEVICE_STATE_CONFIGURED) { 91 if (current_usb_device_state.configure_state == USB_DEVICE_STATE_CONFIGURED) {
92 // debouncing goes for both the detected OS as well as the USB state 92 // debouncing goes for both the detected OS as well as the USB state
93 if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) { 93 if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) {
94 debouncing = false; 94 debouncing = false;
@@ -163,19 +163,19 @@ os_variant_t detected_host_os(void) {
163 163
164void erase_wlength_data(void) { 164void erase_wlength_data(void) {
165 memset(&setups_data, 0, sizeof(setups_data)); 165 memset(&setups_data, 0, sizeof(setups_data));
166 detected_os = OS_UNSURE; 166 detected_os = OS_UNSURE;
167 reported_os = OS_UNSURE; 167 reported_os = OS_UNSURE;
168 current_usb_device_state = USB_DEVICE_STATE_NO_INIT; 168 current_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT;
169 maxprev_usb_device_state = USB_DEVICE_STATE_NO_INIT; 169 maxprev_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT;
170 debouncing = false; 170 debouncing = false;
171 last_time = 0; 171 last_time = 0;
172 first_report = true; 172 first_report = true;
173} 173}
174 174
175void os_detection_notify_usb_device_state_change(enum usb_device_state usb_device_state) { 175void os_detection_notify_usb_device_state_change(struct usb_device_state usb_device_state) {
176 // treat this like any other source of instability 176 // treat this like any other source of instability
177 if (maxprev_usb_device_state < current_usb_device_state) { 177 if (maxprev_usb_device_state.configure_state < current_usb_device_state.configure_state) {
178 maxprev_usb_device_state = current_usb_device_state; 178 maxprev_usb_device_state.configure_state = current_usb_device_state.configure_state;
179 } 179 }
180 current_usb_device_state = usb_device_state; 180 current_usb_device_state = usb_device_state;
181 last_time = timer_read_fast(); 181 last_time = timer_read_fast();
diff --git a/quantum/os_detection.h b/quantum/os_detection.h
index b8cd898335..98a8e805e4 100644
--- a/quantum/os_detection.h
+++ b/quantum/os_detection.h
@@ -31,7 +31,7 @@ typedef enum {
31void process_wlength(const uint16_t w_length); 31void process_wlength(const uint16_t w_length);
32os_variant_t detected_host_os(void); 32os_variant_t detected_host_os(void);
33void erase_wlength_data(void); 33void erase_wlength_data(void);
34void os_detection_notify_usb_device_state_change(enum usb_device_state usb_device_state); 34void os_detection_notify_usb_device_state_change(struct usb_device_state usb_device_state);
35 35
36void os_detection_task(void); 36void os_detection_task(void);
37 37
diff --git a/quantum/os_detection/tests/os_detection.cpp b/quantum/os_detection/tests/os_detection.cpp
index a9f671156b..ea43de144c 100644
--- a/quantum/os_detection/tests/os_detection.cpp
+++ b/quantum/os_detection/tests/os_detection.cpp
@@ -253,9 +253,11 @@ TEST_F(OsDetectionTest, TestDoNotReportIfUsbUnstable) {
253 EXPECT_EQ(detected_host_os(), OS_LINUX); 253 EXPECT_EQ(detected_host_os(), OS_LINUX);
254} 254}
255 255
256static struct usb_device_state usb_device_state_configured = {.configure_state = USB_DEVICE_STATE_CONFIGURED};
257
256TEST_F(OsDetectionTest, TestReportAfterDebounce) { 258TEST_F(OsDetectionTest, TestReportAfterDebounce) {
257 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX); 259 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX);
258 os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); 260 os_detection_notify_usb_device_state_change(usb_device_state_configured);
259 os_detection_task(); 261 os_detection_task();
260 assert_not_reported(); 262 assert_not_reported();
261 263
@@ -291,7 +293,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounce) {
291 293
292TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) { 294TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
293 EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); 295 EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
294 os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); 296 os_detection_notify_usb_device_state_change(usb_device_state_configured);
295 os_detection_task(); 297 os_detection_task();
296 assert_not_reported(); 298 assert_not_reported();
297 299
@@ -318,7 +320,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
318 320
319TEST_F(OsDetectionTest, TestReportUnsure) { 321TEST_F(OsDetectionTest, TestReportUnsure) {
320 EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE); 322 EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
321 os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); 323 os_detection_notify_usb_device_state_change(usb_device_state_configured);
322 os_detection_task(); 324 os_detection_task();
323 assert_not_reported(); 325 assert_not_reported();
324 326
@@ -345,7 +347,7 @@ TEST_F(OsDetectionTest, TestReportUnsure) {
345 347
346TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) { 348TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
347 EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE); 349 EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
348 os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); 350 os_detection_notify_usb_device_state_change(usb_device_state_configured);
349 os_detection_task(); 351 os_detection_task();
350 assert_not_reported(); 352 assert_not_reported();
351 353
@@ -356,7 +358,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
356 358
357 // at this stage, the final result has not been reached yet 359 // at this stage, the final result has not been reached yet
358 EXPECT_EQ(check_sequence({0xFF}), OS_LINUX); 360 EXPECT_EQ(check_sequence({0xFF}), OS_LINUX);
359 os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); 361 os_detection_notify_usb_device_state_change(usb_device_state_configured);
360 advance_time(OS_DETECTION_DEBOUNCE - 1); 362 advance_time(OS_DETECTION_DEBOUNCE - 1);
361 os_detection_task(); 363 os_detection_task();
362 assert_not_reported(); 364 assert_not_reported();
@@ -365,7 +367,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
365 367
366 // the remainder is processed 368 // the remainder is processed
367 EXPECT_EQ(check_sequence({0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); 369 EXPECT_EQ(check_sequence({0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
368 os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); 370 os_detection_notify_usb_device_state_change(usb_device_state_configured);
369 advance_time(OS_DETECTION_DEBOUNCE - 1); 371 advance_time(OS_DETECTION_DEBOUNCE - 1);
370 os_detection_task(); 372 os_detection_task();
371 assert_not_reported(); 373 assert_not_reported();
diff --git a/quantum/process_keycode/process_haptic.c b/quantum/process_keycode/process_haptic.c
index 21d4c5ce30..54cd7b817e 100644
--- a/quantum/process_keycode/process_haptic.c
+++ b/quantum/process_keycode/process_haptic.c
@@ -129,7 +129,7 @@ bool process_haptic(uint16_t keycode, keyrecord_t *record) {
129 } 129 }
130 } 130 }
131 131
132 if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) { 132 if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
133 if (record->event.pressed) { 133 if (record->event.pressed) {
134 // keypress 134 // keypress
135 if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) { 135 if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) {
diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c
index b879bdac77..cf948154f9 100644
--- a/tmk_core/protocol/chibios/chibios.c
+++ b/tmk_core/protocol/chibios/chibios.c
@@ -62,14 +62,13 @@
62 */ 62 */
63 63
64/* declarations */ 64/* declarations */
65uint8_t keyboard_leds(void); 65void send_keyboard(report_keyboard_t *report);
66void send_keyboard(report_keyboard_t *report); 66void send_nkro(report_nkro_t *report);
67void send_nkro(report_nkro_t *report); 67void send_mouse(report_mouse_t *report);
68void send_mouse(report_mouse_t *report); 68void send_extra(report_extra_t *report);
69void send_extra(report_extra_t *report);
70 69
71/* host struct */ 70/* host struct */
72host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; 71host_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};
73 72
74#ifdef VIRTSER_ENABLE 73#ifdef VIRTSER_ENABLE
75void virtser_task(void); 74void virtser_task(void);
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 2024a3bc7f..2a287e0d98 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -54,10 +54,6 @@ extern keymap_config_t keymap_config;
54extern usb_endpoint_in_t usb_endpoints_in[USB_ENDPOINT_IN_COUNT]; 54extern usb_endpoint_in_t usb_endpoints_in[USB_ENDPOINT_IN_COUNT];
55extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT]; 55extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT];
56 56
57uint8_t _Alignas(2) keyboard_idle = 0;
58uint8_t _Alignas(2) keyboard_protocol = 1;
59uint8_t keyboard_led_state = 0;
60
61static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size); 57static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size);
62static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded); 58static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded);
63static bool __attribute__((__unused__)) receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size); 59static bool __attribute__((__unused__)) receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size);
@@ -168,6 +164,7 @@ void usb_event_queue_task(void) {
168 break; 164 break;
169 case USB_EVENT_RESET: 165 case USB_EVENT_RESET:
170 usb_device_state_set_reset(); 166 usb_device_state_set_reset();
167 usb_device_state_set_protocol(USB_PROTOCOL_REPORT);
171 break; 168 break;
172 default: 169 default:
173 // Nothing to do, we don't handle it. 170 // Nothing to do, we don't handle it.
@@ -250,10 +247,10 @@ static void set_led_transfer_cb(USBDriver *usbp) {
250 if (setup->wLength == 2) { 247 if (setup->wLength == 2) {
251 uint8_t report_id = set_report_buf[0]; 248 uint8_t report_id = set_report_buf[0];
252 if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) { 249 if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) {
253 keyboard_led_state = set_report_buf[1]; 250 usb_device_state_set_leds(set_report_buf[1]);
254 } 251 }
255 } else { 252 } else {
256 keyboard_led_state = set_report_buf[0]; 253 usb_device_state_set_leds(set_report_buf[0]);
257 } 254 }
258} 255}
259 256
@@ -269,7 +266,9 @@ static bool usb_requests_hook_cb(USBDriver *usbp) {
269 return usb_get_report_cb(usbp); 266 return usb_get_report_cb(usbp);
270 case HID_REQ_GetProtocol: 267 case HID_REQ_GetProtocol:
271 if (setup->wIndex == KEYBOARD_INTERFACE) { 268 if (setup->wIndex == KEYBOARD_INTERFACE) {
272 usbSetupTransfer(usbp, &keyboard_protocol, sizeof(uint8_t), NULL); 269 static uint8_t keyboard_protocol;
270 keyboard_protocol = usb_device_state_get_protocol();
271 usbSetupTransfer(usbp, &keyboard_protocol, sizeof(keyboard_protocol), NULL);
273 return true; 272 return true;
274 } 273 }
275 break; 274 break;
@@ -292,12 +291,12 @@ static bool usb_requests_hook_cb(USBDriver *usbp) {
292 break; 291 break;
293 case HID_REQ_SetProtocol: 292 case HID_REQ_SetProtocol:
294 if (setup->wIndex == KEYBOARD_INTERFACE) { 293 if (setup->wIndex == KEYBOARD_INTERFACE) {
295 keyboard_protocol = setup->wValue.word; 294 usb_device_state_set_protocol(setup->wValue.lbyte);
296 } 295 }
297 usbSetupTransfer(usbp, NULL, 0, NULL); 296 usbSetupTransfer(usbp, NULL, 0, NULL);
298 return true; 297 return true;
299 case HID_REQ_SetIdle: 298 case HID_REQ_SetIdle:
300 keyboard_idle = setup->wValue.hbyte; 299 usb_device_state_set_idle_rate(setup->wValue.hbyte);
301 return usb_set_idle_cb(usbp); 300 return usb_set_idle_cb(usbp);
302 } 301 }
303 break; 302 break;
@@ -396,11 +395,6 @@ __attribute__((weak)) void restart_usb_driver(USBDriver *usbp) {
396 * --------------------------------------------------------- 395 * ---------------------------------------------------------
397 */ 396 */
398 397
399/* LED status */
400uint8_t keyboard_leds(void) {
401 return keyboard_led_state;
402}
403
404/** 398/**
405 * @brief Send a report to the host, the report is enqueued into an output 399 * @brief Send a report to the host, the report is enqueued into an output
406 * queue and send once the USB endpoint becomes empty. 400 * queue and send once the USB endpoint becomes empty.
@@ -458,7 +452,7 @@ static bool receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t
458 452
459void send_keyboard(report_keyboard_t *report) { 453void send_keyboard(report_keyboard_t *report) {
460 /* If we're in Boot Protocol, don't send any report ID or other funky fields */ 454 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
461 if (!keyboard_protocol) { 455 if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
462 send_report(USB_ENDPOINT_IN_KEYBOARD, &report->mods, 8); 456 send_report(USB_ENDPOINT_IN_KEYBOARD, &report->mods, 8);
463 } else { 457 } else {
464 send_report(USB_ENDPOINT_IN_KEYBOARD, report, KEYBOARD_REPORT_SIZE); 458 send_report(USB_ENDPOINT_IN_KEYBOARD, report, KEYBOARD_REPORT_SIZE);
diff --git a/tmk_core/protocol/host.h b/tmk_core/protocol/host.h
index 959753ae02..d824fca077 100644
--- a/tmk_core/protocol/host.h
+++ b/tmk_core/protocol/host.h
@@ -27,9 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
27extern "C" { 27extern "C" {
28#endif 28#endif
29 29
30extern uint8_t keyboard_idle;
31extern uint8_t keyboard_protocol;
32
33/* host driver */ 30/* host driver */
34void host_set_driver(host_driver_t *driver); 31void host_set_driver(host_driver_t *driver);
35host_driver_t *host_get_driver(void); 32host_driver_t *host_get_driver(void);
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index b0c9758d2f..81da035f0c 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -72,20 +72,14 @@
72# define USB_WAIT_FOR_ENUMERATION 72# define USB_WAIT_FOR_ENUMERATION
73#endif 73#endif
74 74
75uint8_t keyboard_idle = 0;
76/* 0: Boot Protocol, 1: Report Protocol(default) */
77uint8_t keyboard_protocol = 1;
78static uint8_t keyboard_led_state = 0;
79
80static report_keyboard_t keyboard_report_sent; 75static report_keyboard_t keyboard_report_sent;
81 76
82/* Host driver */ 77/* Host driver */
83static uint8_t keyboard_leds(void); 78static void send_keyboard(report_keyboard_t *report);
84static void send_keyboard(report_keyboard_t *report); 79static void send_nkro(report_nkro_t *report);
85static void send_nkro(report_nkro_t *report); 80static void send_mouse(report_mouse_t *report);
86static void send_mouse(report_mouse_t *report); 81static void send_extra(report_extra_t *report);
87static void send_extra(report_extra_t *report); 82host_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};
88host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
89 83
90void send_report(uint8_t endpoint, void *report, size_t size) { 84void send_report(uint8_t endpoint, void *report, size_t size) {
91 uint8_t timeout = 255; 85 uint8_t timeout = 255;
@@ -271,6 +265,7 @@ void EVENT_USB_Device_Disconnect(void) {
271void EVENT_USB_Device_Reset(void) { 265void EVENT_USB_Device_Reset(void) {
272 print("[R]"); 266 print("[R]");
273 usb_device_state_set_reset(); 267 usb_device_state_set_reset();
268 usb_device_state_set_protocol(USB_PROTOCOL_REPORT);
274} 269}
275 270
276/** \brief Event USB Device Connect 271/** \brief Event USB Device Connect
@@ -453,10 +448,10 @@ void EVENT_USB_Device_ControlRequest(void) {
453 uint8_t report_id = Endpoint_Read_8(); 448 uint8_t report_id = Endpoint_Read_8();
454 449
455 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) { 450 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
456 keyboard_led_state = Endpoint_Read_8(); 451 usb_device_state_set_leds(Endpoint_Read_8());
457 } 452 }
458 } else { 453 } else {
459 keyboard_led_state = Endpoint_Read_8(); 454 usb_device_state_set_leds(Endpoint_Read_8());
460 } 455 }
461 456
462 Endpoint_ClearOUT(); 457 Endpoint_ClearOUT();
@@ -473,7 +468,7 @@ void EVENT_USB_Device_ControlRequest(void) {
473 Endpoint_ClearSETUP(); 468 Endpoint_ClearSETUP();
474 while (!(Endpoint_IsINReady())) 469 while (!(Endpoint_IsINReady()))
475 ; 470 ;
476 Endpoint_Write_8(keyboard_protocol); 471 Endpoint_Write_8(usb_device_state_get_protocol());
477 Endpoint_ClearIN(); 472 Endpoint_ClearIN();
478 Endpoint_ClearStatusStage(); 473 Endpoint_ClearStatusStage();
479 } 474 }
@@ -486,7 +481,7 @@ void EVENT_USB_Device_ControlRequest(void) {
486 Endpoint_ClearSETUP(); 481 Endpoint_ClearSETUP();
487 Endpoint_ClearStatusStage(); 482 Endpoint_ClearStatusStage();
488 483
489 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); 484 usb_device_state_set_protocol(USB_ControlRequest.wValue & 0xFF);
490 clear_keyboard(); 485 clear_keyboard();
491 } 486 }
492 } 487 }
@@ -497,7 +492,7 @@ void EVENT_USB_Device_ControlRequest(void) {
497 Endpoint_ClearSETUP(); 492 Endpoint_ClearSETUP();
498 Endpoint_ClearStatusStage(); 493 Endpoint_ClearStatusStage();
499 494
500 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); 495 usb_device_state_set_idle_rate(USB_ControlRequest.wValue >> 8);
501 } 496 }
502 497
503 break; 498 break;
@@ -506,7 +501,7 @@ void EVENT_USB_Device_ControlRequest(void) {
506 Endpoint_ClearSETUP(); 501 Endpoint_ClearSETUP();
507 while (!(Endpoint_IsINReady())) 502 while (!(Endpoint_IsINReady()))
508 ; 503 ;
509 Endpoint_Write_8(keyboard_idle); 504 Endpoint_Write_8(usb_device_state_get_idle_rate());
510 Endpoint_ClearIN(); 505 Endpoint_ClearIN();
511 Endpoint_ClearStatusStage(); 506 Endpoint_ClearStatusStage();
512 } 507 }
@@ -522,13 +517,6 @@ void EVENT_USB_Device_ControlRequest(void) {
522/******************************************************************************* 517/*******************************************************************************
523 * Host driver 518 * Host driver
524 ******************************************************************************/ 519 ******************************************************************************/
525/** \brief Keyboard LEDs
526 *
527 * FIXME: Needs doc
528 */
529static uint8_t keyboard_leds(void) {
530 return keyboard_led_state;
531}
532 520
533/** \brief Send Keyboard 521/** \brief Send Keyboard
534 * 522 *
@@ -536,7 +524,7 @@ static uint8_t keyboard_leds(void) {
536 */ 524 */
537static void send_keyboard(report_keyboard_t *report) { 525static void send_keyboard(report_keyboard_t *report) {
538 /* If we're in Boot Protocol, don't send any report ID or other funky fields */ 526 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
539 if (!keyboard_protocol) { 527 if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
540 send_report(KEYBOARD_IN_EPNUM, &report->mods, 8); 528 send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
541 } else { 529 } else {
542 send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE); 530 send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
diff --git a/tmk_core/protocol/report.c b/tmk_core/protocol/report.c
index 056921d6a0..6203a3116b 100644
--- a/tmk_core/protocol/report.c
+++ b/tmk_core/protocol/report.c
@@ -19,6 +19,7 @@
19#include "host.h" 19#include "host.h"
20#include "keycode_config.h" 20#include "keycode_config.h"
21#include "debug.h" 21#include "debug.h"
22#include "usb_device_state.h"
22#include "util.h" 23#include "util.h"
23#include <string.h> 24#include <string.h>
24 25
@@ -31,7 +32,7 @@ uint8_t has_anykey(void) {
31 uint8_t* p = keyboard_report->keys; 32 uint8_t* p = keyboard_report->keys;
32 uint8_t lp = sizeof(keyboard_report->keys); 33 uint8_t lp = sizeof(keyboard_report->keys);
33#ifdef NKRO_ENABLE 34#ifdef NKRO_ENABLE
34 if (keyboard_protocol && keymap_config.nkro) { 35 if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
35 p = nkro_report->bits; 36 p = nkro_report->bits;
36 lp = sizeof(nkro_report->bits); 37 lp = sizeof(nkro_report->bits);
37 } 38 }
@@ -48,7 +49,7 @@ uint8_t has_anykey(void) {
48 */ 49 */
49uint8_t get_first_key(void) { 50uint8_t get_first_key(void) {
50#ifdef NKRO_ENABLE 51#ifdef NKRO_ENABLE
51 if (keyboard_protocol && keymap_config.nkro) { 52 if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
52 uint8_t i = 0; 53 uint8_t i = 0;
53 for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++) 54 for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
54 ; 55 ;
@@ -68,7 +69,7 @@ bool is_key_pressed(uint8_t key) {
68 return false; 69 return false;
69 } 70 }
70#ifdef NKRO_ENABLE 71#ifdef NKRO_ENABLE
71 if (keyboard_protocol && keymap_config.nkro) { 72 if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
72 if ((key >> 3) < NKRO_REPORT_BITS) { 73 if ((key >> 3) < NKRO_REPORT_BITS) {
73 return nkro_report->bits[key >> 3] & 1 << (key & 7); 74 return nkro_report->bits[key >> 3] & 1 << (key & 7);
74 } else { 75 } else {
@@ -150,7 +151,7 @@ void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
150 */ 151 */
151void add_key_to_report(uint8_t key) { 152void add_key_to_report(uint8_t key) {
152#ifdef NKRO_ENABLE 153#ifdef NKRO_ENABLE
153 if (keyboard_protocol && keymap_config.nkro) { 154 if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
154 add_key_bit(nkro_report, key); 155 add_key_bit(nkro_report, key);
155 return; 156 return;
156 } 157 }
@@ -164,7 +165,7 @@ void add_key_to_report(uint8_t key) {
164 */ 165 */
165void del_key_from_report(uint8_t key) { 166void del_key_from_report(uint8_t key) {
166#ifdef NKRO_ENABLE 167#ifdef NKRO_ENABLE
167 if (keyboard_protocol && keymap_config.nkro) { 168 if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
168 del_key_bit(nkro_report, key); 169 del_key_bit(nkro_report, key);
169 return; 170 return;
170 } 171 }
@@ -179,7 +180,7 @@ void del_key_from_report(uint8_t key) {
179void clear_keys_from_report(void) { 180void clear_keys_from_report(void) {
180 // not clear mods 181 // not clear mods
181#ifdef NKRO_ENABLE 182#ifdef NKRO_ENABLE
182 if (keyboard_protocol && keymap_config.nkro) { 183 if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
183 memset(nkro_report->bits, 0, sizeof(nkro_report->bits)); 184 memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
184 return; 185 return;
185 } 186 }
diff --git a/tmk_core/protocol/usb_device_state.c b/tmk_core/protocol/usb_device_state.c
index 4cd241528d..98ccfbc902 100644
--- a/tmk_core/protocol/usb_device_state.c
+++ b/tmk_core/protocol/usb_device_state.c
@@ -24,15 +24,15 @@
24# include "os_detection.h" 24# include "os_detection.h"
25#endif 25#endif
26 26
27enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT; 27static struct usb_device_state usb_device_state = {.idle_rate = 0, .leds = 0, .protocol = USB_PROTOCOL_REPORT, .configure_state = USB_DEVICE_STATE_NO_INIT};
28 28
29__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { 29__attribute__((weak)) void notify_usb_device_state_change_kb(struct usb_device_state usb_device_state) {
30 notify_usb_device_state_change_user(usb_device_state); 30 notify_usb_device_state_change_user(usb_device_state);
31} 31}
32 32
33__attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {} 33__attribute__((weak)) void notify_usb_device_state_change_user(struct usb_device_state usb_device_state) {}
34 34
35static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { 35static void notify_usb_device_state_change(struct usb_device_state usb_device_state) {
36#if defined(HAPTIC_ENABLE) && HAPTIC_OFF_IN_LOW_POWER 36#if defined(HAPTIC_ENABLE) && HAPTIC_OFF_IN_LOW_POWER
37 haptic_notify_usb_device_state_change(); 37 haptic_notify_usb_device_state_change();
38#endif 38#endif
@@ -44,27 +44,58 @@ static void notify_usb_device_state_change(enum usb_device_state usb_device_stat
44#endif 44#endif
45} 45}
46 46
47void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) { 47void usb_device_state_set_configuration(bool is_configured, uint8_t configuration_number) {
48 usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; 48 usb_device_state.configure_state = is_configured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
49 notify_usb_device_state_change(usb_device_state); 49 notify_usb_device_state_change(usb_device_state);
50} 50}
51 51
52void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) { 52void usb_device_state_set_suspend(bool is_configured, uint8_t configuration_number) {
53 usb_device_state = USB_DEVICE_STATE_SUSPEND; 53 usb_device_state.configure_state = USB_DEVICE_STATE_SUSPEND;
54 notify_usb_device_state_change(usb_device_state); 54 notify_usb_device_state_change(usb_device_state);
55} 55}
56 56
57void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) { 57void usb_device_state_set_resume(bool is_configured, uint8_t configuration_number) {
58 usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; 58 usb_device_state.configure_state = is_configured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
59 notify_usb_device_state_change(usb_device_state); 59 notify_usb_device_state_change(usb_device_state);
60} 60}
61 61
62void usb_device_state_set_reset(void) { 62void usb_device_state_set_reset(void) {
63 usb_device_state = USB_DEVICE_STATE_INIT; 63 usb_device_state.configure_state = USB_DEVICE_STATE_INIT;
64 notify_usb_device_state_change(usb_device_state); 64 notify_usb_device_state_change(usb_device_state);
65} 65}
66 66
67void usb_device_state_init(void) { 67void usb_device_state_init(void) {
68 usb_device_state = USB_DEVICE_STATE_INIT; 68 usb_device_state.configure_state = USB_DEVICE_STATE_INIT;
69 notify_usb_device_state_change(usb_device_state); 69 notify_usb_device_state_change(usb_device_state);
70} 70}
71
72inline usb_configure_state_t usb_device_state_get_configure_state(void) {
73 return usb_device_state.configure_state;
74}
75
76void usb_device_state_set_protocol(usb_hid_protocol_t protocol) {
77 usb_device_state.protocol = protocol == USB_PROTOCOL_BOOT ? USB_PROTOCOL_BOOT : USB_PROTOCOL_REPORT;
78 notify_usb_device_state_change(usb_device_state);
79}
80
81inline usb_hid_protocol_t usb_device_state_get_protocol() {
82 return usb_device_state.protocol;
83}
84
85void usb_device_state_set_leds(uint8_t leds) {
86 usb_device_state.leds = leds;
87 notify_usb_device_state_change(usb_device_state);
88}
89
90inline uint8_t usb_device_state_get_leds(void) {
91 return usb_device_state.leds;
92}
93
94void usb_device_state_set_idle_rate(uint8_t idle_rate) {
95 usb_device_state.idle_rate = idle_rate;
96 notify_usb_device_state_change(usb_device_state);
97}
98
99inline uint8_t usb_device_state_get_idle_rate(void) {
100 return usb_device_state.idle_rate;
101}
diff --git a/tmk_core/protocol/usb_device_state.h b/tmk_core/protocol/usb_device_state.h
index 3be65ea7e1..6d12f144fe 100644
--- a/tmk_core/protocol/usb_device_state.h
+++ b/tmk_core/protocol/usb_device_state.h
@@ -20,20 +20,41 @@
20#include <stdbool.h> 20#include <stdbool.h>
21#include <stdint.h> 21#include <stdint.h>
22 22
23void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber); 23typedef enum {
24void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber);
25void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber);
26void usb_device_state_set_reset(void);
27void usb_device_state_init(void);
28
29enum usb_device_state {
30 USB_DEVICE_STATE_NO_INIT = 0, // We're in this state before calling usb_device_state_init() 24 USB_DEVICE_STATE_NO_INIT = 0, // We're in this state before calling usb_device_state_init()
31 USB_DEVICE_STATE_INIT = 1, // Can consume up to 100mA 25 USB_DEVICE_STATE_INIT = 1, // Can consume up to 100mA
32 USB_DEVICE_STATE_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA 26 USB_DEVICE_STATE_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA
33 USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current 27 USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current
28} usb_configure_state_t;
29
30typedef enum {
31 USB_PROTOCOL_BOOT = 0,
32 USB_PROTOCOL_REPORT = 1,
33} usb_hid_protocol_t;
34
35// note: we can't typedef this struct to usb_device_state_t because it would
36// conflict with the previous definition in:
37// lib/chibios-contrib/ext/nxp-middleware-usb/device/usb_device.h
38struct usb_device_state {
39 uint8_t idle_rate;
40 uint8_t leds;
41 usb_hid_protocol_t protocol;
42 usb_configure_state_t configure_state;
34}; 43};
35 44
36extern enum usb_device_state usb_device_state; 45void usb_device_state_set_configuration(bool is_configured, uint8_t configuration_number);
46void usb_device_state_set_suspend(bool is_configured, uint8_t configuration_number);
47void usb_device_state_set_resume(bool is_configured, uint8_t configuration_number);
48void usb_device_state_set_reset(void);
49void usb_device_state_init(void);
50usb_configure_state_t usb_device_state_get_configure_state(void);
51void usb_device_state_set_protocol(usb_hid_protocol_t protocol);
52usb_hid_protocol_t usb_device_state_get_protocol(void);
53void usb_device_state_set_leds(uint8_t leds);
54uint8_t usb_device_state_get_leds(void);
55void usb_device_state_set_idle_rate(uint8_t idle_rate);
56uint8_t usb_device_state_get_idle_rate(void);
57void usb_device_state_reset_hid_state(void);
37 58
38void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state); 59void notify_usb_device_state_change_kb(struct usb_device_state usb_device_state);
39void notify_usb_device_state_change_user(enum usb_device_state usb_device_state); 60void notify_usb_device_state_change_user(struct usb_device_state usb_device_state);
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index c269ff2b91..2a29fe65d9 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
30#include "debug.h" 30#include "debug.h"
31#include "wait.h" 31#include "wait.h"
32#include "usb_descriptor_common.h" 32#include "usb_descriptor_common.h"
33#include "usb_device_state.h"
33 34
34#ifdef RAW_ENABLE 35#ifdef RAW_ENABLE
35# include "raw_hid.h" 36# include "raw_hid.h"
@@ -85,10 +86,6 @@ _Static_assert(TOTAL_INTERFACES <= MAX_INTERFACES, "There are not enough availab
85# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two. 86# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
86#endif 87#endif
87 88
88static uint8_t keyboard_led_state = 0;
89uint8_t keyboard_idle = 0;
90uint8_t keyboard_protocol = 1;
91
92static report_keyboard_t keyboard_report_sent; 89static report_keyboard_t keyboard_report_sent;
93 90
94static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { 91static void send_report_fragment(uint8_t endpoint, void *data, size_t size) {
@@ -212,24 +209,19 @@ void console_task(void) {
212/*------------------------------------------------------------------* 209/*------------------------------------------------------------------*
213 * Host driver 210 * Host driver
214 *------------------------------------------------------------------*/ 211 *------------------------------------------------------------------*/
215static uint8_t keyboard_leds(void); 212static void send_keyboard(report_keyboard_t *report);
216static void send_keyboard(report_keyboard_t *report); 213static void send_nkro(report_nkro_t *report);
217static void send_nkro(report_nkro_t *report); 214static void send_mouse(report_mouse_t *report);
218static void send_mouse(report_mouse_t *report); 215static void send_extra(report_extra_t *report);
219static void send_extra(report_extra_t *report);
220 216
221static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; 217static 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};
222 218
223host_driver_t *vusb_driver(void) { 219host_driver_t *vusb_driver(void) {
224 return &driver; 220 return &driver;
225} 221}
226 222
227static uint8_t keyboard_leds(void) {
228 return keyboard_led_state;
229}
230
231static void send_keyboard(report_keyboard_t *report) { 223static void send_keyboard(report_keyboard_t *report) {
232 if (!keyboard_protocol) { 224 if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
233 send_report(1, &report->mods, 8); 225 send_report(1, &report->mods, 8);
234 } else { 226 } else {
235 send_report(1, report, sizeof(report_keyboard_t)); 227 send_report(1, report, sizeof(report_keyboard_t));
@@ -304,11 +296,15 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
304 break; 296 break;
305 case USBRQ_HID_GET_IDLE: 297 case USBRQ_HID_GET_IDLE:
306 dprint("GET_IDLE:"); 298 dprint("GET_IDLE:");
307 usbMsgPtr = (usbMsgPtr_t)&keyboard_idle; 299 static uint8_t keyboard_idle;
300 keyboard_idle = usb_device_state_get_idle_rate();
301 usbMsgPtr = (usbMsgPtr_t)&keyboard_idle;
308 return 1; 302 return 1;
309 case USBRQ_HID_GET_PROTOCOL: 303 case USBRQ_HID_GET_PROTOCOL:
310 dprint("GET_PROTOCOL:"); 304 dprint("GET_PROTOCOL:");
311 usbMsgPtr = (usbMsgPtr_t)&keyboard_protocol; 305 static uint8_t keyboard_protocol;
306 keyboard_protocol = usb_device_state_get_protocol();
307 usbMsgPtr = (usbMsgPtr_t)&keyboard_protocol;
312 return 1; 308 return 1;
313 case USBRQ_HID_SET_REPORT: 309 case USBRQ_HID_SET_REPORT:
314 dprint("SET_REPORT:"); 310 dprint("SET_REPORT:");
@@ -320,13 +316,13 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
320 } 316 }
321 return USB_NO_MSG; // to get data in usbFunctionWrite 317 return USB_NO_MSG; // to get data in usbFunctionWrite
322 case USBRQ_HID_SET_IDLE: 318 case USBRQ_HID_SET_IDLE:
323 keyboard_idle = (rq->wValue.word & 0xFF00) >> 8; 319 usb_device_state_set_idle_rate(rq->wValue.word >> 8);
324 dprintf("SET_IDLE: %02X", keyboard_idle); 320 dprintf("SET_IDLE: %02X", usb_device_state_get_idle_rate());
325 break; 321 break;
326 case USBRQ_HID_SET_PROTOCOL: 322 case USBRQ_HID_SET_PROTOCOL:
327 if (rq->wIndex.word == KEYBOARD_INTERFACE) { 323 if (rq->wIndex.word == KEYBOARD_INTERFACE) {
328 keyboard_protocol = rq->wValue.word & 0xFF; 324 usb_device_state_set_protocol(rq->wValue.word & 0xFF);
329 dprintf("SET_PROTOCOL: %02X", keyboard_protocol); 325 dprintf("SET_PROTOCOL: %02X", usb_device_state_get_protocol());
330 } 326 }
331 break; 327 break;
332 default: 328 default:
@@ -347,9 +343,9 @@ uchar usbFunctionWrite(uchar *data, uchar len) {
347 } 343 }
348 switch (last_req.kind) { 344 switch (last_req.kind) {
349 case SET_LED: 345 case SET_LED:
350 dprintf("SET_LED: %02X\n", data[0]); 346 usb_device_state_set_leds(data[0]);
351 keyboard_led_state = data[0]; 347 dprintf("SET_LED: %02X\n", usb_device_state_get_leds());
352 last_req.len = 0; 348 last_req.len = 0;
353 return 1; 349 return 1;
354 break; 350 break;
355 case NONE: 351 case NONE: