qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

led_indicators.md (5053B)


      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 Deprecated functions that provide the LED state as `uint8_t`:
     25 
     26 * `uint8_t host_keyboard_leds()`
     27 
     28 ## Configuration Options
     29 
     30 To configure the indicators, `#define` these in your `config.h`:
     31 
     32 |Define               |Default      |Description                                |
     33 |---------------------|-------------|-------------------------------------------|
     34 |`LED_NUM_LOCK_PIN`   |*Not defined*|The pin that controls the `Num Lock` LED   |
     35 |`LED_CAPS_LOCK_PIN`  |*Not defined*|The pin that controls the `Caps Lock` LED  |
     36 |`LED_SCROLL_LOCK_PIN`|*Not defined*|The pin that controls the `Scroll Lock` LED|
     37 |`LED_COMPOSE_PIN`    |*Not defined*|The pin that controls the `Compose` LED    |
     38 |`LED_KANA_PIN`       |*Not defined*|The pin that controls the `Kana` LED       |
     39 |`LED_PIN_ON_STATE`   |`1`          |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low|
     40 
     41 Unless you are designing your own keyboard, you generally should not need to change the above config options.
     42 
     43 ## LED update function
     44 
     45 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: 
     46 
     47 * Keyboard/revision: `bool led_update_kb(led_t led_state)`
     48 * Keymap: `bool led_update_user(led_t led_state)`
     49 
     50 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.
     51 
     52 ### Example of keyboard LED update implementation
     53 
     54 This is a template indicator function that can be implemented on keyboard level code:
     55 
     56 ```c
     57 bool led_update_kb(led_t led_state) {
     58     bool res = led_update_user(led_state);
     59     if(res) {
     60         // gpio_write_pin sets the pin high for 1 and low for 0.
     61         // In this example the pins are inverted, setting
     62         // it low/0 turns it on, and high/1 turns the LED off.
     63         // This behavior depends on whether the LED is between the pin
     64         // and VCC or the pin and GND.
     65         gpio_write_pin(B0, !led_state.num_lock);
     66         gpio_write_pin(B1, !led_state.caps_lock);
     67         gpio_write_pin(B2, !led_state.scroll_lock);
     68         gpio_write_pin(B3, !led_state.compose);
     69         gpio_write_pin(B4, !led_state.kana);
     70     }
     71     return res;
     72 }
     73 ```
     74 
     75 ### Example of user LED update implementation
     76 
     77 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.
     78 
     79 ```c
     80 #ifdef AUDIO_ENABLE
     81   float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND);
     82   float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND);
     83 #endif
     84 
     85 bool led_update_user(led_t led_state) {
     86     #ifdef AUDIO_ENABLE
     87     static uint8_t caps_state = 0;
     88     if (caps_state != led_state.caps_lock) {
     89         led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off);
     90         caps_state = led_state.caps_lock;
     91     }
     92     #endif
     93     return true;
     94 }
     95 ```
     96 
     97 ## Host keyboard LED state 
     98 
     99 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:
    100 
    101 ```c
    102 bool caps = host_keyboard_led_state().caps_lock;
    103 ```
    104 
    105 ## `led_update_ports()`
    106 
    107 This function writes the LED state to the actual hardware. Call it manually
    108 from your `led_update_*()` callbacks to modify the handling of the standard
    109 keyboard LEDs.
    110 For example when repurposing a standard LED indicator as layer indicator.
    111 
    112 ## Setting Physical LED State
    113 
    114 Some keyboard implementations provide convenient methods for setting the state of the physical LEDs.
    115 
    116 ### Ergodox Boards
    117 
    118 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.
    119 
    120 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)`.
    121 
    122 Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default).