From 0f1540aac8c74b5ebbd178058bcacc44a40a382d Mon Sep 17 00:00:00 2001 From: "ekko.bao" Date: Fri, 11 Jul 2025 07:59:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E4=BA=9B=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/ws63/user_main/app_main.c | 19 ++-- .../user_main/switch_panel/switch_panel.h | 14 +-- .../switch_panel/switch_panel_config.c | 21 ++--- .../switch_panel/switch_panel_hilink.c | 5 ++ .../switch_panel/switch_panel_keys.c | 3 +- .../switch_panel/switch_panel_main.c | 89 +++++++++++++------ readme.md | 10 +-- 7 files changed, 96 insertions(+), 65 deletions(-) diff --git a/application/ws63/user_main/app_main.c b/application/ws63/user_main/app_main.c index 6aa57e3..abf43b3 100755 --- a/application/ws63/user_main/app_main.c +++ b/application/ws63/user_main/app_main.c @@ -6,9 +6,7 @@ * */ -#include #include "hsf.h" -#include "hfgpio.h" #include "switch_panel.h" #ifdef HF_MCU_OTA #include "mcu_update.h" @@ -22,9 +20,9 @@ const int hf_lpt_262_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]= HFM_NOPIN, //HFGPIO_F_JTAG_TMS HFM_NOPIN, //HFGPIO_F_USBDP HFM_NOPIN, //HFGPIO_F_USBDM - LPT26x_GPIO17, //HFGPIO_F_UART0_TX + HFM_NOPIN, //HFGPIO_F_UART0_TX LPT26x_GPIO17 HFM_NOPIN, //HFGPIO_F_UART0_RTS - LPT26x_GPIO18, //HFGPIO_F_UART0_RX + HFM_NOPIN, //HFGPIO_F_UART0_RX LPT26x_GPIO18 HFM_NOPIN, //HFGPIO_F_UART0_CTS HFM_NOPIN, //HFGPIO_F_SPI_MISO HFM_NOPIN, //HFGPIO_F_SPI_CLK @@ -35,9 +33,9 @@ const int hf_lpt_262_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]= LPT26x_GPIO16, //HFGPIO_F_UART1_RX, HFM_NOPIN, //HFGPIO_F_UART1_CTS, - LPT26x_GPIO2, //HFGPIO_F_NLINK - LPT26x_GPIO10, //HFGPIO_F_NREADY - LPT26x_GPIO5, //HFGPIO_F_NRELOAD + HFM_NOPIN, //HFGPIO_F_NLINK LPT26x_GPIO2 + HFM_NOPIN, //HFGPIO_F_NREADY LPT26x_GPIO10 + HFM_NOPIN, //HFGPIO_F_NRELOAD LPT26x_GPIO5 HFM_NOPIN, //HFGPIO_F_SLEEP_RQ HFM_NOPIN, //HFGPIO_F_SLEEP_ON @@ -50,7 +48,7 @@ const int hf_lpt_262_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]= HFM_NOPIN, //HFGPIO_F_RESERVE4 HFM_NOPIN, //HFGPIO_F_RESERVE5 - HFM_NOPIN, //HFGPIO_F_USER_DEFINE + LPT26x_GPIO10, //HFGPIO_F_USER_DEFINE }; const int hf_lpt_263_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]= @@ -237,11 +235,6 @@ int USER_FUNC user_app_main(void) } switch_panel_main(); // 四开关面板主程序 - // 初始化按键扫描系统 - extern int key_system_init(void); - if(key_system_init() != HF_SUCCESS) { - HF_Debug(DEBUG_WARN,"key system init fail!\r\n"); - } #ifdef HF_MCU_OTA if(hf_mcu_init() != HF_SUCCESS) HF_Debug(DEBUG_WARN,"init mcu ota fail!\r\n"); diff --git a/application/ws63/user_main/switch_panel/switch_panel.h b/application/ws63/user_main/switch_panel/switch_panel.h index 1559b66..989a9a2 100644 --- a/application/ws63/user_main/switch_panel/switch_panel.h +++ b/application/ws63/user_main/switch_panel/switch_panel.h @@ -2,14 +2,13 @@ #define __SWITCH_PANEL_H__ #include "hsf.h" -#include "cmsis_os2.h" #include #include -#include "driver/gpio.h" -#include "driver/pinctrl.h" -#include "driver/timer.h" +#include "gpio.h" +#include "pinctrl.h" +#include "timer.h" #include "platform_core_rom.h" -#include "schedule/osal_task.h" +#include "osal_task.h" #include "hfflash.h" #include "hfuart.h" @@ -38,7 +37,7 @@ //====================== 系统常量定义 ====================== #define SWITCH_COUNT 4 // 开关数量 -#define KEY_DEBOUNCE_MS 50 // 按键防抖时间(毫秒) +#define KEY_DEBOUNCE_MS 30 // 按键防抖时间(毫秒) #define KEY_LONG_PRESS_MS 10000 // 长按时间阈值(毫秒) - 用于进入配网 #define CONFIG_TIMEOUT_MS (10*60*1000) // 配网超时时间(10分钟) #define CONFIG_BLINK_MS (3*60*1000) // 配网前3分钟闪烁时间 @@ -144,6 +143,7 @@ extern osal_task *g_config_task_handle; int switch_panel_main(void); // 硬件控制函数 +int key_system_init(void); int switch_panel_gpio_init(void); void set_switch_output(int switch_id, bool state); void set_led_output(int led_id, led_state_t state); @@ -156,6 +156,8 @@ int save_device_state(void); void reset_device_state(void); void sync_hardware_state(void); void fast_report_switch(int switch_id); +void fast_report_master_switch(void); +void set_device_mode(system_mode_t mode); // 开关控制函数 void update_switch_state(int switch_id, bool state); diff --git a/application/ws63/user_main/switch_panel/switch_panel_config.c b/application/ws63/user_main/switch_panel/switch_panel_config.c index c1e059d..7a26cd0 100644 --- a/application/ws63/user_main/switch_panel/switch_panel_config.c +++ b/application/ws63/user_main/switch_panel/switch_panel_config.c @@ -37,8 +37,7 @@ void enter_config_mode(void) { set_device_mode(MODE_CONFIG); // 记录配网开始时间 - g_config_start_time = hfsys_get_time(); - g_config_blink_start_time = g_config_start_time; + g_config_blink_start_time = hfsys_get_time(); // 面板背光快闪1秒表示进入配网模式 panel_led_blink(); @@ -127,7 +126,7 @@ void exit_config_mode(void) { set_device_mode(MODE_NORMAL); // 重置配网相关变量 - g_key_id = -1; + g_config_key_id = -1; g_config_led_blink_state = false; g_panel_led_blink_state = false; @@ -303,14 +302,6 @@ bool check_factory_test_wifi(void) { // 简化实现:直接返回false,实际应该扫描WiFi热点 // TODO: 实际实现需要调用WiFi扫描接口查找 "ShuorongSelfTest" 热点 - static bool test_triggered = false; - - // 模拟产测触发条件(仅作为演示) - if (!test_triggered && g_device_state.power_on_count > 5) { - test_triggered = true; - return false; // 模拟找到产测热点 - } - return false; // 默认未找到产测热点 } @@ -329,7 +320,13 @@ void config_timeout_timer_callback(uintptr_t data) { // 配网闪烁定时器回调 void config_blink_timer_callback(uintptr_t data) { (void)data; - + uint32_t blink_period = 1000000 / (LED_BLINK_FREQ_HZ * 2); // 半周期(微秒) // 执行闪烁操作 config_led_blink(); + if (g_config_blink_timer) { + uapi_timer_start(g_config_blink_timer, + blink_period, + config_blink_timer_callback, + 0); + } } \ No newline at end of file diff --git a/application/ws63/user_main/switch_panel/switch_panel_hilink.c b/application/ws63/user_main/switch_panel/switch_panel_hilink.c index 8f9aad0..c8fc15c 100644 --- a/application/ws63/user_main/switch_panel/switch_panel_hilink.c +++ b/application/ws63/user_main/switch_panel/switch_panel_hilink.c @@ -6,6 +6,11 @@ #include "cJSON.h" #include "switch_panel.h" +static int handle_get_switch_common(int switch_id, const char* svc_id, + const char* in, unsigned int in_len, + char** out, unsigned int* out_len); +static int handle_put_switch_common(int switch_id, const char* svc_id, + const char* payload, unsigned int len); //====================== HiLink 设备事件处理 ====================== // 处理设备上线事件 diff --git a/application/ws63/user_main/switch_panel/switch_panel_keys.c b/application/ws63/user_main/switch_panel/switch_panel_keys.c index eca6ce6..8e5c18e 100644 --- a/application/ws63/user_main/switch_panel/switch_panel_keys.c +++ b/application/ws63/user_main/switch_panel/switch_panel_keys.c @@ -136,8 +136,7 @@ int key_scan_task(void *arg) { handle_key_press(i); } - e_printf("[KEY] 按键%d 松开 (持续时间: %ums)\r\n", - i + 1, press_duration); + e_printf("[KEY] 按键%d 松开 (持续时间: %ums)\r\n", i + 1, press_duration); } // 启动防抖定时器 diff --git a/application/ws63/user_main/switch_panel/switch_panel_main.c b/application/ws63/user_main/switch_panel/switch_panel_main.c index 8c2bd72..942189d 100644 --- a/application/ws63/user_main/switch_panel/switch_panel_main.c +++ b/application/ws63/user_main/switch_panel/switch_panel_main.c @@ -1,13 +1,25 @@ -#include "switch_panel.h" #include "hilink.h" #include "securec.h" #include "hilink_sal_defines.h" #include "driver/pinctrl.h" #include "driver/gpio.h" #include "platform_core_rom.h" +#include "switch_panel.h" //====================== 全局变量 ====================== -device_state_t g_device_state = {0}; +device_state_t g_device_state = { + .is_first_boot = true, + .is_bound = false, + .master_switch = false, + .panel_led = true, + .mode = MODE_NORMAL, + .switches = { + {.switch_on = false, .led_state = false, .physical_key = true}, + {.switch_on = false, .led_state = false, .physical_key = true}, + {.switch_on = false, .led_state = false, .physical_key = true}, + {.switch_on = false, .led_state = false, .physical_key = true} + } +}; timer_handle_t g_key_debounce_timer[SWITCH_COUNT] = {0}; timer_handle_t g_config_timeout_timer = 0; timer_handle_t g_config_blink_timer = 0; @@ -36,6 +48,7 @@ static uint8_t calculate_checksum(const uint8_t* data, int len) static bool read_device_data_from_addr(uint32_t addr, uint8_t* data, uint32_t len) { int total_size = sizeof(device_data_t) + len; + uint8_t checksum = 0; device_data_t *data_all = malloc(total_size); if (data_all == NULL) { e_printf("内存分配失败\r\n"); @@ -48,7 +61,7 @@ static bool read_device_data_from_addr(uint32_t addr, uint8_t* data, uint32_t le goto lab_err; } - uint8_t checksum = calculate_checksum(data_all->data, data_all->data_len); + checksum = calculate_checksum(data_all->data, data_all->data_len); if (checksum != data_all->checksum) { e_printf("check sum error:%x\n", data_all->version); goto lab_err; @@ -131,9 +144,10 @@ int load_device_state(void) { e_printf("面板背光: %d => %d\r\n", g_device_state.panel_led, state.panel_led); e_printf("工作模式: %d => %d\r\n", g_device_state.mode, state.mode); for (int i = 0; i < SWITCH_COUNT; i++) { - e_printf("开关%d: %d => %d\r\n", i + 1, g_device_state.switches[i].switch_on, state.switches[i].switch_on); - e_printf("LED%d: %d => %d\r\n", i + 1, g_device_state.switches[i].led_state, state.switches[i].led_state); - e_printf("物理按键%d: %d => %d\r\n", i + 1, g_device_state.switches[i].physical_key, state.switches[i].physical_key); + e_printf("开关%d: %d => %d, LED%d: %d => %d, 物理按键%d: %d => %d\r\n", + i + 1, g_device_state.switches[i].switch_on, state.switches[i].switch_on, + i + 1, g_device_state.switches[i].led_state, state.switches[i].led_state, + i + 1, g_device_state.switches[i].physical_key, state.switches[i].physical_key); } memcpy(&g_device_state, &state, sizeof(device_state_t)); @@ -144,9 +158,27 @@ int load_device_state(void) { // 保存设备状态到 Flash int save_device_state(void) { int ret = 0; - device_state_t state; + static device_state_t state = {}; bool valid = false; - + if (state.is_first_boot == g_device_state.is_first_boot && + state.is_bound == g_device_state.is_bound && + state.master_switch == g_device_state.master_switch && + state.panel_led == g_device_state.panel_led && + state.mode == g_device_state.mode) + { + for (int i = 0; i < SWITCH_COUNT; i++) { + if (state.switches[i].switch_on != g_device_state.switches[i].switch_on + || state.switches[i].led_state != g_device_state.switches[i].led_state + || state.switches[i].physical_key != g_device_state.switches[i].physical_key) { + valid = true; + break; + } + } + if (!valid) { + e_printf("[STORAGE] 设备状态未变化,跳过保存\r\n"); + return HF_SUCCESS; + } + } // 准备数据 memcpy(&state, &g_device_state, sizeof(device_state_t)); // 保存到主存储区 @@ -167,13 +199,13 @@ int save_device_state(void) { // 重置设备状态为默认值 void reset_device_state(void) { - memset(&g_device_state, 0, sizeof(device_data_t)); + // memset(&g_device_state, 0, sizeof(device_data_t)); // 设置默认状态 g_device_state.master_switch = false; // 总开关关闭 g_device_state.panel_led = true; // 面板背光开启 g_device_state.is_bound = false; // 设备未绑定 - g_device_state.is_first_boot = true; // 标记为首次启动 + g_device_state.is_first_boot = false; // 标记为非首次启动 g_device_state.mode = MODE_NORMAL; // 正常模式 // 所有开关默认关闭,所有LED默认黄灯 @@ -195,12 +227,6 @@ typedef struct { // GPIO初始化配置表 static const gpio_config_t gpio_configs[] = { - // LED指示灯 - 输出 - {LED1_GPIO, GPIO_DIRECTION_OUTPUT, "LED1"}, - {LED2_GPIO, GPIO_DIRECTION_OUTPUT, "LED2"}, - {LED3_GPIO, GPIO_DIRECTION_OUTPUT, "LED3"}, - {LED4_GPIO, GPIO_DIRECTION_OUTPUT, "LED4"}, - // 开关控制 - 输出 {SWITCH1_GPIO, GPIO_DIRECTION_OUTPUT, "SWITCH1"}, {SWITCH2_GPIO, GPIO_DIRECTION_OUTPUT, "SWITCH2"}, @@ -214,7 +240,14 @@ static const gpio_config_t gpio_configs[] = { {KEY4_GPIO, GPIO_DIRECTION_INPUT, "KEY4"}, // 面板背光 - 输出 - {PANEL_LED_GPIO, GPIO_DIRECTION_OUTPUT, "PANEL_LED"} + {PANEL_LED_GPIO, GPIO_DIRECTION_OUTPUT, "PANEL_LED"}, + + // LED指示灯 - 输出 + {LED1_GPIO, GPIO_DIRECTION_OUTPUT, "LED1"}, + {LED2_GPIO, GPIO_DIRECTION_OUTPUT, "LED2"}, + {LED3_GPIO, GPIO_DIRECTION_OUTPUT, "LED3"}, + // {LED4_GPIO, GPIO_DIRECTION_OUTPUT, "LED4"}, + }; #define GPIO_CONFIG_COUNT (sizeof(gpio_configs) / sizeof(gpio_config_t)) @@ -230,7 +263,7 @@ int switch_panel_gpio_init(void) { // uapi_gpio_init(); // 使用循环配置所有GPIO - for (int i = 0; i < GPIO_CONFIG_COUNT; i++) { + for (uint32_t i = 0; i < GPIO_CONFIG_COUNT; i++) { const gpio_config_t* config = &gpio_configs[i]; // 设置为GPIO模式 @@ -353,27 +386,29 @@ int switch_panel_main(void) { } g_initialized = true; e_printf("[MAIN] 开始初始化SORONTEK智能面板...\r\n"); - - // 初始化GPIO - ret = switch_panel_gpio_init(); - if (ret != HF_SUCCESS) { - e_printf("[MAIN] GPIO初始化失败: %d\r\n", ret); - return ret; - } - + // 加载设备状态 ret = load_device_state(); if (ret != HF_SUCCESS) { e_printf("[MAIN] 加载设备状态失败: %d\r\n", ret); return ret; } - // 检查是否首次启动,如果是则标记为非首次 bool first_boot = g_device_state.is_first_boot; if (g_device_state.is_first_boot) { g_device_state.is_first_boot = false; // 标记为非首次启动 e_printf("[MAIN] 检测到首次启动\r\n"); } + // 初始化GPIO + ret = switch_panel_gpio_init(); + if (ret != HF_SUCCESS) { + e_printf("[MAIN] GPIO初始化失败: %d\r\n", ret); + return ret; + } + if(key_system_init() != HF_SUCCESS) { + e_printf("[MAIN] 按键系统初始化失败: %d\r\n", ret); + return ret; + } // 同步硬件状态 sync_hardware_state(); diff --git a/readme.md b/readme.md index 3baf4d4..e5ea931 100644 --- a/readme.md +++ b/readme.md @@ -83,11 +83,11 @@ LED 是整个控制面板的背光灯,高电平亮灯(黄色),低电平灭 7. 线程相关使用 osal_kthread_xx 头文件定义在-> kernel/osal/include/schedule/osal_task.h ### SORONTEK智能面板产测: -1.由信标发送产测信号 - =》识别固定的热点名作为进入产测的信号 -2.开关循环:开1-开2-开3-开4-全关-全开-全关 -3.每1.5秒执行一个动作 -4. 需要校验WIFI 信号强度吗 +1. 由信标发送产测信号 + =》识别固定的热点名 ShuorongSelfTest 作为进入产测的信号 +2. 开关循环:开1-开2-开3-开4-全关-全开-全关 +3. 每1.5秒执行一个动作 +4. 需要校验WIFI 信号强度 -70 ### SORONTEK智能面板配网: 1. 只有设备处于未绑定状态才能进行配网(出厂或者被APP删除)