diff --git a/app/Kconfig b/app/Kconfig index 484bd798..af61f49d 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -187,6 +187,10 @@ if ZMK_RGB_UNDERGLOW config SPI default y +config ZMK_RGB_UNDERGLOW_EXT_POWER + bool "RGB underglow toggling also controls external power" + default y + config ZMK_RGB_UNDERGLOW_HUE_STEP int "RGB underglow hue step in degrees of 360" default 10 @@ -220,7 +224,7 @@ config ZMK_RGB_UNDERGLOW_EFF_START default 0 config ZMK_RGB_UNDERGLOW_ON_START - bool "Whether RGB underglow starts on by default" + bool "RGB underglow starts on by default" default y #ZMK_RGB_UNDERGLOW diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index 084482ea..3e2c2549 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -15,6 +15,7 @@ #include #include +#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -45,34 +46,14 @@ struct rgb_underglow_state { bool on; }; -struct device *led_strip; +static struct device *led_strip; -struct led_rgb pixels[STRIP_NUM_PIXELS]; +static struct led_rgb pixels[STRIP_NUM_PIXELS]; -struct rgb_underglow_state state; +static struct rgb_underglow_state state; -#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) { - return 0; - } - - return rc; - } - - return -ENOENT; -} - -struct settings_handler rgb_conf = {.name = "rgb/underglow", .h_set = rgb_settings_set}; +#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER) +static struct device *ext_power; #endif static struct led_rgb hsb_to_rgb(struct led_hsb hsb) { @@ -228,6 +209,29 @@ static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) { K_TIMER_DEFINE(underglow_tick, zmk_rgb_underglow_tick_handler, NULL); #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) { + k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); + return 0; + } + + return rc; + } + + return -ENOENT; +} + +struct settings_handler rgb_conf = {.name = "rgb/underglow", .h_set = rgb_settings_set}; + static void zmk_rgb_underglow_save_state_work() { settings_save_one("rgb/underglow/state", &state, sizeof(state)); } @@ -244,6 +248,13 @@ static int zmk_rgb_underglow_init(struct device *_arg) { return -EINVAL; } +#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER) + ext_power = device_get_binding("EXT_POWER"); + if (ext_power == NULL) { + LOG_ERR("Unable to retrieve ext_power device: EXT_POWER"); + } +#endif + state = (struct rgb_underglow_state){ hue : CONFIG_ZMK_RGB_UNDERGLOW_HUE_START, saturation : CONFIG_ZMK_RGB_UNDERGLOW_SAT_START, @@ -257,9 +268,9 @@ static int zmk_rgb_underglow_init(struct device *_arg) { #if IS_ENABLED(CONFIG_SETTINGS) settings_register(&rgb_conf); k_delayed_work_init(&underglow_save_work, zmk_rgb_underglow_save_state_work); -#endif - +#else k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); +#endif return 0; } @@ -299,6 +310,22 @@ int zmk_rgb_underglow_toggle() { state.on = !state.on; +#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER) + if (ext_power != NULL) { + int rc; + + if (state.on) { + rc = ext_power_enable(ext_power); + } else { + rc = ext_power_disable(ext_power); + } + + if (rc != 0) { + LOG_ERR("Unable to toggle EXT_POWER: %d", rc); + } + } +#endif + if (state.on) { state.animation_step = 0; k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); diff --git a/docs/docs/features/underglow.md b/docs/docs/features/underglow.md index 2cea913f..3692a6de 100644 --- a/docs/docs/features/underglow.md +++ b/docs/docs/features/underglow.md @@ -35,17 +35,18 @@ If your board or shield does not have RGB underglow configured, refer to [Adding There are various Kconfig options used to configure the RGB underglow feature. These can all be set in the `.conf` file. -| Option | Description | Default | -| ------------------------------------ | ---------------------------------------------- | ------- | -| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_STEP` | Hue step in degrees of 360 used by RGB actions | 10 | -| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_STEP` | Saturation step in percent used by RGB actions | 10 | -| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_STEP` | Brightness step in percent used by RGB actions | 10 | -| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_START` | Default hue 0-359 in degrees | 0 | -| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_START` | Default saturation 0-100 in percent | 100 | -| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_START` | Default brightness 0-100 in percent | 100 | -| `CONFIG_ZMK_RGB_UNDERGLOW_SPD_START` | Default effect speed 1-5 | 3 | -| `CONFIG_ZMK_RGB_UNDERGLOW_EFF_START` | Default effect integer from the effect enum | 0 | -| `CONFIG_ZMK_RGB_UNDERGLOW_ON_START` | Default on state | y | +| Option | Description | Default | +| ------------------------------------ | ----------------------------------------------- | ------- | +| `CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER` | Underglow toggling also controls external power | y | +| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_STEP` | Hue step in degrees of 360 used by RGB actions | 10 | +| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_STEP` | Saturation step in percent used by RGB actions | 10 | +| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_STEP` | Brightness step in percent used by RGB actions | 10 | +| `CONFIG_ZMK_RGB_UNDERGLOW_HUE_START` | Default hue 0-359 in degrees | 0 | +| `CONFIG_ZMK_RGB_UNDERGLOW_SAT_START` | Default saturation 0-100 in percent | 100 | +| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_START` | Default brightness 0-100 in percent | 100 | +| `CONFIG_ZMK_RGB_UNDERGLOW_SPD_START` | Default effect speed 1-5 | 3 | +| `CONFIG_ZMK_RGB_UNDERGLOW_EFF_START` | Default effect integer from the effect enum | 0 | +| `CONFIG_ZMK_RGB_UNDERGLOW_ON_START` | Default on state | y | ## Adding RGB Underglow to a Board