Files
JBao_Temp_Humi_Fan_FW/apps/usr_app/app_function.c
T
wuchuyuan e324ebd99b 精简 usr_app 架构:去掉关机/休眠死代码,按键复用 key.c 状态机,ISR 重活统一延后到任务上下文
Type-C 长供电、上电即工作、无软关机,删除 app_boot/app_power 及 DP0 开关相关逻辑,
去掉空占位 app_fan_run 和无效的 usr_timer_pick_mode/rearm(数码管 4ms 扫描已 priority=1,
系统本来就不会进低功耗)。按键 5s 配对 / 12s OTA 改走 key.c 长按分级,去掉自计时与 1~5s 死区。
新增 app_defer,NVM/配对/OTA 只在 ISR 置位、在 500ms 任务上下文落地,避免再在 usr_timer 里写 flash。
规格书与注释同步精简。
2026-08-31 17:57:52 +08:00

198 lines
7.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_function.c
* @brief CBR3 功能总装实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.31
* @version V2.2.0,上电即开机:短按切档;长按分级满 5s 提示→松手提交配对、
* 满 12s 到点进 OTA;配对/OTA 的实质动作(清绑定写 VM、
* usr_app_ota_init)统一放 app_function_loop(任务上下文)执行,
* 中断层只置标志;DP0 power 恒为开机态(规格书 0 章第 5 条:预留
* 不当开关),已删除 soft_off/is_power_on 等围绕"可关机"的死代码
******************************************************************************/
#include "system/includes.h" /* 必须先于 app_main.hu8/u16/u32 等类型由 SDK 定义 */
#include "app_function.h"
#include "app_pair.h"
#include "app_mode.h"
#include "app_fan.h"
#include "app_nvm.h"
#include "app_defer.h"
#include "app_arbiter.h"
#include "app_cond.h"
#include "app_timer_task.h"
#include "app_th.h"
#include "app_disp.h"
#include "app_led.h"
#include "app_main.h"
#include "usr_le_api.h"
#include "jb_product.h"
#include <string.h>
#define LOG_TAG_CONST APP
#define LOG_TAG "[APP_FUNC]"
#define LOG_INFO_ENABLE
#include "debug.h"
/**
* @brief 初始化功能模块状态
* @note DP0 power 恒为开机态:规格书 0 章第 5 条"预留,不当开关"
* 协议层 DP0 写入本就忽略(jb_product.c),本产品无软关机,
* 这里写死一次即可,不需要额外状态字段
* @return 无
*/
void app_function_init(void)
{
gDevData.power = 1;
}
/**
* @brief 任务上下文周期处理(由 usr_timer_loop 500ms 调用)
* @note ⚠ 本函数是唯一允许做 VM 落盘、清绑定、OTA 启动的地方:
* usr_timer_loop 跑在 BLE 线程(sys_timer 同步接口,任务上下文,栈充足)。
* 20ms 的 usr_timer_tick 是硬件定时器中断上下文,做这些会栈溢出复位。
* @return 无
*/
void app_function_loop(void)
{
app_nvm_flush(); /* 防抖满后真正写 VMsyscfg_write 必须在任务上下文) */
/* OTA 优先于配对:按满 12s 说明用户不是想配网,放弃本次清绑定 */
if (app_defer_take(APP_DEFER_OTA)) {
app_defer_cancel(APP_DEFER_PAIR);
usr_app_ota_init(); /* BLE 侧:置 usr_goto_updata + 1s 定时器切 OTA 广播 */
app_led_request_ota(); /* 200ms 闪,优先级最高 */
log_info("key hold 12s -> ota\n");
} else if (app_defer_take(APP_DEFER_PAIR)) {
/* ⚠ 真正发起配对广播:usr_goto_pair_mode 内部会断连+清绑定(写VM)+重发绑定广播
* 必须在任务上下文调用(写 VM)。仅置 usr_var.usr_goto_pair 标志无效——
* SDK adv 模块只消费 usr_goto_updata,不消费该标志,不会开广播。 */
usr_goto_pair_mode();
app_pair_start(); /* 起 120s 配对会话,灯交由 app_led_run 接管 */
app_led_clear_pair_hint();
log_info("key hold 5s -> pair\n");
}
}
/**
* @brief 同步 DPfan_gear、mode、fault_code),每个业务 tick 调用
* @note DP3/DP4 温湿度在 userHandle500ms)填;DP0 power 不在这里同步,
* 恒为开机态,写死在 app_function_init
* @return 无
*/
void app_function_poll(void)
{
gDevData.fan_gear = app_fan_get_gear(); /* DP2 必须等于当前真实档位 */
gDevData.mode = app_mode_get_active();
/* 规格书 8.2/15:传感器故障优先 2;否则温湿度比较成立报 1 */
if (app_th_is_fault()) {
gDevData.fault_code = 2;
} else if (app_disp_is_alarm()) {
gDevData.fault_code = 1;
} else {
gDevData.fault_code = 0;
}
}
/**
* @brief 短按:风扇档位循环 1→2→3→0→1…(规格书 5.3)
* @note 立刻退出通风/强力改为手动档:用 app_mode_stop() 只清模式、
* 不动档位(若用 set_manual(0) 会恢复模式前快照档,导致通风 1 档
* 短按跳到旧档+1 而非 2 档);配对进行中短按仍可切档
* @return 无
*/
void usr_on_key_short(void)
{
uint8_t g;
app_arbiter_manual_intervene(); /* 手动动作:释放条件/定时占用(12 章) */
app_mode_stop(); /* 退模式(不动档位,下面立刻切循环下一档) */
g = app_fan_get_gear(); /* 当前实际档:手动=手动档;模式中=模式强制档(1/3) */
g = (uint8_t)((g + 1) % 4); /* 1→2→3→0→1 */
app_fan_set_gear(g);
log_info("key short gear=%d\n", g);
}
/**
* @brief 按住满 5s:切配对提示灯,提示"松手即配网,继续按到 12s 进 OTA"
* @note 本回调在 usr_timer 20ms(硬件定时器中断上下文)执行,只准动灯效事件
* (纯 RAM)。清绑定写 VM 在 app_function_loop 做。
* @return 无
*/
void usr_on_key_pair_hint(void)
{
if (app_led_is_ota()) {
return; /* OTA 灯效最高优先级,不打断 */
}
app_led_hint_pair();
log_info("key hold 5s, pair hint (release to pair, keep to 12s for ota)\n");
}
/**
* @brief 按满 5s 后松手:提交配对(只置标志)
* @note ⚠ 本回调在 usr_timer 20ms(硬件定时器中断上下文)执行,只置标志。
* 清绑定(usr_clear_pair_info_noreset 会写 VM)放到任务上下文。
* @return 无
*/
void usr_on_key_pair_start(void)
{
if (app_led_is_ota()) {
return;
}
app_defer_request(APP_DEFER_PAIR);
log_info("key hold 5s released, pair pending\n");
}
/**
* @brief 按住满 12s:进 OTA(只置标志,到点即触发不等松手)
* @note ⚠ 本回调在 usr_timer 20ms(硬件定时器中断上下文)执行,只置标志。
* usr_app_ota_init 涉及 BLE 广播切换,放到任务上下文。
* @return 无
*/
void usr_on_key_ota_start(void)
{
if (app_led_is_ota()) {
return; /* 已在 OTA,不重复发起 */
}
app_defer_request(APP_DEFER_OTA);
log_info("key hold 12s, ota pending\n");
}
/**
* @brief 出厂重置:清业务 VM 与 RAM,保留 BLE 配对(规格书 14 章)
* @return 无
*/
void app_function_factory_reset(void)
{
uint8_t i;
uint8_t *c[7] = {
gDevData.cond_config1, gDevData.cond_config2, gDevData.cond_config3,
gDevData.cond_config4, gDevData.cond_config5, gDevData.cond_config6,
gDevData.cond_config7
};
uint8_t *tm[7] = {
gDevData.time_config1, gDevData.time_config2, gDevData.time_config3,
gDevData.time_config4, gDevData.time_config5, gDevData.time_config6,
gDevData.time_config7
};
app_nvm_reset();
app_arbiter_init();
app_cond_init();
app_timer_init();
app_mode_stop();
app_fan_set_gear(0);
gDevData.mode = 0;
gDevData.fan_gear = 0;
gDevData.cond_en = 0;
gDevData.time_en = 0;
gDevData.fault_en = 0;
gDevData.alarm_en = 0;
gDevData.fault_code = 0;
gDevData.alarm_code = 0;
for (i = 0; i < 7; i++) {
memset(c[i], 0, 7);
memset(tm[i], 0, 8);
}
log_info("factory reset: business vm cleared, pairing kept\n");
}