summaryrefslogtreecommitdiff
path: root/docs/docs/features/backlight.md
blob: ef1c0521ad734691359f8058c02be0feb82f4a5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
---
title: Backlight
sidebar_label: Backlight
---

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

Backlight is a feature used to control array of LEDs, usually placed through or under switches. Unlike [RGB Underglow](underglow.md), backlight currently allows only one color per LED, also LEDs are not addressable, so you can't control individual LEDs.

## Enabling Backlight

To enable backlight on your board or shield, add the following line to your `.conf` file of your user config directory as such:

```
CONFIG_ZMK_BACKLIGHT=y
```

If your board or shield does not have backlight configured, refer to [Adding Backlight to a board or a shield](#adding-backlight-to-a-board-or-a-shield).

## Configuring Backlight

There are various Kconfig options used to configure the backlight feature. These can all be set in the `.conf` file.

| Option                               | Description                                           | Default |
| ------------------------------------ | ----------------------------------------------------- | ------- |
| `CONFIG_ZMK_BACKLIGHT_BRT_STEP`      | Brightness step in percent                            | 20      |
| `CONFIG_ZMK_BACKLIGHT_BRT_START`     | Default brightness in percent                         | 40      |
| `CONFIG_ZMK_BACKLIGHT_ON_START`      | Default backlight state                               | y       |
| `CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE` | Turn off backlight when keyboard goes into idle state | n       |
| `CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB`  | Turn off backlight when USB is disconnected           | n       |

## Adding Backlight to a board or a shield

<Tabs
defaultValue="shield"
values={[
{label: 'Adding to a board', value: 'board'},
{label: 'Adding to a shield', value: 'shield'},
]}>
<TabItem value="board">

First, you must enable PWM by adding the following lines to your `Kconfig.defconfig` file:

```
if ZMK_BACKLIGHT

config PWM
    default y

config LED_PWM
    default y

endif # ZMK_BACKLIGHT
```

Then you have to add the following lines to your `.dts` file:

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

The value `ch0-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 your board uses a P-channel MOSFET to control backlight instead of a N-channel MOSFET, you may want to enable `ch0-inverted`.

Then you have to add the following lines inside the root devicetree node on the same file as before:

```
/ {
    backlight: pwmleds {
        compatible = "pwm-leds";
        label = "Backlight LEDs";
        pwm_led_0 {
            pwms = <&pwm0 45>;
        	label = "Backlight LED 0";
        };
    };
};
```

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

:::info
Note that every LED inside of the backlight node will be treated as a backlight LED, so if you have other PWM LEDs you need to declare them in a separate node. Refer to [Multiple backlight LEDs](#multiple-backlight-leds) if you have multiple backlight LEDs.
:::

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

```
/ {
    chosen {
        zmk,backlight = &backlight;
    };
}:
```

</TabItem>
<TabItem value="shield">

You must first add a `boards/` directory within your shield folder. For each board that supports the shield you must create a `<board>.defconfig` file and a `<board>.overlay` file inside the `boards/` folder.

Inside your `<board>.defconfig` file, add the following lines:

```
if ZMK_BACKLIGHT

config PWM
    default y

config LED_PWM
    default y

endif # ZMK_BACKLIGHT
```

Then add the following lines to your `.overlay` file:

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

The value `ch0-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 your shield uses a P-channel MOSFET to control backlight instead of a N-channel MOSFET, you may want to enable `ch0-inverted`.

Then you have to add the following lines inside the root devicetree node on the same file:

```
/ {
    backlight: pwmleds {
        compatible = "pwm-leds";
        label = "Backlight LEDs";
        pwm_led_0 {
            pwms = <&pwm0 45>;
        	label = "Backlight LED 0";
        };
    };
};
```

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

:::info
Note that every LED inside of the backlight node will be treated as a backlight LED, so if you have other PWM LEDs you need to declare them in a separate node. Refer to [Multiple backlight LEDs](#multiple-backlight-leds) if you have multiple backlight LEDs.
:::

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

```
/ {
    chosen {
        zmk,backlight = &backlight;
    };
}:
```

Optionally, on Pro Micro compatible shields you can add a LED GPIO node to your devicetree, this could be useful if you want your shield to be compatible with newer or untested boards. To do that you have to enable `CONFIG_LED_GPIO` in your `.conf` file and then add the following lines inside the root devicetree node of your `.dtsi` or `.dts` file:

```
/ {
    backlight: gpioleds {
        compatible = "gpio-leds";
        label = "Backlight LEDs";
        gpio_led_0 {
            gpios = <&pro_micro 20 GPIO_ACTIVE_HIGH>;
        	label = "Backlight LED 0";
        };
    };
};
```

If no suitable `<board>.overlay` file is found, this node will act as a fallback, however, without PWM, backlight has limited functionality.

</TabItem>
</Tabs>

### Multiple backlight LEDs

It is possible to control multiple backlight LEDs at the same time. This is useful if, for example, you have a Caps Lock LED connected to a different pin and you want it to be part of the backlight.

In order to do that, first you need to enable PWM for each pin:

```
&pwm0 {
	status = "okay";
	ch0-pin = <45>; /* LED 0 */
	ch1-pin = <46>; /* LED 1 */
	ch2-pin = <47>; /* LED 2 */
    ...
};
```

This part may vary based on your MCU as different MCUs may have a different number of modules and channels.

Then you can simply add each of your LED to the backlight node:

```
backlight: pwmleds {
    compatible = "pwm-leds";
    label = "Backlight LEDs";
    pwm_led_0 {
        pwms = <&pwm0 45>; /* LED 0 */
    };
    pwm_led_1 {
        pwms = <&pwm0 46>; /* LED 1 */
    };
    pwm_led_2 {
        pwms = <&pwm0 47>; /* LED 2 */
    };
    ...
};
```