Skip to content

Commit 4b320f5

Browse files
committed
docs: add led indicators documentation
1 parent 0e0c012 commit 4b320f5

File tree

5 files changed

+188
-0
lines changed

5 files changed

+188
-0
lines changed

docs/docs/development/hardware-metadata-files.md

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ Boards and shields should document the sets of hardware features found on them u
9494
- `display` - Indicates the hardware includes a display for use with the ZMK display functionality.
9595
- `encoder` - Indicates the hardware contains one or more rotary encoders.
9696
- `underglow` - Indicates the hardware includes underglow LEDs.
97+
- `led_indicators` - Indicates the hardware includes LED indicators.
9798
- `pointer` (future) - Used to indicate the hardware includes one or more pointer inputs, e.g. joystick, touchpad, or trackpoint.
9899

99100
### Siblings

docs/docs/features/led-indicators.md

+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
title: LED indicators
3+
sidebar_label: LED indicators
4+
---
5+
6+
import Tabs from '@theme/Tabs';
7+
import TabItem from '@theme/TabItem';
8+
9+
ZMK supports the following LED indicators:
10+
11+
- Num Lock
12+
- Caps Lock
13+
- Scroll Lock
14+
- Compose
15+
- Kana
16+
17+
## Enabling LED indicators
18+
19+
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:
20+
21+
```
22+
CONFIG_ZMK_LED_INDICATORS=y
23+
```
24+
25+
You can also configure the brightness of the LEDs using:
26+
27+
```
28+
CONFIG_ZMK_LED_INDICATORS_BRT=80
29+
```
30+
31+
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).
32+
33+
## Adding LED indicators to a board
34+
35+
You can use any LED driver supported by ZMK or Zephyr, it is recommended to use the `ZMK_LED_PWM` driver.
36+
37+
<Tabs
38+
defaultValue="pwm"
39+
values={[
40+
{label: 'ZMK_LED_PWM driver', value: 'pwm'},
41+
{label: 'Other drivers', value: 'other'},
42+
]}>
43+
<TabItem value="pwm">
44+
45+
First you have to enable the driver by adding the following line to your `.conf` file:
46+
47+
```
48+
CONFIG_ZMK_LED_PWM=y
49+
```
50+
51+
Next, you need to enable PWM by adding the following lines to your `.overlay` file:
52+
53+
```
54+
&pwm0 {
55+
status = "okay";
56+
ch0-pin = <33>;
57+
/* ch0-inverted; */
58+
ch1-pin = <35>;
59+
/* ch1-inverted; */
60+
};
61+
```
62+
63+
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.
64+
65+
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.
66+
**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".
67+
68+
For example, _P1.13_ would give you _32 \* 1 + 13_ = `<45>` and _P0.15_ would give you _32 \* 0 + 15_ = `<15>`.
69+
70+
If you need to invert the signal, you may want to enable `chX-inverted`.
71+
72+
Then you have to add the following lines to your `.dtsi` file inside the root devicetree node:
73+
74+
```
75+
pwmleds: pwmleds {
76+
compatible = "pwm-leds";
77+
label = "LED indicators";
78+
pwm_led_0 {
79+
pwms = <&pwm0 33>;
80+
label = "Caps lock LED";
81+
};
82+
pwm_led_1 {
83+
pwms = <&pwm0 35>;
84+
label = "Num lock LED";
85+
};
86+
};
87+
```
88+
89+
The value inside `pwm_led_X` must be the same as you used before.
90+
91+
Then you have to add the following lines to your `.dtsi` file inside the root devicetree node:
92+
93+
```
94+
led_indicators: led_indicators {
95+
compatible = "zmk,led-indicators";
96+
caps_lock_led {
97+
dev = <&pwmleds>;
98+
index = <0>;
99+
binding = <LED_CAPSLOCK>;
100+
};
101+
num_lock_led {
102+
dev = <&pwmleds>;
103+
index = <1>;
104+
binding = <LED_NUMLOCK>;
105+
};
106+
};
107+
```
108+
109+
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).
110+
111+
112+
Finally you need to add `led_indicators` to the `chosen` element of the root devicetree node:
113+
114+
```
115+
chosen {
116+
...
117+
zmk,led_indicators = &led_indicators;
118+
};
119+
```
120+
121+
</TabItem>
122+
<TabItem value="other">
123+
124+
First, you need to enable your LED driver:
125+
126+
```
127+
&my_led_driver: my_led_driver {
128+
...
129+
};
130+
```
131+
132+
Then you have to add the following lines to your `.dtsi` file inside the root devicetree node:
133+
134+
```
135+
led_indicators: led_indicators {
136+
compatible = "zmk,led-indicators";
137+
caps_lock_led {
138+
dev = <&my_led_driver>;
139+
index = <0>;
140+
binding = <LED_CAPSLOCK>;
141+
};
142+
num_lock_led {
143+
dev = <&my_led_driver>;
144+
index = <1>;
145+
binding = <LED_NUMLOCK>;
146+
};
147+
};
148+
```
149+
150+
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).
151+
152+
Finally you need to add `led_indicators` to the `chosen` element of the root devicetree node:
153+
154+
```
155+
chosen {
156+
...
157+
zmk,led_indicators = &led_indicators;
158+
};
159+
```
160+
161+
</TabItem>
162+
</Tabs>
163+
164+
## Custom behavior
165+
166+
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:
167+
168+
```C
169+
#include <dt-bindings/zmk/led_indicators.h>
170+
171+
static int led_indicators_listener(const zmk_event_t *eh) {
172+
const struct zmk_keycode_state_changed *ev = as_zmk_led_indicator_changed(eh);
173+
zmk_led_indicators_flags_t leds = ev->leds;
174+
175+
if (leds & BIT(LED_CAPSLOCK)) {
176+
// do something
177+
}
178+
179+
return 0;
180+
}
181+
182+
ZMK_LISTENER(led_indicators_listener, led_indicators_listener);
183+
ZMK_SUBSCRIPTION(led_indicators_listener, zmk_led_indicator_changed);
184+
```

docs/docs/hardware.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ In addition to the basic keyboard functionality, there is some initial support f
1818
- Encoders
1919
- Displays
2020
- RGB Underglow
21+
- LED indicators
2122

2223
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).
2324

docs/docs/intro.md

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ZMK is currently missing some features found in other popular firmware. This tab
2828
| [Encoders](features/encoders.md)[^1] ||||
2929
| [Display Support](features/displays.md)[^2] | 🚧 | 🚧 ||
3030
| [RGB Underglow](features/underglow.md) ||||
31+
| [LED indicators](features/led-indicators.md) || ||
3132
| One Shot Keys ||||
3233
| [Combo Keys](features/combos.md) || ||
3334
| Macros | 🚧 |||

docs/sidebars.js

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = {
1414
"features/displays",
1515
"features/encoders",
1616
"features/underglow",
17+
"features/led-indicators",
1718
"features/beta-testing",
1819
],
1920
Behaviors: [

0 commit comments

Comments
 (0)