/****************************************************************************** * @file app_function.c * @brief 功能总装:短按切灯、任务上下文落地配对/OTA * @author cyWu <1917507415@qq.com> * @date 2026.09.04 * @version V1.2.0 * @history * - V1.2.0, 2026.09.08, cyWu, 灯罩适配:出厂复位顺带复位寿命、定时 11B * - V1.1.0, 2026.09.04, cyWu, 精简注释 * - V1.0.0, 2026.09.04, cyWu, 首次发布 ******************************************************************************/ #include "system/includes.h" /* 必须先于 app_main.h:u8/u16/u32 等类型由 SDK 定义 */ #include "app_function.h" #include "app_pair.h" #include "app_relay.h" #include "app_zc.h" #include "app_arbiter.h" #include "app_nvm.h" #include "app_linkage.h" #include "app_timer_task.h" #include "app_runrec.h" #include "app_defer.h" #include "app_led.h" #include "app_light_life.h" #include "app_main.h" #include "usr_le_api.h" #include "jb_product.h" #include "board_pin.h" #include #define LOG_TAG_CONST APP #define LOG_TAG "[APP_FUNC]" #define LOG_INFO_ENABLE #include "debug.h" /** * @brief 初始化功能模块 * @return 无 */ void app_function_init(void) { } /** * @brief 任务上下文周期处理(配对 / OTA / 写 VM 只准在此落地) * @return 无 */ void app_function_loop(void) { uint8_t zc_evt = app_zc_consume_timeout(); if (zc_evt == 1) { log_info("zc timeout 100ms: open request dropped, stay off, fault=2\n"); } else if (zc_evt == 2) { log_info("zc timeout 100ms: force relay off, fault=2\n"); } app_nvm_flush(); if (app_defer_take(APP_DEFER_OTA)) { app_defer_cancel(APP_DEFER_PAIR); usr_app_ota_init(); app_led_request_ota(); log_info("key hold 12s -> ota\n"); } else if (app_defer_take(APP_DEFER_PAIR)) { usr_goto_pair_mode(); app_pair_start(); app_led_clear_pair_hint(); log_info("key hold 5s -> pair\n"); } } /** * @brief 同步 DP0 = 继电器实际态 * @return 无 */ void app_function_poll(void) { gDevData.heat_switch = app_relay_get_actual(); } /** * @brief 短按切换灯泡请求(OTA 中忽略) * @return 无 */ void usr_on_key_short(void) { uint8_t req; if (app_led_is_ota()) { return; } app_arbiter_manual_intervene(); req = app_relay_get_request() ? 0 : 1; app_relay_request(req); log_info("key short light request=%d\n", req); } /** * @brief 按住满 5s:配对提示灯(ISR 只动 RAM) * @return 无 */ void usr_on_key_pair_hint(void) { if (app_led_is_ota()) { return; } app_led_hint_pair(); log_info("key hold 5s, pair hint (release to pair, keep to 12s for ota)\n"); } /** * @brief 按满 5s 后松手:置配对标志(写 VM 在 loop) * @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 标志(BLE 切换在 loop) * @return 无 */ void usr_on_key_ota_start(void) { if (app_led_is_ota()) { return; } app_defer_request(APP_DEFER_OTA); log_info("key hold 12s, ota pending\n"); } /** * @brief 出厂重置:清业务 VM/RAM,保留 BLE 配对(规格书 14 章) * @note VM 由 app_nvm_reset 全清(含 4 个 item);RAM 清灯泡请求、 * 联动 20B、定时 7 组(11B)、31 天运行记录与各使能;剩余寿命回额定 * 2,592,000、告警清 0(app_light_life_reset 立刻写回 VM)。 * 不断开、不软复位。 * @return 无 */ void app_function_factory_reset(void) { uint8_t i; 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_relay_request(0); app_arbiter_init(); app_linkage_init(); app_timer_init(); app_runrec_reset(); app_light_life_reset(); /* 寿命回额定 + 告警 0 + 立刻落盘(14 章/13.2 边沿) */ gDevData.heat_switch = 0; gDevData.factory_reset = 0; gDevData.linkage_delete = 0; gDevData.time_en = 0; gDevData.fault_en = 0; gDevData.alarm_en = 0; gDevData.fault_code = 0; gDevData.alarm_code = 0; memset(gDevData.linkage_config, 0, BOARD_LINKAGE_CFG_LEN); memset(gDevData.run_record, 0, sizeof(gDevData.run_record)); for (i = 0; i < 7; i++) { memset(tm[i], 0, BOARD_TIME_CFG_LEN); } log_info("factory reset: business vm cleared, pairing kept\n"); }