diff options
| -rw-r--r-- | common_features.mk | 1 | ||||
| -rw-r--r-- | quantum/usb_device_state.c | 51 | ||||
| -rw-r--r-- | quantum/usb_device_state.h | 39 | ||||
| -rw-r--r-- | tmk_core/protocol/chibios/chibios.c | 3 | ||||
| -rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 15 | ||||
| -rw-r--r-- | tmk_core/protocol/lufa/lufa.c | 13 |
6 files changed, 120 insertions, 2 deletions
diff --git a/common_features.mk b/common_features.mk index 619359717..a71bcace0 100644 --- a/common_features.mk +++ b/common_features.mk | |||
| @@ -29,6 +29,7 @@ QUANTUM_SRC += \ | |||
| 29 | $(QUANTUM_DIR)/keyboard.c \ | 29 | $(QUANTUM_DIR)/keyboard.c \ |
| 30 | $(QUANTUM_DIR)/keymap_common.c \ | 30 | $(QUANTUM_DIR)/keymap_common.c \ |
| 31 | $(QUANTUM_DIR)/keycode_config.c \ | 31 | $(QUANTUM_DIR)/keycode_config.c \ |
| 32 | $(QUANTUM_DIR)/usb_device_state.c \ | ||
| 32 | $(QUANTUM_DIR)/logging/debug.c \ | 33 | $(QUANTUM_DIR)/logging/debug.c \ |
| 33 | $(QUANTUM_DIR)/logging/sendchar.c \ | 34 | $(QUANTUM_DIR)/logging/sendchar.c \ |
| 34 | 35 | ||
diff --git a/quantum/usb_device_state.c b/quantum/usb_device_state.c new file mode 100644 index 000000000..5ccd309ec --- /dev/null +++ b/quantum/usb_device_state.c | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2021 Andrei Purdea <andrei@purdea.ro> | ||
| 3 | * | ||
| 4 | * This program is free software: you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation, either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "usb_device_state.h" | ||
| 19 | |||
| 20 | enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT; | ||
| 21 | |||
| 22 | __attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { notify_usb_device_state_change_user(usb_device_state); } | ||
| 23 | |||
| 24 | __attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {} | ||
| 25 | |||
| 26 | static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { notify_usb_device_state_change_kb(usb_device_state); } | ||
| 27 | |||
| 28 | void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) { | ||
| 29 | usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; | ||
| 30 | notify_usb_device_state_change(usb_device_state); | ||
| 31 | } | ||
| 32 | |||
| 33 | void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) { | ||
| 34 | usb_device_state = USB_DEVICE_STATE_SUSPEND; | ||
| 35 | notify_usb_device_state_change(usb_device_state); | ||
| 36 | } | ||
| 37 | |||
| 38 | void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) { | ||
| 39 | usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; | ||
| 40 | notify_usb_device_state_change(usb_device_state); | ||
| 41 | } | ||
| 42 | |||
| 43 | void usb_device_state_set_reset(void) { | ||
| 44 | usb_device_state = USB_DEVICE_STATE_INIT; | ||
| 45 | notify_usb_device_state_change(usb_device_state); | ||
| 46 | } | ||
| 47 | |||
| 48 | void usb_device_state_init(void) { | ||
| 49 | usb_device_state = USB_DEVICE_STATE_INIT; | ||
| 50 | notify_usb_device_state_change(usb_device_state); | ||
| 51 | } | ||
diff --git a/quantum/usb_device_state.h b/quantum/usb_device_state.h new file mode 100644 index 000000000..c229311d4 --- /dev/null +++ b/quantum/usb_device_state.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2021 Andrei Purdea <andrei@purdea.ro> | ||
| 3 | * | ||
| 4 | * This program is free software: you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation, either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdbool.h> | ||
| 21 | #include <stdint.h> | ||
| 22 | |||
| 23 | void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber); | ||
| 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() | ||
| 31 | 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 | ||
| 33 | USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current | ||
| 34 | }; | ||
| 35 | |||
| 36 | extern enum usb_device_state usb_device_state; | ||
| 37 | |||
| 38 | void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state); | ||
| 39 | void notify_usb_device_state_change_user(enum usb_device_state usb_device_state); | ||
diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index 78a2e3fcb..e5d3a4c54 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/tmk_core/protocol/chibios/chibios.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include "keyboard.h" | 27 | #include "keyboard.h" |
| 28 | #include "action.h" | 28 | #include "action.h" |
| 29 | #include "action_util.h" | 29 | #include "action_util.h" |
| 30 | #include "usb_device_state.h" | ||
| 30 | #include "mousekey.h" | 31 | #include "mousekey.h" |
| 31 | #include "led.h" | 32 | #include "led.h" |
| 32 | #include "sendchar.h" | 33 | #include "sendchar.h" |
| @@ -139,6 +140,8 @@ void boardInit(void) { | |||
| 139 | } | 140 | } |
| 140 | 141 | ||
| 141 | void protocol_setup(void) { | 142 | void protocol_setup(void) { |
| 143 | usb_device_state_init(); | ||
| 144 | |||
| 142 | // TESTING | 145 | // TESTING |
| 143 | // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); | 146 | // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); |
| 144 | 147 | ||
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index cc282e6a9..9b139b399 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | # include "led.h" | 39 | # include "led.h" |
| 40 | #endif | 40 | #endif |
| 41 | #include "wait.h" | 41 | #include "wait.h" |
| 42 | #include "usb_device_state.h" | ||
| 42 | #include "usb_descriptor.h" | 43 | #include "usb_descriptor.h" |
| 43 | #include "usb_driver.h" | 44 | #include "usb_driver.h" |
| 44 | 45 | ||
| @@ -412,6 +413,7 @@ static inline bool usb_event_queue_dequeue(usbevent_t *event) { | |||
| 412 | } | 413 | } |
| 413 | 414 | ||
| 414 | static inline void usb_event_suspend_handler(void) { | 415 | static inline void usb_event_suspend_handler(void) { |
| 416 | usb_device_state_set_suspend(USB_DRIVER.configuration != 0, USB_DRIVER.configuration); | ||
| 415 | #ifdef SLEEP_LED_ENABLE | 417 | #ifdef SLEEP_LED_ENABLE |
| 416 | sleep_led_enable(); | 418 | sleep_led_enable(); |
| 417 | #endif /* SLEEP_LED_ENABLE */ | 419 | #endif /* SLEEP_LED_ENABLE */ |
| @@ -419,6 +421,7 @@ static inline void usb_event_suspend_handler(void) { | |||
| 419 | 421 | ||
| 420 | static inline void usb_event_wakeup_handler(void) { | 422 | static inline void usb_event_wakeup_handler(void) { |
| 421 | suspend_wakeup_init(); | 423 | suspend_wakeup_init(); |
| 424 | usb_device_state_set_resume(USB_DRIVER.configuration != 0, USB_DRIVER.configuration); | ||
| 422 | #ifdef SLEEP_LED_ENABLE | 425 | #ifdef SLEEP_LED_ENABLE |
| 423 | sleep_led_disable(); | 426 | sleep_led_disable(); |
| 424 | // NOTE: converters may not accept this | 427 | // NOTE: converters may not accept this |
| @@ -440,6 +443,15 @@ void usb_event_queue_task(void) { | |||
| 440 | last_suspend_state = false; | 443 | last_suspend_state = false; |
| 441 | usb_event_wakeup_handler(); | 444 | usb_event_wakeup_handler(); |
| 442 | break; | 445 | break; |
| 446 | case USB_EVENT_CONFIGURED: | ||
| 447 | usb_device_state_set_configuration(USB_DRIVER.configuration != 0, USB_DRIVER.configuration); | ||
| 448 | break; | ||
| 449 | case USB_EVENT_UNCONFIGURED: | ||
| 450 | usb_device_state_set_configuration(false, 0); | ||
| 451 | break; | ||
| 452 | case USB_EVENT_RESET: | ||
| 453 | usb_device_state_set_reset(); | ||
| 454 | break; | ||
| 443 | default: | 455 | default: |
| 444 | // Nothing to do, we don't handle it. | 456 | // Nothing to do, we don't handle it. |
| 445 | break; | 457 | break; |
| @@ -482,13 +494,14 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { | |||
| 482 | if (last_suspend_state) { | 494 | if (last_suspend_state) { |
| 483 | usb_event_queue_enqueue(USB_EVENT_WAKEUP); | 495 | usb_event_queue_enqueue(USB_EVENT_WAKEUP); |
| 484 | } | 496 | } |
| 497 | usb_event_queue_enqueue(USB_EVENT_CONFIGURED); | ||
| 485 | return; | 498 | return; |
| 486 | case USB_EVENT_SUSPEND: | 499 | case USB_EVENT_SUSPEND: |
| 487 | usb_event_queue_enqueue(USB_EVENT_SUSPEND); | ||
| 488 | /* Falls into.*/ | 500 | /* Falls into.*/ |
| 489 | case USB_EVENT_UNCONFIGURED: | 501 | case USB_EVENT_UNCONFIGURED: |
| 490 | /* Falls into.*/ | 502 | /* Falls into.*/ |
| 491 | case USB_EVENT_RESET: | 503 | case USB_EVENT_RESET: |
| 504 | usb_event_queue_enqueue(event); | ||
| 492 | for (int i = 0; i < NUM_USB_DRIVERS; i++) { | 505 | for (int i = 0; i < NUM_USB_DRIVERS; i++) { |
| 493 | chSysLockFromISR(); | 506 | chSysLockFromISR(); |
| 494 | /* Disconnection event on suspend.*/ | 507 | /* Disconnection event on suspend.*/ |
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 4a30d2257..753762358 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #include "usb_descriptor.h" | 52 | #include "usb_descriptor.h" |
| 53 | #include "lufa.h" | 53 | #include "lufa.h" |
| 54 | #include "quantum.h" | 54 | #include "quantum.h" |
| 55 | #include "usb_device_state.h" | ||
| 55 | #include <util/atomic.h> | 56 | #include <util/atomic.h> |
| 56 | 57 | ||
| 57 | #ifdef NKRO_ENABLE | 58 | #ifdef NKRO_ENABLE |
| @@ -414,7 +415,10 @@ void EVENT_USB_Device_Disconnect(void) { | |||
| 414 | * | 415 | * |
| 415 | * FIXME: Needs doc | 416 | * FIXME: Needs doc |
| 416 | */ | 417 | */ |
| 417 | void EVENT_USB_Device_Reset(void) { print("[R]"); } | 418 | void EVENT_USB_Device_Reset(void) { |
| 419 | print("[R]"); | ||
| 420 | usb_device_state_set_reset(); | ||
| 421 | } | ||
| 418 | 422 | ||
| 419 | /** \brief Event USB Device Connect | 423 | /** \brief Event USB Device Connect |
| 420 | * | 424 | * |
| @@ -422,6 +426,8 @@ void EVENT_USB_Device_Reset(void) { print("[R]"); } | |||
| 422 | */ | 426 | */ |
| 423 | void EVENT_USB_Device_Suspend() { | 427 | void EVENT_USB_Device_Suspend() { |
| 424 | print("[S]"); | 428 | print("[S]"); |
| 429 | usb_device_state_set_suspend(USB_Device_ConfigurationNumber != 0, USB_Device_ConfigurationNumber); | ||
| 430 | |||
| 425 | #ifdef SLEEP_LED_ENABLE | 431 | #ifdef SLEEP_LED_ENABLE |
| 426 | sleep_led_enable(); | 432 | sleep_led_enable(); |
| 427 | #endif | 433 | #endif |
| @@ -437,6 +443,8 @@ void EVENT_USB_Device_WakeUp() { | |||
| 437 | suspend_wakeup_init(); | 443 | suspend_wakeup_init(); |
| 438 | #endif | 444 | #endif |
| 439 | 445 | ||
| 446 | usb_device_state_set_resume(USB_DeviceState == DEVICE_STATE_Configured, USB_Device_ConfigurationNumber); | ||
| 447 | |||
| 440 | #ifdef SLEEP_LED_ENABLE | 448 | #ifdef SLEEP_LED_ENABLE |
| 441 | sleep_led_disable(); | 449 | sleep_led_disable(); |
| 442 | // NOTE: converters may not accept this | 450 | // NOTE: converters may not accept this |
| @@ -529,6 +537,8 @@ void EVENT_USB_Device_ConfigurationChanged(void) { | |||
| 529 | /* Setup digitizer endpoint */ | 537 | /* Setup digitizer endpoint */ |
| 530 | ConfigSuccess &= Endpoint_ConfigureEndpoint((DIGITIZER_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, DIGITIZER_EPSIZE, 1); | 538 | ConfigSuccess &= Endpoint_ConfigureEndpoint((DIGITIZER_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, DIGITIZER_EPSIZE, 1); |
| 531 | #endif | 539 | #endif |
| 540 | |||
| 541 | usb_device_state_set_configuration(USB_DeviceState == DEVICE_STATE_Configured, USB_Device_ConfigurationNumber); | ||
| 532 | } | 542 | } |
| 533 | 543 | ||
| 534 | /* FIXME: Expose this table in the docs somehow | 544 | /* FIXME: Expose this table in the docs somehow |
| @@ -1059,6 +1069,7 @@ void protocol_setup(void) { | |||
| 1059 | #endif | 1069 | #endif |
| 1060 | 1070 | ||
| 1061 | setup_mcu(); | 1071 | setup_mcu(); |
| 1072 | usb_device_state_init(); | ||
| 1062 | keyboard_setup(); | 1073 | keyboard_setup(); |
| 1063 | } | 1074 | } |
| 1064 | 1075 | ||
