fix(docs): Update backlight docs (#1894)

Co-authored-by: Cem Aksoylar <caksoylar@users.noreply.github.com>
Co-authored-by: Less/Rikki <86894501+lesshonor@users.noreply.github.com>
This commit is contained in:
ReFil 2023-12-04 17:21:49 +00:00 committed by GitHub
parent 55aed8e89d
commit ecefd6d24b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -37,12 +37,12 @@ There are various Kconfig options used to configure the backlight feature. These
## Adding Backlight to a board or a shield ## Adding Backlight to a board or a shield
<Tabs <Tabs
defaultValue="shield" defaultValue="shieldpin"
values={[ values={[
{label: 'Adding to a board', value: 'board'}, {label: 'Adding to a board', value: 'boardpin'},{label: 'Adding to a shield', value: 'shieldpin'},
{label: 'Adding to a shield', value: 'shield'},
]}> ]}>
<TabItem value="board">
<TabItem value="boardpin">
First, you must enable PWM by adding the following lines to your `Kconfig.defconfig` file: First, you must enable PWM by adding the following lines to your `Kconfig.defconfig` file:
@ -58,43 +58,60 @@ config LED_PWM
endif # ZMK_BACKLIGHT endif # ZMK_BACKLIGHT
``` ```
Then you have to add the following lines to your `.dts` file: Create a `<board>-pinctrl.dtsi` file if it does not already exist, and include it at the beginning of the `<board>.dts` file. `CONFIG_PINCTRL=y` must be added to to `<board>_defconfig` if it isn't already enabled.
The pinctrl file has a `&pinctrl` node that encompasses all pinctrl settings, including I2C or SPI peripherals (e.g. WS2812 LEDs, Battery fuel gauges):
```dts ```dts
&pwm0 { &pinctrl {
status = "okay"; // Other pinctrl definitions for other hardware
ch0-pin = <45>; pwm0_default: pwm0_default {
/* ch0-inverted; */ group1 {
}; psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
``` };
};
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. pwm0_sleep: pwm0_sleep {
**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". group1 {
psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
For example, _P1.13_ would give you _32 \* 1 + 13_ = `<45>` and _P0.15_ would give you _32 \* 0 + 15_ = `<15>`. low-power-enable;
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:
```dts
/ {
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. Pin numbers are handled differently depending on the MCU. On nRF MCUs pins are configured using `(PWM_OUTX, Y, Z)`, where `X` is the PWM channel used (usually 0), `Y` is the first part of the hardware port (_PY.01_) and `Z` is the second part of the hardware port (_P1.Z_).
:::info For example, _P1.13_ would give you `(PWM_OUT0, 1, 13)` and _P0.15_ would give you `(PWM_OUT0, 0, 15)`.
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.
::: Add the PWM device to the `board.dts` file and assign the pinctrl definitions to it:
```dts
&pwm0 {
status = "okay";
pinctrl-0 = <&pwm0_default>;
pinctrl-1 = <&pwm0_sleep>;
pinctrl-names = "default", "sleep";
};
```
Then add the following lines to the same `<board>.dts` file, but inside the root devicetree node:
```dts
/ {
backlight: pwmleds {
compatible = "pwm-leds";
pwm_led_0 {
pwms = <&pwm0 0 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
};
};
};
```
The value inside `pwm_led_0` after `&pwm0` must be the channel number. Since `PWM_OUT0` is defined in the pinctrl node, the channel in this example is 0.
In this example, `PWM_MSEC(10)` is the period of the PWM waveform. This period can be altered if your drive circuitry requires different values or the frequency is audible.
If your board uses a P-channel MOSFET to control backlight instead of a N-channel MOSFET, you may want to change `PWM_POLARITY_NORMAL` for `PWM_POLARITY_INVERTED`.
Finally you need to add backlight to the `chosen` element of the root devicetree node: Finally you need to add backlight to the `chosen` element of the root devicetree node:
@ -107,7 +124,7 @@ Finally you need to add backlight to the `chosen` element of the root devicetree
``` ```
</TabItem> </TabItem>
<TabItem value="shield"> <TabItem value="shieldpin">
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. 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.
@ -128,40 +145,55 @@ endif # ZMK_BACKLIGHT
Then add the following lines to your `.overlay` file: Then add the following lines to your `.overlay` file:
```dts ```dts
&pwm0 { &pinctrl {
status = "okay"; // Other pinctrl definitions for other hardware
ch0-pin = <45>; pwm0_default: pwm0_default {
/* ch0-inverted; */ group1 {
}; psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
``` };
};
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. pwm0_sleep: pwm0_sleep {
**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". group1 {
psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
For example, _P1.13_ would give you _32 \* 1 + 13_ = `<45>` and _P0.15_ would give you _32 \* 0 + 15_ = `<15>`. low-power-enable;
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:
```dts
/ {
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. Pin numbers are handled differently depending on the MCU. On nRF MCUs pins are configured using `(PWM_OUTX, Y, Z)`, where `X` is the PWM channel used (usually 0), `Y` is the first part of the hardware port (_PY.01_) and `Z` is the second part of the hardware port (_P1.Z_).
:::info For example, _P1.13_ would give you `(PWM_OUT0, 1, 13)` and _P0.15_ would give you `(PWM_OUT0, 0, 15)`.
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.
::: Add the PWM device to the `<board>.overlay` file and assign the pinctrl definitions to it:
```dts
&pwm0 {
status = "okay";
pinctrl-0 = <&pwm0_default>;
pinctrl-1 = <&pwm0_sleep>;
pinctrl-names = "default", "sleep";
};
```
Then add the following lines to the same `<board>.overlay` file, but inside the root devicetree node:
```
/ {
backlight: pwmleds {
compatible = "pwm-leds";
pwm_led_0 {
pwms = <&pwm0 0 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
};
};
};
```
In this example, `PWM_MSEC(10)` is the period of the PWM waveform. This period can be altered if your drive circuitry requires different values or the frequency is audible.
If your board uses a P-channel MOSFET to control backlight instead of a N-channel MOSFET, you may want to change `PWM_POLARITY_NORMAL` for `PWM_POLARITY_INVERTED`.
The value inside `pwm_led_0` after `&pwm0` must be the channel number. Since `PWM_OUT0` is defined in the pinctrl node, the channel in this example is 0.
Finally you need to add backlight to the `chosen` element of the root devicetree node: Finally you need to add backlight to the `chosen` element of the root devicetree node:
@ -170,26 +202,9 @@ Finally you need to add backlight to the `chosen` element of the root devicetree
chosen { chosen {
zmk,backlight = &backlight; 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:
```dts
/ {
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> </TabItem>
</Tabs> </Tabs>
@ -197,35 +212,45 @@ If no suitable `<board>.overlay` file is found, this node will act as a fallback
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. 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: In order to do that, first configure PWM for each pin in the pinctrl node:
```dts ```dts
&pwm0 { &pinctrl {
status = "okay"; // Other Pinctrl definitions go here
ch0-pin = <45>; /* LED 0 */ pwm0_default: pwm0_default {
ch1-pin = <46>; /* LED 1 */ group1 {
ch2-pin = <47>; /* LED 2 */ psels = <NRF_PSEL(PWM_OUT0, 0, 20)>, // LED 0
... <NRF_PSEL(PWM_OUT1, 0, 22)>, // LED 1
<NRF_PSEL(PWM_OUT2, 0, 24)>; // LED 2
};
};
pwm0_sleep: pwm0_sleep {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 0, 20)>, // LED 0
<NRF_PSEL(PWM_OUT1, 0, 22)>, // LED 1
<NRF_PSEL(PWM_OUT2, 0, 24)>; // LED 2
low-power-enable;
};
};
}; };
``` ```
This part may vary based on your MCU as different MCUs may have a different number of modules and channels. This part will vary based on your MCU as different MCUs have a different number of modules, channels and configuration options.
Then you can simply add each of your LED to the backlight node: Add each of your LEDs to the backlight node in the same manner as for one LED, using the channel number definitions in the pinctrl node:
```dts ```dts
backlight: pwmleds { backlight: pwmleds {
compatible = "pwm-leds"; compatible = "pwm-leds";
label = "Backlight LEDs"; label = "Backlight LEDs";
pwm_led_0 { pwm_led_0: pwm_led_0 {
pwms = <&pwm0 45>; /* LED 0 */ pwms = <&pwm0 0 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
}; };
pwm_led_1 { pwm_led_1: pwm_led_1 {
pwms = <&pwm0 46>; /* LED 1 */ pwms = <&pwm0 1 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
}; };
pwm_led_2 { pwm_led_2: pwm_led_2 {
pwms = <&pwm0 47>; /* LED 2 */ pwms = <&pwm0 2 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
}; };
...
}; };
``` ```