Skip to content

Commit

Permalink
docs: add led indicators documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
bortoz committed Jan 8, 2022
1 parent eebd319 commit dc29c52
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 0 deletions.
240 changes: 240 additions & 0 deletions docs/docs/features/led-indicators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
---
title: LED indicators
sidebar_label: LED indicators
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

ZMK supports the following LED indicators:

- Num Lock
- Caps Lock
- Scroll Lock
- Compose
- Kana

## Enabling LED indicators

To enable LED indicators on your board or shield, simply enable the `CONFIG_ZMK_LED_INDICATORS` configuration values in the `.conf` file of your user config directory as such:

```
CONFIG_ZMK_LED_INDICATORS=y
```

You can also configure the brightness of the LEDs using:

```
CONFIG_ZMK_LED_INDICATORS_BRT=80
```

If your board or shield does not have LED indicators configured, refer to [Adding LED indicators to a Board](#adding-led-indicators-to-a-board).

## Adding LED indicators to a board

You can use any LED driver supported by ZMK or Zephyr, it is recommended to use either `LED_PWM` or `LED_GPIO` driver.

<Tabs
defaultValue="pwm"
values={[
{label: 'LED PWM driver', value: 'pwm'},
{label: 'LED GPIO driver', value: 'gpio'},
{label: 'Other drivers', value: 'other'},
]}>
<TabItem value="pwm">

First you have to enable the driver by adding the following lines to your `.conf` file:

```
CONFIG_PWM=y
CONFIG_LED_PWM=y
```

Next, you need to enable PWM by adding the following lines to your `.overlay` file:

```
&pwm0 {
status = "okay";
ch0-pin = <33>;
/* ch0-inverted; */
ch1-pin = <35>;
/* ch1-inverted; */
};
```

You have to declere a channel for each LED. A single PWM module has a fixed number of channels depending on your SoC, if you have many LEDs you may want to use `&pwm1` or ` &pwm2` as well.

The value `chX-pin` represents the pin that controls the LEDs. With nRF52 boards, you can calculate the value to use in the following way: you need the hardware port and run it through a function.
**32 \* X + Y** = `<Pin number>` where X is first part of the hardware port "PX.01" and Y is the second part of the hardware port "P1.Y".

For example, _P1.13_ would give you _32 \* 1 + 13_ = `<45>` and _P0.15_ would give you _32 \* 0 + 15_ = `<15>`.

If you need to invert the signal, you may want to enable `chX-inverted`.

Then you have to add the following lines to your `.dtsi` file inside the root devicetree node:

```
pwmleds: pwmleds {
compatible = "pwm-leds";
label = "LED indicators";
pwm_led_0 {
pwms = <&pwm0 33>;
label = "Caps lock LED";
};
pwm_led_1 {
pwms = <&pwm0 35>;
label = "Num lock LED";
};
};
```

The value inside `pwm_led_X` must be the same as you used before.

Then you have to add the following lines to your `.dtsi` file inside the root devicetree node:

```
led_indicators: led_indicators {
compatible = "zmk,led-indicators";
caps_lock_led {
ctrl = <&pwmleds>;
index = <0>;
binding = <LED_CAPSLOCK>;
};
num_lock_led {
ctrl = <&pwmleds>;
index = <1>;
binding = <LED_NUMLOCK>;
};
};
```

You can find the definition of LEDs here: [`dt-bindings/zmk/led_indicators.h`](https://github.com/zmkfirmware/zmk/tree/main/app/include/dt-bindings/zmk/led_indicators.h).

Finally you need to add `led_indicators` to the `chosen` element of the root devicetree node:

```
chosen {
...
zmk,led_indicators = &led_indicators;
};
```

</TabItem>
<TabItem value="gpio">

First you have to enable the driver by adding the following lines to your `.conf` file:

```
CONFIG_LED_GPIO=y
```

Next you have to add the following lines to your `.dtsi` file inside the root devicetree node:

```
gpioleds: gpioleds {
compatible = "gpio-leds";
label = "LED indicators";
gpio_led_0 {
gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
label = "Caps lock LED";
};
gpio_led_1 {
gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
label = "Num lock LED";
};
};
```

Then you have to add the following lines to your `.dtsi` file inside the root devicetree node:

```
led_indicators: led_indicators {
compatible = "zmk,led-indicators";
caps_lock_led {
ctrl = <&gpioleds>;
index = <0>;
binding = <LED_CAPSLOCK>;
};
num_lock_led {
ctrl = <&gpioleds>;
index = <1>;
binding = <LED_NUMLOCK>;
};
};
```

You can find the definition of LEDs here: [`dt-bindings/zmk/led_indicators.h`](https://github.com/zmkfirmware/zmk/tree/main/app/include/dt-bindings/zmk/led_indicators.h).

Finally you need to add `led_indicators` to the `chosen` element of the root devicetree node:

```
chosen {
...
zmk,led_indicators = &led_indicators;
};
```

</TabItem>
<TabItem value="other">

First, you need to enable your LED driver:

```
&my_led_driver: my_led_driver {
...
};
```

Then you have to add the following lines to your `.dtsi` file inside the root devicetree node:

```
led_indicators: led_indicators {
compatible = "zmk,led-indicators";
caps_lock_led {
ctrl = <&my_led_driver>;
index = <0>;
binding = <LED_CAPSLOCK>;
};
num_lock_led {
ctrl = <&my_led_driver>;
index = <1>;
binding = <LED_NUMLOCK>;
};
};
```

You can find the definition of LEDs here: [`dt-bindings/zmk/led_indicators.h`](https://github.com/zmkfirmware/zmk/tree/main/app/include/dt-bindings/zmk/led_indicators.h).

Finally you need to add `led_indicators` to the `chosen` element of the root devicetree node:

```
chosen {
...
zmk,led_indicators = &led_indicators;
};
```

</TabItem>
</Tabs>

## Custom behavior

To implement custom behavior, such as a display widget, you must first **remove** `CONFIG_ZMK_LED_INDICATORS=y` from your `.conf` file. Then you can write a listener to implement the behavior you want, for example:

```C
#include <dt-bindings/zmk/led_indicators.h>

static int led_indicators_listener(const zmk_event_t *eh) {
const struct zmk_keycode_state_changed *ev = as_zmk_led_indicator_changed(eh);
zmk_led_indicators_flags_t leds = ev->leds;

if (leds & BIT(LED_CAPSLOCK)) {
// do something
}

return 0;
}

ZMK_LISTENER(led_indicators_listener, led_indicators_listener);
ZMK_SUBSCRIPTION(led_indicators_listener, zmk_led_indicator_changed);
```
1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
"features/displays",
"features/encoders",
"features/underglow",
"features/led-indicators",
"features/beta-testing",
],
Behaviors: [
Expand Down

0 comments on commit dc29c52

Please sign in to comment.