forked from kofal.net/zmk
docs: Move more sections under hardware integration (#2704)
docs: Move battery sensing hardware integration to new page docs: Refactor lighting hardware integrations to new category docs: Link to pin control page from lighting pages docs: Consolidate lighting feature pages docs: Remove incorrect redirect docs: Consolidate lighting config pages
This commit is contained in:
@@ -1,255 +0,0 @@
|
||||
---
|
||||
title: Backlight
|
||||
sidebar_label: Backlight
|
||||
---
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
|
||||
Backlight is a feature used to control an array of LEDs, usually placed through or under switches.
|
||||
|
||||
:::info
|
||||
Unlike [RGB Underglow](underglow.md), backlight can only control single color LEDs. Additionally, because backlight LEDs all receive the same power, it's not possible to dim 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:
|
||||
|
||||
```ini
|
||||
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="shieldpin"
|
||||
values={[
|
||||
{label: 'Adding to a board', value: 'boardpin'},{label: 'Adding to a shield', value: 'shieldpin'},
|
||||
]}>
|
||||
|
||||
<TabItem value="boardpin">
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
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 `<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
|
||||
&pinctrl {
|
||||
// Other pinctrl definitions for other hardware
|
||||
pwm0_default: pwm0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
|
||||
};
|
||||
};
|
||||
pwm0_sleep: pwm0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
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_).
|
||||
|
||||
For example, _P1.13_ would give you `(PWM_OUT0, 1, 13)` and _P0.15_ would give you `(PWM_OUT0, 0, 15)`.
|
||||
|
||||
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:
|
||||
|
||||
```dts
|
||||
/ {
|
||||
chosen {
|
||||
zmk,backlight = &backlight;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
</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.
|
||||
|
||||
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
|
||||
&pinctrl {
|
||||
// Other pinctrl definitions for other hardware
|
||||
pwm0_default: pwm0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
|
||||
};
|
||||
};
|
||||
pwm0_sleep: pwm0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(PWM_OUT0, 1, 13)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
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_).
|
||||
|
||||
For example, _P1.13_ would give you `(PWM_OUT0, 1, 13)` and _P0.15_ would give you `(PWM_OUT0, 0, 15)`.
|
||||
|
||||
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:
|
||||
|
||||
```dts
|
||||
/ {
|
||||
chosen {
|
||||
zmk,backlight = &backlight;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
</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 configure PWM for each pin in the pinctrl node:
|
||||
|
||||
```dts
|
||||
&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 will vary based on your MCU as different MCUs have a different number of modules, channels and configuration options.
|
||||
|
||||
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
|
||||
backlight: pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
pwm_led_0: pwm_led_0 {
|
||||
pwms = <&pwm0 0 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
pwm_led_1: pwm_led_1 {
|
||||
pwms = <&pwm0 1 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
pwm_led_2: pwm_led_2 {
|
||||
pwms = <&pwm0 2 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
};
|
||||
```
|
||||
@@ -15,25 +15,5 @@ Windows may not properly ask the keyboard to notify it of changes in battery lev
|
||||
|
||||
## Adding a Battery Sensor to a Board
|
||||
|
||||
To enable a battery sensor on a new board, add the driver for the sensor to your board's `.dts` file. ZMK provides two drivers for estimating the battery level using its voltage:
|
||||
|
||||
- `zmk,battery-voltage-divider`: Reads the voltage on an analog input pin.
|
||||
- `zmk,battery-nrf-vddh`: Reads the power supply voltage on a Nordic nRF52's VDDH pin.
|
||||
|
||||
See the [battery level configuration page](../config/battery.md) for the configuration supported by each driver provided by ZMK.
|
||||
|
||||
Zephyr also provides some drivers for fuel gauge ICs such as the TI bq274xx series and Maxim MAX17xxx series. If you use a battery sensor that does not have an existing driver, you will need to write a new driver that supports the `SENSOR_CHAN_GAUGE_STATE_OF_CHARGE` sensor channel and contribute it to Zephyr or ZMK.
|
||||
|
||||
Once you have the sensor driver defined, add a `zmk,battery` property to the `chosen` node and set it to reference the sensor node. For example:
|
||||
|
||||
```dts
|
||||
/ {
|
||||
chosen {
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
vbatt: vbatt {
|
||||
compatible = "zmk,battery-nrf-vddh";
|
||||
};
|
||||
}
|
||||
```
|
||||
If your keyboard is using one of the [boards supported in ZMK](../hardware.mdx) it will already be configured to sense and report battery levels.
|
||||
If you are using a custom board, see [battery sensing hardware integration page](../development/hardware-integration/battery.md) to add support.
|
||||
|
||||
105
docs/docs/features/lighting.md
Normal file
105
docs/docs/features/lighting.md
Normal file
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: Lighting
|
||||
sidebar_label: Lighting
|
||||
---
|
||||
|
||||
ZMK supports two distinct systems in order to control lighting hardware integrated into keyboards.
|
||||
Your keyboard likely uses only one type, depending on the type of LED hardware it supports:
|
||||
|
||||
- [RGB underglow](#rgb-underglow) system controls LED strips composed of addressable RGB LEDs.
|
||||
Most keyboards that have multi-color lighting utilizes these.
|
||||
- [Backlight](#backlight) system controls parallel-connected, non-addressable, single color LEDs.
|
||||
These are found on keyboards that have a single color backlight that only allows for brightness control.
|
||||
|
||||
:::warning
|
||||
|
||||
Although the naming of the systems might imply it, which system you use typically does _not_ depend on the physical location of the LEDs.
|
||||
Instead, you should use the one that supports the LED hardware type that your keyboard has, as described above.
|
||||
|
||||
:::
|
||||
|
||||
## RGB Underglow
|
||||
|
||||
RGB underglow is a feature used to control "strips" of RGB LEDs. Most of the time this is called underglow and creates a glow underneath the board using a ring of LEDs around the edge, hence the name. However, this can be extended to be used to control anything from a single LED to a long string of LEDs anywhere on the keyboard.
|
||||
|
||||
:::info
|
||||
RGB underglow can also be used for per-key lighting. If you have RGB LEDs on your keyboard, this is what you want. For PWM/single color LEDs, see [Backlight section below](#backlight).
|
||||
:::
|
||||
|
||||
ZMK relies on Zephyr's `led-strip` drivers for this feature. The following LEDs/LED families have been implemented:
|
||||
|
||||
- WS2812 (includes WS2812B, WS2813, SK6812, and others)
|
||||
- APA102
|
||||
- LPD880x (includes LPD8803, LPD8806, and others)
|
||||
|
||||
The WS2812 LED family is by far the most popular of these types, so this page will primarily focus on working with it.
|
||||
|
||||
Here you can see the RGB underglow feature in action using WS2812 LEDs.
|
||||
|
||||
<figure class="video-container">
|
||||
<iframe src="//www.youtube.com/embed/2KJkq8ssDU0" frameborder="0" allowfullscreen width="100%"></iframe>
|
||||
</figure>
|
||||
|
||||
### Enabling RGB Underglow
|
||||
|
||||
To enable RGB underglow on your board or shield, simply enable the `CONFIG_ZMK_RGB_UNDERGLOW` and `CONFIG_*_STRIP` configuration values in the `.conf` file for your board or shield.
|
||||
For example:
|
||||
|
||||
```ini
|
||||
CONFIG_ZMK_RGB_UNDERGLOW=y
|
||||
# Use the STRIP config specific to the LEDs you're using
|
||||
CONFIG_WS2812_STRIP=y
|
||||
```
|
||||
|
||||
See [Configuration Overview](../config/index.md) for more instructions on how to use Kconfig.
|
||||
|
||||
If your board or shield does not have RGB underglow configured, refer to the [Adding RGB Underglow Support to a Keyboard](#adding-rgb-underglow-support-to-a-keyboard) section.
|
||||
|
||||
#### Modifying the Number of LEDs
|
||||
|
||||
The number of LEDs specified in the default configuration for your board or shield may not match the number you have installed. For example, the `corne` shield specifies only 10 LEDs per side while supporting up to 27. On a split keyboard, a good sign of this mismatch is if the lit LEDs on each half are symmetrical.
|
||||
|
||||
The `chain-length` property of the `led_strip` node controls the number of underglow LEDs. If it is incorrect for your build, [you can change this property](../config/index.md#changing-devicetree-properties) in your `<keyboard>.keymap` file by adding a stanza like this one outside of any other node (i.e. above or below the `/` node):
|
||||
|
||||
```dts
|
||||
&led_strip {
|
||||
chain-length = <21>;
|
||||
};
|
||||
```
|
||||
|
||||
For split keyboards, set `chain-length` to the number of LEDs installed on each half.
|
||||
|
||||
### Configuring RGB Underglow
|
||||
|
||||
See [RGB underglow configuration](../config/lighting.md#rgb-underglow).
|
||||
|
||||
### Adding RGB Underglow Support to a Keyboard
|
||||
|
||||
See [RGB underglow hardware integration page](../development/hardware-integration/lighting/underglow.md) on adding underglow support to a ZMK keyboard.
|
||||
|
||||
## Backlight
|
||||
|
||||
Backlight is a feature used to control an array of LEDs, usually placed through or under switches.
|
||||
|
||||
:::info
|
||||
Unlike [RGB underglow](#rgb-underglow), backlight can only control single color LEDs. Additionally, because backlight LEDs all receive the same power, it's not possible to dim 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:
|
||||
|
||||
```ini
|
||||
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.
|
||||
See [backlight configuration](../config/lighting.md#backlight) for details.
|
||||
|
||||
### Adding Backlight to a Board or a Shield
|
||||
|
||||
See [backlight hardware integration page](../development/hardware-integration/lighting/backlight.mdx) for information on adding backlight support to a ZMK keyboard.
|
||||
@@ -1,193 +0,0 @@
|
||||
---
|
||||
title: RGB Underglow
|
||||
sidebar_label: RGB Underglow
|
||||
---
|
||||
|
||||
RGB underglow is a feature used to control "strips" of RGB LEDs. Most of the time this is called underglow and creates a glow underneath the board using a ring of LEDs around the edge, hence the name. However, this can be extended to be used to control anything from a single LED to a long string of LEDs anywhere on the keyboard.
|
||||
|
||||
:::info
|
||||
RGB underglow can also be used for per-key lighting. If you have RGB LEDs on your keyboard, this is what you want. For PWM/single color LEDs, see [Backlight](backlight.mdx).
|
||||
:::
|
||||
|
||||
ZMK relies on Zephyr's `led-strip` drivers for this feature. The following LEDs/LED families have been implemented:
|
||||
|
||||
- WS2812 (includes WS2812B, WS2813, SK6812, and others)
|
||||
- APA102
|
||||
- LPD880x (includes LPD8803, LPD8806, and others)
|
||||
|
||||
The WS2812 LED family is by far the most popular of these types, so this page will primarily focus on working with it.
|
||||
|
||||
Here you can see the RGB underglow feature in action using WS2812 LEDs.
|
||||
|
||||
<figure class="video-container">
|
||||
<iframe src="//www.youtube.com/embed/2KJkq8ssDU0" frameborder="0" allowfullscreen width="100%"></iframe>
|
||||
</figure>
|
||||
|
||||
## Enabling RGB Underglow
|
||||
|
||||
To enable RGB underglow on your board or shield, simply enable the `CONFIG_ZMK_RGB_UNDERGLOW` and `CONFIG_*_STRIP` configuration values in the `.conf` file for your board or shield.
|
||||
For example:
|
||||
|
||||
```ini
|
||||
CONFIG_ZMK_RGB_UNDERGLOW=y
|
||||
# Use the STRIP config specific to the LEDs you're using
|
||||
CONFIG_WS2812_STRIP=y
|
||||
```
|
||||
|
||||
See [Configuration Overview](/docs/config) for more instructions on how to use Kconfig.
|
||||
|
||||
If your board or shield does not have RGB underglow configured, refer to [Adding RGB Underglow to a Board](#adding-rgb-underglow-to-a-board).
|
||||
|
||||
### Modifying the Number of LEDs
|
||||
|
||||
The number of LEDs specified in the default configuration for your board or shield may not match the number you have installed. For example, the `corne` shield specifies only 10 LEDs per side while supporting up to 27. On a split keyboard, a good sign of this mismatch is if the lit LEDs on each half are symmetrical.
|
||||
|
||||
The `chain-length` property of the `led_strip` node controls the number of underglow LEDs. If it is incorrect for your build, [you can change this property](../config/index.md#changing-devicetree-properties) in your `<keyboard>.keymap` file by adding a stanza like this one outside of any other node (i.e. above or below the `/` node):
|
||||
|
||||
```dts
|
||||
&led_strip {
|
||||
chain-length = <21>;
|
||||
};
|
||||
```
|
||||
|
||||
For split keyboards, set `chain-length` to the number of LEDs installed on each half.
|
||||
|
||||
## Configuring RGB Underglow
|
||||
|
||||
See [RGB underglow configuration](/docs/config/underglow).
|
||||
|
||||
## Adding RGB Underglow to a Board
|
||||
|
||||
Support for RGB underglow is always added to a board, not a shield. This is because the LED strip drivers rely on hardware-specific interfaces (e.g. SPI, I2S) and configurations, which shields do not control.
|
||||
|
||||
Shields written for boards which support RGB underglow should add a `boards/` folder underneath the shield folder. Inside this `boards/` folder, create a `<board>.overlay` for any of the boards the shield can be used with. Place all hardware-specific configurations in these `.overlay` files.
|
||||
|
||||
For example: the `kyria` shield has a [`boards/nice_nano_v2.overlay`](https://github.com/zmkfirmware/zmk/blob/main/app/boards/shields/kyria/boards/nice_nano_v2.overlay) and a [`boards/nrfmicro_13.overlay`](https://github.com/zmkfirmware/zmk/blob/main/app/boards/shields/kyria/boards/nrfmicro_13.overlay), which configure a WS2812 LED strip for the `nice_nano_v2` and `nrfmicro_13` boards respectively.
|
||||
|
||||
### nRF52-Based Boards
|
||||
|
||||
Using an SPI-based LED strip driver on the `&spi3` interface is the simplest option for nRF52-based boards. If possible, avoid using pins which are limited to low-frequency I/O for this purpose. The resulting interference may result in poor wireless performance.
|
||||
|
||||
:::info
|
||||
|
||||
The list of low frequency I/O pins for the nRF52840 can be found [here](https://docs.nordicsemi.com/bundle/ps_nrf52840/page/pin.html).
|
||||
|
||||
:::
|
||||
|
||||
The following example uses `P0.06` as the "Data In" pin of a WS2812-compatible LED strip:
|
||||
|
||||
```dts
|
||||
#include <dt-bindings/led/led.h>
|
||||
|
||||
&pinctrl {
|
||||
spi3_default: spi3_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_MOSI, 0, 6)>;
|
||||
};
|
||||
};
|
||||
|
||||
spi3_sleep: spi3_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_MOSI, 0, 6)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi3 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&spi3_default>;
|
||||
pinctrl-1 = <&spi3_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
led_strip: ws2812@0 {
|
||||
compatible = "worldsemi,ws2812-spi";
|
||||
|
||||
/* SPI */
|
||||
reg = <0>; /* ignored, but necessary for SPI bindings */
|
||||
spi-max-frequency = <4000000>;
|
||||
|
||||
/* WS2812 */
|
||||
chain-length = <10>; /* number of LEDs */
|
||||
spi-one-frame = <0x70>;
|
||||
spi-zero-frame = <0x40>;
|
||||
color-mapping = <LED_COLOR_ID_GREEN
|
||||
LED_COLOR_ID_RED
|
||||
LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
Standard WS2812 LEDs use a wire protocol where the bits for the colors green, red, and blue values are sent in that order.
|
||||
If your board/shield uses LEDs that require the data sent in a different order, the `color-mapping` property ordering should be changed to match.
|
||||
|
||||
:::
|
||||
|
||||
### Other Boards
|
||||
|
||||
Be sure to check the Zephyr documentation for the LED strip and necessary hardware bindings. Not every board has an `spi3` node, or configures `pinctrl` the same way. Reconcile this with any hardware restrictions found in the manufacturer's datasheet. Additional hardware interfaces may need to be enabled via Kconfig.
|
||||
|
||||
For example: the `sparkfun_pro_micro_rp2040` board can utilize SPI via PIO to run a WS2812 strip on `GP0`:
|
||||
|
||||
```dts
|
||||
#include <dt-bindings/led/led.h>
|
||||
|
||||
&pinctrl {
|
||||
pio0_spi0_default: pio0_spi0_default {
|
||||
group1 {
|
||||
pinmux = <PIO0_P0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pio0 {
|
||||
status = "okay";
|
||||
|
||||
pio0_spi0: pio0_spi0 {
|
||||
pinctrl-0 = <&pio0_spi0_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
compatible = "raspberrypi,pico-spi-pio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
clocks = <&system_clk>;
|
||||
clock-frequency = <4000000>;
|
||||
|
||||
clk-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; /* Must be defined. Select a pin that is not used elsewhere. */
|
||||
mosi-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>; /* Data In pin. */
|
||||
miso-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>; /* Must be defined. Re-using the DI pin is OK for WS2812. */
|
||||
|
||||
led_strip: ws2812@0 {
|
||||
compatible = "worldsemi,ws2812-spi";
|
||||
|
||||
/* SPI */
|
||||
reg = <0>; /* ignored, but necessary for SPI bindings */
|
||||
spi-max-frequency = <4000000>;
|
||||
|
||||
/* WS2812 */
|
||||
chain-length = <10>; /* number of LEDs */
|
||||
spi-one-frame = <0x70>;
|
||||
spi-zero-frame = <0x40>;
|
||||
color-mapping = <LED_COLOR_ID_GREEN
|
||||
LED_COLOR_ID_RED
|
||||
LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### Final Steps
|
||||
|
||||
Once the `led_strip` is properly defined, add it to the `chosen` node under the root devicetree node:
|
||||
|
||||
```dts
|
||||
/ {
|
||||
chosen {
|
||||
zmk,underglow = &led_strip;
|
||||
};
|
||||
};
|
||||
```
|
||||
Reference in New Issue
Block a user