diff options
Diffstat (limited to 'docs/features/led_indicators.md')
| -rw-r--r-- | docs/features/led_indicators.md | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/docs/features/led_indicators.md b/docs/features/led_indicators.md new file mode 100644 index 0000000000..8435c69a55 --- /dev/null +++ b/docs/features/led_indicators.md | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | # LED Indicators | ||
| 2 | |||
| 3 | ::: tip | ||
| 4 | LED indicators on split keyboards will require state information synced to the slave half (e.g. `#define SPLIT_LED_STATE_ENABLE`). See [data sync options](split_keyboard#data-sync-options) for more details. | ||
| 5 | ::: | ||
| 6 | |||
| 7 | QMK provides methods to read 5 of the LEDs defined in the HID spec: | ||
| 8 | |||
| 9 | * Num Lock | ||
| 10 | * Caps Lock | ||
| 11 | * Scroll Lock | ||
| 12 | * Compose | ||
| 13 | * Kana | ||
| 14 | |||
| 15 | There are three ways to get the lock LED state: | ||
| 16 | * Configuration options in `config.h` | ||
| 17 | * Implement `led_update_*` function | ||
| 18 | * Call `led_t host_keyboard_led_state()` | ||
| 19 | |||
| 20 | ::: warning | ||
| 21 | The `host_keyboard_led_state()` may reflect an updated state before `led_update_user()` is called. | ||
| 22 | ::: | ||
| 23 | |||
| 24 | Two deprecated functions that provide the LED state as `uint8_t`: | ||
| 25 | |||
| 26 | * `uint8_t led_set_user(uint8_t usb_led)` | ||
| 27 | * `uint8_t host_keyboard_leds()` | ||
| 28 | |||
| 29 | ## Configuration Options | ||
| 30 | |||
| 31 | To configure the indicators, `#define` these in your `config.h`: | ||
| 32 | |||
| 33 | |Define |Default |Description | | ||
| 34 | |---------------------|-------------|-------------------------------------------| | ||
| 35 | |`LED_NUM_LOCK_PIN` |*Not defined*|The pin that controls the `Num Lock` LED | | ||
| 36 | |`LED_CAPS_LOCK_PIN` |*Not defined*|The pin that controls the `Caps Lock` LED | | ||
| 37 | |`LED_SCROLL_LOCK_PIN`|*Not defined*|The pin that controls the `Scroll Lock` LED| | ||
| 38 | |`LED_COMPOSE_PIN` |*Not defined*|The pin that controls the `Compose` LED | | ||
| 39 | |`LED_KANA_PIN` |*Not defined*|The pin that controls the `Kana` LED | | ||
| 40 | |`LED_PIN_ON_STATE` |`1` |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low| | ||
| 41 | |||
| 42 | Unless you are designing your own keyboard, you generally should not need to change the above config options. | ||
| 43 | |||
| 44 | ## LED update function | ||
| 45 | |||
| 46 | When the configuration options do not provide enough flexibility, the following callbacks allow custom control of the LED behavior. These functions will be called when one of those 5 LEDs changes state: | ||
| 47 | |||
| 48 | * Keyboard/revision: `bool led_update_kb(led_t led_state)` | ||
| 49 | * Keymap: `bool led_update_user(led_t led_state)` | ||
| 50 | |||
| 51 | Both receives LED state as a struct parameter. Returning `true` in `led_update_user()` will allow the keyboard level code in `led_update_kb()` to run as well. Returning `false` will override the keyboard level code, depending on how the keyboard level function is set up. | ||
| 52 | |||
| 53 | ::: tip | ||
| 54 | This boolean return type of `led_update_user` allows for overriding keyboard LED controls, and is thus recommended over the void `led_set_user` function. | ||
| 55 | ::: | ||
| 56 | |||
| 57 | ### Example of keyboard LED update implementation | ||
| 58 | |||
| 59 | This is a template indicator function that can be implemented on keyboard level code: | ||
| 60 | |||
| 61 | ```c | ||
| 62 | bool led_update_kb(led_t led_state) { | ||
| 63 | bool res = led_update_user(led_state); | ||
| 64 | if(res) { | ||
| 65 | // gpio_write_pin sets the pin high for 1 and low for 0. | ||
| 66 | // In this example the pins are inverted, setting | ||
| 67 | // it low/0 turns it on, and high/1 turns the LED off. | ||
| 68 | // This behavior depends on whether the LED is between the pin | ||
| 69 | // and VCC or the pin and GND. | ||
| 70 | gpio_write_pin(B0, !led_state.num_lock); | ||
| 71 | gpio_write_pin(B1, !led_state.caps_lock); | ||
| 72 | gpio_write_pin(B2, !led_state.scroll_lock); | ||
| 73 | gpio_write_pin(B3, !led_state.compose); | ||
| 74 | gpio_write_pin(B4, !led_state.kana); | ||
| 75 | } | ||
| 76 | return res; | ||
| 77 | } | ||
| 78 | ``` | ||
| 79 | |||
| 80 | ### Example of user LED update implementation | ||
| 81 | |||
| 82 | This is an incomplete example will play a sound if Caps Lock is turned on or off. It returns `true` to allow keyboard LED function to maintain their state. | ||
| 83 | |||
| 84 | ```c | ||
| 85 | #ifdef AUDIO_ENABLE | ||
| 86 | float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); | ||
| 87 | float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); | ||
| 88 | #endif | ||
| 89 | |||
| 90 | bool led_update_user(led_t led_state) { | ||
| 91 | #ifdef AUDIO_ENABLE | ||
| 92 | static uint8_t caps_state = 0; | ||
| 93 | if (caps_state != led_state.caps_lock) { | ||
| 94 | led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); | ||
| 95 | caps_state = led_state.caps_lock; | ||
| 96 | } | ||
| 97 | #endif | ||
| 98 | return true; | ||
| 99 | } | ||
| 100 | ``` | ||
| 101 | |||
| 102 | ## Host keyboard LED state | ||
| 103 | |||
| 104 | The `host_keyboard_led_state()` function will report the LED state returned from the host computer as `led_t`. This is useful for reading the LED state outside `led_update_*`. For example, you can get the boolean state of Caps Lock from the host with: | ||
| 105 | |||
| 106 | ```c | ||
| 107 | bool caps = host_keyboard_led_state().caps_lock; | ||
| 108 | ``` | ||
| 109 | |||
| 110 | ## `led_update_ports()` | ||
| 111 | |||
| 112 | This function writes the LED state to the actual hardware. Call it manually | ||
| 113 | from your `led_update_*()` callbacks to modify the handling of the standard | ||
| 114 | keyboard LEDs. | ||
| 115 | For example when repurposing a standard LED indicator as layer indicator. | ||
| 116 | |||
| 117 | ## Setting Physical LED State | ||
| 118 | |||
| 119 | Some keyboard implementations provide convenient methods for setting the state of the physical LEDs. | ||
| 120 | |||
| 121 | ### Ergodox Boards | ||
| 122 | |||
| 123 | 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. | ||
| 124 | |||
| 125 | 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)`. | ||
| 126 | |||
| 127 | Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default). | ||
