From 1abee4a87a3a6b875349946679d352b67dbaf9fb Mon Sep 17 00:00:00 2001 From: zvecr Date: Sat, 31 Oct 2020 22:40:35 +0000 Subject: [PATCH 1/7] First pass --- common_features.mk | 1 + docs/_summary.md | 1 + docs/custom_quantum_functions.md | 102 ----------------------------- docs/feature_led_indicators.md | 101 ++++++++++++++++++++++++++++ keyboards/cospad/config.h | 2 + keyboards/cospad/cospad.c | 16 ----- quantum/led.c | 109 +++++++++++++++++++++++++++++++ quantum/quantum.c | 52 --------------- tmk_core/common/led.h | 6 +- 9 files changed, 216 insertions(+), 174 deletions(-) create mode 100644 docs/feature_led_indicators.md create mode 100644 quantum/led.c diff --git a/common_features.mk b/common_features.mk index 5f232d5f0dda..ba66c5324839 100644 --- a/common_features.mk +++ b/common_features.mk @@ -17,6 +17,7 @@ SERIAL_PATH := $(QUANTUM_PATH)/serial_link QUANTUM_SRC += \ $(QUANTUM_DIR)/quantum.c \ + $(QUANTUM_DIR)/led.c \ $(QUANTUM_DIR)/keymap_common.c \ $(QUANTUM_DIR)/keycode_config.c diff --git a/docs/_summary.md b/docs/_summary.md index 2e874fb1cd6d..44030d812d47 100644 --- a/docs/_summary.md +++ b/docs/_summary.md @@ -105,6 +105,7 @@ * [Encoders](feature_encoders.md) * [Haptic Feedback](feature_haptic_feedback.md) * [Joystick](feature_joystick.md) + * [LED Indicators](feature_led_indicators.md) * [Proton C Conversion](proton_c_conversion.md) * [PS/2 Mouse](feature_ps2_mouse.md) * [Split Keyboard](feature_split_keyboard.md) diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md index bf3a60377cdd..a459042b32e2 100644 --- a/docs/custom_quantum_functions.md +++ b/docs/custom_quantum_functions.md @@ -88,108 +88,6 @@ keyrecord_t record { } ``` -# LED Control - -QMK provides methods to read 5 of the LEDs defined in the HID spec: - -* Num Lock -* Caps Lock -* Scroll Lock -* Compose -* Kana - -There are two ways to get the lock LED state: - -* by implementing `bool led_update_kb(led_t led_state)` or `_user(led_t led_state)`; or -* by calling `led_t host_keyboard_led_state()` - -!> `host_keyboard_led_state()` may already reflect a new value before `led_update_user()` is called. - -Two more deprecated functions exist that provide the LED state as a `uint8_t`: - -* `uint8_t led_set_kb(uint8_t usb_led)` and `_user(uint8_t usb_led)` -* `uint8_t host_keyboard_leds()` - -## `led_update_user()` - -This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. - -By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and -return `false` when you would prefer not to run the code in `led_update_kb()`. - -Some examples include: - - - overriding the LEDs to use them for something else like layer indication - - return `false` because you do not want the `_kb()` function to run, as it would override your layer behavior. - - play a sound when an LED turns on or off. - - return `true` because you want the `_kb` function to run, and this is in addition to the default LED behavior. - -?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead. - -### Example `led_update_kb()` Implementation - -```c -bool led_update_kb(led_t led_state) { - bool res = led_update_user(led_state); - if(res) { - // writePin sets the pin high for 1 and low for 0. - // In this example the pins are inverted, setting - // it low/0 turns it on, and high/1 turns the LED off. - // This behavior depends on whether the LED is between the pin - // and VCC or the pin and GND. - writePin(B0, !led_state.num_lock); - writePin(B1, !led_state.caps_lock); - writePin(B2, !led_state.scroll_lock); - writePin(B3, !led_state.compose); - writePin(B4, !led_state.kana); - } - return res; -} -``` - -### Example `led_update_user()` Implementation - -This incomplete example would play a sound if Caps Lock is turned on or off. It returns `true`, because you also want the LEDs to maintain their state. - -```c -#ifdef AUDIO_ENABLE - float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); - float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); -#endif - -bool led_update_user(led_t led_state) { - #ifdef AUDIO_ENABLE - static uint8_t caps_state = 0; - if (caps_state != led_state.caps_lock) { - led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); - caps_state = led_state.caps_lock; - } - #endif - return true; -} -``` - -### `led_update_*` Function Documentation - -* Keyboard/Revision: `bool led_update_kb(led_t led_state)` -* Keymap: `bool led_update_user(led_t led_state)` - -## `host_keyboard_led_state()` - -Call this function to get the last received LED state as a `led_t`. This is useful for reading the LED state outside `led_update_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code). - -## Setting Physical LED State - -Some keyboard implementations provide convenience methods for setting the state of the physical LEDs. - -### Ergodox Boards - -The Ergodox implementations provide `ergodox_right_led_1`/`2`/`3_on`/`off()` to turn individual LEDs on or off, as well as `ergodox_right_led_on`/`off(uint8_t led)` to turn them on or off by their index. - -In addition, it is possible to specify the brightness level of all LEDs with `ergodox_led_all_set(uint8_t n)`; of individual LEDs with `ergodox_right_led_1`/`2`/`3_set(uint8_t n)`; or by index with `ergodox_right_led_set(uint8_t led, uint8_t n)`. - -Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default). - # Keyboard Initialization Code There are several steps in the keyboard initialization process. Depending on what you want to do, it will influence which function you should use. diff --git a/docs/feature_led_indicators.md b/docs/feature_led_indicators.md new file mode 100644 index 000000000000..1a52448c5ecf --- /dev/null +++ b/docs/feature_led_indicators.md @@ -0,0 +1,101 @@ +# LED Indicators + +QMK provides methods to read 5 of the LEDs defined in the HID spec: + +* Num Lock +* Caps Lock +* Scroll Lock +* Compose +* Kana + +There are two ways to get the lock LED state: + +* by implementing `bool led_update_kb(led_t led_state)` or `_user(led_t led_state)`; or +* by calling `led_t host_keyboard_led_state()` + +!> `host_keyboard_led_state()` may already reflect a new value before `led_update_user()` is called. + +Two more deprecated functions exist that provide the LED state as a `uint8_t`: + +* `uint8_t led_set_kb(uint8_t usb_led)` and `_user(uint8_t usb_led)` +* `uint8_t host_keyboard_leds()` + +## `led_update_*()` + +This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. + +By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and +return `false` when you would prefer not to run the code in `led_update_kb()`. + +Some examples include: + + - overriding the LEDs to use them for something else like layer indication + - return `false` because you do not want the `_kb()` function to run, as it would override your layer behavior. + - play a sound when an LED turns on or off. + - return `true` because you want the `_kb` function to run, and this is in addition to the default LED behavior. + +?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead. + +### Example `led_update_kb()` Implementation + +```c +bool led_update_kb(led_t led_state) { + bool res = led_update_user(led_state); + if(res) { + // writePin sets the pin high for 1 and low for 0. + // In this example the pins are inverted, setting + // it low/0 turns it on, and high/1 turns the LED off. + // This behavior depends on whether the LED is between the pin + // and VCC or the pin and GND. + writePin(B0, !led_state.num_lock); + writePin(B1, !led_state.caps_lock); + writePin(B2, !led_state.scroll_lock); + writePin(B3, !led_state.compose); + writePin(B4, !led_state.kana); + } + return res; +} +``` + +### Example `led_update_user()` Implementation + +This incomplete example would play a sound if Caps Lock is turned on or off. It returns `true`, because you also want the LEDs to maintain their state. + +```c +#ifdef AUDIO_ENABLE + float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); + float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); +#endif + +bool led_update_user(led_t led_state) { + #ifdef AUDIO_ENABLE + static uint8_t caps_state = 0; + if (caps_state != led_state.caps_lock) { + led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); + caps_state = led_state.caps_lock; + } + #endif + return true; +} +``` + +### `led_update_*` Function Documentation + +* Keyboard/Revision: `bool led_update_kb(led_t led_state)` +* Keymap: `bool led_update_user(led_t led_state)` + +## `host_keyboard_led_state()` + +Call this function to get the last received LED state as a `led_t`. This is useful for reading the LED state outside `led_update_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code). + +## Setting Physical LED State + +Some keyboard implementations provide convenience methods for setting the state of the physical LEDs. + +### Ergodox Boards + +The Ergodox implementations provide `ergodox_right_led_1`/`2`/`3_on`/`off()` to turn individual LEDs on or off, as well as `ergodox_right_led_on`/`off(uint8_t led)` to turn them on or off by their index. + +In addition, it is possible to specify the brightness level of all LEDs with `ergodox_led_all_set(uint8_t n)`; of individual LEDs with `ergodox_right_led_1`/`2`/`3_set(uint8_t n)`; or by index with `ergodox_right_led_set(uint8_t led, uint8_t n)`. + +Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default). diff --git a/keyboards/cospad/config.h b/keyboards/cospad/config.h index 8d2994b7bdc2..20a96ce42f64 100644 --- a/keyboards/cospad/config.h +++ b/keyboards/cospad/config.h @@ -53,6 +53,8 @@ along with this program. If not, see . */ #define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 +#define LED_NUM_LOCK_PIN B2 + #define BACKLIGHT_PIN F7 // #define BACKLIGHT_BREATHING #define BACKLIGHT_LEVELS 3 diff --git a/keyboards/cospad/cospad.c b/keyboards/cospad/cospad.c index c1f3a70479d3..e7772f29084f 100644 --- a/keyboards/cospad/cospad.c +++ b/keyboards/cospad/cospad.c @@ -14,19 +14,3 @@ * along with this program. If not, see . */ #include "cospad.h" - -void keyboard_pre_init_kb(void) { - led_init_ports(); - keyboard_pre_init_user(); -} - -void led_init_ports(void) { - setPinOutput(B2); -} - -bool led_update_kb(led_t led_state) { - if (led_update_user(led_state)) { - writePin(B2, !led_state.num_lock); - } - return true; -} diff --git a/quantum/led.c b/quantum/led.c new file mode 100644 index 000000000000..3d7628efaad3 --- /dev/null +++ b/quantum/led.c @@ -0,0 +1,109 @@ +#include "quantum.h" + +#ifdef BACKLIGHT_ENABLE +# include "backlight.h" +extern backlight_config_t backlight_config; +#endif + +#ifndef LED_PIN_ON_STATE +# define LED_PIN_ON_STATE 0 +#endif + +/** \brief Lock LED set callback - keymap/user level + * + * \deprecated Use led_update_user() instead. + */ +__attribute__((weak)) void led_set_user(uint8_t usb_led) {} + +/** \brief Lock LED set callback - keyboard level + * + * \deprecated Use led_update_kb() instead. + */ +__attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } + +/** \brief Lock LED update callback - keymap/user level + * + * \return True if led_update_kb() should run its own code, false otherwise. + */ +__attribute__((weak)) bool led_update_user(led_t led_state) { return true; } + +/** \brief Lock LED update callback - keyboard level + * + * \return Ignored for now. + */ +__attribute__((weak)) bool led_update_kb(led_t led_state) { + bool res = led_update_user(led_state); + if (res) { +#if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN) + // TODO: refactor to call led_init_ports in core && remove init from keyboards + static bool s_init = false; + if (!s_init) { + led_init_ports(); + s_init = true; + } + +# if LED_PIN_ON_STATE == 0 + // invert the whole thing to avoid having to conditionally !led_state.x later + led_state.raw = ~led_state.raw; +# endif + +# ifdef LED_NUM_LOCK_PIN + writePin(LED_NUM_LOCK_PIN, led_state.num_lock); +# endif +# ifdef LED_CAPS_LOCK_PIN + writePin(LED_CAPS_LOCK_PIN, led_state.caps_lock); +# endif +# ifdef LED_SCROLL_LOCK_PIN + writePin(LED_SCROLL_LOCK_PIN, led_state.scroll_lock); +# endif +# ifdef LED_COMPOSE_PIN + writePin(LED_COMPOSE_PIN, led_state.compose); +# endif +# ifdef LED_KANA_PIN + writePin(LED_KANA_PIN, led_state.kana); +# endif +#endif + } + return res; +} + +__attribute__((weak)) void led_init_ports(void) { +#ifdef LED_NUM_LOCK_PIN + setPinOutput(LED_NUM_LOCK_PIN); +#endif +#ifdef LED_CAPS_LOCK_PIN + setPinOutput(LED_CAPS_LOCK_PIN); +#endif +#ifdef LED_SCROLL_LOCK_PIN + setPinOutput(LED_SCROLL_LOCK_PIN); +#endif +#ifdef LED_COMPOSE_PIN + setPinOutput(LED_COMPOSE_PIN); +#endif +#ifdef LED_KANA_PIN + setPinOutput(LED_KANA_PIN); +#endif +} + +__attribute__((weak)) void led_set(uint8_t usb_led) { +#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) + // Use backlight as Caps Lock indicator + uint8_t bl_toggle_lvl = 0; + + if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) { + // Turning Caps Lock ON and backlight is disabled in config + // Toggling backlight to the brightest level + bl_toggle_lvl = BACKLIGHT_LEVELS; + } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) { + // Turning Caps Lock OFF and backlight is enabled in config + // Toggling backlight and restoring config level + bl_toggle_lvl = backlight_config.level; + } + + // Set level without modify backlight_config to keep ability to restore state + backlight_set(bl_toggle_lvl); +#endif + + led_set_kb(usb_led); + led_update_kb((led_t)usb_led); +} \ No newline at end of file diff --git a/quantum/quantum.c b/quantum/quantum.c index dab6c9172fc0..4227e88551e0 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -23,7 +23,6 @@ #ifdef BACKLIGHT_ENABLE # include "backlight.h" -extern backlight_config_t backlight_config; #endif #ifdef FAUXCLICKY_ENABLE @@ -725,55 +724,6 @@ void api_send_unicode(uint32_t unicode) { #endif } -/** \brief Lock LED set callback - keymap/user level - * - * \deprecated Use led_update_user() instead. - */ -__attribute__((weak)) void led_set_user(uint8_t usb_led) {} - -/** \brief Lock LED set callback - keyboard level - * - * \deprecated Use led_update_kb() instead. - */ -__attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } - -/** \brief Lock LED update callback - keymap/user level - * - * \return True if led_update_kb() should run its own code, false otherwise. - */ -__attribute__((weak)) bool led_update_user(led_t led_state) { return true; } - -/** \brief Lock LED update callback - keyboard level - * - * \return Ignored for now. - */ -__attribute__((weak)) bool led_update_kb(led_t led_state) { return led_update_user(led_state); } - -__attribute__((weak)) void led_init_ports(void) {} - -__attribute__((weak)) void led_set(uint8_t usb_led) { -#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) - // Use backlight as Caps Lock indicator - uint8_t bl_toggle_lvl = 0; - - if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) { - // Turning Caps Lock ON and backlight is disabled in config - // Toggling backlight to the brightest level - bl_toggle_lvl = BACKLIGHT_LEVELS; - } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) { - // Turning Caps Lock OFF and backlight is enabled in config - // Toggling backlight and restoring config level - bl_toggle_lvl = backlight_config.level; - } - - // Set level without modify backlight_config to keep ability to restore state - backlight_set(bl_toggle_lvl); -#endif - - led_set_kb(usb_led); - led_update_kb((led_t)usb_led); -} - //------------------------------------------------------------------------------ // Override these functions in your keymap file to play different tunes on // different events such as startup and bootloader jump @@ -781,5 +731,3 @@ __attribute__((weak)) void led_set(uint8_t usb_led) { __attribute__((weak)) void startup_user() {} __attribute__((weak)) void shutdown_user() {} - -//------------------------------------------------------------------------------ diff --git a/tmk_core/common/led.h b/tmk_core/common/led.h index 990282862b5a..81c664d606e0 100644 --- a/tmk_core/common/led.h +++ b/tmk_core/common/led.h @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef LED_H -#define LED_H +#pragma once + #include "stdint.h" #include "stdbool.h" @@ -52,5 +52,3 @@ void led_init_ports(void); #ifdef __cplusplus } #endif - -#endif From 4c24130e25b6c6aad7dcfca31bce848f54687dcf Mon Sep 17 00:00:00 2001 From: zvecr Date: Sat, 31 Oct 2020 23:02:56 +0000 Subject: [PATCH 2/7] Add config options to docs --- docs/feature_led_indicators.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/feature_led_indicators.md b/docs/feature_led_indicators.md index 1a52448c5ecf..ad49c1446034 100644 --- a/docs/feature_led_indicators.md +++ b/docs/feature_led_indicators.md @@ -8,8 +8,8 @@ QMK provides methods to read 5 of the LEDs defined in the HID spec: * Compose * Kana -There are two ways to get the lock LED state: - +There are three ways to get the lock LED state: +* by specifying configuration options within `config.h` * by implementing `bool led_update_kb(led_t led_state)` or `_user(led_t led_state)`; or * by calling `led_t host_keyboard_led_state()` @@ -20,6 +20,21 @@ Two more deprecated functions exist that provide the LED state as a `uint8_t`: * `uint8_t led_set_kb(uint8_t usb_led)` and `_user(uint8_t usb_led)` * `uint8_t host_keyboard_leds()` +## Configuration Options + +To configure the indicators, `#define` these in your `config.h`: + +|Define |Default |Description | +|---------------------|-------------|-------------------------------------------| +|`LED_NUM_LOCK_PIN` |*Not defined*|The pin that controls the `Num Lock` LED | +|`LED_CAPS_LOCK_PIN` |*Not defined*|The pin that controls the `Caps Lock` LED | +|`LED_SCROLL_LOCK_PIN`|*Not defined*|The pin that controls the `Scroll Lock` LED| +|`LED_COMPOSE_PIN` |*Not defined*|The pin that controls the `Compose` LED | +|`LED_KANA_PIN` |*Not defined*|The pin that controls the `Kana` LED | +|`LED_PIN_ON_STATE` |`0` |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low| + +Unless you are designing your own keyboard, you generally should not need to change the above config options. + ## `led_update_*()` This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. From 1bc53a6cb6b65fd485f38a56cff80b25c7daa8a9 Mon Sep 17 00:00:00 2001 From: zvecr Date: Sat, 31 Oct 2020 23:12:59 +0000 Subject: [PATCH 3/7] Update some wording --- docs/feature_led_indicators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/feature_led_indicators.md b/docs/feature_led_indicators.md index ad49c1446034..2a527ed2a318 100644 --- a/docs/feature_led_indicators.md +++ b/docs/feature_led_indicators.md @@ -37,7 +37,7 @@ Unless you are designing your own keyboard, you generally should not need to cha ## `led_update_*()` -This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. +When the configuration options do not provide enough flexibility, the API hooks provided allow custom control of the LED behavior. These functions will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and return `false` when you would prefer not to run the code in `led_update_kb()`. From da8be0e90119798bfc1fccc36678d32892fce798 Mon Sep 17 00:00:00 2001 From: zvecr Date: Sun, 1 Nov 2020 00:56:41 +0000 Subject: [PATCH 4/7] Slight tidy up of backlight caps logic --- quantum/led.c | 62 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/quantum/led.c b/quantum/led.c index 3d7628efaad3..b68b44b2edfb 100644 --- a/quantum/led.c +++ b/quantum/led.c @@ -1,14 +1,54 @@ +/* Copyright 2020 zvecr + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "quantum.h" #ifdef BACKLIGHT_ENABLE # include "backlight.h" extern backlight_config_t backlight_config; +#else +// Cannot use BACKLIGHT_CAPS_LOCK without backlight being enabled +# undef BACKLIGHT_CAPS_LOCK #endif #ifndef LED_PIN_ON_STATE # define LED_PIN_ON_STATE 0 #endif +#if defined(BACKLIGHT_CAPS_LOCK) +/** \brief Caps Lock indicator using backlight (for keyboards without dedicated LED) + */ +static void handle_backlight_caps_lock(led_t led_state) { + // Use backlight as Caps Lock indicator + uint8_t bl_toggle_lvl = 0; + + if (led_state.caps_lock && !backlight_config.enable) { + // Turning Caps Lock ON and backlight is disabled in config + // Toggling backlight to the brightest level + bl_toggle_lvl = BACKLIGHT_LEVELS; + } else if (!led_state.caps_lock && backlight_config.enable) { + // Turning Caps Lock OFF and backlight is enabled in config + // Toggling backlight and restoring config level + bl_toggle_lvl = backlight_config.level; + } + + // Set level without modify backlight_config to keep ability to restore state + backlight_set(bl_toggle_lvl); +} +#endif + /** \brief Lock LED set callback - keymap/user level * * \deprecated Use led_update_user() instead. @@ -67,6 +107,8 @@ __attribute__((weak)) bool led_update_kb(led_t led_state) { return res; } +/** \brief Initialise any LED related hardware and/or state + */ __attribute__((weak)) void led_init_ports(void) { #ifdef LED_NUM_LOCK_PIN setPinOutput(LED_NUM_LOCK_PIN); @@ -85,23 +127,11 @@ __attribute__((weak)) void led_init_ports(void) { #endif } +/** \brief Entrypoint for protocol to LED binding + */ __attribute__((weak)) void led_set(uint8_t usb_led) { -#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) - // Use backlight as Caps Lock indicator - uint8_t bl_toggle_lvl = 0; - - if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) { - // Turning Caps Lock ON and backlight is disabled in config - // Toggling backlight to the brightest level - bl_toggle_lvl = BACKLIGHT_LEVELS; - } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) { - // Turning Caps Lock OFF and backlight is enabled in config - // Toggling backlight and restoring config level - bl_toggle_lvl = backlight_config.level; - } - - // Set level without modify backlight_config to keep ability to restore state - backlight_set(bl_toggle_lvl); +#ifdef BACKLIGHT_CAPS_LOCK + handle_backlight_caps_lock((led_t)usb_led); #endif led_set_kb(usb_led); From 08651139af68dd5d690a4745b23b6761ad24e4aa Mon Sep 17 00:00:00 2001 From: zvecr Date: Sun, 1 Nov 2020 01:12:29 +0000 Subject: [PATCH 5/7] Init pin to correct state --- quantum/led.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/quantum/led.c b/quantum/led.c index b68b44b2edfb..8360684ded22 100644 --- a/quantum/led.c +++ b/quantum/led.c @@ -112,18 +112,23 @@ __attribute__((weak)) bool led_update_kb(led_t led_state) { __attribute__((weak)) void led_init_ports(void) { #ifdef LED_NUM_LOCK_PIN setPinOutput(LED_NUM_LOCK_PIN); + writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE); #endif #ifdef LED_CAPS_LOCK_PIN setPinOutput(LED_CAPS_LOCK_PIN); + writePin(LED_CAPS_LOCK_PIN, !LED_PIN_ON_STATE); #endif #ifdef LED_SCROLL_LOCK_PIN setPinOutput(LED_SCROLL_LOCK_PIN); + writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE); #endif #ifdef LED_COMPOSE_PIN setPinOutput(LED_COMPOSE_PIN); + writePin(LED_COMPOSE_PIN, !LED_PIN_ON_STATE); #endif #ifdef LED_KANA_PIN setPinOutput(LED_KANA_PIN); + writePin(LED_KANA_PIN, !LED_PIN_ON_STATE); #endif } From 9bb6ddadc5beead125c2515ed58101b82587cff3 Mon Sep 17 00:00:00 2001 From: zvecr Date: Sun, 1 Nov 2020 01:27:44 +0000 Subject: [PATCH 6/7] Move init location --- quantum/led.c | 7 ------- quantum/quantum.c | 4 ++++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/quantum/led.c b/quantum/led.c index 8360684ded22..18022068f270 100644 --- a/quantum/led.c +++ b/quantum/led.c @@ -75,13 +75,6 @@ __attribute__((weak)) bool led_update_kb(led_t led_state) { bool res = led_update_user(led_state); if (res) { #if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN) - // TODO: refactor to call led_init_ports in core && remove init from keyboards - static bool s_init = false; - if (!s_init) { - led_init_ports(); - s_init = true; - } - # if LED_PIN_ON_STATE == 0 // invert the whole thing to avoid having to conditionally !led_state.x later led_state.raw = ~led_state.raw; diff --git a/quantum/quantum.c b/quantum/quantum.c index 4227e88551e0..0b2f98762dd8 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -601,6 +601,10 @@ void matrix_init_quantum() { if (!eeconfig_is_enabled()) { eeconfig_init(); } +#if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN) + // TODO: remove calls to led_init_ports from keyboards and remove ifdef + led_init_ports(); +#endif #ifdef BACKLIGHT_ENABLE # ifdef LED_MATRIX_ENABLE led_matrix_init(); From a1e4b8ec19cfbc16cabbec92a91727428ce3121e Mon Sep 17 00:00:00 2001 From: zvecr Date: Sat, 7 Nov 2020 15:37:47 +0000 Subject: [PATCH 7/7] Reverse default state --- docs/feature_led_indicators.md | 2 +- keyboards/cospad/config.h | 1 + quantum/led.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/feature_led_indicators.md b/docs/feature_led_indicators.md index 2a527ed2a318..10e095ab155b 100644 --- a/docs/feature_led_indicators.md +++ b/docs/feature_led_indicators.md @@ -31,7 +31,7 @@ To configure the indicators, `#define` these in your `config.h`: |`LED_SCROLL_LOCK_PIN`|*Not defined*|The pin that controls the `Scroll Lock` LED| |`LED_COMPOSE_PIN` |*Not defined*|The pin that controls the `Compose` LED | |`LED_KANA_PIN` |*Not defined*|The pin that controls the `Kana` LED | -|`LED_PIN_ON_STATE` |`0` |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low| +|`LED_PIN_ON_STATE` |`1` |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low| Unless you are designing your own keyboard, you generally should not need to change the above config options. diff --git a/keyboards/cospad/config.h b/keyboards/cospad/config.h index 20a96ce42f64..648fa29a6fd7 100644 --- a/keyboards/cospad/config.h +++ b/keyboards/cospad/config.h @@ -54,6 +54,7 @@ along with this program. If not, see . #define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 #define LED_NUM_LOCK_PIN B2 +#define LED_PIN_ON_STATE 0 #define BACKLIGHT_PIN F7 // #define BACKLIGHT_BREATHING diff --git a/quantum/led.c b/quantum/led.c index 18022068f270..3e30b1a5ad8a 100644 --- a/quantum/led.c +++ b/quantum/led.c @@ -24,7 +24,7 @@ extern backlight_config_t backlight_config; #endif #ifndef LED_PIN_ON_STATE -# define LED_PIN_ON_STATE 0 +# define LED_PIN_ON_STATE 1 #endif #if defined(BACKLIGHT_CAPS_LOCK)