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 Oct 23, 2021
1 parent 0e0c012 commit 4b320f5
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/docs/development/hardware-metadata-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Boards and shields should document the sets of hardware features found on them u
- `display` - Indicates the hardware includes a display for use with the ZMK display functionality.
- `encoder` - Indicates the hardware contains one or more rotary encoders.
- `underglow` - Indicates the hardware includes underglow LEDs.
- `led_indicators` - Indicates the hardware includes LED indicators.
- `pointer` (future) - Used to indicate the hardware includes one or more pointer inputs, e.g. joystick, touchpad, or trackpoint.

### Siblings
Expand Down
184 changes: 184 additions & 0 deletions docs/docs/features/led-indicators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
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 the `ZMK_LED_PWM` driver.

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

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

```
CONFIG_ZMK_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. To calculate the value to use, you need a bit of math. 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 {
dev = <&pwmleds>;
index = <0>;
binding = <LED_CAPSLOCK>;
};
num_lock_led {
dev = <&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="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 {
dev = <&my_led_driver>;
index = <0>;
binding = <LED_CAPSLOCK>;
};
num_lock_led {
dev = <&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/docs/hardware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ In addition to the basic keyboard functionality, there is some initial support f
- Encoders
- Displays
- RGB Underglow
- LED indicators

Until detailed documentation is available, feel free to ask questions about how these are supported in the [Discord server](https://zmk.dev/community/discord/invite).

Expand Down
1 change: 1 addition & 0 deletions docs/docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ZMK is currently missing some features found in other popular firmware. This tab
| [Encoders](features/encoders.md)[^1] ||||
| [Display Support](features/displays.md)[^2] | 🚧 | 🚧 ||
| [RGB Underglow](features/underglow.md) ||||
| [LED indicators](features/led-indicators.md) || ||
| One Shot Keys ||||
| [Combo Keys](features/combos.md) || ||
| Macros | 🚧 |||
Expand Down
1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = {
"features/displays",
"features/encoders",
"features/underglow",
"features/led-indicators",
"features/beta-testing",
],
Behaviors: [
Expand Down

0 comments on commit 4b320f5

Please sign in to comment.