aboutsummaryrefslogtreecommitdiff
path: root/docs/feature_backlight.md
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2020-07-03 19:05:59 +1000
committerGitHub <noreply@github.com>2020-07-03 10:05:59 +0100
commit2c98c4dd4e05f02a87154c914319f2b772bf81c9 (patch)
tree3037ec1e94c981244a6ba75445057dc3e7a5ca29 /docs/feature_backlight.md
parent8c66c5aa9b08d732329408847dc6cf7645e67ae1 (diff)
downloadqmk_firmware-2c98c4dd4e05f02a87154c914319f2b772bf81c9.tar.gz
qmk_firmware-2c98c4dd4e05f02a87154c914319f2b772bf81c9.zip
Backlight docs wordsmithing (#9631)
Diffstat (limited to 'docs/feature_backlight.md')
-rw-r--r--docs/feature_backlight.md259
1 files changed, 115 insertions, 144 deletions
diff --git a/docs/feature_backlight.md b/docs/feature_backlight.md
index 7e4401b40..9e467c708 100644
--- a/docs/feature_backlight.md
+++ b/docs/feature_backlight.md
@@ -1,4 +1,4 @@
1# Backlighting 1# Backlighting :id=backlighting
2 2
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. 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 4
@@ -6,103 +6,106 @@ QMK is able to control the brightness of these LEDs by switching them on and off
6 6
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. 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.
8 8
9## Feature Configuration
10
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: 9Most 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:
12 10
13```makefile 11```makefile
14BACKLIGHT_ENABLE = yes 12BACKLIGHT_ENABLE = yes
15``` 13```
16 14
17## Keycodes 15## Keycodes :id=keycodes
18Once enabled the following keycodes below can be used to change the backlight level. 16
19 17Once enabled, the following keycodes below can be used to change the backlight level.
20|Key |Description | 18
21|---------|------------------------------------------| 19|Key |Description |
22|`BL_TOGG`|Turn the backlight on or off | 20|---------|-----------------------------------|
23|`BL_STEP`|Cycle through backlight levels | 21|`BL_TOGG`|Turn the backlight on or off |
24|`BL_ON` |Set the backlight to max brightness | 22|`BL_STEP`|Cycle through backlight levels |
25|`BL_OFF` |Turn the backlight off | 23|`BL_ON` |Set the backlight to max brightness|
26|`BL_INC` |Increase the backlight level | 24|`BL_OFF` |Turn the backlight off |
27|`BL_DEC` |Decrease the backlight level | 25|`BL_INC` |Increase the backlight level |
28|`BL_BRTG`|Toggle backlight breathing | 26|`BL_DEC` |Decrease the backlight level |
29 27|`BL_BRTG`|Toggle backlight breathing |
30## Backlight Functions 28
31 29## Functions :id=functions
32|Function |Description | 30
33|----------|-----------------------------------------------------------| 31These functions can be used to change the backlighting in custom code:
34|`backlight_toggle()` |Turn the backlight on or off | 32
35|`backlight_enable()` |Turn the backlight on | 33|Function |Description |
36|`backlight_disable()` |Turn the backlight off | 34|------------------------|--------------------------------------------|
37|`backlight_step()` |Cycle through backlight levels | 35|`backlight_toggle()` |Turn the backlight on or off |
38|`backlight_increase()` |Increase the backlight level | 36|`backlight_enable()` |Turn the backlight on |
39|`backlight_decrease()` |Decrease the backlight level | 37|`backlight_disable()` |Turn the backlight off |
40|`backlight_level(x)` |Sets the backlight level to specified level | 38|`backlight_step()` |Cycle through backlight levels |
41|`get_backlight_level()` |Return the current backlight level | 39|`backlight_increase()` |Increase the backlight level |
42|`is_backlight_enabled()`|Return whether the backlight is currently on | 40|`backlight_decrease()` |Decrease the backlight level |
43 41|`backlight_level(x)` |Sets the backlight level to specified level |
44### Backlight Breathing Functions 42|`get_backlight_level()` |Return the current backlight level |
45 43|`is_backlight_enabled()`|Return whether the backlight is currently on|
46|Function |Description | 44
47|----------|---------------------------------------------------| 45If backlight breathing is enabled (see below), the following functions are also available:
48|`breathing_toggle()` |Turn the backlight breathing on or off | 46
49|`breathing_enable()` |Turns on backlight breathing | 47|Function |Description |
50|`breathing_disable()` |Turns off backlight breathing | 48|---------------------|--------------------------------------|
51 49|`breathing_toggle()` |Turn the backlight breathing on or off|
52## Driver Configuration 50|`breathing_enable()` |Turns on backlight breathing |
51|`breathing_disable()`|Turns off backlight breathing |
52
53## Configuration :id=configuration
53 54
54To select which driver to use, configure your `rules.mk` with the following: 55To select which driver to use, configure your `rules.mk` with the following:
55 56
56```makefile 57```makefile
57BACKLIGHT_DRIVER = software # Valid driver values are 'pwm,software,no' 58BACKLIGHT_DRIVER = software
58``` 59```
59 60
60See below for help on individual drivers. 61Valid driver values are `pwm`, `software`, `custom` or `no`. See below for help on individual drivers.
61 62
62## Common Driver Configuration 63To configure the backlighting, `#define` these in your `config.h`:
63 64
64To change the behavior of the backlighting, `#define` these in your `config.h`: 65|Define |Default |Description |
66|---------------------|-------------|-------------------------------------------------------------------------------------|
67|`BACKLIGHT_PIN` |*Not defined*|The pin that controls the LED(s) |
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` |`1` |The state of the backlight pin when the backlight is "on" - `1` for high, `0` for low|
65 73
66|Define |Default |Description | 74Unless you are designing your own keyboard, you generally should not need to change the `BACKLIGHT_PIN` or `BACKLIGHT_ON_STATE`.
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 75
74### Backlight On State 76### Backlight On State :id=backlight-on-state
75 77
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*. 78Most 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. 79Sometimes, 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 80
79This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define. 81This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define.
80 82
81## AVR driver 83### AVR Driver :id=avr-driver
84
85The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be:
82 86
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:
84```makefile 87```makefile
85BACKLIGHT_DRIVER = pwm 88BACKLIGHT_DRIVER = pwm
86``` 89```
87 90
88### Caveats 91#### Caveats :id=avr-caveats
89 92
90Hardware PWM is supported according to the following table: 93On AVR boards, QMK automatically decides which driver to use according to the following table:
91 94
92|Backlight Pin|AT90USB64/128|ATmega16/32U4|ATmega16/32U2|ATmega32A|ATmega328/P| 95|Backlight Pin|AT90USB64/128|ATmega16/32U4|ATmega16/32U2|ATmega32A|ATmega328/P|
93|-------------|-------------|-------------|-------------|---------|----------| 96|-------------|-------------|-------------|-------------|---------|-----------|
94|`B1` | | | | |Timer 1 | 97|`B1` | | | | |Timer 1 |
95|`B2` | | | | |Timer 1 | 98|`B2` | | | | |Timer 1 |
96|`B5` |Timer 1 |Timer 1 | | | | 99|`B5` |Timer 1 |Timer 1 | | | |
97|`B6` |Timer 1 |Timer 1 | | | | 100|`B6` |Timer 1 |Timer 1 | | | |
98|`B7` |Timer 1 |Timer 1 |Timer 1 | | | 101|`B7` |Timer 1 |Timer 1 |Timer 1 | | |
99|`C4` |Timer 3 | | | | | 102|`C4` |Timer 3 | | | | |
100|`C5` |Timer 3 | |Timer 1 | | | 103|`C5` |Timer 3 | |Timer 1 | | |
101|`C6` |Timer 3 |Timer 3 |Timer 1 | | | 104|`C6` |Timer 3 |Timer 3 |Timer 1 | | |
102|`D4` | | | |Timer 1 | | 105|`D4` | | | |Timer 1 | |
103|`D5` | | | |Timer 1 | | 106|`D5` | | | |Timer 1 | |
104 107
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: 108All other pins will use timer-assisted software PWM:
106 109
107|Audio Pin|Audio Timer|Software PWM Timer| 110|Audio Pin|Audio Timer|Software PWM Timer|
108|---------|-----------|------------------| 111|---------|-----------|------------------|
@@ -113,44 +116,9 @@ All other pins will use software PWM. If the [Audio](feature_audio.md) feature i
113|`B6` |Timer 1 |Timer 3 | 116|`B6` |Timer 1 |Timer 3 |
114|`B7` |Timer 1 |Timer 3 | 117|`B7` |Timer 1 |Timer 3 |
115 118
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. 119When both timers are in use for Audio, the backlight PWM cannot use a hardware timer, and 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.
117
118### AVR Configuration
119
120To change the behavior of the backlighting, `#define` these in your `config.h`:
121
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.
138
139### Multiple backlight pins
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
147```c
148#define BACKLIGHT_LED_COUNT 2
149#undef BACKLIGHT_PIN
150#define BACKLIGHT_PINS { F5, B2 }
151```
152 120
153### Hardware PWM Implementation 121#### Hardware PWM Implementation :id=hardware-pwm-implementation
154 122
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. 123When 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. 124The 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.
@@ -159,7 +127,7 @@ In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus th
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. 127The 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. 128In 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.
161 129
162### Timer Assisted PWM Implementation 130#### Timer Assisted PWM Implementation :id=timer-assisted-implementation
163 131
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. 132When `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. 133When resetting to 0, the CPU will fire an OVF (overflow) interrupt that will turn the LEDs on, starting the duty cycle.
@@ -168,81 +136,84 @@ In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus th
168 136
169The breathing effect is the same as in the hardware PWM implementation. 137The breathing effect is the same as in the hardware PWM implementation.
170 138
171## ARM Driver 139### ARM Driver :id=arm-configuration
140
141While still in its early stages, ARM backlight support aims to eventually have feature parity with AVR. The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be:
172 142
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:
174```makefile 143```makefile
175BACKLIGHT_DRIVER = pwm 144BACKLIGHT_DRIVER = pwm
176``` 145```
177 146
178### Caveats 147#### ChibiOS Configuration :id=arm-configuration
179 148
180Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration. 149The following `#define`s apply only to ARM-based keyboards:
181 150
182?> Backlight support for STMF072 has had limited testing, YMMV. If unsure, set `BACKLIGHT_ENABLE = no` in your rules.mk. 151|Define |Default|Description |
152|-----------------------|-------|-----------------------------------|
153|`BACKLIGHT_PWM_DRIVER` |`PWMD4`|The PWM driver to use |
154|`BACKLIGHT_PWM_CHANNEL`|`3` |The PWM channel to use |
155|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use|
183 156
184### ARM Configuration 157See the ST datasheet for your particular MCU to determine these values. Unless you are designing your own keyboard, you generally should not need to change them.
185 158
186To change the behavior of the backlighting, `#define` these in your `config.h`: 159#### Caveats :id=arm-caveats
187 160
188|Define |Default |Description | 161Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration.
189|------------------------|-------------|-------------------------------------------------------------------------------------------------------------| 162
190|`BACKLIGHT_PIN` |`B7` |The pin that controls the LEDs. Unless you are designing your own keyboard, you shouldn't need to change this| 163?> Backlight support for STM32F072 has had limited testing, so YMMV. If unsure, set `BACKLIGHT_ENABLE = no` in your `rules.mk`.
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| 164
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| 165### Software PWM Driver :id=software-pwm-driver
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|
194 166
195## Software PWM Driver :id=software-pwm-driver 167In this mode, PWM is "emulated" 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`:
196 168
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 169```makefile
199BACKLIGHT_DRIVER = software 170BACKLIGHT_DRIVER = software
200``` 171```
201 172
202### Software PWM Configuration 173#### Multiple Backlight Pins :id=multiple-backlight-pins
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 |
210
211### Multiple backlight pins
212 174
213Most keyboards have only one backlight pin which control all backlight LEDs (especially if the backlight is connected to an hardware PWM pin). 175Most 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. 176In software PWM, it is possible to define multiple backlight pins, which 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. 177
178This feature allows to set, for instance, the Caps Lock LED's (or any other controllable LED) brightness at the same level as the other LEDs of the backlight. This is useful if you have mapped Control 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, as it is usually wired to a separate pin from the backlight.
216 179
217To activate multiple backlight pins, you need to add something like this to your user `config.h`: 180To activate multiple backlight pins, add something like this to your `config.h`, instead of `BACKLIGHT_PIN`:
218 181
219```c 182```c
220#undef BACKLIGHT_PIN
221#define BACKLIGHT_PINS { F5, B2 } 183#define BACKLIGHT_PINS { F5, B2 }
222``` 184```
223 185
224## Custom Driver 186### Custom Driver :id=custom-driver
225 187
226To enable, add this to your rules.mk: 188If none of the above drivers apply to your board (for example, you are using a separate IC to control the backlight), you can implement a custom backlight driver using this simple API provided by QMK. To enable, add this to your `rules.mk`:
227 189
228```makefile 190```makefile
229BACKLIGHT_DRIVER = custom 191BACKLIGHT_DRIVER = custom
230``` 192```
231 193
232When implementing the custom driver API, the provided keyboard hooks are as follows: 194Then implement any of these hooks:
233 195
234```c 196```c
235void backlight_init_ports(void) { 197void backlight_init_ports(void) {
236 // Optional - Run on startup 198 // Optional - runs on startup
237 // - usually you want to configure pins here 199 // Usually you want to configure pins here
238} 200}
239void backlight_set(uint8_t level) { 201void backlight_set(uint8_t level) {
240 // Optional - Run on level change 202 // Optional - runs on level change
241 // - usually you want to respond to the new value 203 // Usually you want to respond to the new value
242} 204}
243 205
244void backlight_task(void) { 206void backlight_task(void) {
245 // Optional - Run periodically 207 // Optional - runs periodically
246 // - long running actions here can cause performance issues 208 // Note that this is called in the main keyboard loop,
209 // so long running actions here can cause performance issues
247} 210}
248``` 211```
212
213## Example Schematic
214
215In this typical example, the backlight LEDs are all connected in parallel towards an N-channel MOSFET. Its gate pin is wired to one of the microcontroller's GPIO pins through a 470Ω resistor to avoid ringing.
216A pulldown resistor is also placed between the gate pin and ground to keep it at a defined state when it is not otherwise being driven by the MCU.
217The values of these resistors are not critical - see [this Electronics StackExchange question](https://electronics.stackexchange.com/q/68748) for more information.
218
219![Backlight example circuit](https://i.imgur.com/BmAvoUC.png)