feat(led): 添加LED按键淡入淡出效果并重构LED条模块

添加了完整的LED效果系统架构,包括:
- 新增主题颜色定义文件theme_color.h
- 实现key fade LED效果算法,支持按键触发的渐变效果
- 创建LED效果注册机制和通用接口
- 配置17个LED像素与按键映射关系
- 将原有简单的周期性效果替换为基于按键事件的动态效果

CMakeLists.txt中添加了新的源文件路径和实现文件。

BREAKING CHANGE: LED效果从固定的周期性变化改为响应按键事件的动态效果。
This commit is contained in:
2026-04-13 15:56:45 +08:00
parent ff8f0d81d7
commit 23e23f63a7
8 changed files with 407 additions and 55 deletions

View File

@@ -0,0 +1,155 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <zephyr/sys/util.h>
#include "led_effect/led_effect.h"
#define KEY_FADE_LEVEL_MAX 255U
#define KEY_FADE_STEP_PER_TICK 12U
struct led_effect_key_fade_state {
const struct led_key_map *key_map;
size_t key_map_len;
size_t pixel_count;
uint8_t default_brightness;
uint8_t level[17];
struct theme_rgb theme;
};
static struct led_effect_key_fade_state key_fade_state;
static const struct led_key_map *find_key(const struct led_effect *effect,
uint16_t key_id)
{
const struct led_effect_key_fade_state *state = effect->state;
for (size_t i = 0; i < state->key_map_len; i++) {
if (state->key_map[i].key_id == key_id) {
return &state->key_map[i];
}
}
return NULL;
}
static int led_effect_key_fade_init(struct led_effect *effect,
const struct led_effect_config *cfg)
{
struct led_effect_key_fade_state *state = effect->state;
if ((effect == NULL) || (cfg == NULL) || (cfg->key_map == NULL) ||
(cfg->pixel_count > ARRAY_SIZE(state->level))) {
return -EINVAL;
}
memset(state, 0, sizeof(*state));
state->key_map = cfg->key_map;
state->key_map_len = cfg->key_map_len;
state->pixel_count = cfg->pixel_count;
state->default_brightness = cfg->default_brightness;
state->theme.r = BLINKY_THEME_DEFAULT_R;
state->theme.g = BLINKY_THEME_DEFAULT_G;
state->theme.b = BLINKY_THEME_DEFAULT_B;
return 0;
}
static void led_effect_key_fade_reset(struct led_effect *effect)
{
struct led_effect_key_fade_state *state = effect->state;
memset(state->level, 0, sizeof(state->level));
}
static void led_effect_key_fade_set_theme(struct led_effect *effect,
const struct theme_rgb *theme)
{
struct led_effect_key_fade_state *state = effect->state;
if (theme == NULL) {
return;
}
state->theme = *theme;
}
static void led_effect_key_fade_on_key_press(struct led_effect *effect,
uint16_t key_id)
{
struct led_effect_key_fade_state *state = effect->state;
const struct led_key_map *map = find_key(effect, key_id);
if ((map == NULL) || (map->led_idx >= state->pixel_count)) {
return;
}
state->level[map->led_idx] =
(state->default_brightness == 0U) ? KEY_FADE_LEVEL_MAX :
state->default_brightness;
}
static bool led_effect_key_fade_tick(struct led_effect *effect, uint32_t dt_ms,
struct led_rgb *pixels, size_t pixel_count)
{
struct led_effect_key_fade_state *state = effect->state;
bool active = false;
bool visible = false;
uint8_t decay;
ARG_UNUSED(dt_ms);
if ((pixels == NULL) || (pixel_count < state->pixel_count)) {
return false;
}
memset(pixels, 0, sizeof(*pixels) * pixel_count);
decay = KEY_FADE_STEP_PER_TICK;
for (size_t i = 0; i < state->pixel_count; i++) {
uint8_t level = state->level[i];
if (level == 0U) {
continue;
}
visible = true;
pixels[i].r = (uint8_t)(((uint16_t)state->theme.r * level) / 255U);
pixels[i].g = (uint8_t)(((uint16_t)state->theme.g * level) / 255U);
pixels[i].b = (uint8_t)(((uint16_t)state->theme.b * level) / 255U);
state->level[i] = (level > decay) ? (uint8_t)(level - decay) : 0U;
active = active || (state->level[i] > 0U);
}
return visible || active;
}
static bool led_effect_key_fade_is_active(const struct led_effect *effect)
{
const struct led_effect_key_fade_state *state = effect->state;
for (size_t i = 0; i < state->pixel_count; i++) {
if (state->level[i] > 0U) {
return true;
}
}
return false;
}
static const struct led_effect_ops key_fade_ops = {
.init = led_effect_key_fade_init,
.reset = led_effect_key_fade_reset,
.set_theme = led_effect_key_fade_set_theme,
.on_key_press = led_effect_key_fade_on_key_press,
.tick = led_effect_key_fade_tick,
.is_active = led_effect_key_fade_is_active,
};
struct led_effect led_effect_key_fade = {
.ops = &key_fade_ops,
.state = &key_fade_state,
};