Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,9 @@ menuconfig ZMK_RGB_UNDERGLOW

if ZMK_RGB_UNDERGLOW

config ZMK_RGB_UNDERGLOW_TICK_PERIOD_MS
int "RGB animation tick period (ms)"

config ZMK_RGB_UNDERGLOW_EXT_POWER
bool "RGB underglow toggling also controls external power"

Expand Down
3 changes: 3 additions & 0 deletions app/Kconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ if ZMK_RGB_UNDERGLOW
config SPI
default y

config ZMK_RGB_UNDERGLOW_TICK_PERIOD_MS
default 50

config ZMK_RGB_UNDERGLOW_EXT_POWER
default y

Expand Down
58 changes: 31 additions & 27 deletions app/src/rgb_underglow.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,34 +207,48 @@ static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) {
k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &underglow_tick_work);
}

K_TIMER_DEFINE(underglow_tick, zmk_rgb_underglow_tick_handler, NULL);
static void zmk_rgb_underglow_off_handler(struct k_work *work) {
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0};
}

led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS);
}

K_WORK_DEFINE(underglow_off_work, zmk_rgb_underglow_off_handler);

static void zmk_rgb_underglow_tick_stop_handler(struct k_timer *timer) {

k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &underglow_off_work);
}

K_TIMER_DEFINE(underglow_tick, zmk_rgb_underglow_tick_handler, zmk_rgb_underglow_tick_stop_handler);

#if IS_ENABLED(CONFIG_SETTINGS)
static int rgb_settings_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg) {
const char *next;
int rc;

if (settings_name_steq(name, "state", &next) && !next) {
if (len != sizeof(state)) {
return -EINVAL;
}

rc = read_cb(cb_arg, &state, sizeof(state));
if (rc >= 0) {
if (state.on) {
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
}
return read_cb(cb_arg, &state, sizeof(state));
}

return 0;
}
return -ENOENT;
}

return rc;
static int rgb_settings_commit(void) {
if (state.on) {
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(CONFIG_ZMK_RGB_UNDERGLOW_TICK_PERIOD_MS));
}

return -ENOENT;
return 0;
}

SETTINGS_STATIC_HANDLER_DEFINE(rgb_underglow, "rgb/underglow", NULL, rgb_settings_set, NULL, NULL);
SETTINGS_STATIC_HANDLER_DEFINE(rgb_underglow, "rgb/underglow", NULL, rgb_settings_set,
rgb_settings_commit, NULL);

static void zmk_rgb_underglow_save_state_work(struct k_work *_work) {
settings_save_one("rgb/underglow/state", &state, sizeof(state));
Expand Down Expand Up @@ -273,9 +287,11 @@ static int zmk_rgb_underglow_init(void) {
state.on = zmk_usb_is_powered();
#endif

#if !IS_ENABLED(CONFIG_SETTINGS)
if (state.on) {
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(CONFIG_ZMK_RGB_UNDERGLOW_TICK_PERIOD_MS));
}
#endif

return 0;
}
Expand Down Expand Up @@ -312,21 +328,11 @@ int zmk_rgb_underglow_on(void) {

state.on = true;
state.animation_step = 0;
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(CONFIG_ZMK_RGB_UNDERGLOW_TICK_PERIOD_MS));

return zmk_rgb_underglow_save_state();
}

static void zmk_rgb_underglow_off_handler(struct k_work *work) {
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0};
}

led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS);
}

K_WORK_DEFINE(underglow_off_work, zmk_rgb_underglow_off_handler);

int zmk_rgb_underglow_off(void) {
if (!led_strip)
return -ENODEV;
Expand All @@ -340,10 +346,8 @@ int zmk_rgb_underglow_off(void) {
}
#endif

k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &underglow_off_work);

k_timer_stop(&underglow_tick);
state.on = false;
k_timer_stop(&underglow_tick);

return zmk_rgb_underglow_save_state();
}
Expand Down
35 changes: 18 additions & 17 deletions docs/docs/config/lighting.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,24 @@ RGB underglow depends on [Zephyr's LED strip driver](https://github.com/zephyrpr

Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/app/Kconfig)

| Config | Type | Description | Default |
| ---------------------------------------- | ---- | --------------------------------------------------------- | ------- |
| `CONFIG_ZMK_RGB_UNDERGLOW` | bool | Enable RGB underglow | n |
| `CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER` | bool | Underglow toggling also controls external power | y |
| `CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE` | bool | Turn off RGB underglow when keyboard goes into idle state | n |
| `CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB` | bool | Turn off RGB underglow when USB is disconnected | n |
| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_STEP` | int | Hue step in degrees (0-359) used by RGB actions | 10 |
| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_STEP` | int | Saturation step in percent used by RGB actions | 10 |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_STEP` | int | Brightness step in percent used by RGB actions | 10 |
| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_START` | int | Default hue in degrees (0-359) | 0 |
| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_START` | int | Default saturation percent (0-100) | 100 |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_START` | int | Default brightness in percent (0-100) | 100 |
| `CONFIG_ZMK_RGB_UNDERGLOW_SPD_START` | int | Default effect speed (1-5) | 3 |
| `CONFIG_ZMK_RGB_UNDERGLOW_EFF_START` | int | Default effect index from the effect list (see below) | 0 |
| `CONFIG_ZMK_RGB_UNDERGLOW_ON_START` | bool | Default on state | y |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_MIN` | int | Minimum brightness in percent (0-100) | 0 |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_MAX` | int | Maximum brightness in percent (0-100) | 100 |
| Config | Type | Description | Default |
| ----------------------------------------- | ---- | --------------------------------------------------------------------------- | ------- |
| `CONFIG_ZMK_RGB_UNDERGLOW` | bool | Enable RGB underglow | n |
| `CONFIG_ZMK_RGB_UNDERGLOW_TICK_PERIOD_MS` | int | Period in milliseconds, between ticks of the underglow animation processing | 50 |
| `CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER` | bool | Underglow toggling also controls external power | y |
| `CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE` | bool | Turn off RGB underglow when keyboard goes into idle state | n |
| `CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB` | bool | Turn off RGB underglow when USB is disconnected | n |
| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_STEP` | int | Hue step in degrees (0-359) used by RGB actions | 10 |
| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_STEP` | int | Saturation step in percent used by RGB actions | 10 |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_STEP` | int | Brightness step in percent used by RGB actions | 10 |
| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_START` | int | Default hue in degrees (0-359) | 0 |
| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_START` | int | Default saturation percent (0-100) | 100 |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_START` | int | Default brightness in percent (0-100) | 100 |
| `CONFIG_ZMK_RGB_UNDERGLOW_SPD_START` | int | Default effect speed (1-5) | 3 |
| `CONFIG_ZMK_RGB_UNDERGLOW_EFF_START` | int | Default effect index from the effect list (see below) | 0 |
| `CONFIG_ZMK_RGB_UNDERGLOW_ON_START` | bool | Default on state | y |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_MIN` | int | Minimum brightness in percent (0-100) | 0 |
| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_MAX` | int | Maximum brightness in percent (0-100) | 100 |

Values for `CONFIG_ZMK_RGB_UNDERGLOW_EFF_START`:

Expand Down
Loading