Kellen Carey
4 years ago
committed by
GitHub
51 changed files with 911 additions and 282 deletions
@ -0,0 +1,6 @@ |
|||||||
|
|
||||||
|
config BOARD_ENABLE_DCDC |
||||||
|
bool "Enable DCDC mode" |
||||||
|
select SOC_DCDC_NRF52X |
||||||
|
default y |
||||||
|
depends on BOARD_NICE_NANO |
@ -0,0 +1,58 @@ |
|||||||
|
|
||||||
|
if SHIELD_CORNE_LEFT |
||||||
|
|
||||||
|
config ZMK_KEYBOARD_NAME |
||||||
|
default "Corne Left" |
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
|
||||||
|
if SHIELD_CORNE_RIGHT |
||||||
|
|
||||||
|
config ZMK_KEYBOARD_NAME |
||||||
|
default "Corne Right" |
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
if SHIELD_CORNE_LEFT || SHIELD_CORNE_RIGHT |
||||||
|
|
||||||
|
config ZMK_SPLIT |
||||||
|
default y |
||||||
|
|
||||||
|
if ZMK_DISPLAY |
||||||
|
|
||||||
|
config I2C |
||||||
|
default y |
||||||
|
|
||||||
|
config SSD1306 |
||||||
|
default y |
||||||
|
|
||||||
|
config SSD1306_REVERSE_MODE |
||||||
|
default y |
||||||
|
|
||||||
|
endif # ZMK_DISPLAY |
||||||
|
|
||||||
|
if LVGL |
||||||
|
|
||||||
|
config LVGL_HOR_RES |
||||||
|
default 128 |
||||||
|
|
||||||
|
config LVGL_VER_RES |
||||||
|
default 32 |
||||||
|
|
||||||
|
config LVGL_VDB_SIZE |
||||||
|
default 64 |
||||||
|
|
||||||
|
config LVGL_DPI |
||||||
|
default 148 |
||||||
|
|
||||||
|
config LVGL_BITS_PER_PIXEL |
||||||
|
default 1 |
||||||
|
|
||||||
|
choice LVGL_COLOR_DEPTH |
||||||
|
default LVGL_COLOR_DEPTH_1 |
||||||
|
endchoice |
||||||
|
|
||||||
|
endif # LVGL |
||||||
|
|
||||||
|
endif |
@ -0,0 +1,8 @@ |
|||||||
|
# Copyright (c) 2020 Pete Johanson |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
config SHIELD_CORNE_LEFT |
||||||
|
def_bool $(shields_list_contains,corne_left) |
||||||
|
|
||||||
|
config SHIELD_CORNE_RIGHT |
||||||
|
def_bool $(shields_list_contains,corne_right) |
@ -0,0 +1,29 @@ |
|||||||
|
&spi1 { |
||||||
|
compatible = "nordic,nrf-spi"; |
||||||
|
/* Cannot be used together with i2c0. */ |
||||||
|
status = "okay"; |
||||||
|
mosi-pin = <6>; |
||||||
|
// Unused pins, needed for SPI definition, but not used by the ws2812 driver itself. |
||||||
|
sck-pin = <5>; |
||||||
|
miso-pin = <7>; |
||||||
|
|
||||||
|
led_strip: ws2812@0 { |
||||||
|
compatible = "worldsemi,ws2812-spi"; |
||||||
|
label = "SK6812mini"; |
||||||
|
|
||||||
|
/* SPI */ |
||||||
|
reg = <0>; /* ignored, but necessary for SPI bindings */ |
||||||
|
spi-max-frequency = <4000000>; |
||||||
|
|
||||||
|
/* WS2812 */ |
||||||
|
chain-length = <6>; /* There are per-key RGB, but the first 6 are underglow */ |
||||||
|
spi-one-frame = <0x70>; |
||||||
|
spi-zero-frame = <0x40>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
/ { |
||||||
|
chosen { |
||||||
|
zmk,underglow = &led_strip; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,6 @@ |
|||||||
|
# Uncomment the following lines to enable the Corne RGB Underglow |
||||||
|
# ZMK_RGB_UNDERGLOW=y |
||||||
|
# CONFIG_WS2812_STRIP=y |
||||||
|
|
||||||
|
# Uncomment the following line to enable the Corne OLED Display |
||||||
|
# CONFIG_ZMK_DISPLAY=y |
@ -0,0 +1,79 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Pete Johanson |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <dt-bindings/zmk/matrix-transform.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
chosen { |
||||||
|
zmk,kscan = &kscan0; |
||||||
|
zmk,matrix_transform = &default_transform; |
||||||
|
}; |
||||||
|
|
||||||
|
default_transform: keymap_transform_0 { |
||||||
|
compatible = "zmk,matrix-transform"; |
||||||
|
columns = <12>; |
||||||
|
rows = <4>; |
||||||
|
// | SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | | SW6 | SW5 | SW4 | SW3 | SW2 | SW1 | |
||||||
|
// | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | |
||||||
|
// | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | |
||||||
|
// | SW19 | SW20 | SW21 | | SW21 | SW20 | SW19 | |
||||||
|
map = < |
||||||
|
RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,12) |
||||||
|
RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,12) |
||||||
|
RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) RC(2,12) |
||||||
|
RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) |
||||||
|
>; |
||||||
|
}; |
||||||
|
|
||||||
|
five_column_transform: keymap_transform_1 { |
||||||
|
compatible = "zmk,matrix-transform"; |
||||||
|
columns = <10>; |
||||||
|
rows = <4>; |
||||||
|
// | SW2 | SW3 | SW4 | SW5 | SW6 | | SW6 | SW5 | SW4 | SW3 | SW2 | |
||||||
|
// | SW8 | SW9 | SW10 | SW11 | SW12 | | SW12 | SW11 | SW10 | SW9 | SW8 | |
||||||
|
// | SW14 | SW15 | SW16 | SW17 | SW18 | | SW18 | SW17 | SW16 | SW15 | SW14 | |
||||||
|
// | SW19 | SW20 | SW21 | | SW21 | SW20 | SW19 | |
||||||
|
map = < |
||||||
|
RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) |
||||||
|
RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) |
||||||
|
RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) |
||||||
|
RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) |
||||||
|
>; |
||||||
|
}; |
||||||
|
|
||||||
|
kscan0: kscan { |
||||||
|
compatible = "zmk,kscan-gpio-matrix"; |
||||||
|
label = "KSCAN"; |
||||||
|
|
||||||
|
diode-direction = "col2row"; |
||||||
|
row-gpios |
||||||
|
= <&pro_micro_d 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
// TODO: per-key RGB node(s)? |
||||||
|
}; |
||||||
|
|
||||||
|
&pro_micro_i2c { |
||||||
|
status = "okay"; |
||||||
|
|
||||||
|
ssd1306@3c { |
||||||
|
compatible = "solomon,ssd1306fb"; |
||||||
|
reg = <0x3c>; |
||||||
|
label = "DISPLAY"; |
||||||
|
width = <128>; |
||||||
|
height = <32>; |
||||||
|
segment-offset = <0>; |
||||||
|
page-offset = <0>; |
||||||
|
display-offset = <0>; |
||||||
|
multiplex-ratio = <63>; |
||||||
|
prechargep = <0x22>; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,22 @@ |
|||||||
|
#include <behaviors.dtsi> |
||||||
|
#include <dt-bindings/zmk/keys.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
keymap { |
||||||
|
compatible = "zmk,keymap"; |
||||||
|
|
||||||
|
default_layer { |
||||||
|
// --------------------------------------------------------------------------------------------------------------------------------- |
||||||
|
// | ESC | Q | W | E | R | T | | Y | U | I | O | P | \ | |
||||||
|
// | TAB | A | S | D | F | G | | H | J | K | L | ; | ' | |
||||||
|
// | SHIFT | Z | X | C | V | B | | N | M | , | . | / | CTRL | |
||||||
|
// | GUI | DEL | RET | | TAB | BSPC | R-ALT | |
||||||
|
bindings = < |
||||||
|
&kp ESC &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSLH |
||||||
|
&kp TAB &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SCLN &kp QUOT |
||||||
|
&kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RCTL |
||||||
|
&kp LGUI &kp DEL &kp RET &kp TAB &kp BKSP &kp RALT |
||||||
|
>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,2 @@ |
|||||||
|
CONFIG_ZMK_SPLIT=y |
||||||
|
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y |
@ -0,0 +1,18 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Pete Johanson |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "corne.dtsi" |
||||||
|
|
||||||
|
&kscan0 { |
||||||
|
col-gpios |
||||||
|
= <&pro_micro_a 3 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 2 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 1 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 0 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 15 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 14 GPIO_ACTIVE_HIGH> |
||||||
|
; |
||||||
|
}; |
@ -0,0 +1,2 @@ |
|||||||
|
CONFIG_ZMK_SPLIT=y |
||||||
|
CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y |
@ -0,0 +1,23 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Pete Johanson |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "corne.dtsi" |
||||||
|
|
||||||
|
&default_transform { |
||||||
|
col-offset = <6>; |
||||||
|
}; |
||||||
|
|
||||||
|
&kscan0 { |
||||||
|
col-gpios |
||||||
|
= <&pro_micro_d 14 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 15 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 0 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 1 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 2 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 3 GPIO_ACTIVE_HIGH> |
||||||
|
; |
||||||
|
}; |
||||||
|
|
@ -0,0 +1,10 @@ |
|||||||
|
# Uncomment these two line to add support for encoders to your firmware |
||||||
|
# CONFIG_EC11=y |
||||||
|
# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y |
||||||
|
|
||||||
|
# Uncomment the following line to enable the Kyria OLED Display |
||||||
|
# CONFIG_ZMK_DISPLAY=y |
||||||
|
|
||||||
|
# Uncomment the following lines to enable RGB underglow |
||||||
|
# CONFIG_ZMK_RGB_UNDERGLOW=y |
||||||
|
# CONFIG_WS2812_STRIP=y |
@ -0,0 +1,2 @@ |
|||||||
|
# Uncomment the following line to enable the Lily58 OLED Display |
||||||
|
# CONFIG_ZMK_DISPLAY=y |
@ -1,18 +0,0 @@ |
|||||||
description: | |
|
||||||
Allows defining the various keymap layers for use. |
|
||||||
|
|
||||||
compatible: "zmk,layers" |
|
||||||
|
|
||||||
child-binding: |
|
||||||
description: "A layer to be used in a keymap" |
|
||||||
|
|
||||||
properties: |
|
||||||
label: |
|
||||||
type: string |
|
||||||
required: true |
|
||||||
bindings: |
|
||||||
type: phandle-array |
|
||||||
required: true |
|
||||||
sensor-bindings: |
|
||||||
type: phandle-array |
|
||||||
required: false |
|
@ -0,0 +1,52 @@ |
|||||||
|
--- |
||||||
|
title: ZMK State Of The Firmware \#1 |
||||||
|
author: Pete Johanson |
||||||
|
author_title: Project Creator |
||||||
|
author_url: https://gitlab.com/petejohanson |
||||||
|
author_image_url: https://www.gravatar.com/avatar/2001ceff7e9dc753cf96fcb2e6f41110 |
||||||
|
tags: [SOTF, keyboards, firmware, oss, ble] |
||||||
|
--- |
||||||
|
|
||||||
|
Welcome to the first ZMK "State Of The Firmware"! |
||||||
|
|
||||||
|
With interest and Discord activity growing, it seemed important to lay out the progress made recently, current major bugs/showstoppers, and planned next steps. |
||||||
|
|
||||||
|
## Recent Activity |
||||||
|
|
||||||
|
There's been lots of various activity in ZMK land! |
||||||
|
|
||||||
|
- [Nicell](https://github.com/Nicell) (nice!nano creator) contributed initial [RGB Underglow](/docs/feature/underglow) ([#64](https://github.com/zmkfirmware/zmk/pull/64)) support to ZMK. |
||||||
|
- Tons of [documentation](/docs) work. |
||||||
|
- Refactoring ([#73](https://github.com/zmkfirmware/zmk/pull/73), [#74](https://github.com/zmkfirmware/zmk/pull/74)) of [keymaps](/docs/feature/keymaps) to make them simpler for users. |
||||||
|
- Mod-Tap Behavior (docs coming!) is much improved ([#69](https://github.com/zmkfirmware/zmk/pull/69)) and usable now. |
||||||
|
- An initial [`setup.sh`](http://localhost:3000/docs/user-setup#user-config-setup-script) script was created, allowing users to quickly bootstrap a "user config" setup and push it to GitHub, where GitHub Actions will build the firmware for you. |
||||||
|
- Corne shield ([#80](https://github.com/zmkfirmware/zmk/pull/80)) shield definition was added. |
||||||
|
- Initial [encoder](/docs/feature/encoders) support ([#61](https://github.com/zmkfirmware/zmk/pull/61)) was added. |
||||||
|
|
||||||
|
## Bugs and Showstoppers |
||||||
|
|
||||||
|
Despite the flurry of activity, there are still some serious bugs and show stoppers that potential ZMK users should be aware of: |
||||||
|
|
||||||
|
- [Bluetooth Related](https://github.com/zmkfirmware/zmk/issues/58) - There are several key bugs and fixes needed, including one complete show stopper: |
||||||
|
- Fully working split wireless is not working. In particular, both split halves can properly pair, but once they do so, pairing with the _central_ host will not work. Workaround: You can currently have both halves pair, and use USB on the central side (Left side right now for Kyria, Corne, Lily58) and receive HID events over USB. |
||||||
|
- BT bond information is not currently stored to the devices, so after powering off or restarting your device, users need to re-pair |
||||||
|
- USB - There is one important USB related bug which is a showstopper: |
||||||
|
- The Zephyr USB stack does not have a built in queue for endpoint data being written. As a result, HID events sent by ZMK are sometimes [dropped, or lost](https://github.com/zmkfirmware/zmk/issues/84). |
||||||
|
|
||||||
|
## Next Steps |
||||||
|
|
||||||
|
There's plenty of places to go next! To help keep folks in the loop for what's next, I've created a [Core Functionality](https://github.com/zmkfirmware/zmk/projects/1) project/kanban board in GitHub, where users should be able to get some visibility into items being focused on. |
||||||
|
|
||||||
|
Of course, at the top of that list currently is the above bugs/showstoppers, and then from there, I hope to: |
||||||
|
|
||||||
|
- Work on power management. |
||||||
|
- Improve our documentation on various aspects of the system, mostly around: |
||||||
|
- End user documentation for understanding how to use ZMK, better installation docs, etc. |
||||||
|
- Developer focused documentation, so interested contributors can start building out more behaviors and ZMK functionality. |
||||||
|
- Implement true "hold" detection, useful for several behaviors such as Mod-Tap and Layer-Tap. |
||||||
|
- Hopefully acquire a proper and official USB Product ID for use for the project. |
||||||
|
- Fun things that come up along the way! |
||||||
|
|
||||||
|
## Thanks! |
||||||
|
|
||||||
|
A big thanks for everyone who has shown interest in the project, tested things, asked questions, and contributed PRs ([Nicell](https://github.com/Nicell), [CrossR](https://github.com/CrossR), [careyk007](https://github.com/careyk007)). |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,41 @@ |
|||||||
|
--- |
||||||
|
title: Layers |
||||||
|
--- |
||||||
|
|
||||||
|
## Summary |
||||||
|
|
||||||
|
Often, you may want a certain key position to alter which layers are enabled, change the default layer, etc. |
||||||
|
Some of those behaviors are still in the works; the ones that are working now are documented here. |
||||||
|
|
||||||
|
## Defines To Refer To Layers |
||||||
|
|
||||||
|
When working with layers, you may have several different key positions with bindings that enable/disable those layers. |
||||||
|
To make it easier to refer to those layers in your key bindings, and to change which layers are where later, you can |
||||||
|
add a set of `#define`s at the top of your keymap file, and use those layer in your keymap. |
||||||
|
|
||||||
|
For example, if you have three layers, you can add the following to the top of your keymap: |
||||||
|
|
||||||
|
``` |
||||||
|
#define DEFAULT 0 |
||||||
|
#define LOWER 1 |
||||||
|
#define RAISE 2 |
||||||
|
``` |
||||||
|
|
||||||
|
This allows you to use those defines, e.g. `LOWER` later in your keymap. |
||||||
|
|
||||||
|
## Momentary Layer |
||||||
|
|
||||||
|
The "momentary layer" behavior allows you to enable a layer while a certain key is pressed. Immediately upon |
||||||
|
activation of the key, the layer is enabled, and immediately open release of the key, the layer is disabled |
||||||
|
again. |
||||||
|
|
||||||
|
### Behavior Binding |
||||||
|
|
||||||
|
- Reference: `&mo` |
||||||
|
- Parameter: The layer number to enable/disable, e.g. `1` |
||||||
|
|
||||||
|
Example: |
||||||
|
|
||||||
|
``` |
||||||
|
&mo LOWER |
||||||
|
``` |
@ -0,0 +1,50 @@ |
|||||||
|
--- |
||||||
|
title: Lighting |
||||||
|
--- |
||||||
|
|
||||||
|
## Summary |
||||||
|
|
||||||
|
Lighting is often used for either aesthetics or for the practical purposes of lighting up keys in the dark. |
||||||
|
Currently ZMK supports RGB underglow, which can be changed and configured using its behavior. |
||||||
|
|
||||||
|
## RGB Action Defines |
||||||
|
|
||||||
|
RGB actions defines are provided through the [`dt-bindings/zmk/rgb.h`](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/rgb.h) header, |
||||||
|
which is added at the top of the keymap file: |
||||||
|
|
||||||
|
``` |
||||||
|
#include <dt-bindings/zmk/rgb.h> |
||||||
|
``` |
||||||
|
|
||||||
|
This will allow you to reference the actions defined in this header such as `RGB_TOG`. |
||||||
|
|
||||||
|
Here is a table describing the action for each define: |
||||||
|
|
||||||
|
| Define | Action | |
||||||
|
|-----------|-----------------------------------------------------------| |
||||||
|
| `RGB_TOG` | Toggles the RGB feature on and off | |
||||||
|
| `RGB_HUI` | Increases the hue of the RGB feature | |
||||||
|
| `RGB_HUD` | Decreases the hue of the RGB feature | |
||||||
|
| `RGB_SAI` | Increases the saturation of the RGB feature | |
||||||
|
| `RGB_SAD` | Decreases the saturation of the RGB feature | |
||||||
|
| `RGB_BRI` | Increases the brightness of the RGB feature | |
||||||
|
| `RGB_BRD` | Decreases the brightness of the RGB feature | |
||||||
|
| `RGB_SPI` | Increases the speed of the RGB feature effect's animation | |
||||||
|
| `RGB_SPD` | Decreases the speed of the RGB feature effect's animation | |
||||||
|
| `RGB_EFF` | Cycles the RGB feature's effect forwards | |
||||||
|
| `RGB_EFR` | Cycles the RGB feature's effect reverse | |
||||||
|
|
||||||
|
## RGB Underglow |
||||||
|
|
||||||
|
The "RGB underglow" behavior completes an RGB action given on press. |
||||||
|
|
||||||
|
### Behavior Binding |
||||||
|
|
||||||
|
- Reference: `&rgb_ug` |
||||||
|
- Parameter: The RGB action define, e.g. `RGB_TOG` or `RGB_BRI` |
||||||
|
|
||||||
|
Example: |
||||||
|
|
||||||
|
``` |
||||||
|
&rgb_ug RGB_TOG |
||||||
|
``` |
@ -1,5 +1,125 @@ |
|||||||
--- |
--- |
||||||
title: RGB Underglow |
title: RGB Underglow |
||||||
|
sidebar_label: RGB Underglow |
||||||
--- |
--- |
||||||
|
|
||||||
TODO: Documentation on 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. |
||||||
|
|
||||||
|
ZMK supports all the RGB LEDs supported by Zephyr. Here's the current list supported: |
||||||
|
|
||||||
|
- WS2812-ish (WS2812B, WS2813, SK6812, or compatible) |
||||||
|
- APA102 |
||||||
|
- LPD880x (LPD8803, LPD8806, or compatible) |
||||||
|
|
||||||
|
Of the compatible types, the WS2812 LED family is by far the most popular type. Currently each of these types of LEDs are expected to be run using SPI with a couple of exceptions. |
||||||
|
|
||||||
|
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 `ZMK_RGB_UNDERGLOW` and `X_STRIP` configuration values in the `.conf` file of your user config directory as such: |
||||||
|
|
||||||
|
``` |
||||||
|
CONFIG_ZMK_RGB_UNDERGLOW=y |
||||||
|
# Use the STRIP config specific to the LEDs you're using |
||||||
|
CONFIG_WS2812_STRIP=y |
||||||
|
``` |
||||||
|
|
||||||
|
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). |
||||||
|
|
||||||
|
## Configuring RGB Underglow |
||||||
|
|
||||||
|
There are various Kconfig options used to configure the RGB underglow feature. These can all be set in the `.conf` file. |
||||||
|
|
||||||
|
| Option | Description | Default | |
||||||
|
| ---------------------------- | ---------------------------------------------- | ------- | |
||||||
|
| `ZMK_RGB_UNDERGLOW_HUE_STEP` | Hue step in degrees of 360 used by RGB actions | `10` | |
||||||
|
| `ZMK_RGB_UNDERGLOW_SAT_STEP` | Saturation step in percent used by RGB actions | `10` | |
||||||
|
| `ZMK_RGB_UNDERGLOW_BRT_STEP` | Brightness step in percent used by RGB actions | `10` | |
||||||
|
|
||||||
|
## Adding RGB Underglow to a Board |
||||||
|
|
||||||
|
RGB underglow is always added to a board, not a shield. This is a consequence of needing to configure SPI to control the LEDs. |
||||||
|
If you have a shield with RGB underglow, you must add a `boards/` directory within your shield folder to define the RGB underglow individually for each board that supports the shield. |
||||||
|
Inside the `boards/` folder, you define a `<board>.overlay` for each different board. |
||||||
|
For example, the Kyria shield has a `boards/nice_nano.overlay` file that defines the RGB underglow for the `nice_nano` board specifically. |
||||||
|
|
||||||
|
The first step to adding support for underglow is to select you SPI output. With nRF52 boards, you can just use `&spi1` and define the pins you want to use. |
||||||
|
For other boards, you must select an SPI definition that has the `MOSI` pin as your data pin going to your LED strip. |
||||||
|
|
||||||
|
Here's an example of an nRF52 SPI definition: |
||||||
|
|
||||||
|
``` |
||||||
|
&spi1 { |
||||||
|
compatible = "nordic,nrf-spi"; |
||||||
|
status = "okay"; |
||||||
|
mosi-pin = <6>; |
||||||
|
// Unused pins, needed for SPI definition, but not used by the ws2812 driver itself. |
||||||
|
sck-pin = <5>; |
||||||
|
miso-pin = <7>; |
||||||
|
|
||||||
|
led_strip: ws2812@0 { |
||||||
|
compatible = "worldsemi,ws2812-spi"; |
||||||
|
label = "WS2812"; |
||||||
|
|
||||||
|
/* 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>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
``` |
||||||
|
|
||||||
|
:::info |
||||||
|
|
||||||
|
If you are configuring SPI for an nRF52840 (or other nRF52) based board, double check that you are using pins that aren't restricted to low frequency I/O. |
||||||
|
Ignoring these restrictions may result in poor wireless performance. You can find the list of low frequency I/O pins [here](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fpin.html&cp=4_0_0_6_0). |
||||||
|
|
||||||
|
::: |
||||||
|
|
||||||
|
Here's another example for a non-nRF52 board on `spi1`: |
||||||
|
|
||||||
|
``` |
||||||
|
&spi1 { |
||||||
|
|
||||||
|
led_strip: ws2812@0 { |
||||||
|
compatible = "worldsemi,ws2812-spi"; |
||||||
|
label = "WS2812"; |
||||||
|
|
||||||
|
/* SPI */ |
||||||
|
reg = <0>; |
||||||
|
spi-max-frequency = <5250000>; |
||||||
|
|
||||||
|
/* WS2812 */ |
||||||
|
chain-length = <10>; /* number of LEDs */ |
||||||
|
spi-one-frame = <0x70>; /* make sure to configure this properly for your SOC */ |
||||||
|
spi-zero-frame = <0x40>; /* make sure to configure this properly for your SOC */ |
||||||
|
}; |
||||||
|
}; |
||||||
|
``` |
||||||
|
|
||||||
|
Once you have your `led_strip` properly defined you need to add it to the root devicetree node `chosen` element: |
||||||
|
|
||||||
|
``` |
||||||
|
/ { |
||||||
|
chosen { |
||||||
|
zmk,underglow = &led_strip; |
||||||
|
}; |
||||||
|
}; |
||||||
|
``` |
||||||
|
|
||||||
|
Finally you need to enable the `ZMK_RGB_UNDERGLOW` and `X_STRIP` configuration values in the `.conf` file of your board (or set a default in the `Kconfig.defconfig`): |
||||||
|
|
||||||
|
``` |
||||||
|
CONFIG_ZMK_RGB_UNDERGLOW=y |
||||||
|
# Use the STRIP config specific to the LEDs you're using |
||||||
|
CONFIG_WS2812_STRIP=y |
||||||
|
``` |
||||||
|
Loading…
Reference in new issue