2020 February 29 Breaking Changes Update (#8064)
[jackhill/qmk/firmware.git] / docs / feature_backlight.md
CommitLineData
9b879b12 1# Backlighting
2
38aefaf7
JC
3Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. This feature is distinct from both the [RGB underglow](feature_rgblight.md) and [RGB matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously install multiple different single coloured LEDs on a keyboard.
4
5QMK is able to control the brightness of these LEDs by switching them on and off rapidly in a certain ratio, a technique known as *Pulse Width Modulation*, or PWM. By altering the duty cycle of the PWM signal, it creates the illusion of dimming.
9b879b12 6
98fa82ce 7The MCU can only supply so much current to its GPIO pins. Instead of powering the backlight directly from the MCU, the backlight pin is connected to a transistor or MOSFET that switches the power to the LEDs.
9b879b12 8
3d54b1ad 9## Feature Configuration
98fa82ce 10
9b7a3a0b 11Most keyboards have backlighting enabled by default if they support it, but if it is not working for you, check that your `rules.mk` includes the following:
98fa82ce 12
4531cc87 13```makefile
3d54b1ad 14BACKLIGHT_ENABLE = yes
9b7a3a0b 15```
16
98fa82ce 17## Keycodes
38aefaf7 18Once enabled the following keycodes below can be used to change the backlight level.
9b879b12 19
4c675a83 20|Key |Description |
21|---------|------------------------------------------|
22|`BL_TOGG`|Turn the backlight on or off |
23|`BL_STEP`|Cycle through backlight levels |
cfcf0fd3 24|`BL_ON` |Set the backlight to max brightness |
25|`BL_OFF` |Turn the backlight off |
26|`BL_INC` |Increase the backlight level |
27|`BL_DEC` |Decrease the backlight level |
28|`BL_BRTG`|Toggle backlight breathing |
4931510a 29
4531cc87
JC
30## Backlight Functions
31
32|Function |Description |
33|----------|-----------------------------------------------------------|
34|`backlight_toggle()` |Turn the backlight on or off |
35|`backlight_enable()` |Turn the backlight on |
36|`backlight_disable()` |Turn the backlight off |
37|`backlight_step()` |Cycle through backlight levels |
38|`backlight_increase()` |Increase the backlight level |
39|`backlight_decrease()` |Decrease the backlight level |
40|`backlight_level(x)` |Sets the backlight level to specified level |
41|`get_backlight_level()` |Return the current backlight level |
42|`is_backlight_enabled()`|Return whether the backlight is currently on |
43
44### Backlight Breathing Functions
45
46|Function |Description |
47|----------|---------------------------------------------------|
48|`breathing_toggle()` |Turn the backlight breathing on or off |
49|`breathing_enable()` |Turns on backlight breathing |
50|`breathing_disable()` |Turns off backlight breathing |
51
3d54b1ad 52## Driver Configuration
53
54To select which driver to use, configure your `rules.mk` with the following:
55
56```makefile
57BACKLIGHT_DRIVER = software # Valid driver values are 'pwm,software,no'
58```
59
60See below for help on individual drivers.
61
4531cc87
JC
62## Common Driver Configuration
63
64To change the behavior of the backlighting, `#define` these in your `config.h`:
65
66|Define |Default |Description |
67|---------------------|-------------|--------------------------------------------------------------------------------------|
68|`BACKLIGHT_LEVELS` |`3` |The number of brightness levels (maximum 31 excluding off) |
69|`BACKLIGHT_CAPS_LOCK`|*Not defined*|Enable Caps Lock indicator using backlight (for keyboards without dedicated LED) |
70|`BACKLIGHT_BREATHING`|*Not defined*|Enable backlight breathing, if supported |
71|`BREATHING_PERIOD` |`6` |The length of one backlight "breath" in seconds |
72|`BACKLIGHT_ON_STATE` |`0` |The state of the backlight pin when the backlight is "on" - `1` for high, `0` for low |
73
74### Backlight On State
75
76Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*.
77Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead.
78
79This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define.
80
38aefaf7 81## AVR driver
9b7a3a0b 82
3d54b1ad 83On AVR boards, the default driver currently sniffs the configuration to pick the best scenario. The driver is configured by default, however the equivalent setting within rules.mk would be:
4531cc87 84```makefile
3d54b1ad 85BACKLIGHT_DRIVER = pwm
4531cc87
JC
86```
87
38aefaf7 88### Caveats
9b7a3a0b 89
b61baf42
BF
90Hardware PWM is supported according to the following table:
91
3642a82d 92|Backlight Pin|AT90USB64/128|ATmega16/32U4|ATmega16/32U2|ATmega32A|ATmega328P|
93|-------------|-------------|-------------|-------------|---------|----------|
94|`B1` | | | | |Timer 1 |
95|`B2` | | | | |Timer 1 |
96|`B5` |Timer 1 |Timer 1 | | | |
97|`B6` |Timer 1 |Timer 1 | | | |
98|`B7` |Timer 1 |Timer 1 |Timer 1 | | |
99|`C4` |Timer 3 | | | | |
100|`C5` |Timer 3 | |Timer 1 | | |
101|`C6` |Timer 3 |Timer 3 |Timer 1 | | |
102|`D4` | | | |Timer 1 | |
103|`D5` | | | |Timer 1 | |
4d72aa42 104
105All other pins will use software PWM. If the [Audio](feature_audio.md) feature is disabled or only using one timer, the backlight PWM can be triggered by a hardware timer:
106
107|Audio Pin|Audio Timer|Software PWM Timer|
108|---------|-----------|------------------|
109|`C4` |Timer 3 |Timer 1 |
110|`C5` |Timer 3 |Timer 1 |
111|`C6` |Timer 3 |Timer 1 |
112|`B5` |Timer 1 |Timer 3 |
113|`B6` |Timer 1 |Timer 3 |
114|`B7` |Timer 1 |Timer 3 |
115
116When both timers are in use for Audio, the backlight PWM will not use a hardware timer, but will instead be triggered during the matrix scan. In this case, breathing is not supported, and the backlight might flicker, because the PWM computation may not be called with enough timing precision.
9b7a3a0b 117
38aefaf7 118### AVR Configuration
4931510a 119
38aefaf7 120To change the behavior of the backlighting, `#define` these in your `config.h`:
4931510a 121
26eef35f
JY
122|Define |Default |Description |
123|---------------------|-------------|-------------------------------------------------------------------------------------------------------------|
124|`BACKLIGHT_PIN` |`B7` |The pin that controls the LEDs. Unless you are designing your own keyboard, you shouldn't need to change this|
125|`BACKLIGHT_PINS` |*Not defined*|experimental: see below for more information |
126|`BACKLIGHT_LEVELS` |`3` |The number of brightness levels (maximum 31 excluding off) |
127|`BACKLIGHT_CAPS_LOCK`|*Not defined*|Enable Caps Lock indicator using backlight (for keyboards without dedicated LED) |
128|`BACKLIGHT_BREATHING`|*Not defined*|Enable backlight breathing, if supported |
129|`BREATHING_PERIOD` |`6` |The length of one backlight "breath" in seconds |
130|`BACKLIGHT_ON_STATE` |`1` |The state of the backlight pin when the backlight is "on" - `1` for high, `0` for low |
131
132### Backlight On State
133
134Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*.
135Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead.
136
137This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define.
4931510a 138
38aefaf7 139### Multiple backlight pins
b61baf42
BF
140
141Most keyboards have only one backlight pin which control all backlight LEDs (especially if the backlight is connected to an hardware PWM pin).
142In software PWM, it is possible to define multiple backlight pins. All those pins will be turned on and off at the same time during the PWM duty cycle.
143This feature allows to set for instance the Caps Lock LED (or any other controllable LED) brightness at the same level as the other LEDs of the backlight. This is useful if you have mapped LCTRL in place of Caps Lock and you need the Caps Lock LED to be part of the backlight instead of being activated when Caps Lock is on.
144
145To activate multiple backlight pins, you need to add something like this to your user `config.h`:
146
38aefaf7 147```c
b61baf42
BF
148#define BACKLIGHT_LED_COUNT 2
149#undef BACKLIGHT_PIN
150#define BACKLIGHT_PINS { F5, B2 }
38aefaf7 151```
b61baf42 152
38aefaf7 153### Hardware PWM Implementation
4931510a 154
98fa82ce 155When using the supported pins for backlighting, QMK will use a hardware timer configured to output a PWM signal. This timer will count up to `ICRx` (by default `0xFFFF`) before resetting to 0.
156The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the backlight pin will go low, and is pulled high again when the counter resets.
157In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on.
4931510a 158
98fa82ce 159The breathing effect is achieved by registering an interrupt handler for `TIMER1_OVF_vect` that is called whenever the counter resets, roughly 244 times per second.
160In this handler, the value of an incrementing counter is mapped onto a precomputed brightness curve. To turn off breathing, the interrupt handler is simply disabled, and the brightness reset to the level stored in EEPROM.
eb19fb5b 161
4531cc87 162### Timer Assisted PWM Implementation
b61baf42
BF
163
164When `BACKLIGHT_PIN` is not set to a hardware backlight pin, QMK will use a hardware timer configured to trigger software interrupts. This time will count up to `ICRx` (by default `0xFFFF`) before resetting to 0.
165When resetting to 0, the CPU will fire an OVF (overflow) interrupt that will turn the LEDs on, starting the duty cycle.
166The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the CPU will fire a Compare Output match interrupt, which will turn the LEDs off.
167In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on.
168
169The breathing effect is the same as in the hardware PWM implementation.
170
38aefaf7
JC
171## ARM Driver
172
3d54b1ad 173While still in its early stages, ARM backlight support aims to eventually have feature parity with AVR. The driver is configured by default, however the equivalent setting within rules.mk would be:
4531cc87 174```makefile
3d54b1ad 175BACKLIGHT_DRIVER = pwm
4531cc87
JC
176```
177
38aefaf7
JC
178### Caveats
179
4531cc87 180Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration.
38aefaf7 181
17ff5512 182?> Backlight support for STMF072 has had limited testing, YMMV. If unsure, set `BACKLIGHT_ENABLE = no` in your rules.mk.
38aefaf7
JC
183
184### ARM Configuration
185
186To change the behavior of the backlighting, `#define` these in your `config.h`:
187
188|Define |Default |Description |
189|------------------------|-------------|-------------------------------------------------------------------------------------------------------------|
190|`BACKLIGHT_PIN` |`B7` |The pin that controls the LEDs. Unless you are designing your own keyboard, you shouldn't need to change this|
191|`BACKLIGHT_PWM_DRIVER` |`PWMD4` |The PWM driver to use, see ST datasheets for pin to PWM timer mapping. Unless you are designing your own keyboard, you shouldn't need to change this|
192|`BACKLIGHT_PWM_CHANNEL` |`3` |The PWM channel to use, see ST datasheets for pin to PWM channel mapping. Unless you are designing your own keyboard, you shouldn't need to change this|
193|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use, see ST datasheets for pin AF mapping. Unless you are designing your own keyboard, you shouldn't need to change this|
38aefaf7 194
4531cc87 195## Software PWM Driver
eb19fb5b 196
4531cc87
JC
197Emulation of PWM while running other keyboard tasks, it offers maximum hardware compatibility without extra platform configuration. The tradeoff is the backlight might jitter when the keyboard is busy. To enable, add this to your rules.mk:
198```makefile
3d54b1ad 199BACKLIGHT_DRIVER = software
4531cc87 200```
eb19fb5b 201
4531cc87
JC
202### Software PWM Configuration
203
204To change the behavior of the backlighting, `#define` these in your `config.h`:
205
206|Define |Default |Description |
207|-----------------|-------------|-------------------------------------------------------------------------------------------------------------|
208|`BACKLIGHT_PIN` |`B7` |The pin that controls the LEDs. Unless you are designing your own keyboard, you shouldn't need to change this|
209|`BACKLIGHT_PINS` |*Not defined*|experimental: see below for more information |
eb19fb5b 210
4531cc87
JC
211### Multiple backlight pins
212
213Most keyboards have only one backlight pin which control all backlight LEDs (especially if the backlight is connected to an hardware PWM pin).
214In software PWM, it is possible to define multiple backlight pins. All those pins will be turned on and off at the same time during the PWM duty cycle.
215This feature allows to set for instance the Caps Lock LED (or any other controllable LED) brightness at the same level as the other LEDs of the backlight. This is useful if you have mapped LCTRL in place of Caps Lock and you need the Caps Lock LED to be part of the backlight instead of being activated when Caps Lock is on.
216
217To activate multiple backlight pins, you need to add something like this to your user `config.h`:
218
219```c
220#undef BACKLIGHT_PIN
221#define BACKLIGHT_PINS { F5, B2 }
222```
3d54b1ad 223
224## Custom Driver
225
226To enable, add this to your rules.mk:
227
228```makefile
229BACKLIGHT_DRIVER = custom
230```
231
232When implementing the custom driver API, the provided keyboard hooks are as follows:
233
234```c
235void backlight_init_ports(void) {
236 // Optional - Run on startup
237 // - usually you want to configure pins here
238}
239void backlight_set(uint8_t level) {
240 // Optional - Run on level change
241 // - usually you want to respond to the new value
242}
243
244void backlight_task(void) {
245 // Optional - Run periodically
246 // - long running actions here can cause performance issues
247}
248```