Files
JBao_Heat_Pad_FW/apps/usr_app/app_led.c
T

191 lines
4.7 KiB
C

/******************************************************************************
* @file app_led.c
* @brief 灯效:跟继电器实际态;OTA / 配对优先(规格书第 6 章)
* @author cyWu <1917507415@qq.com>
* @date 2026.09.04
* @version V1.1.0
* @history
* - V1.1.0, 2026.09.04, cyWu, 精简注释
* - V1.0.0, 2026.09.04, cyWu, 首次发布
******************************************************************************/
#include "app_led.h"
#include "led_manager.h"
#include "bsp_hw.h"
#include "board_pin.h"
#include "app_pair.h"
#include "app_relay.h"
#include "system/includes.h"
#define LOG_TAG_CONST APP
#define LOG_TAG "[APP_LED]"
#define LOG_INFO_ENABLE
#include "debug.h"
typedef struct {
uint8_t inited; /**< 1=已初始化 */
uint8_t ota; /**< 1=OTA 灯效中,app_led_run 只跑交替 */
uint8_t pair_hint; /**< 1=长按已满 5s 但还没松手提交配对,维持配对快闪 */
} AppLedCtx_t;
static AppLedCtx_t s_led;
/**
* @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_led.inited) {
return APP_LED_OK;
}
#if BOARD_LED_ENABLE
user_led_init();
s_led.ota = 0;
s_led.pair_hint = 0;
s_led.inited = 1;
#else
log_info("led disabled\n");
#endif
return APP_LED_OK;
}
/**
* @brief 查询模块是否已初始化
* @return APP_LED_OK=已初始化,APP_LED_ERR_NOT_INIT=未初始化
*/
AppLed_Ret_t app_led_get_status(void)
{
return s_led.inited ? APP_LED_OK : APP_LED_ERR_NOT_INIT;
}
/**
* @brief 长按满 5s:绿灯 100ms 快闪提示(红灯灭)
* @return 无
*/
void app_led_hint_pair(void)
{
if (!s_led.inited || s_led.ota) {
return;
}
s_led.pair_hint = 1;
LED_EventAllDelete(); /* 清掉跟继电器灯,避免红绿混色 */
bsp_led_all_off();
LED_EventAdd(LED_EVENT_PAIRING);
}
/**
* @brief 结束"将配网"提示,交回 app_led_run 按 app_pair 状态接管
* @return 无
*/
void app_led_clear_pair_hint(void)
{
s_led.pair_hint = 0;
}
/**
* @brief 进入 OTA:清掉其它灯,挂红绿交替一直闪
* @return 无
*/
void app_led_request_ota(void)
{
if (!s_led.inited) {
return;
}
s_led.ota = 1;
s_led.pair_hint = 0; /* 已改判 OTA,撤销配网提示 */
LED_EventAllDelete();
bsp_led_all_off();
LED_EventAdd(LED_EVENT_OTA);
}
/**
* @brief 查询是否处于 OTA 灯效
* @return 1=OTA 灯效中,0=否
*/
uint8_t app_led_is_ota(void)
{
return s_led.ota;
}
/**
* @brief 按优先级刷新灯(20ms 业务节拍)
* @param dt 距上次调用的毫秒数
* @return 无
*/
void app_led_run(uint16_t dt)
{
AppPairEvt_t pair_evt;
if (!s_led.inited) {
return;
}
#if BOARD_LED_ENABLE
/* OTA 期间只跑红绿交替 */
if (s_led.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_HEAT_ON);
LED_EventDelete(LED_EVENT_HEAT_OFF);
LED_EventDelete(LED_EVENT_PAIRING);
led_restart(LED_EVENT_PAIR_OK);
log_info("led pair ok 3s\n");
} else if (pair_evt == APP_PAIR_EVT_FAIL) {
LED_EventDelete(LED_EVENT_HEAT_ON);
LED_EventDelete(LED_EVENT_HEAT_OFF);
LED_EventDelete(LED_EVENT_PAIRING);
led_restart(LED_EVENT_PAIR_FAIL);
log_info("led pair fail 3s\n");
}
/* 配对提示 / 配对中:维持绿灯快闪(add 幂等,不重置计时) */
if (s_led.pair_hint || app_pair_is_active()) {
if (!LED_IsEventExist(LED_EVENT_PAIR_OK) &&
!LED_IsEventExist(LED_EVENT_PAIR_FAIL)) {
LED_EventAdd(LED_EVENT_PAIRING);
}
} else if (!LED_IsEventExist(LED_EVENT_PAIR_OK) &&
!LED_IsEventExist(LED_EVENT_PAIR_FAIL)) {
/* 无高事件:灯跟继电器实际态(过零完成之后) */
if (app_relay_get_actual()) {
LED_EventAdd(LED_EVENT_HEAT_ON);
} else {
LED_EventAdd(LED_EVENT_HEAT_OFF);
}
}
user_led_handle();
#endif
}
/**
* @brief 清空全部灯事件并灭灯
* @return 无
*/
void app_led_clear(void)
{
#if BOARD_LED_ENABLE
LED_EventAllDelete();
bsp_led_all_off();
#endif
}