diff options
| author | Joel Challis <git@zvecr.com> | 2020-11-08 22:31:16 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-08 22:31:16 +0000 |
| commit | 1ff5ee255fadcd6bfc4defb68ef097d67ebd40ad (patch) | |
| tree | 559d771e6c2490ea7816b095b0e6e9a196462ec0 /quantum | |
| parent | 9cd3ffa5ba1187c0bc11b613078d89b503dcf419 (diff) | |
| download | qmk_firmware-1ff5ee255fadcd6bfc4defb68ef097d67ebd40ad.tar.gz qmk_firmware-1ff5ee255fadcd6bfc4defb68ef097d67ebd40ad.zip | |
Indicator LEDs as config (#10816)
* First pass
* Add config options to docs
* Update some wording
* Slight tidy up of backlight caps logic
* Init pin to correct state
* Move init location
* Reverse default state
Diffstat (limited to 'quantum')
| -rw-r--r-- | quantum/led.c | 137 | ||||
| -rw-r--r-- | quantum/quantum.c | 56 |
2 files changed, 141 insertions, 52 deletions
diff --git a/quantum/led.c b/quantum/led.c new file mode 100644 index 000000000..3e30b1a5a --- /dev/null +++ b/quantum/led.c | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | /* Copyright 2020 zvecr<git@zvecr.com> | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include "quantum.h" | ||
| 17 | |||
| 18 | #ifdef BACKLIGHT_ENABLE | ||
| 19 | # include "backlight.h" | ||
| 20 | extern backlight_config_t backlight_config; | ||
| 21 | #else | ||
| 22 | // Cannot use BACKLIGHT_CAPS_LOCK without backlight being enabled | ||
| 23 | # undef BACKLIGHT_CAPS_LOCK | ||
| 24 | #endif | ||
| 25 | |||
| 26 | #ifndef LED_PIN_ON_STATE | ||
| 27 | # define LED_PIN_ON_STATE 1 | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #if defined(BACKLIGHT_CAPS_LOCK) | ||
| 31 | /** \brief Caps Lock indicator using backlight (for keyboards without dedicated LED) | ||
| 32 | */ | ||
| 33 | static void handle_backlight_caps_lock(led_t led_state) { | ||
| 34 | // Use backlight as Caps Lock indicator | ||
| 35 | uint8_t bl_toggle_lvl = 0; | ||
| 36 | |||
| 37 | if (led_state.caps_lock && !backlight_config.enable) { | ||
| 38 | // Turning Caps Lock ON and backlight is disabled in config | ||
| 39 | // Toggling backlight to the brightest level | ||
| 40 | bl_toggle_lvl = BACKLIGHT_LEVELS; | ||
| 41 | } else if (!led_state.caps_lock && backlight_config.enable) { | ||
| 42 | // Turning Caps Lock OFF and backlight is enabled in config | ||
| 43 | // Toggling backlight and restoring config level | ||
| 44 | bl_toggle_lvl = backlight_config.level; | ||
| 45 | } | ||
| 46 | |||
| 47 | // Set level without modify backlight_config to keep ability to restore state | ||
| 48 | backlight_set(bl_toggle_lvl); | ||
| 49 | } | ||
| 50 | #endif | ||
| 51 | |||
| 52 | /** \brief Lock LED set callback - keymap/user level | ||
| 53 | * | ||
| 54 | * \deprecated Use led_update_user() instead. | ||
| 55 | */ | ||
| 56 | __attribute__((weak)) void led_set_user(uint8_t usb_led) {} | ||
| 57 | |||
| 58 | /** \brief Lock LED set callback - keyboard level | ||
| 59 | * | ||
| 60 | * \deprecated Use led_update_kb() instead. | ||
| 61 | */ | ||
| 62 | __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } | ||
| 63 | |||
| 64 | /** \brief Lock LED update callback - keymap/user level | ||
| 65 | * | ||
| 66 | * \return True if led_update_kb() should run its own code, false otherwise. | ||
| 67 | */ | ||
| 68 | __attribute__((weak)) bool led_update_user(led_t led_state) { return true; } | ||
| 69 | |||
| 70 | /** \brief Lock LED update callback - keyboard level | ||
| 71 | * | ||
| 72 | * \return Ignored for now. | ||
| 73 | */ | ||
| 74 | __attribute__((weak)) bool led_update_kb(led_t led_state) { | ||
| 75 | bool res = led_update_user(led_state); | ||
| 76 | if (res) { | ||
| 77 | #if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN) | ||
| 78 | # if LED_PIN_ON_STATE == 0 | ||
| 79 | // invert the whole thing to avoid having to conditionally !led_state.x later | ||
| 80 | led_state.raw = ~led_state.raw; | ||
| 81 | # endif | ||
| 82 | |||
| 83 | # ifdef LED_NUM_LOCK_PIN | ||
| 84 | writePin(LED_NUM_LOCK_PIN, led_state.num_lock); | ||
| 85 | # endif | ||
| 86 | # ifdef LED_CAPS_LOCK_PIN | ||
| 87 | writePin(LED_CAPS_LOCK_PIN, led_state.caps_lock); | ||
| 88 | # endif | ||
| 89 | # ifdef LED_SCROLL_LOCK_PIN | ||
| 90 | writePin(LED_SCROLL_LOCK_PIN, led_state.scroll_lock); | ||
| 91 | # endif | ||
| 92 | # ifdef LED_COMPOSE_PIN | ||
| 93 | writePin(LED_COMPOSE_PIN, led_state.compose); | ||
| 94 | # endif | ||
| 95 | # ifdef LED_KANA_PIN | ||
| 96 | writePin(LED_KANA_PIN, led_state.kana); | ||
| 97 | # endif | ||
| 98 | #endif | ||
| 99 | } | ||
| 100 | return res; | ||
| 101 | } | ||
| 102 | |||
| 103 | /** \brief Initialise any LED related hardware and/or state | ||
| 104 | */ | ||
| 105 | __attribute__((weak)) void led_init_ports(void) { | ||
| 106 | #ifdef LED_NUM_LOCK_PIN | ||
| 107 | setPinOutput(LED_NUM_LOCK_PIN); | ||
| 108 | writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE); | ||
| 109 | #endif | ||
| 110 | #ifdef LED_CAPS_LOCK_PIN | ||
| 111 | setPinOutput(LED_CAPS_LOCK_PIN); | ||
| 112 | writePin(LED_CAPS_LOCK_PIN, !LED_PIN_ON_STATE); | ||
| 113 | #endif | ||
| 114 | #ifdef LED_SCROLL_LOCK_PIN | ||
| 115 | setPinOutput(LED_SCROLL_LOCK_PIN); | ||
| 116 | writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE); | ||
| 117 | #endif | ||
| 118 | #ifdef LED_COMPOSE_PIN | ||
| 119 | setPinOutput(LED_COMPOSE_PIN); | ||
| 120 | writePin(LED_COMPOSE_PIN, !LED_PIN_ON_STATE); | ||
| 121 | #endif | ||
| 122 | #ifdef LED_KANA_PIN | ||
| 123 | setPinOutput(LED_KANA_PIN); | ||
| 124 | writePin(LED_KANA_PIN, !LED_PIN_ON_STATE); | ||
| 125 | #endif | ||
| 126 | } | ||
| 127 | |||
| 128 | /** \brief Entrypoint for protocol to LED binding | ||
| 129 | */ | ||
| 130 | __attribute__((weak)) void led_set(uint8_t usb_led) { | ||
| 131 | #ifdef BACKLIGHT_CAPS_LOCK | ||
| 132 | handle_backlight_caps_lock((led_t)usb_led); | ||
| 133 | #endif | ||
| 134 | |||
| 135 | led_set_kb(usb_led); | ||
| 136 | led_update_kb((led_t)usb_led); | ||
| 137 | } \ No newline at end of file | ||
diff --git a/quantum/quantum.c b/quantum/quantum.c index dab6c9172..0b2f98762 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | 23 | ||
| 24 | #ifdef BACKLIGHT_ENABLE | 24 | #ifdef BACKLIGHT_ENABLE |
| 25 | # include "backlight.h" | 25 | # include "backlight.h" |
| 26 | extern backlight_config_t backlight_config; | ||
| 27 | #endif | 26 | #endif |
| 28 | 27 | ||
| 29 | #ifdef FAUXCLICKY_ENABLE | 28 | #ifdef FAUXCLICKY_ENABLE |
| @@ -602,6 +601,10 @@ void matrix_init_quantum() { | |||
| 602 | if (!eeconfig_is_enabled()) { | 601 | if (!eeconfig_is_enabled()) { |
| 603 | eeconfig_init(); | 602 | eeconfig_init(); |
| 604 | } | 603 | } |
| 604 | #if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN) | ||
| 605 | // TODO: remove calls to led_init_ports from keyboards and remove ifdef | ||
| 606 | led_init_ports(); | ||
| 607 | #endif | ||
| 605 | #ifdef BACKLIGHT_ENABLE | 608 | #ifdef BACKLIGHT_ENABLE |
| 606 | # ifdef LED_MATRIX_ENABLE | 609 | # ifdef LED_MATRIX_ENABLE |
| 607 | led_matrix_init(); | 610 | led_matrix_init(); |
| @@ -725,55 +728,6 @@ void api_send_unicode(uint32_t unicode) { | |||
| 725 | #endif | 728 | #endif |
| 726 | } | 729 | } |
| 727 | 730 | ||
| 728 | /** \brief Lock LED set callback - keymap/user level | ||
| 729 | * | ||
| 730 | * \deprecated Use led_update_user() instead. | ||
| 731 | */ | ||
| 732 | __attribute__((weak)) void led_set_user(uint8_t usb_led) {} | ||
| 733 | |||
| 734 | /** \brief Lock LED set callback - keyboard level | ||
| 735 | * | ||
| 736 | * \deprecated Use led_update_kb() instead. | ||
| 737 | */ | ||
| 738 | __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } | ||
| 739 | |||
| 740 | /** \brief Lock LED update callback - keymap/user level | ||
| 741 | * | ||
| 742 | * \return True if led_update_kb() should run its own code, false otherwise. | ||
| 743 | */ | ||
| 744 | __attribute__((weak)) bool led_update_user(led_t led_state) { return true; } | ||
| 745 | |||
| 746 | /** \brief Lock LED update callback - keyboard level | ||
| 747 | * | ||
| 748 | * \return Ignored for now. | ||
| 749 | */ | ||
| 750 | __attribute__((weak)) bool led_update_kb(led_t led_state) { return led_update_user(led_state); } | ||
| 751 | |||
| 752 | __attribute__((weak)) void led_init_ports(void) {} | ||
| 753 | |||
| 754 | __attribute__((weak)) void led_set(uint8_t usb_led) { | ||
| 755 | #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) | ||
| 756 | // Use backlight as Caps Lock indicator | ||
| 757 | uint8_t bl_toggle_lvl = 0; | ||
| 758 | |||
| 759 | if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) { | ||
| 760 | // Turning Caps Lock ON and backlight is disabled in config | ||
| 761 | // Toggling backlight to the brightest level | ||
| 762 | bl_toggle_lvl = BACKLIGHT_LEVELS; | ||
| 763 | } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) { | ||
| 764 | // Turning Caps Lock OFF and backlight is enabled in config | ||
| 765 | // Toggling backlight and restoring config level | ||
| 766 | bl_toggle_lvl = backlight_config.level; | ||
| 767 | } | ||
| 768 | |||
| 769 | // Set level without modify backlight_config to keep ability to restore state | ||
| 770 | backlight_set(bl_toggle_lvl); | ||
| 771 | #endif | ||
| 772 | |||
| 773 | led_set_kb(usb_led); | ||
| 774 | led_update_kb((led_t)usb_led); | ||
| 775 | } | ||
| 776 | |||
| 777 | //------------------------------------------------------------------------------ | 731 | //------------------------------------------------------------------------------ |
| 778 | // Override these functions in your keymap file to play different tunes on | 732 | // Override these functions in your keymap file to play different tunes on |
| 779 | // different events such as startup and bootloader jump | 733 | // different events such as startup and bootloader jump |
| @@ -781,5 +735,3 @@ __attribute__((weak)) void led_set(uint8_t usb_led) { | |||
| 781 | __attribute__((weak)) void startup_user() {} | 735 | __attribute__((weak)) void startup_user() {} |
| 782 | 736 | ||
| 783 | __attribute__((weak)) void shutdown_user() {} | 737 | __attribute__((weak)) void shutdown_user() {} |
| 784 | |||
| 785 | //------------------------------------------------------------------------------ | ||
