Skip to content

Commit

Permalink
Remove non-pinctrl configuration options
Browse files Browse the repository at this point in the history
  • Loading branch information
ReFil committed Nov 20, 2023
1 parent b89bf69 commit 0f565ac
Showing 1 changed file with 37 additions and 180 deletions.
217 changes: 37 additions & 180 deletions docs/docs/features/backlight.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,79 +37,11 @@ There are various Kconfig options used to configure the backlight feature. These
## Adding Backlight to a board or a shield

<Tabs
defaultValue="shieldnopin"
defaultValue="boardpin"
values={[
{label: 'Adding to a board without using Pinctrl', value: 'boardnopin'},{label: 'Adding to a board using Pinctrl', value: 'boardpin'},
{label: 'Adding to a shield without using Pinctrl', value: 'shieldnopin'},{label: 'Adding to a shield using Pinctrl', value: 'shieldpin'},
{label: 'Adding to a board', value: 'boardpin'},{label: 'Adding to a shield', value: 'shieldpin'},
]}>
<TabItem value="boardnopin">

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

```kconfig
if ZMK_BACKLIGHT
config PWM
default y
config LED_PWM
default y
endif # ZMK_BACKLIGHT
```

Since the Zephyr 3.2 update the PWM driver has been revised, permitting the use of the pinctrl API to select the pins. For now the old method of pin select is also functional, as long as you don't enable pinctrl for the board at all.

If you do not want to use pinctrl add the following lines to your `.dts` file:

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

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>`.

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 0 10000 PWM_POLARITY_NORMAL>;
label = "Backlight LED 0";
};
};
};
```

The value inside `pwm_led_0` after `&pwm0` must be the channel number. Since (`<ch0-pin>`) is used in the `&pwm0` node the channel in this example is 0.

In this example `10000` is the period of the PWM waveform, some drive circuitry might require different values, it could also be altered in the event the drive 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`.

:::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:

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

</TabItem>
<TabItem value="boardpin">

First, you must enable PWM by adding the following lines to your `Kconfig.defconfig` file:
Expand All @@ -126,7 +58,7 @@ config LED_PWM
endif # ZMK_BACKLIGHT
```

When using the pinctrl API you should create a pinctrl.dtsi file if it's not created already, and include it at the beginning of the `board.dts` file. You also need to add `CONFIG_PINCTRL=y` to board_defconfig if it's not already enabled.
When using the pinctrl API you should create a pinctrl.dtsi file if it's not created already, and include it at the beginning of the `board.dts` file. You also need to add `CONFIG_PINCTRL=y` to board_defconfig if it's not already enabled. To use some of the definitions for the PWM node you need to include `#include <dt-bindings/led/led.h>` at the beginning of the `board.dts` file.

A pinctrl file has an `&pinctrl` node that encompasses all pinctrl settings including for I2C or SPI peripherals (e.g. WS2812 LEDs, Battery fuel gauges):

Expand Down Expand Up @@ -169,15 +101,15 @@ Then you have to add the following lines inside the root devicetree node on the
backlight: pwmleds {
compatible = "pwm-leds";
pwm_led_0 {
pwms = <&pwm0 0 10000 PWM_POLARITY_NORMAL>;
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 `10000` is the period of the PWM waveform, some drive circuitry might require different values, it could also be altered in the event the drive frequency is audible.
In this example `PWM_MSEC(10)` is the period of the PWM waveform, some drive circuitry might require different values, it could also be altered in the event the drive 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`.

Expand All @@ -191,97 +123,10 @@ Finally you need to add backlight to the `chosen` element of the root devicetree
};
```

</TabItem>
<TabItem value="shieldnopin">

Since the Zephyr 3.2 update the PWM driver has been revised, permitting the use of the pinctrl API to select the pins. For now the old method of pin select is also functional, but note that if you are modifying a shield and the board already has pinctrl enabled then you have to use the pinctrl API as well.

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:

```kconfig
if ZMK_BACKLIGHT
config PWM
default y
config LED_PWM
default y
endif # ZMK_BACKLIGHT
```

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

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

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>`.

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 10000 PWM_POLARITY_NORMAL>;
label = "Backlight LED 0";
};
};
};
```

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

In this example `10000` is the period of the PWM waveform, some drive circuitry might require different values, it could also be altered in the event the drive 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`.

:::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:

```dts
/ {
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:

```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 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. To use some of the definitions for the PWM node you need to include `#include <dt-bindings/led/led.h>` at the beginning of the `<board>.overlay` file.

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

Expand Down Expand Up @@ -338,16 +183,18 @@ Then you have to add the following lines inside the root devicetree node on the
backlight: pwmleds {
compatible = "pwm-leds";
pwm_led_0 {
pwms = <&pwm0 0 10000 PWM_POLARITY_NORMAL>;
pwms = <&pwm0 0 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
};
};
};
```

In this example `10000` is the period of the PWM waveform, some drive circuitry might require different values, it could also be altered in the event the drive frequency is audible.
In this example `PWM_MSEC(10)` is the period of the PWM waveform, some drive circuitry might require different values, it could also be altered in the event the drive 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:

```
Expand All @@ -365,35 +212,45 @@ Finally you need to add backlight to the `chosen` element of the root devicetree

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 you need to enable a PWM for each pin in the pinctrl node:

```dts
&pwm0 {
status = "okay";
ch0-pin = <45>; /* LED 0 */
ch1-pin = <46>; /* LED 1 */
ch2-pin = <47>; /* LED 2 */
...
```
&pinctrl {
// Other Pinctrl definitions go here
pwm0_default: pwm0_default {
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
};
};
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:
Then you can simply add each of your LED to the backlight node in the same manner as for one LED, using the channel number definitions in the pinctrl node:

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

0 comments on commit 0f565ac

Please sign in to comment.