优化程序架构
This commit is contained in:
+134
-125
@@ -1,29 +1,65 @@
|
||||
/******************************************************************************
|
||||
* @file app_led.c
|
||||
* @brief CBC2 灯效:充电 > 配对 > APP 暂停 > 低电 > 切模式闪 > 开机绿灯提示后灭
|
||||
* @brief CBC2 灯效适配:充电红与待机绿可同时亮,不再 if-else 互斥
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.25
|
||||
* @version V1.1.0
|
||||
* @version V2.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.21, cyWu, 首次发布
|
||||
* - V1.1.0, 2026.08.25, cyWu, 开机绿灯只提示几秒,避免待机常亮耗电
|
||||
* - V1.1.0, 2026.08.25, cyWu, 开机绿灯只提示几秒
|
||||
* - V2.0.0, 2026.08.25, cyWu, 改用充电板 LED 事件表,红绿通道独立
|
||||
* - V2.1.0, 2026.08.25, cyWu, 自己从 app_power/app_pair 取数并内部组装
|
||||
* - V2.2.0, 2026.08.25, cyWu, 重启/清场逻辑各提一个小函数,把意图写进注释
|
||||
******************************************************************************/
|
||||
|
||||
#include "app_led.h"
|
||||
#include "led_manager.h"
|
||||
#include "bsp_hw.h"
|
||||
#include "board_pin.h"
|
||||
#include "app_power.h"
|
||||
#include "app_pair.h"
|
||||
|
||||
static uint8_t s_initialized;
|
||||
static uint16_t s_phase_ms;
|
||||
static uint8_t s_mode_left;
|
||||
static uint16_t s_mode_ms;
|
||||
static uint8_t s_mode_on;
|
||||
static uint16_t s_pair_res_ms;
|
||||
static uint8_t s_pair_res; /* 0 none 1 ok 2 fail */
|
||||
static uint16_t s_power_green_ms; /* 开机绿灯剩余 ms,0 则待机灭灯 */
|
||||
|
||||
static void led_start_pair_result(uint8_t ok);
|
||||
|
||||
/**
|
||||
* @brief 灯效初始化,先全灭
|
||||
* @brief 重新播放一次「一次性/限时」灯效,让它从第 0 帧重新开始
|
||||
* @note led.c 的 LED_EventAdd 只有在“该优先级槽位当前不是这个事件”时才会把
|
||||
* currentTime 重置为现在;如果动画正播到一半直接再 Add 一次,事件已经
|
||||
* 占着槽位,不会重置,会接着上次的进度走。所以要先 Delete 清空槽位,
|
||||
* 再 Add 才能强制重新计时——这不是多余代码,是“重启”这个事件的手段。
|
||||
* @param evt 要重启的事件(切模式闪、开机绿灯提示、配对结果)
|
||||
* @return 无
|
||||
*/
|
||||
static void led_restart(LED_Event_t evt)
|
||||
{
|
||||
LED_EventDelete(evt);
|
||||
LED_EventAdd(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绿灯正被切模式/配对结果占用(不含配对快闪本身)
|
||||
* @return 1=绿灯忙
|
||||
*/
|
||||
static uint8_t green_pattern_busy(void)
|
||||
{
|
||||
return (uint8_t)(LED_IsEventExist(LED_EVENT_MODE)
|
||||
|| LED_IsEventExist(LED_EVENT_PAIR_OK)
|
||||
|| LED_IsEventExist(LED_EVENT_PAIR_FAIL));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绿灯正被配对/切模式/结果占用时,不要再挂待机绿
|
||||
* @return 1=绿灯忙
|
||||
*/
|
||||
static uint8_t green_busy(void)
|
||||
{
|
||||
return (uint8_t)(LED_IsEventExist(LED_EVENT_PAIRING) || green_pattern_busy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 灯效初始化
|
||||
* @return APP_LED_OK=成功
|
||||
*/
|
||||
AppLed_Ret_t app_led_init(void)
|
||||
@@ -31,8 +67,7 @@ AppLed_Ret_t app_led_init(void)
|
||||
if (s_initialized) {
|
||||
return APP_LED_OK;
|
||||
}
|
||||
bsp_led_all_off();
|
||||
s_power_green_ms = BOARD_LED_POWER_ON_MS;
|
||||
user_led_init();
|
||||
s_initialized = 1;
|
||||
return APP_LED_OK;
|
||||
}
|
||||
@@ -47,160 +82,134 @@ AppLed_Ret_t app_led_get_status(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 请求切模式绿灯闪两下
|
||||
* @brief 请求切模式绿灯闪两下(与配对灯同优先级,会盖住配对闪)
|
||||
* @return 无
|
||||
*/
|
||||
void app_led_request_mode_blink(void)
|
||||
{
|
||||
s_mode_left = BOARD_LED_MODE_BLINK_N;
|
||||
s_mode_ms = 0;
|
||||
s_mode_on = 0;
|
||||
if (!s_initialized) {
|
||||
return;
|
||||
}
|
||||
led_restart(LED_EVENT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 重新亮几秒开机绿灯(上电 / APP 再开)
|
||||
* @brief 重新挂待机绿灯(常亮或提示几秒,看 BOARD_LED_STANDBY_ON)
|
||||
* @return 无
|
||||
*/
|
||||
void app_led_hint_power_on(void)
|
||||
{
|
||||
s_power_green_ms = BOARD_LED_POWER_ON_MS;
|
||||
if (!s_initialized) {
|
||||
return;
|
||||
}
|
||||
led_restart(LED_EVENT_STANDBY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 播放一次性配对结果灯:成功常绿,失败红绿交替
|
||||
* @param ok 1=成功,0=失败
|
||||
* @brief 播放一次性配对结果灯
|
||||
* @param ok 1=成功常绿,0=失败红绿交替
|
||||
* @return 无
|
||||
*/
|
||||
void app_led_start_pair_result(uint8_t ok)
|
||||
static void led_start_pair_result(uint8_t ok)
|
||||
{
|
||||
s_pair_res = ok ? 1 : 2;
|
||||
s_pair_res_ms = ok ? BOARD_LED_PAIR_OK_MS : BOARD_LED_PAIR_FAIL_MS;
|
||||
s_phase_ms = 0;
|
||||
LED_EventDelete(LED_EVENT_PAIRING);
|
||||
led_restart(ok ? LED_EVENT_PAIR_OK : LED_EVENT_PAIR_FAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按优先级刷新灯
|
||||
* @param ctx 当前充电/配对/开关/低电;为空则直接返回
|
||||
* @param dt 距上次调用的毫秒数
|
||||
* @brief 功能关闭(DP0=0)时清掉所有“功能相关”的灯事件
|
||||
* @note 故意不用 LED_EventAllDelete():那会把优先级表全清空,连充电红/满灯
|
||||
* (LED_EVENT_CHARGE / LED_EVENT_CHARGE_FULL)也会跟着灭掉。但充电状态
|
||||
* 和 DP0 开关是两码事——设备功能关着也可能正在充电,充电灯必须继续亮,
|
||||
* 所以这里只挑功能相关的几个事件逐个删,充电事件不动它。
|
||||
* @return 无
|
||||
*/
|
||||
void app_led_tick_1ms(const AppLedCtx_t *ctx, uint16_t dt)
|
||||
static void led_clear_function_events(void)
|
||||
{
|
||||
uint8_t red = 0;
|
||||
uint8_t green = 0;
|
||||
LED_EventDelete(LED_EVENT_STANDBY);
|
||||
LED_EventDelete(LED_EVENT_PAIRING);
|
||||
LED_EventDelete(LED_EVENT_MODE);
|
||||
LED_EventDelete(LED_EVENT_PAIR_OK);
|
||||
LED_EventDelete(LED_EVENT_PAIR_FAIL);
|
||||
LED_EventDelete(LED_EVENT_LOWBAT);
|
||||
}
|
||||
|
||||
if (!s_initialized || !ctx) {
|
||||
return;
|
||||
}
|
||||
if (dt == 0) {
|
||||
dt = 1;
|
||||
}
|
||||
/**
|
||||
* @brief 按优先级刷新灯:充电/低电从 app_power 取,配对从 app_pair 取,
|
||||
* 只有“功能是否开”这一项由调用方传入
|
||||
* @param dt 距上次调用的毫秒数
|
||||
* @param app_power 1=功能开(DP0),0=功能关,功能灯全灭
|
||||
* @return 无
|
||||
*/
|
||||
void app_led_run(uint16_t dt, uint8_t app_power)
|
||||
{
|
||||
uint8_t charge_led;
|
||||
uint8_t low_bat;
|
||||
uint8_t pairing;
|
||||
uint8_t func_on;
|
||||
AppPairEvt_t pair_evt;
|
||||
|
||||
s_phase_ms = (uint16_t)(s_phase_ms + dt);
|
||||
|
||||
/* 1-2 充电独占 */
|
||||
if (ctx->charge_led == 1) {
|
||||
red = 1;
|
||||
green = 0;
|
||||
bsp_led_red_set(1);
|
||||
bsp_led_green_set(0);
|
||||
return;
|
||||
}
|
||||
if (ctx->charge_led == 2) {
|
||||
bsp_led_red_set(0);
|
||||
bsp_led_green_set(1);
|
||||
if (!s_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 3 配对快闪 */
|
||||
if (ctx->pairing) {
|
||||
uint16_t t = s_phase_ms % (BOARD_LED_FAST_ON_MS + BOARD_LED_FAST_OFF_MS);
|
||||
green = (t < BOARD_LED_FAST_ON_MS) ? 1 : 0;
|
||||
bsp_led_red_set(0);
|
||||
bsp_led_green_set(green);
|
||||
return;
|
||||
pair_evt = app_pair_tick_1ms(dt);
|
||||
if (pair_evt == APP_PAIR_EVT_OK) {
|
||||
led_start_pair_result(1);
|
||||
} else if (pair_evt == APP_PAIR_EVT_FAIL) {
|
||||
led_start_pair_result(0);
|
||||
}
|
||||
|
||||
/* 4 配对结果一次性 */
|
||||
if (s_pair_res && s_pair_res_ms) {
|
||||
if (s_pair_res == 1) {
|
||||
green = 1;
|
||||
} else {
|
||||
uint16_t t = s_phase_ms % (BOARD_LED_ALT_MS * 2);
|
||||
if (t < BOARD_LED_ALT_MS) {
|
||||
red = 1;
|
||||
} else {
|
||||
green = 1;
|
||||
}
|
||||
}
|
||||
if (s_pair_res_ms > dt) {
|
||||
s_pair_res_ms = (uint16_t)(s_pair_res_ms - dt);
|
||||
} else {
|
||||
s_pair_res_ms = 0;
|
||||
s_pair_res = 0;
|
||||
}
|
||||
bsp_led_red_set(red);
|
||||
bsp_led_green_set(green);
|
||||
return;
|
||||
charge_led = app_power_charge_led();
|
||||
low_bat = app_power_low_bat();
|
||||
func_on = app_power ? 1 : 0;
|
||||
pairing = (uint8_t)(app_pair_is_active() && func_on);
|
||||
|
||||
if (charge_led == 1) {
|
||||
LED_EventAdd(LED_EVENT_CHARGE);
|
||||
} else {
|
||||
LED_EventDelete(LED_EVENT_CHARGE);
|
||||
}
|
||||
|
||||
/* 5 APP 暂停:功能灯灭 */
|
||||
if (ctx->life_on && ctx->app_power == 0) {
|
||||
bsp_led_all_off();
|
||||
return;
|
||||
if (charge_led == 2) {
|
||||
LED_EventAdd(LED_EVENT_CHARGE_FULL);
|
||||
} else {
|
||||
LED_EventDelete(LED_EVENT_CHARGE_FULL);
|
||||
}
|
||||
|
||||
/* 6 低电 */
|
||||
if (ctx->life_on && ctx->low_bat && ctx->app_power) {
|
||||
uint16_t t = s_phase_ms % BOARD_LED_LOWBAT_PERIOD_MS;
|
||||
red = (t < BOARD_LED_LOWBAT_ON_MS) ? 1 : 0;
|
||||
bsp_led_red_set(red);
|
||||
bsp_led_green_set(0);
|
||||
return;
|
||||
if (pairing && !green_pattern_busy()) {
|
||||
LED_EventAdd(LED_EVENT_PAIRING);
|
||||
} else if (!pairing) {
|
||||
LED_EventDelete(LED_EVENT_PAIRING);
|
||||
}
|
||||
|
||||
/* 7 切模式闪 2 下 */
|
||||
if (s_mode_left) {
|
||||
s_mode_ms = (uint16_t)(s_mode_ms + dt);
|
||||
if (!s_mode_on) {
|
||||
if (s_mode_ms >= BOARD_LED_MODE_OFF_MS) {
|
||||
s_mode_ms = 0;
|
||||
s_mode_on = 1;
|
||||
}
|
||||
green = 0;
|
||||
} else {
|
||||
if (s_mode_ms >= BOARD_LED_MODE_ON_MS) {
|
||||
s_mode_ms = 0;
|
||||
s_mode_on = 0;
|
||||
s_mode_left--;
|
||||
}
|
||||
green = 1;
|
||||
}
|
||||
bsp_led_red_set(0);
|
||||
bsp_led_green_set(green);
|
||||
return;
|
||||
if (func_on && low_bat && (charge_led == 0)) {
|
||||
LED_EventAdd(LED_EVENT_LOWBAT);
|
||||
} else {
|
||||
LED_EventDelete(LED_EVENT_LOWBAT);
|
||||
}
|
||||
|
||||
if (!func_on) {
|
||||
led_clear_function_events();
|
||||
} else {
|
||||
#if BOARD_LED_STANDBY_ON
|
||||
/* 待机绿灯常亮 */
|
||||
if (ctx->life_on && ctx->app_power) {
|
||||
bsp_led_red_set(0);
|
||||
bsp_led_green_set(1);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
/* 开机绿灯只亮几秒,用来对比灭灯待机电流 */
|
||||
if (ctx->life_on && ctx->app_power && s_power_green_ms) {
|
||||
if (s_power_green_ms > dt) {
|
||||
s_power_green_ms = (uint16_t)(s_power_green_ms - dt);
|
||||
if ((charge_led != 2) && !pairing && !green_busy()) {
|
||||
LED_EventAdd(LED_EVENT_STANDBY);
|
||||
} else {
|
||||
s_power_green_ms = 0;
|
||||
LED_EventDelete(LED_EVENT_STANDBY);
|
||||
}
|
||||
bsp_led_red_set(0);
|
||||
bsp_led_green_set(1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
user_led_handle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 清空全部灯事件并灭灯
|
||||
* @return 无
|
||||
*/
|
||||
void app_led_clear(void)
|
||||
{
|
||||
LED_EventAllDelete();
|
||||
bsp_led_all_off();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user