Skip to content

Commit

Permalink
docs: Refactor lighting hardware integrations to new section
Browse files Browse the repository at this point in the history
  • Loading branch information
caksoylar committed Dec 11, 2024
1 parent 0f9abbc commit cfe0536
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 176 deletions.
2 changes: 1 addition & 1 deletion docs/blog/2022-04-02-zephyr-3-0.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The following changes have [already been completed](https://github.com/zmkfirmwa

### RGB Underglow

Zephyr's WS2812 `led_strip` driver added a new required property. When adding [underglow](/docs/features/underglow#adding-rgb-underglow-to-a-board) to a board, you now must also add the additional include `#include <dt-bindings/led/led.h>` at the top of your devicetree file, and add a `color-mapping` property like:
Zephyr's WS2812 `led_strip` driver added a new required property. When adding [underglow](/docs/features/underglow#adding-rgb-underglow-support-to-a-keyboard) to a board, you now must also add the additional include `#include <dt-bindings/led/led.h>` at the top of your devicetree file, and add a `color-mapping` property like:

```dts
led_strip: ws2812@0 {
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/config/backlight.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Backlight Configuration
sidebar_label: Backlight
---

See the [backlight feature page](../features/backlight.mdx) for more details, including instructions for adding backlight support to a board.
See the [backlight feature page](../features/backlight.md) for more details, and [hardware integration page](../development/hardware-integration/lighting/backlight.mdx) for adding backlight support to a board.

See [Configuration Overview](index.md) for instructions on how to change these settings.

Expand Down Expand Up @@ -37,4 +37,4 @@ See the Zephyr devicetree bindings for LED drivers:
- [gpio-leds](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/led/gpio-leds.html)
- [pwm-leds](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/led/pwm-leds.html)

See the [backlight feature page](../features/backlight.mdx) for examples of the properties that must be set to enable backlighting.
See the [backlight hardware integration page](../development/hardware-integration/lighting/backlight.mdx) for examples of the properties that must be set to enable backlighting.
4 changes: 2 additions & 2 deletions docs/docs/config/underglow.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: RGB Underglow Configuration
sidebar_label: RGB Underglow
---

See the [RGB Underglow feature page](../features/underglow.md) for more details, including instructions for adding underglow support to a board.
See the [RGB Underglow feature page](../features/underglow.md) for more details, and [hardware integration page](../development/hardware-integration/lighting/underglow.md) for adding underglow support to a board.

See [Configuration Overview](index.md) for instructions on how to change these settings.

Expand Down Expand Up @@ -48,4 +48,4 @@ The `*_START` settings only determine the initial underglow state. Any changes y

ZMK does not have any Devicetree properties of its own. See the Devicetree bindings for [Zephyr's LED strip drivers](https://github.com/zephyrproject-rtos/zephyr/tree/main/dts/bindings/led_strip).

See the [RGB underglow feature page](../features/underglow.md) for examples of the properties that must be set to enable underglow.
See the [RGB underglow hardware integration page](../development/hardware-integration/lighting/underglow.md) for examples of the properties that must be set to enable underglow.
Original file line number Diff line number Diff line change
@@ -1,45 +1,18 @@
---
title: Backlight
sidebar_label: Backlight
description: Lighting system that controls an array of single-color LEDs.
---

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
Please see [backlight feature page](../../../features/backlight.md) for an introduction on the feature.

<Tabs
defaultValue="shieldpin"
values={[
{label: 'Adding to a board', value: 'boardpin'},{label: 'Adding to a shield', value: 'shieldpin'},
defaultValue="shieldpin"
values={[
{label: 'Adding to a board', value: 'boardpin'},{label: 'Adding to a shield', value: 'shieldpin'},
]}>

<TabItem value="boardpin">
Expand All @@ -60,7 +33,7 @@ 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):
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 {
Expand Down Expand Up @@ -161,6 +134,8 @@ Then add the following lines to your `.overlay` file:
};
```

See the documentation page on [pin control](../pinctrl.mdx) for detailed information on setting up pins for hardware protocols such as PWM that is used for controlling backlight LEDs.

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)`.
Expand Down
17 changes: 17 additions & 0 deletions docs/docs/development/hardware-integration/lighting/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Lighting
sidebar_label: Lighting
---

import DocCardList from "@theme/DocCardList";

The following pages detail adding lighting support to ZMK keyboards, which currently supports two lighting systems: underglow and backlight.

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

:::

<DocCardList />
141 changes: 141 additions & 0 deletions docs/docs/development/hardware-integration/lighting/underglow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
title: RGB Underglow
sidebar_label: RGB Underglow
description: Lighting system that controls strips of RGB LEDs.
---

Please see [RGB underglow feature page](../../../features/underglow.md) for an introduction on the feature.

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;
};
};
```
29 changes: 29 additions & 0 deletions docs/docs/features/backlight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Backlight
sidebar_label: Backlight
---

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.
See [backlight configuration](../config/backlight.md) 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.
Loading

0 comments on commit cfe0536

Please sign in to comment.