/****************************************************************************** * @file app_led.c * @brief CBR3 灯效适配:单灯 PC2,OTA/配对/常亮 * @author cyWu <1917507415@qq.com> * @date 2026.08.31 * @version V1.1.0,新增 s_pair_hint:长按满 5s 到松手提交配对这段窗口内维持 * 配对快闪,避免被 app_led_run 叠上开机常亮 ******************************************************************************/ #include "app_led.h" #include "led_manager.h" #include "bsp_hw.h" #include "board_pin.h" #include "app_pair.h" static uint8_t s_initialized; static uint8_t s_ota; /* 1=OTA 灯效中,app_led_run 不再叠其它灯 */ static uint8_t s_pair_hint; /* 1=长按已满 5s 但还没松手提交配对,维持配对快闪 */ /** * @brief 重新播放一次「一次性/限时」灯效,让它从第 0 帧重新开始 * @note 先 Delete 清空槽位再 Add,强制重新计时(见 led.c LED_EventAdd 语义) * @param evt 要重启的事件 * @return 无 */ static void led_restart(LED_Event_t evt) { LED_EventDelete(evt); LED_EventAdd(evt); } /** * @brief 灯效初始化 * @return APP_LED_OK=成功 */ AppLed_Ret_t app_led_init(void) { if (s_initialized) { return APP_LED_OK; } user_led_init(); 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_hint_power_on(void) { if (!s_initialized || s_ota) { return; } led_restart(LED_EVENT_STANDBY); } /** * @brief 长按满 5s:挂配对快闪,提示"松手即配网,继续按到 12s 进 OTA" * @return 无 */ void app_led_hint_pair(void) { if (!s_initialized || s_ota) { return; } s_pair_hint = 1; LED_EventAllDelete(); bsp_led_set(0); LED_EventAdd(LED_EVENT_PAIRING); } /** * @brief 结束"将配网"提示,交回 app_led_run 按 app_pair 状态接管 * @return 无 */ void app_led_clear_pair_hint(void) { s_pair_hint = 0; } /** * @brief 进入 OTA:清掉其它灯,挂 200ms 闪一直闪 * @return 无 */ void app_led_request_ota(void) { if (!s_initialized) { return; } s_ota = 1; s_pair_hint = 0; /* 已改判 OTA,撤销配网提示 */ LED_EventAllDelete(); bsp_led_set(0); LED_EventAdd(LED_EVENT_OTA); } /** * @brief 查询是否处于 OTA 灯效 * @return 1=OTA 灯效中,0=否 */ uint8_t app_led_is_ota(void) { return s_ota; } /** * @brief 按优先级刷新灯 * @param dt 距上次调用的毫秒数 * @param power_on 1=开机态(挂常亮),0=关机态(灯灭) * @return 无 */ void app_led_run(uint16_t dt, uint8_t power_on) { AppPairEvt_t pair_evt; if (!s_initialized) { return; } /* OTA 期间只跑 200ms 闪 */ if (s_ota) { LED_EventAdd(LED_EVENT_OTA); user_led_handle(); return; } /* 配对成功/失败是边沿事件,只在那一拍切灯效 */ pair_evt = app_pair_tick_1ms(dt); if (pair_evt == APP_PAIR_EVT_OK) { LED_EventDelete(LED_EVENT_PAIRING); led_restart(LED_EVENT_PAIR_OK); } else if (pair_evt == APP_PAIR_EVT_FAIL) { LED_EventDelete(LED_EVENT_PAIRING); led_restart(LED_EVENT_PAIR_FAIL); } if (!power_on) { LED_EventDelete(LED_EVENT_STANDBY); LED_EventDelete(LED_EVENT_PAIRING); } else if (s_pair_hint || app_pair_is_active()) { LED_EventAdd(LED_EVENT_PAIRING); LED_EventDelete(LED_EVENT_STANDBY); } else if (!LED_IsEventExist(LED_EVENT_PAIR_OK) && !LED_IsEventExist(LED_EVENT_PAIR_FAIL)) { LED_EventAdd(LED_EVENT_STANDBY); } user_led_handle(); } /** * @brief 清空全部灯事件并灭灯 * @return 无 */ void app_led_clear(void) { LED_EventAllDelete(); bsp_led_set(0); }