Some more vibing

This commit is contained in:
Your Name
2026-05-24 14:52:55 +03:00
parent bc20f1a29b
commit 440509b89c
11 changed files with 435 additions and 67 deletions
+12 -1
View File
@@ -6,7 +6,7 @@
#define NVS_ID_CONFIG 1
#define CONFIG_ID 0xDEADBEEF
#define CONFIG_VERSION 2
#define CONFIG_VERSION 7
static struct nvs_fs nvs;
static app_config_t ram_config;
@@ -18,6 +18,17 @@ static const app_config_t default_config = {
.phase_a_ms = (20 * 60 * 1000),
.phase_b_ms = (20 * 1000),
},
.light_config = {
.min = 5,
.max = 600,
.gain = 0b00000100,
},
.color = {
.r = 1,
.g = 0.2,
.b = 0,
},
.color_duration = 2000,
};
int config_init(void)
+11 -1
View File
@@ -4,11 +4,21 @@
#include <stdint.h>
#include <stdbool.h>
#include "mode.h"
#include "led.h"
struct light_config_t {
uint16_t min;
uint16_t max;
uint8_t gain;
};
typedef struct {
uint32_t id;
uint16_t version;
struct mode_config mode_config;
struct mode_config_t mode_config;
struct light_config_t light_config;
struct color_t color;
uint16_t color_duration;
} app_config_t;
int config_init(void);
+13
View File
@@ -88,11 +88,24 @@ static int cmd_dbg_leds_fade_to(const struct shell *sh, size_t argc, char **argv
atoi(argv[4]) < 0 ? -1.0f : atoi(argv[4]) / 255.0f);
}
static int cmd_dbg_led_color(const struct shell *sh, size_t argc, char **argv)
{
struct color_t color;
if (led_color_from_str(argv[1], &color) != 0) {
shell_error(sh, "Unknown color: %s", argv[1]);
return -EINVAL;
}
leds_set_all(color.r, color.g, color.b);
leds_update();
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(debug_leds_cmds,
SHELL_CMD(all, NULL, "Set all LEDs <r> <g> <b>.", cmd_dbg_leds_all),
SHELL_CMD(clear, NULL, "Clear all LEDs.", cmd_dbg_leds_clear),
SHELL_CMD(fade, NULL, "Fade in/out <ms> <r> <g> <b>.", cmd_dbg_leds_fade),
SHELL_CMD(fade_to, NULL, "Fade to color <ms> <r> <g> <b>.", cmd_dbg_leds_fade_to),
SHELL_CMD(color, NULL, "Set to color <color>. eg. yellow", cmd_dbg_led_color),
SHELL_SUBCMD_SET_END
);
+6
View File
@@ -0,0 +1,6 @@
#include "helpers.h"
float map(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef HELPERS_H
#define HELPERS_H
float map(float x, float in_min, float in_max, float out_min, float out_max);
#endif // HELPERS_H
+177 -17
View File
@@ -1,4 +1,7 @@
#include "led.h"
#include "light.h"
#include "config.h"
#include "helpers.h"
#include <zephyr/kernel.h>
#include <zephyr/device.h>
@@ -15,11 +18,15 @@ LOG_MODULE_REGISTER(leds, LOG_LEVEL_INF);
static const struct device *const strip = DEVICE_DT_GET(STRIP_NODE);
static struct led_rgb pixels[STRIP_NUM_PIXELS];
/* Saved strip color for fade_to interpolation */
/* Saved strip color for fade_to interpolation (logical, pre-brightness) */
static float saved_r = 0.0f;
static float saved_g = 0.0f;
static float saved_b = 0.0f;
/* Light sensor config loaded during init */
static uint16_t light_min = 0;
static uint16_t light_max = 1023;
#define NR_LEDS 8
#define PWM_RESOLUTION 255
@@ -36,6 +43,88 @@ static const struct pwm_dt_spec *leds[NR_LEDS] = {
&led1, &led2, &led3, &led4, &led5, &led6, &led7, &led8
};
static const led_color_entry_t color_table[] = {
{ "red", { LED_COLOR_RED } },
{ "green", { LED_COLOR_GREEN } },
{ "blue", { LED_COLOR_BLUE } },
{ "yellow", { LED_COLOR_YELLOW } },
{ "cyan", { LED_COLOR_CYAN } },
{ "magenta", { LED_COLOR_MAGENTA } },
{ "white", { LED_COLOR_WHITE } },
{ "warm_white", { LED_COLOR_WARM_WHITE } },
{ "cold_white", { LED_COLOR_COLD_WHITE } },
{ "black", { LED_COLOR_BLACK } },
{ "orange", { LED_COLOR_ORANGE } },
{ "deep_orange", { LED_COLOR_DEEP_ORANGE } },
{ "amber", { LED_COLOR_AMBER } },
{ "coral", { LED_COLOR_CORAL } },
{ "tomato", { LED_COLOR_TOMATO } },
{ "crimson", { LED_COLOR_CRIMSON } },
{ "scarlet", { LED_COLOR_SCARLET } },
{ "pink", { LED_COLOR_PINK } },
{ "hot_pink", { LED_COLOR_HOT_PINK } },
{ "deep_pink", { LED_COLOR_DEEP_PINK } },
{ "purple", { LED_COLOR_PURPLE } },
{ "deep_purple", { LED_COLOR_DEEP_PURPLE } },
{ "violet", { LED_COLOR_VIOLET } },
{ "indigo", { LED_COLOR_INDIGO } },
{ "lavender", { LED_COLOR_LAVENDER } },
{ "lime", { LED_COLOR_LIME } },
{ "chartreuse", { LED_COLOR_CHARTREUSE } },
{ "mint", { LED_COLOR_MINT } },
{ "teal", { LED_COLOR_TEAL } },
{ "forest_green", { LED_COLOR_FOREST_GREEN } },
{ "olive", { LED_COLOR_OLIVE } },
{ "sky_blue", { LED_COLOR_SKY_BLUE } },
{ "deep_sky_blue", { LED_COLOR_DEEP_SKY_BLUE } },
{ "dodger_blue", { LED_COLOR_DODGER_BLUE } },
{ "royal_blue", { LED_COLOR_ROYAL_BLUE } },
{ "navy", { LED_COLOR_NAVY } },
{ "steel_blue", { LED_COLOR_STEEL_BLUE } },
{ "ice_blue", { LED_COLOR_ICE_BLUE } },
{ "gold", { LED_COLOR_GOLD } },
{ "silver", { LED_COLOR_SILVER } },
};
const int color_table_size = ARRAY_SIZE(color_table);
int led_color_from_str(const char *name, struct color_t *out)
{
for (int i = 0; i < ARRAY_SIZE(color_table); i++) {
if (strcasecmp(color_table[i].name, name) == 0) {
*out = color_table[i].color;
return 0;
}
}
return -EINVAL;
}
const char *led_color_to_str(const struct color_t *color)
{
for (int i = 0; i < ARRAY_SIZE(color_table); i++) {
if (color_table[i].color.r == color->r &&
color_table[i].color.g == color->g &&
color_table[i].color.b == color->b) {
return color_table[i].name;
}
}
return "custom";
}
int led_color_count(void)
{
return ARRAY_SIZE(color_table);
}
const led_color_entry_t *led_color_get(int index)
{
if (index < 0 || index >= ARRAY_SIZE(color_table)) {
return NULL;
}
return &color_table[index];
}
/* ---------- PWM helpers ---------- */
static int set_pwm(const struct pwm_dt_spec *dev, uint32_t value, uint32_t max_brightness)
{
if (value <= max_brightness && max_brightness > 0) {
@@ -45,13 +134,69 @@ static int set_pwm(const struct pwm_dt_spec *dev, uint32_t value, uint32_t max_b
return -EINVAL;
}
/* ---------- brightness helpers ---------- */
/**
* Read the light sensor and return a brightness multiplier in [0.0, 1.0].
* The raw value is mapped from [light_min, light_max] → [0.0, 1.0] and
* clamped so out-of-range readings never over- or under-drive the LEDs.
*/
static float get_brightness(void)
{
struct light_data_t data;
light_read(&data);
float b = map((float)data.value,
(float)light_min, (float)light_max,
0.0f, 1.0f);
if (b < 0.0f) b = 0.0f;
if (b > 1.0f) b = 1.0f;
return b;
}
static float get_brightness_pwm(void)
{
for (int j = 0; j < NR_LEDS; j++) {
set_pwm(leds[j], 0, PWM_RESOLUTION);
}
return get_brightness();
}
/**
* Like set_pwm() but scales `value` by the current ambient brightness before
* writing. All PWM-facing call sites go through here.
*/
static int set_pwm_bright(const struct pwm_dt_spec *dev, uint32_t value,
uint32_t max_brightness, float brightness)
{
uint32_t scaled = (uint32_t)((float)value * brightness);
return set_pwm(dev, scaled, max_brightness);
}
/* ---------- init ---------- */
int led_init(void)
{
/* Load light config so brightness mapping is ready before first use */
app_config_t cfg;
config_get(&cfg);
light_min = cfg.light_config.min;
light_max = cfg.light_config.max;
/* Sanity-check: inverted or zero range would make map() degenerate */
if (light_min >= light_max) {
LOG_WRN("Invalid light_config range [%u, %u], using defaults",
light_min, light_max);
light_min = 0;
light_max = 1023;
}
LOG_INF("Light config: min=%u max=%u", light_min, light_max);
for (int i = 0; i < NR_LEDS; i++) {
if (!device_is_ready(leds[i]->dev)) {
LOG_ERR("PWM LED %d not ready", i);
return -ENODEV;
}
set_pwm(leds[i], 0, PWM_RESOLUTION);
}
LOG_INF("PWM LEDs initialized");
@@ -60,21 +205,25 @@ int led_init(void)
return -ENODEV;
}
LOG_INF("LED strip initialized with %d pixels", STRIP_NUM_PIXELS);
leds_clear();
return 0;
}
/* Fade all PWM LEDs in then out over duration ms */
/* ---------- PWM LED effects ---------- */
int led_fade(uint32_t duration)
{
uint32_t step = (duration * 1000) / (PWM_RESOLUTION * 2);
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) { set_pwm(leds[j], i, PWM_RESOLUTION); }
float b = get_brightness();
for (int j = 0; j < NR_LEDS; j++) { set_pwm_bright(leds[j], i, PWM_RESOLUTION, b); }
k_sleep(K_USEC(step));
}
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) { set_pwm(leds[j], PWM_RESOLUTION - i - 1, PWM_RESOLUTION); }
float b = get_brightness();
for (int j = 0; j < NR_LEDS; j++) { set_pwm_bright(leds[j], PWM_RESOLUTION - i - 1, PWM_RESOLUTION, b); }
k_sleep(K_USEC(step));
}
return 0;
@@ -84,7 +233,8 @@ int led_fade_in(uint32_t duration)
{
uint32_t step = (duration * 1000) / PWM_RESOLUTION;
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) { set_pwm(leds[j], i, PWM_RESOLUTION); }
float b = get_brightness();
for (int j = 0; j < NR_LEDS; j++) { set_pwm_bright(leds[j], i, PWM_RESOLUTION, b); }
k_sleep(K_USEC(step));
}
return 0;
@@ -94,30 +244,44 @@ int led_fade_out(uint32_t duration)
{
uint32_t step = (duration * 1000) / PWM_RESOLUTION;
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) { set_pwm(leds[j], PWM_RESOLUTION - i - 1, PWM_RESOLUTION); }
float b = get_brightness();
for (int j = 0; j < NR_LEDS; j++) { set_pwm_bright(leds[j], PWM_RESOLUTION - i - 1, PWM_RESOLUTION, b); }
k_sleep(K_USEC(step));
}
return 0;
}
/* Light N+fraction LEDs to represent progress [0.0, 1.0] */
int led_set_progress(float progress)
{
float b = get_brightness(); /* LEDs blanked; write real values below */
uint32_t total = (uint32_t)(progress * NR_LEDS * PWM_RESOLUTION);
for (int i = 0; i < NR_LEDS; i++) {
uint32_t val;
if (total > PWM_RESOLUTION) {
set_pwm(leds[i], PWM_RESOLUTION, PWM_RESOLUTION);
val = PWM_RESOLUTION;
total -= PWM_RESOLUTION;
} else {
set_pwm(leds[i], total, PWM_RESOLUTION);
val = total;
total = 0;
}
set_pwm_bright(leds[i], val, PWM_RESOLUTION, b);
}
return 0;
}
/* --- Addressable LED strip --- */
/* ---------- addressable strip ---------- */
/**
* Write r/g/b to a pixel after applying the ambient brightness multiplier.
* `r`, `g`, `b` are logical values in [0.0, 1.0]; `brightness` scales them.
*/
static void set_pixel_bright(int idx, float r, float g, float b, float brightness)
{
pixels[idx].r = (uint8_t)(r * brightness * STRIP_MAX_BRIGHTNESS);
pixels[idx].g = (uint8_t)(g * brightness * STRIP_MAX_BRIGHTNESS);
pixels[idx].b = (uint8_t)(b * brightness * STRIP_MAX_BRIGHTNESS);
}
int leds_set_color(uint8_t led_index, float r, float g, float b)
{
@@ -125,18 +289,15 @@ int leds_set_color(uint8_t led_index, float r, float g, float b)
LOG_ERR("LED index %d out of range (max %d)", led_index, STRIP_NUM_PIXELS - 1);
return -EINVAL;
}
pixels[led_index].r = r * STRIP_MAX_BRIGHTNESS;
pixels[led_index].g = g * STRIP_MAX_BRIGHTNESS;
pixels[led_index].b = b * STRIP_MAX_BRIGHTNESS;
set_pixel_bright(led_index, r, g, b, get_brightness());
return 0;
}
int leds_set_all(float r, float g, float b)
{
float brightness = get_brightness();
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
pixels[i].r = r * STRIP_MAX_BRIGHTNESS;
pixels[i].g = g * STRIP_MAX_BRIGHTNESS;
pixels[i].b = b * STRIP_MAX_BRIGHTNESS;
set_pixel_bright(i, r, g, b, brightness);
}
saved_r = r;
saved_g = g;
@@ -206,7 +367,6 @@ int leds_fade_out(uint32_t duration, float r, float g, float b)
return 0;
}
/* Fade from current saved color to target; pass -1.0 to keep a channel unchanged */
int leds_fade_to(uint32_t duration, float r, float g, float b)
{
float target_r = (r < 0.0f) ? saved_r : r;
+80
View File
@@ -3,12 +3,92 @@
#include <stdint.h>
/* ---------- predefined colors (r, g, b) in [0.0, 1.0] ---------- */
/* Primaries */
#define LED_COLOR_RED 1.0f, 0.0f, 0.0f
#define LED_COLOR_GREEN 0.0f, 1.0f, 0.0f
#define LED_COLOR_BLUE 0.0f, 0.0f, 1.0f
/* Secondaries */
#define LED_COLOR_YELLOW 1.0f, 1.0f, 0.0f
#define LED_COLOR_CYAN 0.0f, 1.0f, 1.0f
#define LED_COLOR_MAGENTA 1.0f, 0.0f, 1.0f
/* Whites */
#define LED_COLOR_WHITE 1.0f, 1.0f, 1.0f
#define LED_COLOR_WARM_WHITE 1.0f, 0.89f, 0.70f
#define LED_COLOR_COLD_WHITE 0.90f, 0.95f, 1.0f
#define LED_COLOR_BLACK 0.0f, 0.0f, 0.0f
/* Oranges & reds */
#define LED_COLOR_ORANGE 1.0f, 0.50f, 0.0f
#define LED_COLOR_DEEP_ORANGE 1.0f, 0.25f, 0.0f
#define LED_COLOR_AMBER 1.0f, 0.75f, 0.0f
#define LED_COLOR_CORAL 1.0f, 0.31f, 0.19f
#define LED_COLOR_TOMATO 1.0f, 0.27f, 0.23f
#define LED_COLOR_CRIMSON 0.86f, 0.08f, 0.24f
#define LED_COLOR_SCARLET 1.0f, 0.14f, 0.0f
/* Pinks & purples */
#define LED_COLOR_PINK 1.0f, 0.40f, 0.70f
#define LED_COLOR_HOT_PINK 1.0f, 0.07f, 0.58f
#define LED_COLOR_DEEP_PINK 1.0f, 0.08f, 0.58f
#define LED_COLOR_PURPLE 0.50f, 0.0f, 1.0f
#define LED_COLOR_DEEP_PURPLE 0.40f, 0.0f, 0.80f
#define LED_COLOR_VIOLET 0.56f, 0.0f, 1.0f
#define LED_COLOR_INDIGO 0.29f, 0.0f, 0.51f
#define LED_COLOR_LAVENDER 0.71f, 0.49f, 0.86f
/* Greens */
#define LED_COLOR_LIME 0.75f, 1.0f, 0.0f
#define LED_COLOR_CHARTREUSE 0.50f, 1.0f, 0.0f
#define LED_COLOR_MINT 0.24f, 1.0f, 0.49f
#define LED_COLOR_TEAL 0.0f, 0.50f, 0.50f
#define LED_COLOR_FOREST_GREEN 0.13f, 0.55f, 0.13f
#define LED_COLOR_OLIVE 0.50f, 0.50f, 0.0f
/* Blues */
#define LED_COLOR_SKY_BLUE 0.53f, 0.81f, 0.98f
#define LED_COLOR_DEEP_SKY_BLUE 0.0f, 0.75f, 1.0f
#define LED_COLOR_DODGER_BLUE 0.12f, 0.56f, 1.0f
#define LED_COLOR_ROYAL_BLUE 0.25f, 0.41f, 0.88f
#define LED_COLOR_NAVY 0.0f, 0.0f, 0.50f
#define LED_COLOR_STEEL_BLUE 0.27f, 0.51f, 0.71f
#define LED_COLOR_ICE_BLUE 0.60f, 0.85f, 1.0f
/* Neutrals */
#define LED_COLOR_GOLD 1.0f, 0.84f, 0.0f
#define LED_COLOR_SILVER 0.75f, 0.75f, 0.75f
/* ---------- color lookup by name ---------- */
struct color_t {
float r;
float g;
float b;
};
typedef struct {
const char *name;
struct color_t color;
} led_color_entry_t;
int led_color_from_str(const char *name, struct color_t *out);
const char *led_color_to_str(const struct color_t *color);
int led_color_count(void);
const led_color_entry_t *led_color_get(int index);
/* ---------- PWM LED functions ---------- */
int led_init(void);
int led_fade(uint32_t duration);
int led_fade_in(uint32_t duration);
int led_fade_out(uint32_t duration);
int led_set_progress(float progress);
/* ---------- addressable LED strip functions ---------- */
int leds_set_color(uint8_t led_index, float r, float g, float b);
int leds_set_all(float r, float g, float b);
int leds_update(void);
+10
View File
@@ -1,5 +1,7 @@
#include "light.h"
#include "zbus_channels.h"
#include "led.h"
#include "config.h"
#include <zephyr/kernel.h>
#include <zephyr/device.h>
@@ -15,6 +17,8 @@ static const uint8_t i2c_address = 0x38;
static const struct device *const i2c_dev = DEVICE_DT_GET(DT_ALIAS(i2c_1));
static struct light_config_t cfg;
int light_init(void)
{
if (!device_is_ready(i2c_dev)) {
@@ -22,10 +26,16 @@ int light_init(void)
return -ENODEV;
}
app_config_t app_cfg;
config_get(&app_cfg);
cfg = app_cfg.light_config;
const uint8_t RESET[2] = {0x00, 0b00000001}; // reset
const uint8_t ALS_GAIN[2] = {0x04, cfg.gain}; // configure ALS gain
const uint8_t ENABLE_ALS[2] = {0x00, 0b00000001}; // enable ALS
i2c_write(i2c_dev, RESET, sizeof(RESET), i2c_address); k_sleep(K_MSEC(100));
i2c_write(i2c_dev, ALS_GAIN, sizeof(ALS_GAIN), i2c_address); k_sleep(K_MSEC(10));
i2c_write(i2c_dev, ENABLE_ALS, sizeof(ENABLE_ALS), i2c_address); k_sleep(K_MSEC(100));
return 0;
+7 -5
View File
@@ -13,7 +13,9 @@ K_THREAD_STACK_DEFINE(mode_stack, 1024);
static struct k_thread mode_thread;
static atomic_t running = ATOMIC_INIT(0);
static struct mode_config cfg;
static struct mode_config_t cfg;
static struct color_t color;
static uint16_t color_duration = 2000;
static void mode_thread_fn(void *p1, void *p2, void *p3)
{
@@ -30,10 +32,8 @@ static void mode_thread_fn(void *p1, void *p2, void *p3)
/* Phase B: color animation over phase_b_ms */
start = k_uptime_get();
while (atomic_get(&running) && k_uptime_get() - start < cfg.phase_b_ms) {
leds_fade_to(500, 1, -1, -1);
leds_fade_to(500, -1, 1, -1);
leds_fade_to(500, -1, 0, -1);
leds_fade_to(500, 0, -1, -1);
leds_fade_to(color_duration/2, color.r, color.g, color.b);
leds_fade_to(color_duration/2, 0, 0, 0);
}
}
@@ -46,6 +46,8 @@ void mode_init(void)
app_config_t app_cfg;
config_get(&app_cfg);
cfg = app_cfg.mode_config;
color = app_cfg.color;
color_duration = app_cfg.color_duration;
LOG_INF("Mode init: phase_a=%d ms, phase_b=%d ms", cfg.phase_a_ms, cfg.phase_b_ms);
}
+1 -1
View File
@@ -3,7 +3,7 @@
#include <stdint.h>
struct mode_config {
struct mode_config_t {
int32_t phase_a_ms;
int32_t phase_b_ms;
};
+70
View File
@@ -1,13 +1,27 @@
// User-facing shell commands.
// mode set <phase_a_ms> <phase_b_ms> — save config and restart
// mode color <name> — save color by name and restart
// mode duration <ms> — save color duration and restart
// mode status — show current config
//
#include "mode.h"
#include "config.h"
#include "led.h"
#include <zephyr/shell/shell.h>
#include <stdlib.h>
/* Print a color as 0-255 integers — %f is unavailable without
CONFIG_CBPRINTF_FP_SUPPORT, and integer RGB is more readable anyway. */
static void print_color(const struct shell *sh, const struct color_t *color)
{
shell_print(sh, " color=%s rgb=(%d, %d, %d)",
led_color_to_str(color),
(int)(color->r * 255),
(int)(color->g * 255),
(int)(color->b * 255));
}
static int cmd_mode_set(const struct shell *sh, size_t argc, char **argv)
{
app_config_t cfg;
@@ -21,19 +35,75 @@ static int cmd_mode_set(const struct shell *sh, size_t argc, char **argv)
return 0;
}
static int cmd_mode_color(const struct shell *sh, size_t argc, char **argv)
{
struct color_t color;
if (led_color_from_str(argv[1], &color) != 0) {
shell_error(sh, "Unknown color: %s", argv[1]);
return -EINVAL;
}
app_config_t cfg;
config_get(&cfg);
cfg.color = color;
config_save(&cfg);
mode_init();
mode_restart();
shell_print(sh, "Color saved and restarting.");
print_color(sh, &color);
return 0;
}
static int cmd_mode_duration(const struct shell *sh, size_t argc, char **argv)
{
int val = atoi(argv[1]);
if (val <= 0) {
shell_error(sh, "Duration must be a positive integer (ms)");
return -EINVAL;
}
app_config_t cfg;
config_get(&cfg);
cfg.color_duration = (uint16_t)val;
config_save(&cfg);
mode_init();
mode_restart();
shell_print(sh, "Color duration saved: %d ms. Restarting.", cfg.color_duration);
return 0;
}
static int cmd_mode_status(const struct shell *sh, size_t argc, char **argv)
{
app_config_t cfg;
config_get(&cfg);
shell_print(sh, "phase_a=%d ms, phase_b=%d ms",
cfg.mode_config.phase_a_ms,
cfg.mode_config.phase_b_ms);
print_color(sh, &cfg.color);
shell_print(sh, " duration=%d ms", cfg.color_duration);
return 0;
}
static int cmd_mode_colors(const struct shell *sh, size_t argc, char **argv)
{
for (int i = 0; i < led_color_count(); i++) {
const led_color_entry_t *entry = led_color_get(i);
shell_print(sh, " %-16s rgb=(%d, %d, %d)",
entry->name,
(int)(entry->color.r * 255),
(int)(entry->color.g * 255),
(int)(entry->color.b * 255));
}
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(mode_cmds,
SHELL_CMD_ARG(set, NULL, "Set <phase_a_ms> <phase_b_ms>, save and restart.", cmd_mode_set, 3, 0),
SHELL_CMD_ARG(color, NULL, "Set color by name (e.g. deep_orange), save and restart.", cmd_mode_color, 2, 0),
SHELL_CMD_ARG(duration, NULL, "Set color duration <ms>, save and restart.", cmd_mode_duration, 2, 0),
SHELL_CMD( status, NULL, "Show current config.", cmd_mode_status),
SHELL_CMD( colors, NULL, "List all available colors.", cmd_mode_colors),
SHELL_SUBCMD_SET_END
);