diff options
| author | Stefan Kerkmann <karlk90@pm.me> | 2024-10-18 09:57:08 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-18 09:57:08 +0200 |
| commit | 3f9d4644126483bbd937f2be75a8878a1c986630 (patch) | |
| tree | 0c91e51941b048b87c816e05f36e8a6b50753b9b /tmk_core | |
| parent | 80f8aae3ec733cfbd6957a70f5fe436e5b92e725 (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>
Diffstat (limited to 'tmk_core')
| -rw-r--r-- | tmk_core/protocol/chibios/chibios.c | 11 | ||||
| -rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 24 | ||||
| -rw-r--r-- | tmk_core/protocol/host.h | 3 | ||||
| -rw-r--r-- | tmk_core/protocol/lufa/lufa.c | 38 | ||||
| -rw-r--r-- | tmk_core/protocol/report.c | 13 | ||||
| -rw-r--r-- | tmk_core/protocol/usb_device_state.c | 55 | ||||
| -rw-r--r-- | tmk_core/protocol/usb_device_state.h | 41 | ||||
| -rw-r--r-- | tmk_core/protocol/vusb/vusb.c | 44 |
8 files changed, 128 insertions, 101 deletions
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 */ |
| 65 | uint8_t keyboard_leds(void); | 65 | void send_keyboard(report_keyboard_t *report); |
| 66 | void send_keyboard(report_keyboard_t *report); | 66 | void send_nkro(report_nkro_t *report); |
| 67 | void send_nkro(report_nkro_t *report); | 67 | void send_mouse(report_mouse_t *report); |
| 68 | void send_mouse(report_mouse_t *report); | 68 | void send_extra(report_extra_t *report); |
| 69 | void send_extra(report_extra_t *report); | ||
| 70 | 69 | ||
| 71 | /* host struct */ | 70 | /* host struct */ |
| 72 | host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; | 71 | host_driver_t chibios_driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra}; |
| 73 | 72 | ||
| 74 | #ifdef VIRTSER_ENABLE | 73 | #ifdef VIRTSER_ENABLE |
| 75 | void virtser_task(void); | 74 | void 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; | |||
| 54 | extern usb_endpoint_in_t usb_endpoints_in[USB_ENDPOINT_IN_COUNT]; | 54 | extern usb_endpoint_in_t usb_endpoints_in[USB_ENDPOINT_IN_COUNT]; |
| 55 | extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT]; | 55 | extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT]; |
| 56 | 56 | ||
| 57 | uint8_t _Alignas(2) keyboard_idle = 0; | ||
| 58 | uint8_t _Alignas(2) keyboard_protocol = 1; | ||
| 59 | uint8_t keyboard_led_state = 0; | ||
| 60 | |||
| 61 | static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size); | 57 | static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size); |
| 62 | static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded); | 58 | static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded); |
| 63 | static bool __attribute__((__unused__)) receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size); | 59 | static 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 */ | ||
| 400 | uint8_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 | ||
| 459 | void send_keyboard(report_keyboard_t *report) { | 453 | void 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/>. | |||
| 27 | extern "C" { | 27 | extern "C" { |
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | extern uint8_t keyboard_idle; | ||
| 31 | extern uint8_t keyboard_protocol; | ||
| 32 | |||
| 33 | /* host driver */ | 30 | /* host driver */ |
| 34 | void host_set_driver(host_driver_t *driver); | 31 | void host_set_driver(host_driver_t *driver); |
| 35 | host_driver_t *host_get_driver(void); | 32 | host_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 | ||
| 75 | uint8_t keyboard_idle = 0; | ||
| 76 | /* 0: Boot Protocol, 1: Report Protocol(default) */ | ||
| 77 | uint8_t keyboard_protocol = 1; | ||
| 78 | static uint8_t keyboard_led_state = 0; | ||
| 79 | |||
| 80 | static report_keyboard_t keyboard_report_sent; | 75 | static report_keyboard_t keyboard_report_sent; |
| 81 | 76 | ||
| 82 | /* Host driver */ | 77 | /* Host driver */ |
| 83 | static uint8_t keyboard_leds(void); | 78 | static void send_keyboard(report_keyboard_t *report); |
| 84 | static void send_keyboard(report_keyboard_t *report); | 79 | static void send_nkro(report_nkro_t *report); |
| 85 | static void send_nkro(report_nkro_t *report); | 80 | static void send_mouse(report_mouse_t *report); |
| 86 | static void send_mouse(report_mouse_t *report); | 81 | static void send_extra(report_extra_t *report); |
| 87 | static void send_extra(report_extra_t *report); | 82 | host_driver_t lufa_driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra}; |
| 88 | host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; | ||
| 89 | 83 | ||
| 90 | void send_report(uint8_t endpoint, void *report, size_t size) { | 84 | void 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) { | |||
| 271 | void EVENT_USB_Device_Reset(void) { | 265 | void 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 | */ | ||
| 529 | static 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 | */ |
| 537 | static void send_keyboard(report_keyboard_t *report) { | 525 | static 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 | */ |
| 49 | uint8_t get_first_key(void) { | 50 | uint8_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 | */ |
| 151 | void add_key_to_report(uint8_t key) { | 152 | void 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 | */ |
| 165 | void del_key_from_report(uint8_t key) { | 166 | void 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) { | |||
| 179 | void clear_keys_from_report(void) { | 180 | void 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 | ||
| 27 | enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT; | 27 | static 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 | ||
| 35 | static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { | 35 | static 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 | ||
| 47 | void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) { | 47 | void 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 | ||
| 52 | void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) { | 52 | void 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 | ||
| 57 | void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) { | 57 | void 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 | ||
| 62 | void usb_device_state_set_reset(void) { | 62 | void 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 | ||
| 67 | void usb_device_state_init(void) { | 67 | void 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 | |||
| 72 | inline usb_configure_state_t usb_device_state_get_configure_state(void) { | ||
| 73 | return usb_device_state.configure_state; | ||
| 74 | } | ||
| 75 | |||
| 76 | void 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 | |||
| 81 | inline usb_hid_protocol_t usb_device_state_get_protocol() { | ||
| 82 | return usb_device_state.protocol; | ||
| 83 | } | ||
| 84 | |||
| 85 | void 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 | |||
| 90 | inline uint8_t usb_device_state_get_leds(void) { | ||
| 91 | return usb_device_state.leds; | ||
| 92 | } | ||
| 93 | |||
| 94 | void 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 | |||
| 99 | inline 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 | ||
| 23 | void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber); | 23 | typedef enum { |
| 24 | void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber); | ||
| 25 | void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber); | ||
| 26 | void usb_device_state_set_reset(void); | ||
| 27 | void usb_device_state_init(void); | ||
| 28 | |||
| 29 | enum 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 | |||
| 30 | typedef 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 | ||
| 38 | struct 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 | ||
| 36 | extern enum usb_device_state usb_device_state; | 45 | void usb_device_state_set_configuration(bool is_configured, uint8_t configuration_number); |
| 46 | void usb_device_state_set_suspend(bool is_configured, uint8_t configuration_number); | ||
| 47 | void usb_device_state_set_resume(bool is_configured, uint8_t configuration_number); | ||
| 48 | void usb_device_state_set_reset(void); | ||
| 49 | void usb_device_state_init(void); | ||
| 50 | usb_configure_state_t usb_device_state_get_configure_state(void); | ||
| 51 | void usb_device_state_set_protocol(usb_hid_protocol_t protocol); | ||
| 52 | usb_hid_protocol_t usb_device_state_get_protocol(void); | ||
| 53 | void usb_device_state_set_leds(uint8_t leds); | ||
| 54 | uint8_t usb_device_state_get_leds(void); | ||
| 55 | void usb_device_state_set_idle_rate(uint8_t idle_rate); | ||
| 56 | uint8_t usb_device_state_get_idle_rate(void); | ||
| 57 | void usb_device_state_reset_hid_state(void); | ||
| 37 | 58 | ||
| 38 | void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state); | 59 | void notify_usb_device_state_change_kb(struct usb_device_state usb_device_state); |
| 39 | void notify_usb_device_state_change_user(enum usb_device_state usb_device_state); | 60 | void 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 | ||
| 88 | static uint8_t keyboard_led_state = 0; | ||
| 89 | uint8_t keyboard_idle = 0; | ||
| 90 | uint8_t keyboard_protocol = 1; | ||
| 91 | |||
| 92 | static report_keyboard_t keyboard_report_sent; | 89 | static report_keyboard_t keyboard_report_sent; |
| 93 | 90 | ||
| 94 | static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { | 91 | static 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 | *------------------------------------------------------------------*/ |
| 215 | static uint8_t keyboard_leds(void); | 212 | static void send_keyboard(report_keyboard_t *report); |
| 216 | static void send_keyboard(report_keyboard_t *report); | 213 | static void send_nkro(report_nkro_t *report); |
| 217 | static void send_nkro(report_nkro_t *report); | 214 | static void send_mouse(report_mouse_t *report); |
| 218 | static void send_mouse(report_mouse_t *report); | 215 | static void send_extra(report_extra_t *report); |
| 219 | static void send_extra(report_extra_t *report); | ||
| 220 | 216 | ||
| 221 | static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; | 217 | static host_driver_t driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra}; |
| 222 | 218 | ||
| 223 | host_driver_t *vusb_driver(void) { | 219 | host_driver_t *vusb_driver(void) { |
| 224 | return &driver; | 220 | return &driver; |
| 225 | } | 221 | } |
| 226 | 222 | ||
| 227 | static uint8_t keyboard_leds(void) { | ||
| 228 | return keyboard_led_state; | ||
| 229 | } | ||
| 230 | |||
| 231 | static void send_keyboard(report_keyboard_t *report) { | 223 | static 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: |
