/****************************************************************************** * @file app_led.c * @brief CBC2 灯效:充电 > 配对 > APP 暂停 > 低电 > 切模式闪 > 开机绿灯提示后灭 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V1.1.0 * @history * - V1.0.0, 2026.08.21, cyWu, 首次发布 * - V1.1.0, 2026.08.25, cyWu, 开机绿灯只提示几秒,避免待机常亮耗电 ******************************************************************************/ #include "app_led.h" #include "bsp_hw.h" #include "board_pin.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 则待机灭灯 */ /** * @brief 灯效初始化,先全灭 * @return APP_LED_OK=成功 */ 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; s_initialized = 1; return APP_LED_OK; } /** * @brief 查询模块是否已初始化 * @return APP_LED_OK=已初始化,APP_LED_ERR_NOT_INIT=未初始化 */ AppLed_Ret_t app_led_get_status(void) { return s_initialized ? APP_LED_OK : APP_LED_ERR_NOT_INIT; } /** * @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; } /** * @brief 重新亮几秒开机绿灯(上电 / APP 再开) * @return 无 */ void app_led_hint_power_on(void) { s_power_green_ms = BOARD_LED_POWER_ON_MS; } /** * @brief 播放一次性配对结果灯:成功常绿,失败红绿交替 * @param ok 1=成功,0=失败 * @return 无 */ void app_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; } /** * @brief 按优先级刷新灯 * @param ctx 当前充电/配对/开关/低电;为空则直接返回 * @param dt 距上次调用的毫秒数 * @return 无 */ void app_led_tick_1ms(const AppLedCtx_t *ctx, uint16_t dt) { uint8_t red = 0; uint8_t green = 0; if (!s_initialized || !ctx) { return; } if (dt == 0) { dt = 1; } 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); 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; } /* 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; } /* 5 APP 暂停:功能灯灭 */ if (ctx->life_on && ctx->app_power == 0) { bsp_led_all_off(); return; } /* 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; } /* 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 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); } else { s_power_green_ms = 0; } bsp_led_red_set(0); bsp_led_green_set(1); return; } #endif bsp_led_all_off(); }