Files
blinky/src/settings_module.c
skiinder 54c5f76c84 feat: 添加蓝牙多槽位绑定支持模块
- 新增 ble_bond_multi_module.c 实现多槽位蓝牙绑定管理功能
- 添加 ble_bond_multi_event 事件系统支持槽位状态广播
- 在 CMakeLists.txt 中注册新模块和事件源文件
- 更新 Kconfig 配置添加 BLINKY_BLE_BOND_MULTI 选项
- 修改 prj.conf 配置支持 4 个配对设备和 5 个身份标识
- 关闭默认 CAF ble_bond 模块使用自定义实现
- 更新 ui_settings_controller.h 接口支持槽位元数据设置
- 在 display_module.c 中添加事件订阅刷新UI显示
- 编写详细的设计文档 ble_multi_slot_design.md
2026-04-25 15:40:49 +08:00

235 lines
4.6 KiB
C

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <app_event_manager.h>
#define MODULE settings_module
#include <caf/events/click_event.h>
#include <caf/events/module_state_event.h>
#include <caf/events/power_event.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>
#include "ble_bond_multi_event.h"
#include "encoder_event.h"
#include "module_lifecycle.h"
#include "settings_mode_event.h"
#include "theme_color.h"
#include "theme_rgb_update_event.h"
#include "ui/ui_settings_controller.h"
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
#define SETTINGS_MUTE_KEY_ID 0x180U
struct settings_module_ctx {
struct module_lifecycle_ctx lc;
bool active;
struct theme_rgb current_theme;
};
static int do_init(void);
static int do_start(void);
static int do_stop(void);
static const struct module_lifecycle_cfg lifecycle_cfg = {
.mode = ML_MODE_POWER,
.stopped_state = MODULE_STATE_STANDBY,
};
static const struct module_lifecycle_ops lifecycle_ops = {
.do_init = do_init,
.do_start = do_start,
.do_stop = do_stop,
};
static struct settings_module_ctx ctx = {
.lc = {
.state = LC_UNINIT,
.cfg = &lifecycle_cfg,
.ops = &lifecycle_ops,
},
};
static void settings_exit(void)
{
if (!ctx.active) {
return;
}
ctx.active = false;
ui_settings_controller_close();
submit_settings_mode_event(false);
}
static void settings_enter(void)
{
if (ctx.active) {
return;
}
ctx.active = true;
submit_settings_mode_event(true);
ui_settings_controller_open();
}
static int do_init(void)
{
ctx.active = false;
ctx.current_theme = (struct theme_rgb) {
.r = BLINKY_THEME_DEFAULT_R,
.g = BLINKY_THEME_DEFAULT_G,
.b = BLINKY_THEME_DEFAULT_B,
};
ui_settings_theme_set_current(ctx.current_theme);
return 0;
}
static int do_start(void)
{
return 0;
}
static int do_stop(void)
{
settings_exit();
return 0;
}
static bool handle_click_event(const struct click_event *event)
{
if (!module_lifecycle_is_running(&ctx.lc) ||
(event->key_id != SETTINGS_MUTE_KEY_ID)) {
return false;
}
if (!ctx.active) {
if (event->click == CLICK_LONG) {
settings_enter();
}
return false;
}
switch (event->click) {
case CLICK_SHORT:
ui_settings_controller_select();
break;
case CLICK_LONG:
{
bool active = ui_settings_controller_back();
if (!active) {
settings_exit();
}
}
break;
default:
break;
}
return false;
}
static bool handle_encoder_event(const struct encoder_event *event)
{
if (!module_lifecycle_is_running(&ctx.lc) || !ctx.active) {
return false;
}
ui_settings_controller_move(event->detents);
return false;
}
static bool handle_theme_rgb_update_event(
const struct theme_rgb_update_event *event)
{
ctx.current_theme = event->theme;
ui_settings_theme_set_current(event->theme);
if (ctx.active) {
ui_settings_controller_refresh(false);
}
return false;
}
static bool handle_ble_bond_multi_event(
const struct ble_bond_multi_event *event)
{
ui_settings_ble_set_current_slot(event->current_slot);
for (uint8_t i = 0U; i < ARRAY_SIZE(event->slots); i++) {
ui_settings_ble_set_slot_meta(i + 1U, &event->slots[i]);
}
if (ctx.active) {
ui_settings_controller_refresh(false);
}
return false;
}
static bool app_event_handler(const struct app_event_header *aeh)
{
if (is_click_event(aeh)) {
return handle_click_event(cast_click_event(aeh));
}
if (is_encoder_event(aeh)) {
return handle_encoder_event(cast_encoder_event(aeh));
}
if (is_theme_rgb_update_event(aeh)) {
return handle_theme_rgb_update_event(
cast_theme_rgb_update_event(aeh));
}
if (is_ble_bond_multi_event(aeh)) {
return handle_ble_bond_multi_event(
cast_ble_bond_multi_event(aeh));
}
if (is_module_state_event(aeh)) {
const struct module_state_event *event = cast_module_state_event(aeh);
if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) {
(void)module_set_lifecycle(&ctx.lc, LC_RUNNING);
}
return false;
}
if (is_power_down_event(aeh)) {
if (module_lifecycle_is_initialized(&ctx.lc)) {
(void)module_set_lifecycle(&ctx.lc, LC_STOPPED);
}
return false;
}
if (is_wake_up_event(aeh)) {
if (module_lifecycle_is_initialized(&ctx.lc)) {
(void)module_set_lifecycle(&ctx.lc, LC_RUNNING);
}
return false;
}
return false;
}
APP_EVENT_LISTENER(MODULE, app_event_handler);
APP_EVENT_SUBSCRIBE(MODULE, click_event);
APP_EVENT_SUBSCRIBE(MODULE, encoder_event);
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
APP_EVENT_SUBSCRIBE(MODULE, theme_rgb_update_event);
APP_EVENT_SUBSCRIBE(MODULE, ble_bond_multi_event);
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);