Files
JBao_Heat_Pad_FW/apps/usr_app/app_relay.c
T

157 lines
4.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/******************************************************************************
* @file app_relay.c
* @brief 继电器:请求等过零执行;超时则关强断、开放弃
* @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 "system/includes.h"
#include "app_relay.h"
#include "bsp_hw.h"
#include "board_pin.h"
#include "jb_product.h"
#define LOG_TAG_CONST APP
#define LOG_TAG "[RELAY]"
#define LOG_INFO_ENABLE
#include "debug.h"
typedef struct {
uint8_t request; /**< 上层意图:0=关 1=开 */
uint8_t actual; /**< 过零后的 GPIO 真值 */
} AppRelayCtx_t;
static AppRelayCtx_t s_relay;
/**
* @brief 写继电器 GPIO 并更新 actual(过零 ISR / 超时路径)
* @param on 1=吸合 0=断开
* @return 无
*/
static void relay_apply(uint8_t on)
{
bsp_relay_set(on);
s_relay.actual = on;
}
/**
* @brief 初始化继电器:GPIO 上电默认关;P0 无 VM,请求=实际=关
* @return 无
*/
void app_relay_init(void)
{
s_relay.request = 0;
s_relay.actual = 0;
bsp_relay_set(0);
log_info("relay init, request=off actual=off\n");
}
/**
* @brief 请求加热开/关(手动/APP 写 DP0/定时/联动统一入口)
* @param on 1=开 0=关
* @return 无
*/
void app_relay_request(uint8_t on)
{
on = on ? 1 : 0;
if (on == s_relay.request) {
return; /* 意图没变:不重复发起(避免连续同向请求反复计超时) */
}
s_relay.request = on;
#if BOARD_ZC_ENABLE
if (on == s_relay.actual) {
/* 例如 PC3 已因超时强关(actual=0),收到关请求:无需等沿,直接同步 */
log_info("request %s but actual already %d, sync\n", on ? "ON" : "OFF",
s_relay.actual);
return;
}
log_info("request %s, wait zc edge\n", on ? "ON" : "OFF");
/* 等 app_zc_poll 计数 / bsp_zc 沿回调执行 */
#else
/* 无过零(调试):开不吸合,关立即强断(规格书 7.2 / 4 章) */
if (on) {
gDevData.fault_code = 2;
log_info("zc disabled: open request rejected, stay off\n");
s_relay.request = 0; /* 放弃开请求,回落到实际(不吸合) */
} else {
log_info("zc disabled: force relay off\n");
relay_apply(0);
}
#endif
}
/**
* @brief 过零沿:有 pending 则切 GPIO
* @note FPIN ISR 上下文,禁止 printf / 写 VM / 切 BLE
* @return 无
*/
void app_relay_zc_edge(void)
{
if (s_relay.request == s_relay.actual) {
return; /* 无 pending,仅记录过零(由 app_zc 管超时) */
}
relay_apply(s_relay.request);
/* 7.2:下一次成功过零切变后清设备故障(RAM 写,ISR 安全) */
gDevData.fault_code = 0;
}
/**
* @brief 过零超时:关则强断,开则放弃并保持关,fault_code=2
* @note 20ms 节拍调用;与 FPIN ISR 抢状态,关中断后复检
* @return 无
*/
void app_relay_zc_timeout(void)
{
local_irq_disable();
if (s_relay.request == s_relay.actual) {
local_irq_enable();
return;
}
gDevData.fault_code = 2;
if (s_relay.request) {
/* 开请求超时:禁止无过零吸合,放弃本次开请求,保持关 */
s_relay.request = 0;
s_relay.actual = 0;
bsp_relay_set(0);
} else {
/* 关请求超时:强制断开(安全路径,规格书 7.2) */
bsp_relay_set(0);
s_relay.actual = 0;
}
local_irq_enable();
}
/**
* @brief 当前请求态
* @return 1=请求开,0=请求关
*/
uint8_t app_relay_get_request(void)
{
return s_relay.request;
}
/**
* @brief 当前实际吸合态
* @return 1=已吸合,0=已断开
*/
uint8_t app_relay_get_actual(void)
{
return s_relay.actual;
}
/**
* @brief 是否已同步(无 pending
* @return 1=request==actual
*/
uint8_t app_relay_synced(void)
{
return (s_relay.request == s_relay.actual) ? 1 : 0;
}