claude 生成初步代码
This commit is contained in:
@ -94,6 +94,7 @@ set(PRIVATE_HEADER
|
|||||||
${ROOT_DIR}/protocol/wifi/source/host/inc/liteOS
|
${ROOT_DIR}/protocol/wifi/source/host/inc/liteOS
|
||||||
${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.1.0/harden/src/internal_include
|
${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.1.0/harden/src/internal_include
|
||||||
${ROOT_DIR}/include
|
${ROOT_DIR}/include
|
||||||
|
${ROOT_DIR}/application/ws63/user_main/
|
||||||
)
|
)
|
||||||
|
|
||||||
# use this when you want to add ccflags like -include xxx
|
# use this when you want to add ccflags like -include xxx
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
//static bool g_switch = 0;
|
//static bool g_switch = 0;
|
||||||
int sid_switch;
|
int sid_switch;
|
||||||
static bool g_autoUpdate = 0;
|
static bool g_autoUpdate = 0;
|
||||||
|
static int ble_adv_time = 0;
|
||||||
static HILINK_BT_DevInfo g_btDevInfo = {0};
|
static HILINK_BT_DevInfo g_btDevInfo = {0};
|
||||||
extern int set_get_ble_mac(void);
|
extern int set_get_ble_mac(void);
|
||||||
extern int HILINK_Printf(const char *format, ...);
|
extern int HILINK_Printf(const char *format, ...);
|
||||||
@ -258,6 +258,7 @@ static void ReporFwvCheckSum(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int ble_sdk_running = 0;
|
||||||
static void HILINK_BT_StateChangeHandler(HILINK_BT_SdkStatus event, const void *param)
|
static void HILINK_BT_StateChangeHandler(HILINK_BT_SdkStatus event, const void *param)
|
||||||
{
|
{
|
||||||
(void)param;
|
(void)param;
|
||||||
@ -275,7 +276,8 @@ static void HILINK_BT_StateChangeHandler(HILINK_BT_SdkStatus event, const void *
|
|||||||
BLE_SetAdvType(BLE_ADV_LOCAL_NAME);
|
BLE_SetAdvType(BLE_ADV_LOCAL_NAME);
|
||||||
|
|
||||||
/* BLE配网广播控制:参数代表广播时间,0:停止;0xFFFFFFFF:一直广播,其他:广播指定时间后停止,单位秒 */
|
/* BLE配网广播控制:参数代表广播时间,0:停止;0xFFFFFFFF:一直广播,其他:广播指定时间后停止,单位秒 */
|
||||||
(void)BLE_CfgNetAdvCtrl(BLE_ADV_TIME);
|
(void)BLE_CfgNetAdvCtrl(ble_adv_time);
|
||||||
|
ble_sdk_running = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,12 +432,20 @@ unsigned int GetWifiRecoveryType(void)
|
|||||||
{
|
{
|
||||||
return (0x01 | 0x02);
|
return (0x01 | 0x02);
|
||||||
}
|
}
|
||||||
|
int start_hilink_ble_net_config(int32_t net_cfg_time_s)
|
||||||
|
{
|
||||||
|
ble_adv_time = net_cfg_time_s;
|
||||||
|
if (ble_sdk_running) {
|
||||||
|
e_printf("set ble adv time: %ds\n", ble_adv_time);
|
||||||
|
BLE_CfgNetAdvCtrl(ble_adv_time);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int hilink_ble_main(void)
|
int hilink_ble_main(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
hfdbg_set_level(1);
|
hfset_hilink_mode(SMTLK_BLE_FAST_CONNECT);
|
||||||
hfset_hilink_mode(2);
|
|
||||||
int hilink_entry_mode=hfget_hilink_mode();
|
int hilink_entry_mode=hfget_hilink_mode();
|
||||||
printf("hilink_entry_mode:%d\r\n",hilink_entry_mode);
|
printf("hilink_entry_mode:%d\r\n",hilink_entry_mode);
|
||||||
if(hilink_entry_mode != SMTLK_SOFTAP)
|
if(hilink_entry_mode != SMTLK_SOFTAP)
|
||||||
@ -454,6 +464,7 @@ int hilink_ble_main(void)
|
|||||||
HILINK_EnableSle();
|
HILINK_EnableSle();
|
||||||
HILINK_EnablePrescan();
|
HILINK_EnablePrescan();
|
||||||
HILINK_SetProtType(17);
|
HILINK_SetProtType(17);
|
||||||
|
e_printf("SMTLK_BLE_FAST_CONNECT\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = HILINK_SetNetConfigMode(HILINK_NETCONFIG_OTHER);
|
ret = HILINK_SetNetConfigMode(HILINK_NETCONFIG_OTHER);
|
||||||
@ -482,6 +493,7 @@ int hilink_ble_main(void)
|
|||||||
HILINK_SAL_NOTICE("ble sdk init fail\r\n");
|
HILINK_SAL_NOTICE("ble sdk init fail\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
e_printf("ble sdk init success\r\n");
|
||||||
//set_get_ble_mac();
|
//set_get_ble_mac();
|
||||||
}
|
}
|
||||||
else if(hilink_entry_mode == SMTLK_SOFTAP)
|
else if(hilink_entry_mode == SMTLK_SOFTAP)
|
||||||
@ -528,6 +540,16 @@ int hilink_ble_main(void)
|
|||||||
HILINK_SAL_NOTICE("HILINK_Main start error");
|
HILINK_SAL_NOTICE("HILINK_Main start error");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
e_printf("HILINK_Main start success\r\n");
|
||||||
hf_set_hilink_main_runing();
|
hf_set_hilink_main_runing();
|
||||||
|
// HILINK_RestoreFactorySettings();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE
|
||||||
|
// EKKO remove indie upgrade
|
||||||
|
int hilink_indie_upgrade_main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
@ -17,15 +17,15 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define ProductId "2Q4G"
|
#define ProductId "2Q4S"
|
||||||
#define deviceTypeId "201"
|
#define deviceTypeId "21S"
|
||||||
#define manufacturerID "gub"
|
#define manufacturerID "gub"
|
||||||
#define deviceModel "S15"
|
#define deviceModel "SR-SW-020-10S"
|
||||||
#define configName "SR_S"
|
#define configName "SR_S"
|
||||||
#define configType "witch"
|
#define configType "witch"
|
||||||
#define enterpriseEnglishName "SORONTEK"
|
#define enterpriseEnglishName "SORONTEK"
|
||||||
#define brandEn "SORONTEK"
|
#define brandEn "SORONTEK"
|
||||||
#define deviceName "SORONTEK智能面板"
|
#define deviceName "SORONTEK智能开关面板"
|
||||||
#define productSeries ""
|
#define productSeries ""
|
||||||
|
|
||||||
#define DEVICE_HIVERSION "1.0.0"
|
#define DEVICE_HIVERSION "1.0.0"
|
||||||
|
@ -15,12 +15,20 @@
|
|||||||
#include "hsf.h"
|
#include "hsf.h"
|
||||||
#include "hilink_entry.h"
|
#include "hilink_entry.h"
|
||||||
|
|
||||||
|
extern void handle_device_online(void);
|
||||||
|
extern void handle_device_unbind(void);
|
||||||
|
extern void handle_device_offline(void);
|
||||||
|
|
||||||
|
// 声明外部函数
|
||||||
|
#include "switch_panel/switch_panel.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* 服务信息定义
|
* 服务信息定义
|
||||||
* 注意:(1)适配格式{svcType, svcId}
|
* 注意:(1)适配格式{svcType, svcId}
|
||||||
* (2)与devicepartner平台物模型定义必须保持一致
|
* (2)与devicepartner平台物模型定义必须保持一致
|
||||||
*/
|
*/
|
||||||
|
// 四开关面板服务信息定义
|
||||||
static const HILINK_SvcInfo SVC_INFO[] = {
|
static const HILINK_SvcInfo SVC_INFO[] = {
|
||||||
{ "switch", "switch3" },
|
{ "switch", "switch3" },
|
||||||
{ "switch", "switch2" },
|
{ "switch", "switch2" },
|
||||||
@ -31,6 +39,7 @@ static const HILINK_SvcInfo SVC_INFO[] = {
|
|||||||
// { "checkSum", "checkSum" },
|
// { "checkSum", "checkSum" },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int HILINK_GetDevInfo(HILINK_DevInfo *devinfo)
|
int HILINK_GetDevInfo(HILINK_DevInfo *devinfo)
|
||||||
{
|
{
|
||||||
if (devinfo == NULL) {
|
if (devinfo == NULL) {
|
||||||
@ -126,9 +135,9 @@ int HILINK_GetSvcInfo(HILINK_SvcInfo *svcInfo[], unsigned int size)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
e_printf("HILINK_GetSvcInfo svcNum:%d\r\n", svcNum);
|
||||||
return svcNum;
|
return svcNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AC参数 */
|
/* AC参数 */
|
||||||
unsigned char A_C[48] = {
|
unsigned char A_C[48] = {
|
||||||
0x66, 0x22, 0x33, 0x5F, 0x75, 0x31, 0x29, 0x6A, 0x27, 0x34, 0x57, 0x44, 0x32, 0x42, 0x27, 0x59, 0xE1, \
|
0x66, 0x22, 0x33, 0x5F, 0x75, 0x31, 0x29, 0x6A, 0x27, 0x34, 0x57, 0x44, 0x32, 0x42, 0x27, 0x59, 0xE1, \
|
||||||
@ -145,21 +154,6 @@ unsigned char *HILINK_GetAutoAc(void)
|
|||||||
extern int HILINK_HILINK_Printf(const char *format, ...);
|
extern int HILINK_HILINK_Printf(const char *format, ...);
|
||||||
|
|
||||||
|
|
||||||
// 设备状态定义
|
|
||||||
typedef struct{
|
|
||||||
int switch3_on;
|
|
||||||
int switch3_name;
|
|
||||||
int switch2_on;
|
|
||||||
int switch2_name;
|
|
||||||
int switch1_on;
|
|
||||||
int switch1_name;
|
|
||||||
int switch_on;
|
|
||||||
int switch4_on;
|
|
||||||
int switch4_name;
|
|
||||||
}t_device_info;
|
|
||||||
// 分配一个对象记录设备状态
|
|
||||||
static t_device_info g_device_info = {0};
|
|
||||||
|
|
||||||
// 服务处理函数定义
|
// 服务处理函数定义
|
||||||
typedef int (*handle_put_func)(const char* svc_id, const char* payload, unsigned int len);
|
typedef int (*handle_put_func)(const char* svc_id, const char* payload, unsigned int len);
|
||||||
typedef int (*handle_get_func)(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
typedef int (*handle_get_func)(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
||||||
@ -178,147 +172,12 @@ int not_support_put(const char* svc_id, const char* payload, unsigned int len)
|
|||||||
HILINK_Printf("sid:%s NOT SUPPORT PUT function \r\n", svc_id);
|
HILINK_Printf("sid:%s NOT SUPPORT PUT function \r\n", svc_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// 处理从 HILINK_PutCharState 传递过来的信息
|
// 服务处理函数
|
||||||
int handle_put_switch(const char* svc_id, const char* payload, unsigned int len)
|
|
||||||
{
|
|
||||||
cJSON* pJson = cJSON_Parse(payload);
|
|
||||||
if (pJson == NULL){
|
|
||||||
HILINK_Printf("JSON parse failed in PUT cmd: ID-%s \r\n", svc_id);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
cJSON* item = cJSON_GetObjectItem(pJson, "on");
|
|
||||||
if (item != NULL)
|
|
||||||
g_device_info.switch_on = item->valueint;
|
|
||||||
if (pJson != NULL)
|
|
||||||
cJSON_Delete(pJson);
|
|
||||||
HILINK_Printf("handle func:%s, sid:%s \r\n", __FUNCTION__, svc_id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// 处理从 HILINK_GetCharState 传递过来的信息
|
|
||||||
int handle_get_switch(const char* svc_id, const char* in, unsigned int in_len,char** out, unsigned int* out_len)
|
|
||||||
{
|
|
||||||
*out_len = 20;
|
|
||||||
*out = (char*)malloc(*out_len);
|
|
||||||
if (NULL == *out)
|
|
||||||
return -1;
|
|
||||||
*out_len = sprintf_s(*out, *out_len, "{\"on\":%d}", g_device_info.switch_on);
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, *out:%s\r\n",__FUNCTION__ , __LINE__,svc_id, *out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// 服务处理信息注册
|
|
||||||
|
|
||||||
int handle_put_switch3(const char* svc_id, const char* payload, unsigned int len)
|
|
||||||
{
|
|
||||||
cJSON* pJson = cJSON_Parse(payload);
|
|
||||||
if (!pJson)
|
|
||||||
return -1;
|
|
||||||
cJSON* on_item = cJSON_GetObjectItem(pJson, "on");
|
|
||||||
if (on_item)
|
|
||||||
g_device_info.switch3_on = on_item->valueint;
|
|
||||||
cJSON* name_item = cJSON_GetObjectItem(pJson, "name");
|
|
||||||
if (name_item)
|
|
||||||
g_device_info.switch3_name = name_item->valueint;
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, payload:%s\r\n", __FUNCTION__, __LINE__, svc_id, payload);
|
|
||||||
cJSON_Delete(pJson);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_get_switch3(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
|
||||||
{
|
|
||||||
*out_len = 64;
|
|
||||||
*out = (char*)malloc(*out_len);
|
|
||||||
if (*out == NULL)
|
|
||||||
return -1;
|
|
||||||
*out_len = sprintf_s(*out, *out_len, "{\"on\":%d, \"name\":%d}", g_device_info.switch3_on, g_device_info.switch3_name);
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, *out:%s\r\n", __FUNCTION__, __LINE__, svc_id, *out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_put_switch2(const char* svc_id, const char* payload, unsigned int len)
|
|
||||||
{
|
|
||||||
cJSON* pJson = cJSON_Parse(payload);
|
|
||||||
if (!pJson)
|
|
||||||
return -1;
|
|
||||||
cJSON* on_item = cJSON_GetObjectItem(pJson, "on");
|
|
||||||
if (on_item)
|
|
||||||
g_device_info.switch2_on = on_item->valueint;
|
|
||||||
cJSON* name_item = cJSON_GetObjectItem(pJson, "name");
|
|
||||||
if (name_item)
|
|
||||||
g_device_info.switch2_name = name_item->valueint;
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, payload:%s\r\n", __FUNCTION__, __LINE__, svc_id, payload);
|
|
||||||
cJSON_Delete(pJson);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_get_switch2(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
|
||||||
{
|
|
||||||
*out_len = 64;
|
|
||||||
*out = (char*)malloc(*out_len);
|
|
||||||
if (*out == NULL)
|
|
||||||
return -1;
|
|
||||||
*out_len = sprintf_s(*out, *out_len, "{\"on\":%d, \"name\":%d}", g_device_info.switch2_on, g_device_info.switch2_name);
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, *out:%s\r\n", __FUNCTION__, __LINE__, svc_id, *out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_put_switch1(const char* svc_id, const char* payload, unsigned int len)
|
|
||||||
{
|
|
||||||
cJSON* pJson = cJSON_Parse(payload);
|
|
||||||
if (!pJson)
|
|
||||||
return -1;
|
|
||||||
cJSON* on_item = cJSON_GetObjectItem(pJson, "on");
|
|
||||||
if (on_item)
|
|
||||||
g_device_info.switch1_on = on_item->valueint;
|
|
||||||
cJSON* name_item = cJSON_GetObjectItem(pJson, "name");
|
|
||||||
if (name_item)
|
|
||||||
g_device_info.switch1_name = name_item->valueint;
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, payload:%s\r\n", __FUNCTION__, __LINE__, svc_id, payload);
|
|
||||||
cJSON_Delete(pJson);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_get_switch1(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
|
||||||
{
|
|
||||||
*out_len = 64;
|
|
||||||
*out = (char*)malloc(*out_len);
|
|
||||||
if (*out == NULL)
|
|
||||||
return -1;
|
|
||||||
*out_len = sprintf_s(*out, *out_len, "{\"on\":%d, \"name\":%d}", g_device_info.switch1_on, g_device_info.switch1_name);
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, *out:%s\r\n", __FUNCTION__, __LINE__, svc_id, *out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_put_switch4(const char* svc_id, const char* payload, unsigned int len)
|
|
||||||
{
|
|
||||||
cJSON* pJson = cJSON_Parse(payload);
|
|
||||||
if (!pJson)
|
|
||||||
return -1;
|
|
||||||
cJSON* on_item = cJSON_GetObjectItem(pJson, "on");
|
|
||||||
if (on_item)
|
|
||||||
g_device_info.switch4_on = on_item->valueint;
|
|
||||||
cJSON* name_item = cJSON_GetObjectItem(pJson, "name");
|
|
||||||
if (name_item)
|
|
||||||
g_device_info.switch4_name = name_item->valueint;
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, payload:%s\r\n", __FUNCTION__, __LINE__, svc_id, payload);
|
|
||||||
cJSON_Delete(pJson);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_get_switch4(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
|
||||||
{
|
|
||||||
*out_len = 64;
|
|
||||||
*out = (char*)malloc(*out_len);
|
|
||||||
if (*out == NULL)
|
|
||||||
return -1;
|
|
||||||
*out_len = sprintf_s(*out, *out_len, "{\"on\":%d, \"name\":%d}", g_device_info.switch4_on, g_device_info.switch4_name);
|
|
||||||
HILINK_Printf("%s:%d svcId:%s, *out:%s\r\n", __FUNCTION__, __LINE__, svc_id, *out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
HANDLE_SVC_INFO g_device_profile[] = {
|
HANDLE_SVC_INFO g_device_profile[] = {
|
||||||
{"switch3", handle_put_switch3, handle_get_switch3},
|
|
||||||
{"switch2", handle_put_switch2, handle_get_switch2},
|
|
||||||
{"switch1", handle_put_switch1, handle_get_switch1},
|
|
||||||
{"switch", handle_put_switch, handle_get_switch},
|
{"switch", handle_put_switch, handle_get_switch},
|
||||||
|
{"switch1", handle_put_switch1, handle_get_switch1},
|
||||||
|
{"switch2", handle_put_switch2, handle_get_switch2},
|
||||||
|
{"switch3", handle_put_switch3, handle_get_switch3},
|
||||||
{"switch4", handle_put_switch4, handle_get_switch4},
|
{"switch4", handle_put_switch4, handle_get_switch4},
|
||||||
};
|
};
|
||||||
// 服务总数量
|
// 服务总数量
|
||||||
@ -366,6 +225,7 @@ int handle_get_cmd(const char* svc_id, const char* in, unsigned int in_len, char
|
|||||||
}
|
}
|
||||||
return function(svc_id, in, in_len, out,out_len);
|
return function(svc_id, in, in_len, out,out_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快速上报函数,用于上报服务状态信息
|
// 快速上报函数,用于上报服务状态信息
|
||||||
int fast_report(const char* svc_id)
|
int fast_report(const char* svc_id)
|
||||||
{
|
{
|
||||||
@ -377,7 +237,7 @@ int fast_report(const char* svc_id)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = HILINK_ReportCharState(svc_id, payload, len);
|
err = HILINK_ReportCharState(svc_id, payload, len);
|
||||||
HILINK_Printf("report %s result is %d \r\n", svc_id, err);
|
HILINK_Printf("report %s result is %d, payload:%s \r\n", svc_id, err, payload);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -389,7 +249,10 @@ int fast_report(const char* svc_id)
|
|||||||
*/
|
*/
|
||||||
int HILINK_PutCharState(const char *svcId, const char *payload, unsigned int len)
|
int HILINK_PutCharState(const char *svcId, const char *payload, unsigned int len)
|
||||||
{
|
{
|
||||||
|
e_printf("[HILINK_PutCharState] 收到控制指令: svcId=%s, payload=%s\r\n", svcId, payload);
|
||||||
|
|
||||||
if ((svcId == NULL) || (payload == NULL)) {
|
if ((svcId == NULL) || (payload == NULL)) {
|
||||||
|
e_printf("[HILINK_PutCharState] 参数无效\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +260,10 @@ int HILINK_PutCharState(const char *svcId, const char *payload, unsigned int len
|
|||||||
if (json == NULL) {
|
if (json == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
int err = handle_put_cmd(svcId, payload, len);
|
int err = handle_put_cmd(svcId, payload, len);
|
||||||
|
e_printf("[HILINK_PutCharState] 控制指令处理完成,返回值: %d\r\n", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE
|
#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE
|
||||||
@ -498,6 +364,7 @@ void HILINK_NotifyDevStatus(int status)
|
|||||||
BLE_CfgNetAdvCtrl(0);
|
BLE_CfgNetAdvCtrl(0);
|
||||||
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
|
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
|
||||||
#endif
|
#endif
|
||||||
|
handle_device_offline();
|
||||||
break;
|
break;
|
||||||
case HILINK_M2M_CLOUD_ONLINE:
|
case HILINK_M2M_CLOUD_ONLINE:
|
||||||
/* 设备连接云端成功,请在此处添加实现 */
|
/* 设备连接云端成功,请在此处添加实现 */
|
||||||
@ -506,6 +373,8 @@ void HILINK_NotifyDevStatus(int status)
|
|||||||
BLE_CfgNetAdvCtrl(0);
|
BLE_CfgNetAdvCtrl(0);
|
||||||
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
|
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
|
||||||
#endif
|
#endif
|
||||||
|
/* 设备连接云端成功,请在此处添加实现 */
|
||||||
|
handle_device_online(); // 处理设备上线
|
||||||
break;
|
break;
|
||||||
case HILINK_M2M_LONG_OFFLINE:
|
case HILINK_M2M_LONG_OFFLINE:
|
||||||
/* 设备与云端连接长时间断开,请在此处添加实现 */
|
/* 设备与云端连接长时间断开,请在此处添加实现 */
|
||||||
@ -542,9 +411,11 @@ void HILINK_NotifyDevStatus(int status)
|
|||||||
break;
|
break;
|
||||||
case HILINK_DEVICE_UNREGISTER:
|
case HILINK_DEVICE_UNREGISTER:
|
||||||
/* 设备被解绑,请在此处添加实现 */
|
/* 设备被解绑,请在此处添加实现 */
|
||||||
|
handle_device_unbind();
|
||||||
break;
|
break;
|
||||||
case HILINK_REVOKE_FLAG_SET:
|
case HILINK_REVOKE_FLAG_SET:
|
||||||
/* 设备被复位标记置位,请在此处添加实现 */
|
/* 设备被复位标记置位,请在此处添加实现 */
|
||||||
|
handle_device_unbind();
|
||||||
break;
|
break;
|
||||||
case HILINK_NEGO_REG_INFO_FAIL:
|
case HILINK_NEGO_REG_INFO_FAIL:
|
||||||
/* 设备协商配网信息失败 */
|
/* 设备协商配网信息失败 */
|
||||||
@ -589,6 +460,7 @@ int HILINK_ProcessBeforeRestart(int flag)
|
|||||||
/* APP删除设备触发模组重启 */
|
/* APP删除设备触发模组重启 */
|
||||||
if (flag == 1) {
|
if (flag == 1) {
|
||||||
/* 实现模组重启前的操作(如:保存系统状态等) */
|
/* 实现模组重启前的操作(如:保存系统状态等) */
|
||||||
|
handle_device_unbind(); // 处理设备解绑
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,12 @@ void HSF_API HF_Debug(int debug_level, const char *format , ... );
|
|||||||
#define hfdbg_warn(...) HF_Debug(DEBUG_WARN,"[warnning %d %s %d]",hfsys_get_time(),__FUNCTION__,__LINE__); \
|
#define hfdbg_warn(...) HF_Debug(DEBUG_WARN,"[warnning %d %s %d]",hfsys_get_time(),__FUNCTION__,__LINE__); \
|
||||||
HF_Debug(DEBUG_WARN,__VA_ARGS__)
|
HF_Debug(DEBUG_WARN,__VA_ARGS__)
|
||||||
#define u_printf(...) HF_Debug(DEBUG_LEVEL_USER,__VA_ARGS__)
|
#define u_printf(...) HF_Debug(DEBUG_LEVEL_USER,__VA_ARGS__)
|
||||||
|
#define e_printf(...) \
|
||||||
|
do { \
|
||||||
|
HF_Debug(DEBUG_WARN, "[Ekko]%d %s():%d: ", hfsys_get_time(), \
|
||||||
|
__FUNCTION__, __LINE__); \
|
||||||
|
HF_Debug(DEBUG_WARN, __VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
int hfuart_config(hfuart_handle_t huart, int baudrate, ENCOMPARITY_E parity, ENCOMBITS_E databits, ENCOMSTOPBITS_E stopbits, ENCOMUARTCTL_E fc);
|
int hfuart_config(hfuart_handle_t huart, int baudrate, ENCOMPARITY_E parity, ENCOMBITS_E databits, ENCOMSTOPBITS_E stopbits, ENCOMUARTCTL_E fc);
|
||||||
|
|
||||||
|
@ -6,12 +6,18 @@ set(COMPONENT_NAME "user_main")
|
|||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/app_main.c
|
${CMAKE_CURRENT_SOURCE_DIR}/app_main.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/switch_panel/switch_panel_main.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/switch_panel/switch_panel_keys.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/switch_panel/switch_panel_hilink.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/switch_panel/switch_panel_config.c
|
||||||
)
|
)
|
||||||
|
|
||||||
if (DEFINES MATCHES "HF_MCU_OTA")
|
if (DEFINES MATCHES "HF_MCU_OTA")
|
||||||
list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/mcu_update.c)
|
list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/mcu_update.c)
|
||||||
endif()
|
endif()
|
||||||
set(PUBLIC_HEADER
|
set(PUBLIC_HEADER
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/switch_panel/
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PRIVATE_HEADER
|
set(PRIVATE_HEADER
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "hsf.h"
|
#include "hsf.h"
|
||||||
|
#include "hfgpio.h"
|
||||||
|
#include "switch_panel.h"
|
||||||
#ifdef HF_MCU_OTA
|
#ifdef HF_MCU_OTA
|
||||||
#include "mcu_update.h"
|
#include "mcu_update.h"
|
||||||
#endif
|
#endif
|
||||||
@ -196,6 +199,15 @@ int hf_atcmd_appver(pat_session_t s,int argc,char *argv[],char *rsp,int len)
|
|||||||
}
|
}
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPOTLIGHT_UT
|
||||||
|
extern int hf_atcmd_pwm(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||||
|
extern int hf_atcmd_pwm_query(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||||
|
extern int hf_atcmd_light(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||||
|
extern int hf_atcmd_light_query(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||||
|
extern int hf_atcmd_reset(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||||
|
extern int hf_atcmd_reset_factory(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||||
|
#endif
|
||||||
const hfat_cmd_t user_define_at_cmds_table[]=
|
const hfat_cmd_t user_define_at_cmds_table[]=
|
||||||
{
|
{
|
||||||
{"APPVER", hf_atcmd_appver, "AT+APPVER: get version. \r\n",NULL},
|
{"APPVER", hf_atcmd_appver, "AT+APPVER: get version. \r\n",NULL},
|
||||||
@ -204,16 +216,32 @@ const hfat_cmd_t user_define_at_cmds_table[]=
|
|||||||
{"MCUVER", hf_atcmd_mcuver, "AT+MCUVER: get mcu version. \r\n",NULL},
|
{"MCUVER", hf_atcmd_mcuver, "AT+MCUVER: get mcu version. \r\n",NULL},
|
||||||
{"OTAWAITTIME", hf_atcmd_ota_wait_time, "AT+OTAWAITTIME: set/get uart send mcu ota time\r\n", NULL},
|
{"OTAWAITTIME", hf_atcmd_ota_wait_time, "AT+OTAWAITTIME: set/get uart send mcu ota time\r\n", NULL},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_SPOTLIGHT_UT
|
||||||
|
{"RESET", hf_atcmd_reset, "AT+RESET: reset. \r\n",NULL},
|
||||||
|
{"FACTORY", hf_atcmd_reset_factory, "AT+FACTORY: factory. \r\n",NULL},
|
||||||
|
{"UTPWM", hf_atcmd_pwm, "AT+PWM=<channel>,<duty>: Set PWM duty cycle (0-1000)\r\n", NULL},
|
||||||
|
{"UTLIGHT", hf_atcmd_light, "AT+LIGHT=<brightness>,<cct>: Set brightness(0-1000) and CCT(2700-6000)\r\n", NULL},
|
||||||
|
{"UTPWMQ", NULL, "AT+PWMQ=<channel>,<duty>: Set PWM duty cycle (0-1000)\r\n", hf_atcmd_pwm_query},
|
||||||
|
{"UTLIGHTQ", NULL, "AT+LIGHTQ=<brightness>,<cct>: Set brightness(0-1000) and CCT(2700-6000)\r\n", hf_atcmd_light_query},
|
||||||
|
#endif
|
||||||
{NULL, NULL, NULL, NULL} //the last item must be null
|
{NULL, NULL, NULL, NULL} //the last item must be null
|
||||||
};
|
};
|
||||||
|
|
||||||
int USER_FUNC user_app_main(void)
|
int USER_FUNC user_app_main(void)
|
||||||
{
|
{
|
||||||
|
hfdbg_set_level(1);
|
||||||
//AT+UART uart0
|
//AT+UART uart0
|
||||||
if(hfnet_start_uart(HFTHREAD_PRIORITIES_LOW,(hfnet_callback_t)uart_recv_callback)!=HF_SUCCESS)
|
if(hfnet_start_uart(HFTHREAD_PRIORITIES_LOW,(hfnet_callback_t)uart_recv_callback)!=HF_SUCCESS)
|
||||||
{
|
{
|
||||||
HF_Debug(DEBUG_WARN,"start uart fail!\r\n");
|
HF_Debug(DEBUG_WARN,"start uart fail!\r\n");
|
||||||
}
|
}
|
||||||
|
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
|
#ifdef HF_MCU_OTA
|
||||||
if(hf_mcu_init() != HF_SUCCESS)
|
if(hf_mcu_init() != HF_SUCCESS)
|
||||||
HF_Debug(DEBUG_WARN,"init mcu ota fail!\r\n");
|
HF_Debug(DEBUG_WARN,"init mcu ota fail!\r\n");
|
||||||
|
4
application/ws63/user_main/spotlight/factory_test.h
Normal file
4
application/ws63/user_main/spotlight/factory_test.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#ifndef FACTORY_TEST_H
|
||||||
|
#define FACTORY_TEST_H
|
||||||
|
void try_detect_factory_test(void);
|
||||||
|
#endif // FACTORY_TEST_H
|
209
application/ws63/user_main/switch_panel/switch_panel.h
Normal file
209
application/ws63/user_main/switch_panel/switch_panel.h
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
#ifndef __SWITCH_PANEL_H__
|
||||||
|
#define __SWITCH_PANEL_H__
|
||||||
|
|
||||||
|
#include "hsf.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/pinctrl.h"
|
||||||
|
#include "driver/timer.h"
|
||||||
|
#include "platform_core_rom.h"
|
||||||
|
#include "schedule/osal_task.h"
|
||||||
|
#include "hfflash.h"
|
||||||
|
#include "hfuart.h"
|
||||||
|
|
||||||
|
//====================== 硬件引脚定义 ======================
|
||||||
|
// 根据CLAUDE.md中的物理连接定义,使用标准GPIO枚举
|
||||||
|
// LED指示灯引脚 (控制按键指示灯颜色: 高电平=白灯, 低电平=黄灯)
|
||||||
|
#define LED1_GPIO GPIO_00 // GPIO 0 - 按键1指示灯
|
||||||
|
#define LED2_GPIO GPIO_02 // GPIO 2 - 按键2指示灯
|
||||||
|
#define LED3_GPIO GPIO_05 // GPIO 5 - 按键3指示灯
|
||||||
|
#define LED4_GPIO GPIO_10 // GPIO 10 - 按键4指示灯
|
||||||
|
|
||||||
|
// 开关控制引脚 (控制实际开关: 高电平=开, 低电平=关)
|
||||||
|
#define SWITCH1_GPIO GPIO_12 // GPIO 12 - 开关1控制
|
||||||
|
#define SWITCH2_GPIO GPIO_13 // GPIO 13 - 开关2控制
|
||||||
|
#define SWITCH3_GPIO GPIO_14 // GPIO 14 - 开关3控制
|
||||||
|
#define SWITCH4_GPIO GPIO_07 // GPIO 7 - 开关4控制
|
||||||
|
|
||||||
|
// 物理按键输入引脚 (输入检测: 低电平=按下, 高电平=松开)
|
||||||
|
#define KEY1_GPIO GPIO_09 // GPIO 9 - 按键1输入
|
||||||
|
#define KEY2_GPIO GPIO_04 // GPIO 4 - 按键2输入
|
||||||
|
#define KEY3_GPIO GPIO_11 // GPIO 11 - 按键3输入
|
||||||
|
#define KEY4_GPIO GPIO_08 // GPIO 8 - 按键4输入
|
||||||
|
|
||||||
|
// 面板背光引脚 (控制面板背光: 高电平=亮黄灯, 低电平=灭灯)
|
||||||
|
#define PANEL_LED_GPIO GPIO_03 // GPIO 3 - 面板背光
|
||||||
|
|
||||||
|
//====================== 系统常量定义 ======================
|
||||||
|
#define SWITCH_COUNT 4 // 开关数量
|
||||||
|
#define KEY_DEBOUNCE_MS 50 // 按键防抖时间(毫秒)
|
||||||
|
#define KEY_LONG_PRESS_MS 10000 // 长按时间阈值(毫秒) - 用于进入配网
|
||||||
|
#define CONFIG_TIMEOUT_MS (10*60*1000) // 配网超时时间(10分钟)
|
||||||
|
#define CONFIG_BLINK_MS (3*60*1000) // 配网前3分钟闪烁时间
|
||||||
|
#define PANEL_BLINK_MS 1000 // 面板背光快闪时间(1秒)
|
||||||
|
#define LED_BLINK_FREQ_HZ 1 // 配网时LED闪烁频率(1Hz)
|
||||||
|
|
||||||
|
//====================== 设备状态定义 ======================
|
||||||
|
// 开关状态
|
||||||
|
typedef enum {
|
||||||
|
SWITCH_OFF = 0,
|
||||||
|
SWITCH_ON = 1
|
||||||
|
} switch_state_t;
|
||||||
|
|
||||||
|
// 按键状态
|
||||||
|
typedef enum {
|
||||||
|
KEY_RELEASED = 1, // 高电平 - 按键松开
|
||||||
|
KEY_PRESSED = 0 // 低电平 - 按键按下
|
||||||
|
} key_state_t;
|
||||||
|
|
||||||
|
// LED状态
|
||||||
|
typedef enum {
|
||||||
|
LED_YELLOW = 0, // 低电平 - 黄灯
|
||||||
|
LED_WHITE = 1 // 高电平 - 白灯
|
||||||
|
} led_state_t;
|
||||||
|
|
||||||
|
// 面板背光状态
|
||||||
|
typedef enum {
|
||||||
|
PANEL_LED_OFF = 0, // 低电平 - 背光关闭
|
||||||
|
PANEL_LED_ON = 1 // 高电平 - 背光开启(黄色)
|
||||||
|
} panel_led_state_t;
|
||||||
|
|
||||||
|
// 系统工作模式
|
||||||
|
typedef enum {
|
||||||
|
MODE_NORMAL = 0, // 正常工作模式
|
||||||
|
MODE_CONFIG, // 配网模式
|
||||||
|
MODE_FACTORY_TEST, // 产测模式
|
||||||
|
MODE_UNBIND // 设备解绑模式
|
||||||
|
} system_mode_t;
|
||||||
|
|
||||||
|
//====================== 设备状态结构 ======================
|
||||||
|
// 单个开关状态信息
|
||||||
|
typedef struct {
|
||||||
|
bool switch_on; // 开关状态 (true=开, false=关)
|
||||||
|
bool led_state; // LED状态 (true=白灯, false=黄灯)
|
||||||
|
bool physical_key; // 物理按键状态 (true=松开, false=按下)
|
||||||
|
} switch_info_t;
|
||||||
|
|
||||||
|
|
||||||
|
// 系统设备状态
|
||||||
|
typedef struct {
|
||||||
|
switch_info_t switches[SWITCH_COUNT]; // 4个开关的状态
|
||||||
|
bool master_switch; // 总开关状态
|
||||||
|
bool panel_led; // 面板背光状态
|
||||||
|
bool is_bound; // 设备绑定状态
|
||||||
|
bool is_first_boot; // 是否第一次上电
|
||||||
|
system_mode_t mode; // 系统工作模式
|
||||||
|
uint32_t reserved[10]; // 保留字段
|
||||||
|
} device_state_t;
|
||||||
|
|
||||||
|
|
||||||
|
//====================== Flash存储相关 ======================
|
||||||
|
// Flash存储地址定义
|
||||||
|
#define SUPPORT_SAVE_TO_FLASH 1
|
||||||
|
|
||||||
|
// 定义Flash存储地址和大小
|
||||||
|
#define DEVICE_DATA_FLASH_SIZE 0x001000 // 使用一个页的大小
|
||||||
|
#define DEVICE_DATA_FLASH_ADDR 0x000000 // 主数据区地址
|
||||||
|
#define DEVICE_DATA_BACKUP_ADDR (DEVICE_DATA_FLASH_ADDR + DEVICE_DATA_FLASH_SIZE) // 备份数据区地址
|
||||||
|
|
||||||
|
// 设备数据结构
|
||||||
|
typedef struct {
|
||||||
|
uint8_t checksum; // 校验和
|
||||||
|
uint32_t magic; // 魔数,用于验证数据有效性
|
||||||
|
uint32_t version; // 版本号
|
||||||
|
uint32_t data_len; // 数据长度
|
||||||
|
uint8_t data[0]; // 数据
|
||||||
|
} device_data_t;
|
||||||
|
|
||||||
|
#define DEVICE_DATA_MAGIC 0x4C505426 // "LPT&"的ASCII码
|
||||||
|
#define DEVICE_DATA_VERSION 1 // 数据版本号
|
||||||
|
|
||||||
|
//====================== 配网相关定义 ======================
|
||||||
|
#define FACTORY_TEST_SSID "ShuorongSelfTest" // 产测热点名称
|
||||||
|
#define CONFIG_ENTRY_COUNT 3 // 连续重启次数进入配网
|
||||||
|
|
||||||
|
//====================== 任务和定时器相关 ======================
|
||||||
|
#define TASK_STACK_SIZE 2048
|
||||||
|
#define TASK_PRIORITY_HIGH OSAL_TASK_PRIORITY_HIGH
|
||||||
|
#define TASK_PRIORITY_NORM OSAL_TASK_PRIORITY_MIDDLE
|
||||||
|
#define TASK_PRIORITY_LOW OSAL_TASK_PRIORITY_LOW
|
||||||
|
|
||||||
|
//====================== 全局变量声明 ======================
|
||||||
|
extern device_state_t g_device_state;
|
||||||
|
extern timer_handle_t g_key_debounce_timer[SWITCH_COUNT];
|
||||||
|
extern timer_handle_t g_config_timeout_timer;
|
||||||
|
extern timer_handle_t g_config_blink_timer;
|
||||||
|
extern osal_task *g_key_scan_task_handle;
|
||||||
|
extern osal_task *g_config_task_handle;
|
||||||
|
|
||||||
|
//====================== 函数声明 ======================
|
||||||
|
|
||||||
|
// 主程序函数
|
||||||
|
int switch_panel_main(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);
|
||||||
|
void set_panel_led(panel_led_state_t state);
|
||||||
|
bool get_key_input(int key_id);
|
||||||
|
|
||||||
|
// 设备状态管理函数
|
||||||
|
int load_device_state(void);
|
||||||
|
int save_device_state(void);
|
||||||
|
void reset_device_state(void);
|
||||||
|
void sync_hardware_state(void);
|
||||||
|
void fast_report_switch(int switch_id);
|
||||||
|
|
||||||
|
// 开关控制函数
|
||||||
|
void update_switch_state(int switch_id, bool state);
|
||||||
|
void update_master_switch(bool state);
|
||||||
|
void apply_master_switch_control(void);
|
||||||
|
|
||||||
|
// 按键处理函数
|
||||||
|
int key_scan_task(void *arg);
|
||||||
|
void handle_key_press(int key_id);
|
||||||
|
void handle_key_long_press(int key_id);
|
||||||
|
|
||||||
|
// 配网相关函数
|
||||||
|
void enter_config_mode(void);
|
||||||
|
void exit_config_mode(void);
|
||||||
|
int config_mode_task(void *arg);
|
||||||
|
void config_led_blink(void);
|
||||||
|
void panel_led_blink(void);
|
||||||
|
|
||||||
|
// 产测相关函数
|
||||||
|
void enter_factory_test_mode(void);
|
||||||
|
void factory_test_sequence(void);
|
||||||
|
bool check_factory_test_wifi(void);
|
||||||
|
|
||||||
|
// HiLink设备事件处理
|
||||||
|
void handle_device_online(void);
|
||||||
|
void handle_device_offline(void);
|
||||||
|
void handle_device_unbind(void);
|
||||||
|
void sync_cloud_state(void);
|
||||||
|
|
||||||
|
// HiLink服务处理函数
|
||||||
|
int handle_put_switch(const char* svc_id, const char* payload, unsigned int len);
|
||||||
|
int handle_get_switch(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
||||||
|
int handle_put_switch1(const char* svc_id, const char* payload, unsigned int len);
|
||||||
|
int handle_get_switch1(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
||||||
|
int handle_put_switch2(const char* svc_id, const char* payload, unsigned int len);
|
||||||
|
int handle_get_switch2(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
||||||
|
int handle_put_switch3(const char* svc_id, const char* payload, unsigned int len);
|
||||||
|
int handle_get_switch3(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
||||||
|
int handle_put_switch4(const char* svc_id, const char* payload, unsigned int len);
|
||||||
|
int handle_get_switch4(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
||||||
|
|
||||||
|
// 调试和工具函数
|
||||||
|
void print_device_state(void);
|
||||||
|
const char* get_mode_string(system_mode_t mode);
|
||||||
|
|
||||||
|
// 定时器回调函数
|
||||||
|
void key_debounce_timer_callback(uintptr_t data);
|
||||||
|
void config_timeout_timer_callback(uintptr_t data);
|
||||||
|
void config_blink_timer_callback(uintptr_t data);
|
||||||
|
|
||||||
|
#endif // __SWITCH_PANEL_H__
|
335
application/ws63/user_main/switch_panel/switch_panel_config.c
Normal file
335
application/ws63/user_main/switch_panel/switch_panel_config.c
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
#include "stdint.h"
|
||||||
|
#include "hsf.h"
|
||||||
|
#include "hfsys.h"
|
||||||
|
#include "hfgpio.h"
|
||||||
|
#include "switch_panel.h"
|
||||||
|
#include "hilink.h"
|
||||||
|
#include "hsf.h"
|
||||||
|
#include "hfconfig.h"
|
||||||
|
#include "pinctrl.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "soc_osal.h"
|
||||||
|
#include "systick.h"
|
||||||
|
|
||||||
|
//====================== 配网相关变量 ======================
|
||||||
|
static bool g_config_led_blink_state = false;
|
||||||
|
static bool g_panel_led_blink_state = false;
|
||||||
|
static uint32_t g_config_blink_start_time = 0;
|
||||||
|
static int g_config_key_id = -1; // 触发配网的按键
|
||||||
|
|
||||||
|
//====================== 产测相关变量 ======================
|
||||||
|
static bool g_factory_test_running = false;
|
||||||
|
static int g_factory_test_step = 0;
|
||||||
|
static uint32_t g_factory_test_start_time = 0;
|
||||||
|
|
||||||
|
//====================== 配网模式函数 ======================
|
||||||
|
|
||||||
|
// 进入配网模式
|
||||||
|
void enter_config_mode(void) {
|
||||||
|
if (g_device_state.mode == MODE_CONFIG) {
|
||||||
|
e_printf("[CONFIG] 已在配网模式中\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[CONFIG] 进入配网模式\r\n");
|
||||||
|
|
||||||
|
// 更新设备模式
|
||||||
|
set_device_mode(MODE_CONFIG);
|
||||||
|
|
||||||
|
// 记录配网开始时间
|
||||||
|
g_config_start_time = hfsys_get_time();
|
||||||
|
g_config_blink_start_time = g_config_start_time;
|
||||||
|
|
||||||
|
// 面板背光快闪1秒表示进入配网模式
|
||||||
|
panel_led_blink();
|
||||||
|
|
||||||
|
// 创建配网任务
|
||||||
|
if (!g_config_task_handle) {
|
||||||
|
g_config_task_handle = osal_kthread_create((osal_kthread_handler)config_mode_task,
|
||||||
|
NULL,
|
||||||
|
"config_task",
|
||||||
|
TASK_STACK_SIZE);
|
||||||
|
if (!g_config_task_handle) {
|
||||||
|
e_printf("[CONFIG] 创建配网任务失败\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置任务优先级
|
||||||
|
osal_kthread_set_priority(g_config_task_handle, TASK_PRIORITY_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建配网超时定时器
|
||||||
|
if (!g_config_timeout_timer) {
|
||||||
|
int ret = uapi_timer_create(TIMER_INDEX_1, &g_config_timeout_timer);
|
||||||
|
if (ret != ERRCODE_SUCC) {
|
||||||
|
e_printf("[CONFIG] 创建配网超时定时器失败: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_config_timeout_timer) {
|
||||||
|
uapi_timer_start(g_config_timeout_timer,
|
||||||
|
CONFIG_TIMEOUT_MS * 1000,
|
||||||
|
config_timeout_timer_callback,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建闪烁定时器
|
||||||
|
if (!g_config_blink_timer) {
|
||||||
|
int ret = uapi_timer_create(TIMER_INDEX_2, &g_config_blink_timer);
|
||||||
|
if (ret != ERRCODE_SUCC) {
|
||||||
|
e_printf("[CONFIG] 创建配网闪烁定时器失败: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_config_blink_timer) {
|
||||||
|
uint32_t blink_period = 1000000 / (LED_BLINK_FREQ_HZ * 2); // 半周期(微秒)
|
||||||
|
uapi_timer_start(g_config_blink_timer,
|
||||||
|
blink_period,
|
||||||
|
config_blink_timer_callback,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[CONFIG] 配网模式已开启,超时时间: %d分钟\r\n", CONFIG_TIMEOUT_MS / 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退出配网模式
|
||||||
|
void exit_config_mode(void) {
|
||||||
|
if (g_device_state.mode != MODE_CONFIG) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[CONFIG] 退出配网模式\r\n");
|
||||||
|
|
||||||
|
// 停止定时器
|
||||||
|
if (g_config_timeout_timer) {
|
||||||
|
uapi_timer_stop(g_config_timeout_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_config_blink_timer) {
|
||||||
|
uapi_timer_stop(g_config_blink_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终止配网任务
|
||||||
|
if (g_config_task_handle) {
|
||||||
|
osal_kthread_destroy(g_config_task_handle, 1);
|
||||||
|
g_config_task_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复正常LED状态
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_led_output(i, g_device_state.switches[i].led_state ? LED_WHITE : LED_YELLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复面板背光状态
|
||||||
|
set_panel_led(g_device_state.panel_led ? PANEL_LED_ON : PANEL_LED_OFF);
|
||||||
|
|
||||||
|
// 更新设备模式
|
||||||
|
set_device_mode(MODE_NORMAL);
|
||||||
|
|
||||||
|
// 重置配网相关变量
|
||||||
|
g_key_id = -1;
|
||||||
|
g_config_led_blink_state = false;
|
||||||
|
g_panel_led_blink_state = false;
|
||||||
|
|
||||||
|
e_printf("[CONFIG] 已退出配网模式\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配网模式任务
|
||||||
|
int config_mode_task(void *arg) {
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
e_printf("[CONFIG] 配网任务开始\r\n");
|
||||||
|
|
||||||
|
while (g_device_state.mode == MODE_CONFIG && !osal_kthread_should_stop()) {
|
||||||
|
// 检查是否有产测热点
|
||||||
|
if (check_factory_test_wifi()) {
|
||||||
|
e_printf("[CONFIG] 检测到产测热点,进入产测模式\r\n");
|
||||||
|
exit_config_mode();
|
||||||
|
enter_factory_test_mode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每秒检查一次
|
||||||
|
osal_msleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[CONFIG] 配网任务结束\r\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配网LED闪烁
|
||||||
|
void config_led_blink(void) {
|
||||||
|
uint32_t current_time = hfsys_get_time();
|
||||||
|
uint32_t elapsed_time = current_time - g_config_blink_start_time;
|
||||||
|
|
||||||
|
// 前3分钟闪烁,后7分钟常亮
|
||||||
|
if (elapsed_time < CONFIG_BLINK_MS) {
|
||||||
|
// 只有触发配网的按键LED闪烁,其他LED保持常亮
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
if (i == g_config_key_id) {
|
||||||
|
// 触发配网的按键LED闪烁
|
||||||
|
g_config_led_blink_state = !g_config_led_blink_state;
|
||||||
|
set_led_output(i, g_config_led_blink_state ? LED_WHITE : LED_YELLOW);
|
||||||
|
} else {
|
||||||
|
// 其他按键LED保持常亮
|
||||||
|
set_led_output(i, LED_YELLOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 超过3分钟后,所有LED保持常亮
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_led_output(i, LED_YELLOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 面板背光快闪
|
||||||
|
void panel_led_blink(void) {
|
||||||
|
// 快闪1秒
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
set_panel_led(PANEL_LED_ON);
|
||||||
|
osal_msleep(50);
|
||||||
|
set_panel_led(PANEL_LED_OFF);
|
||||||
|
osal_msleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复原状态
|
||||||
|
set_panel_led(g_device_state.panel_led ? PANEL_LED_ON : PANEL_LED_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 产测模式函数 ======================
|
||||||
|
|
||||||
|
// 进入产测模式
|
||||||
|
void enter_factory_test_mode(void) {
|
||||||
|
e_printf("[FACTORY] 进入产测模式\r\n");
|
||||||
|
|
||||||
|
// 更新设备模式
|
||||||
|
set_device_mode(MODE_FACTORY_TEST);
|
||||||
|
|
||||||
|
// 初始化产测变量
|
||||||
|
g_factory_test_running = true;
|
||||||
|
g_factory_test_step = 0;
|
||||||
|
g_factory_test_start_time = hfsys_get_time();
|
||||||
|
|
||||||
|
// 开始产测序列
|
||||||
|
factory_test_sequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 产测序列
|
||||||
|
void factory_test_sequence(void) {
|
||||||
|
e_printf("[FACTORY] 开始产测序列\r\n");
|
||||||
|
|
||||||
|
// 步骤1: 开始指示 - 交替闪烁白黄灯500ms
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
for (int j = 0; j < SWITCH_COUNT; j++) {
|
||||||
|
set_led_output(j, (i % 2) ? LED_WHITE : LED_YELLOW);
|
||||||
|
}
|
||||||
|
osal_msleep(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤2-5: 单个开关测试 (开1->4, 每个1.5秒)
|
||||||
|
for (int switch_id = 0; switch_id < SWITCH_COUNT; switch_id++) {
|
||||||
|
e_printf("[FACTORY] 测试开关%d\r\n", switch_id + 1);
|
||||||
|
|
||||||
|
// 所有开关关闭,所有LED黄灯
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_switch_output(i, false);
|
||||||
|
set_led_output(i, LED_YELLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前测试的开关开启且LED白灯
|
||||||
|
set_switch_output(switch_id, true);
|
||||||
|
set_led_output(switch_id, LED_WHITE);
|
||||||
|
|
||||||
|
// 保持1.5秒
|
||||||
|
osal_msleep(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤6: 全关 (1.5秒)
|
||||||
|
e_printf("[FACTORY] 测试全关\r\n");
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_switch_output(i, false);
|
||||||
|
set_led_output(i, LED_YELLOW);
|
||||||
|
}
|
||||||
|
osal_msleep(1500);
|
||||||
|
|
||||||
|
// 步骤7: 全开 (1.5秒)
|
||||||
|
e_printf("[FACTORY] 测试全开\r\n");
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_switch_output(i, true);
|
||||||
|
set_led_output(i, LED_WHITE);
|
||||||
|
}
|
||||||
|
osal_msleep(1500);
|
||||||
|
|
||||||
|
// 步骤8: 再次全关
|
||||||
|
e_printf("[FACTORY] 结束测试 - 全关\r\n");
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_switch_output(i, false);
|
||||||
|
set_led_output(i, LED_YELLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: WiFi信号强度校验
|
||||||
|
bool wifi_test_pass = check_factory_test_wifi();
|
||||||
|
|
||||||
|
// 显示最终结果
|
||||||
|
if (wifi_test_pass) {
|
||||||
|
e_printf("[FACTORY] 产测全部通过\r\n");
|
||||||
|
// 所有开关开启表示通过
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_switch_output(i, true);
|
||||||
|
set_led_output(i, LED_WHITE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e_printf("[FACTORY] 产测失败\r\n");
|
||||||
|
// 所有开关关闭表示失败
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_switch_output(i, false);
|
||||||
|
set_led_output(i, LED_YELLOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 产测完成,返回正常模式
|
||||||
|
g_factory_test_running = false;
|
||||||
|
set_device_mode(MODE_NORMAL);
|
||||||
|
|
||||||
|
// 恢复设备默认状态
|
||||||
|
sync_hardware_state();
|
||||||
|
|
||||||
|
e_printf("[FACTORY] 产测序列完成\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查产测热点
|
||||||
|
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; // 默认未找到产测热点
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 定时器回调函数 ======================
|
||||||
|
|
||||||
|
// 配网超时定时器回调
|
||||||
|
void config_timeout_timer_callback(uintptr_t data) {
|
||||||
|
(void)data;
|
||||||
|
|
||||||
|
e_printf("[CONFIG] 配网超时,退出配网模式\r\n");
|
||||||
|
|
||||||
|
// 超时退出配网模式
|
||||||
|
exit_config_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配网闪烁定时器回调
|
||||||
|
void config_blink_timer_callback(uintptr_t data) {
|
||||||
|
(void)data;
|
||||||
|
|
||||||
|
// 执行闪烁操作
|
||||||
|
config_led_blink();
|
||||||
|
}
|
255
application/ws63/user_main/switch_panel/switch_panel_hilink.c
Normal file
255
application/ws63/user_main/switch_panel/switch_panel_hilink.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include "hsf.h"
|
||||||
|
#include "hfgpio.h"
|
||||||
|
#include "hilink.h"
|
||||||
|
#include "securec.h"
|
||||||
|
#include "cJSON.h"
|
||||||
|
#include "switch_panel.h"
|
||||||
|
|
||||||
|
//====================== HiLink 设备事件处理 ======================
|
||||||
|
|
||||||
|
// 处理设备上线事件
|
||||||
|
void handle_device_online(void) {
|
||||||
|
e_printf("[HILINK] 设备上线\r\n");
|
||||||
|
|
||||||
|
// 更新设备绑定状态
|
||||||
|
g_device_state.is_bound = true;
|
||||||
|
|
||||||
|
// 退出配网模式
|
||||||
|
if (g_device_state.mode == MODE_CONFIG) {
|
||||||
|
exit_config_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步所有状态到云端
|
||||||
|
sync_cloud_state();
|
||||||
|
|
||||||
|
// 保存状态
|
||||||
|
save_device_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理设备下线事件
|
||||||
|
void handle_device_offline(void) {
|
||||||
|
e_printf("[HILINK] 设备下线\r\n");
|
||||||
|
|
||||||
|
// 设备下线时保持现有状态,不做特殊处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理设备解绑事件
|
||||||
|
void handle_device_unbind(void) {
|
||||||
|
e_printf("[HILINK] 设备解绑\r\n");
|
||||||
|
|
||||||
|
// 更新设备绑定状态
|
||||||
|
g_device_state.is_bound = false;
|
||||||
|
g_device_state.mode = MODE_UNBIND;
|
||||||
|
|
||||||
|
// 重置为出厂默认状态
|
||||||
|
reset_device_state();
|
||||||
|
g_device_state.is_bound = false; // 保持未绑定状态
|
||||||
|
|
||||||
|
// 同步硬件状态
|
||||||
|
sync_hardware_state();
|
||||||
|
|
||||||
|
// 保存状态
|
||||||
|
save_device_state();
|
||||||
|
|
||||||
|
e_printf("[HILINK] 设备已重置为出厂默认状态\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步所有状态到云端
|
||||||
|
void sync_cloud_state(void) {
|
||||||
|
e_printf("[HILINK] 开始同步状态到云端\r\n");
|
||||||
|
|
||||||
|
// 上报总开关状态
|
||||||
|
extern int fast_report(const char* svc_id);
|
||||||
|
fast_report("switch");
|
||||||
|
|
||||||
|
// 上报所有子开关状态
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
char svc_id[16] = {0};
|
||||||
|
snprintf(svc_id, sizeof(svc_id), "switch%d", i + 1);
|
||||||
|
fast_report(svc_id);
|
||||||
|
// osDelay(pdMS_TO_TICKS(100)); // 防止上报过快
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[HILINK] 状态同步完成\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== HiLink 服务处理函数 ======================
|
||||||
|
|
||||||
|
// 处理总开关PUT命令
|
||||||
|
int handle_put_switch(const char* svc_id, const char* payload, unsigned int len) {
|
||||||
|
if (!svc_id || !payload) {
|
||||||
|
e_printf("[HILINK] handle_put_switch 参数无效\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[HILINK] 收到总开关控制命令: %s\r\n", payload);
|
||||||
|
|
||||||
|
cJSON* json = cJSON_Parse(payload);
|
||||||
|
if (!json) {
|
||||||
|
e_printf("[HILINK] JSON解析失败\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* on_item = cJSON_GetObjectItem(json, "on");
|
||||||
|
if (on_item && cJSON_IsBool(on_item)) {
|
||||||
|
bool state = cJSON_IsTrue(on_item);
|
||||||
|
update_master_switch(state);
|
||||||
|
e_printf("[HILINK] 总开关设置为: %s\r\n", state ? "开" : "关");
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理总开关GET命令
|
||||||
|
int handle_get_switch(const char* svc_id, const char* in, unsigned int in_len,
|
||||||
|
char** out, unsigned int* out_len) {
|
||||||
|
if (!out || !out_len) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = 32;
|
||||||
|
*out = (char*)malloc(*out_len);
|
||||||
|
if (!*out) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = snprintf(*out, *out_len, "{\"on\":%s}",
|
||||||
|
g_device_state.master_switch ? "true" : "false");
|
||||||
|
|
||||||
|
e_printf("[HILINK] 返回总开关状态: %s\r\n", *out);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关1 PUT命令
|
||||||
|
int handle_put_switch1(const char* svc_id, const char* payload, unsigned int len) {
|
||||||
|
return handle_put_switch_common(0, svc_id, payload, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关1 GET命令
|
||||||
|
int handle_get_switch1(const char* svc_id, const char* in, unsigned int in_len,
|
||||||
|
char** out, unsigned int* out_len) {
|
||||||
|
return handle_get_switch_common(0, svc_id, in, in_len, out, out_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关2 PUT命令
|
||||||
|
int handle_put_switch2(const char* svc_id, const char* payload, unsigned int len) {
|
||||||
|
return handle_put_switch_common(1, svc_id, payload, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关2 GET命令
|
||||||
|
int handle_get_switch2(const char* svc_id, const char* in, unsigned int in_len,
|
||||||
|
char** out, unsigned int* out_len) {
|
||||||
|
return handle_get_switch_common(1, svc_id, in, in_len, out, out_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关3 PUT命令
|
||||||
|
int handle_put_switch3(const char* svc_id, const char* payload, unsigned int len) {
|
||||||
|
return handle_put_switch_common(2, svc_id, payload, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关3 GET命令
|
||||||
|
int handle_get_switch3(const char* svc_id, const char* in, unsigned int in_len,
|
||||||
|
char** out, unsigned int* out_len) {
|
||||||
|
return handle_get_switch_common(2, svc_id, in, in_len, out, out_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关4 PUT命令
|
||||||
|
int handle_put_switch4(const char* svc_id, const char* payload, unsigned int len) {
|
||||||
|
return handle_put_switch_common(3, svc_id, payload, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开关4 GET命令
|
||||||
|
int handle_get_switch4(const char* svc_id, const char* in, unsigned int in_len,
|
||||||
|
char** out, unsigned int* out_len) {
|
||||||
|
return handle_get_switch_common(3, svc_id, in, in_len, out, out_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 子开关通用处理函数 ======================
|
||||||
|
|
||||||
|
// 子开关PUT命令通用处理函数
|
||||||
|
static int handle_put_switch_common(int switch_id, const char* svc_id,
|
||||||
|
const char* payload, unsigned int len) {
|
||||||
|
if (switch_id < 0 || switch_id >= SWITCH_COUNT || !svc_id || !payload) {
|
||||||
|
e_printf("[HILINK] handle_put_switch%d 参数无效\r\n", switch_id + 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[HILINK] 收到开关%d控制命令: %s\r\n", switch_id + 1, payload);
|
||||||
|
|
||||||
|
cJSON* json = cJSON_Parse(payload);
|
||||||
|
if (!json) {
|
||||||
|
e_printf("[HILINK] JSON解析失败\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* on_item = cJSON_GetObjectItem(json, "on");
|
||||||
|
if (on_item && cJSON_IsBool(on_item)) {
|
||||||
|
bool state = cJSON_IsTrue(on_item);
|
||||||
|
update_switch_state(switch_id, state);
|
||||||
|
e_printf("[HILINK] 开关%d设置为: %s\r\n",
|
||||||
|
switch_id + 1, state ? "开" : "关");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有name字段(预留功能)
|
||||||
|
cJSON* name_item = cJSON_GetObjectItem(json, "name");
|
||||||
|
if (name_item && cJSON_IsString(name_item)) {
|
||||||
|
e_printf("[HILINK] 开关%d名称: %s\r\n",
|
||||||
|
switch_id + 1, cJSON_GetStringValue(name_item));
|
||||||
|
// TODO: 将来可以存储开关名称
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 子开关GET命令通用处理函数
|
||||||
|
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) {
|
||||||
|
if (switch_id < 0 || switch_id >= SWITCH_COUNT || !out || !out_len) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = 64;
|
||||||
|
*out = (char*)malloc(*out_len);
|
||||||
|
if (!*out) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回开关状态和名称
|
||||||
|
*out_len = snprintf(*out, *out_len,
|
||||||
|
"{\"on\":%s,\"name\":\"开关%d\"}",
|
||||||
|
g_device_state.switches[switch_id].switch_on ? "true" : "false",
|
||||||
|
switch_id + 1);
|
||||||
|
|
||||||
|
e_printf("[HILINK] 返回开关%d状态: %s\r\n", switch_id + 1, *out);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== HiLink 事件扩展函数 ======================
|
||||||
|
|
||||||
|
// 检查设备是否在线
|
||||||
|
bool is_device_online(void) {
|
||||||
|
return g_device_state.is_bound;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取设备当前模式
|
||||||
|
system_mode_t get_current_mode(void) {
|
||||||
|
return g_device_state.mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置设备工作模式
|
||||||
|
void set_device_mode(system_mode_t mode) {
|
||||||
|
if (g_device_state.mode != mode) {
|
||||||
|
system_mode_t old_mode = g_device_state.mode;
|
||||||
|
g_device_state.mode = mode;
|
||||||
|
|
||||||
|
e_printf("[MODE] 设备模式切换: %s -> %s\r\n",
|
||||||
|
get_mode_string(old_mode), get_mode_string(mode));
|
||||||
|
|
||||||
|
// 保存模式变更
|
||||||
|
save_device_state();
|
||||||
|
}
|
||||||
|
}
|
293
application/ws63/user_main/switch_panel/switch_panel_keys.c
Normal file
293
application/ws63/user_main/switch_panel/switch_panel_keys.c
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
#include "switch_panel.h"
|
||||||
|
#include "hilink.h"
|
||||||
|
|
||||||
|
//====================== 按键检测相关变量 ======================
|
||||||
|
static bool g_key_states[SWITCH_COUNT] = {true, true, true, true}; // 上一次按键状态
|
||||||
|
static uint32_t g_key_press_time[SWITCH_COUNT] = {0}; // 按键按下开始时间
|
||||||
|
static bool g_key_debounce_flag[SWITCH_COUNT] = {false}; // 防抖标志
|
||||||
|
static bool g_is_long_press_handled[SWITCH_COUNT] = {false}; // 长按处理标志
|
||||||
|
|
||||||
|
// 定时器参数
|
||||||
|
typedef struct {
|
||||||
|
int key_id;
|
||||||
|
} key_timer_param_t;
|
||||||
|
|
||||||
|
static key_timer_param_t g_timer_params[SWITCH_COUNT];
|
||||||
|
|
||||||
|
//====================== 开关控制函数 ======================
|
||||||
|
|
||||||
|
// 更新单个开关状态
|
||||||
|
void update_switch_state(int switch_id, bool state) {
|
||||||
|
if (switch_id < 0 || switch_id >= SWITCH_COUNT) {
|
||||||
|
e_printf("[SWITCH] 无效的开关ID: %d\r\n", switch_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查总开关是否允许操作
|
||||||
|
if (!g_device_state.master_switch && state) {
|
||||||
|
e_printf("[SWITCH] 总开关关闭,不允许开启开关%d\r\n", switch_id + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新开关状态
|
||||||
|
if (g_device_state.switches[switch_id].switch_on != state) {
|
||||||
|
g_device_state.switches[switch_id].switch_on = state;
|
||||||
|
|
||||||
|
// 更新LED指示灯(开关开启时LED白灯,关闭时LED黄灯)
|
||||||
|
g_device_state.switches[switch_id].led_state = state;
|
||||||
|
|
||||||
|
// 同步硬件状态
|
||||||
|
set_switch_output(switch_id, state);
|
||||||
|
set_led_output(switch_id, state ? LED_WHITE : LED_YELLOW);
|
||||||
|
|
||||||
|
e_printf("[SWITCH] 开关%d 状态更新: %s\r\n",
|
||||||
|
switch_id + 1, state ? "开" : "关");
|
||||||
|
|
||||||
|
// 立即保存状态
|
||||||
|
save_device_state();
|
||||||
|
|
||||||
|
// 上报状态给云端
|
||||||
|
if (g_device_state.is_bound) {
|
||||||
|
fast_report_switch(switch_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新总开关状态
|
||||||
|
void update_master_switch(bool state) {
|
||||||
|
if (g_device_state.master_switch != state) {
|
||||||
|
g_device_state.master_switch = state;
|
||||||
|
|
||||||
|
e_printf("[SWITCH] 总开关状态更新: %s\r\n", state ? "开" : "关");
|
||||||
|
|
||||||
|
// 应用总开关控制逻辑
|
||||||
|
apply_master_switch_control();
|
||||||
|
|
||||||
|
// 立即保存状态
|
||||||
|
save_device_state();
|
||||||
|
|
||||||
|
// 上报状态给云端
|
||||||
|
if (g_device_state.is_bound) {
|
||||||
|
fast_report_master_switch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用总开关控制逻辑
|
||||||
|
void apply_master_switch_control(void) {
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
if (!g_device_state.master_switch) {
|
||||||
|
// 总开关关闭时,关闭所有开关但保持LED状态
|
||||||
|
set_switch_output(i, false);
|
||||||
|
} else {
|
||||||
|
// 总开关开启时,恢复各开关的原状态
|
||||||
|
set_switch_output(i, g_device_state.switches[i].switch_on);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LED状态保持不变,始终显示实际的开关状态
|
||||||
|
set_led_output(i, g_device_state.switches[i].led_state ? LED_WHITE : LED_YELLOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 按键检测与处理 ======================
|
||||||
|
|
||||||
|
// 按键防抖定时器回调
|
||||||
|
void key_debounce_timer_callback(uintptr_t data) {
|
||||||
|
key_timer_param_t *param = (key_timer_param_t *)data;
|
||||||
|
if (!param) return;
|
||||||
|
|
||||||
|
int key_id = param->key_id;
|
||||||
|
if (key_id < 0 || key_id >= SWITCH_COUNT) return;
|
||||||
|
|
||||||
|
// 清除防抖标志
|
||||||
|
g_key_debounce_flag[key_id] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按键扫描任务
|
||||||
|
int key_scan_task(void *arg) {
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
e_printf("[KEY] 按键扫描任务开始\r\n");
|
||||||
|
|
||||||
|
while (!osal_kthread_should_stop()) {
|
||||||
|
// 扫描所有按键
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
bool current_state = get_key_input(i);
|
||||||
|
uint32_t current_time = hfsys_get_time();
|
||||||
|
|
||||||
|
// 检测按键状态变化
|
||||||
|
if (current_state != g_key_states[i] && !g_key_debounce_flag[i]) {
|
||||||
|
if (current_state == KEY_PRESSED) {
|
||||||
|
// 按键按下
|
||||||
|
g_key_press_time[i] = current_time;
|
||||||
|
g_is_long_press_handled[i] = false;
|
||||||
|
|
||||||
|
e_printf("[KEY] 按键%d 按下\r\n", i + 1);
|
||||||
|
} else {
|
||||||
|
// 按键松开
|
||||||
|
uint32_t press_duration = current_time - g_key_press_time[i];
|
||||||
|
|
||||||
|
if (press_duration >= KEY_LONG_PRESS_MS && !g_is_long_press_handled[i]) {
|
||||||
|
// 长按事件(如果在按下期间没有处理)
|
||||||
|
handle_key_long_press(i);
|
||||||
|
g_is_long_press_handled[i] = true;
|
||||||
|
} else if (press_duration < KEY_LONG_PRESS_MS) {
|
||||||
|
// 短按事件
|
||||||
|
handle_key_press(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[KEY] 按键%d 松开 (持续时间: %ums)\r\n",
|
||||||
|
i + 1, press_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动防抖定时器
|
||||||
|
g_key_debounce_flag[i] = true;
|
||||||
|
if (g_key_debounce_timer[i]) {
|
||||||
|
uapi_timer_start(g_key_debounce_timer[i],
|
||||||
|
KEY_DEBOUNCE_MS * 1000,
|
||||||
|
key_debounce_timer_callback,
|
||||||
|
(uintptr_t)&g_timer_params[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_key_states[i] = current_state;
|
||||||
|
g_device_state.switches[i].physical_key = current_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否达到长按时间(在按下期间监测)
|
||||||
|
if (current_state == KEY_PRESSED && !g_is_long_press_handled[i]) {
|
||||||
|
uint32_t press_duration = current_time - g_key_press_time[i];
|
||||||
|
if (press_duration >= KEY_LONG_PRESS_MS) {
|
||||||
|
handle_key_long_press(i);
|
||||||
|
g_is_long_press_handled[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 休眠一段时间再继续扫描
|
||||||
|
osal_msleep(10); // 10ms扫描间隔
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理按键短按事件
|
||||||
|
void handle_key_press(int key_id) {
|
||||||
|
if (key_id < 0 || key_id >= SWITCH_COUNT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[KEY] 处理按键%d 短按事件\r\n", key_id + 1);
|
||||||
|
|
||||||
|
// 在配网模式下,忽略短按事件
|
||||||
|
if (g_device_state.mode == MODE_CONFIG) {
|
||||||
|
e_printf("[KEY] 配网模式下,忽略短按事件\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在产测模式下,忽略短按事件
|
||||||
|
if (g_device_state.mode == MODE_FACTORY_TEST) {
|
||||||
|
e_printf("[KEY] 产测模式下,忽略短按事件\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正常模式下切换开关状态
|
||||||
|
bool current_state = g_device_state.switches[key_id].switch_on;
|
||||||
|
update_switch_state(key_id, !current_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理按键长按事件
|
||||||
|
void handle_key_long_press(int key_id) {
|
||||||
|
if (key_id < 0 || key_id >= SWITCH_COUNT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[KEY] 处理按键%d 长按事件\r\n", key_id + 1);
|
||||||
|
|
||||||
|
// 只有第一个按键支持长按进入配网模式
|
||||||
|
if (key_id == 0) {
|
||||||
|
e_printf("[KEY] 长按第一个按键,进入配网模式\r\n");
|
||||||
|
|
||||||
|
// 只有在正常模式下才能进入配网模式
|
||||||
|
if (g_device_state.mode == MODE_NORMAL) {
|
||||||
|
enter_config_mode();
|
||||||
|
} else {
|
||||||
|
e_printf("[KEY] 非正常模式,不能进入配网模式\r\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e_printf("[KEY] 非第一个按键的长按,忽略\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 初始化函数 ======================
|
||||||
|
|
||||||
|
int key_system_init(void) {
|
||||||
|
int ret = ERRCODE_SUCC;
|
||||||
|
|
||||||
|
// 初始化定时器
|
||||||
|
ret = uapi_timer_init();
|
||||||
|
if (ret != ERRCODE_SUCC) {
|
||||||
|
e_printf("[KEY] 定时器初始化失败: %d\r\n", ret);
|
||||||
|
return HF_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化定时器参数
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
g_timer_params[i].key_id = i;
|
||||||
|
|
||||||
|
// 创建防抖定时器
|
||||||
|
ret = uapi_timer_create(TIMER_INDEX_0, &g_key_debounce_timer[i]);
|
||||||
|
if (ret != ERRCODE_SUCC) {
|
||||||
|
e_printf("[KEY] 创建按键%d防抖定时器失败: %d\r\n", i + 1, ret);
|
||||||
|
return HF_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化按键状态
|
||||||
|
g_key_states[i] = get_key_input(i);
|
||||||
|
g_device_state.switches[i].physical_key = g_key_states[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建按键扫描任务
|
||||||
|
g_key_scan_task_handle = osal_kthread_create((osal_kthread_handler)key_scan_task,
|
||||||
|
NULL,
|
||||||
|
"key_scan",
|
||||||
|
TASK_STACK_SIZE);
|
||||||
|
if (!g_key_scan_task_handle) {
|
||||||
|
e_printf("[KEY] 创建按键扫描任务失败\r\n");
|
||||||
|
return HF_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置任务优先级
|
||||||
|
ret = osal_kthread_set_priority(g_key_scan_task_handle, TASK_PRIORITY_NORM);
|
||||||
|
if (ret != 0) {
|
||||||
|
e_printf("[KEY] 设置按键扫描任务优先级失败: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[KEY] 按键系统初始化完成\r\n");
|
||||||
|
return HF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 快速上报函数 ======================
|
||||||
|
|
||||||
|
// 快速上报单个开关状态
|
||||||
|
void fast_report_switch(int switch_id) {
|
||||||
|
if (switch_id < 0 || switch_id >= SWITCH_COUNT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char svc_id[16] = {0};
|
||||||
|
snprintf(svc_id, sizeof(svc_id), "switch%d", switch_id + 1);
|
||||||
|
|
||||||
|
// 使用已有的fast_report函数
|
||||||
|
extern int fast_report(const char* svc_id);
|
||||||
|
fast_report(svc_id);
|
||||||
|
|
||||||
|
e_printf("[REPORT] 已上报开关%d状态\r\n", switch_id + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快速上报总开关状态
|
||||||
|
void fast_report_master_switch(void) {
|
||||||
|
extern int fast_report(const char* svc_id);
|
||||||
|
fast_report("switch");
|
||||||
|
|
||||||
|
e_printf("[REPORT] 已上报总开关状态\r\n");
|
||||||
|
}
|
432
application/ws63/user_main/switch_panel/switch_panel_main.c
Normal file
432
application/ws63/user_main/switch_panel/switch_panel_main.c
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
//====================== 全局变量 ======================
|
||||||
|
device_state_t g_device_state = {0};
|
||||||
|
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;
|
||||||
|
osal_task *g_key_scan_task_handle = NULL;
|
||||||
|
osal_task *g_config_task_handle = NULL;
|
||||||
|
|
||||||
|
static bool g_initialized = false;
|
||||||
|
static uint32_t g_config_start_time = 0;
|
||||||
|
static bool g_config_led_state = false;
|
||||||
|
|
||||||
|
//====================== 存储管理函数 ======================
|
||||||
|
|
||||||
|
// 计算数据校验码
|
||||||
|
|
||||||
|
// 计算校验和
|
||||||
|
static uint8_t calculate_checksum(const uint8_t* data, int len)
|
||||||
|
{
|
||||||
|
uint8_t sum = 0;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sum ^= data[i];
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从指定地址读取设备数据
|
||||||
|
static bool read_device_data_from_addr(uint32_t addr, uint8_t* data, uint32_t len)
|
||||||
|
{
|
||||||
|
int total_size = sizeof(device_data_t) + len;
|
||||||
|
device_data_t *data_all = malloc(total_size);
|
||||||
|
if (data_all == NULL) {
|
||||||
|
e_printf("内存分配失败\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = hfuflash_read(addr, (char*)data_all, total_size);
|
||||||
|
if (ret != total_size) {
|
||||||
|
e_printf("从地址0x%x读取设备数据失败,实际读取长度:%d\r\n", addr, ret);
|
||||||
|
goto lab_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_all->magic != DEVICE_DATA_MAGIC) {
|
||||||
|
e_printf("magic error:%x\n", data_all->magic);
|
||||||
|
goto lab_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_all->version > DEVICE_DATA_VERSION) {
|
||||||
|
e_printf("versoin missmatch:%x\n", data_all->version);
|
||||||
|
goto lab_err;
|
||||||
|
}
|
||||||
|
memcpy_s(data, len, data_all->data, data_all->data_len);
|
||||||
|
free(data_all);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
lab_err:
|
||||||
|
free(data_all);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入数据到指定地址
|
||||||
|
static bool write_device_data_to_addr(uint32_t addr, uint8_t* data, uint32_t len)
|
||||||
|
{
|
||||||
|
int ret = hfuflash_erase_page(addr, 1);
|
||||||
|
if (ret != HF_SUCCESS) {
|
||||||
|
e_printf("擦除地址0x%x的Flash页失败,错误码:%d\r\n", addr, ret);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32_t total_size = sizeof(device_data_t) + len;
|
||||||
|
device_data_t *data_all = malloc(total_size);
|
||||||
|
if (data_all == NULL) {
|
||||||
|
e_printf("内存分配失败\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(data_all, 0, total_size);
|
||||||
|
memcpy_s(data_all->data, len, data, len);
|
||||||
|
data_all->checksum = calculate_checksum(data_all->data, data_all->data_len);
|
||||||
|
data_all->magic = DEVICE_DATA_MAGIC;
|
||||||
|
data_all->version = DEVICE_DATA_VERSION;
|
||||||
|
ret = hfuflash_write(addr, (char*)data_all, total_size);
|
||||||
|
if (ret != total_size) {
|
||||||
|
e_printf("写入数据到地址0x%x失败,实际写入长度:%d\r\n", addr, ret);
|
||||||
|
free(data_all);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
free(data_all);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 从 Flash 加载设备状态
|
||||||
|
int load_device_state(void) {
|
||||||
|
int ret = 0;
|
||||||
|
device_state_t state;
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
// 尝试读取主数据区
|
||||||
|
valid = read_device_data_from_addr(DEVICE_DATA_FLASH_ADDR, (uint8_t*)&state, sizeof(state));
|
||||||
|
|
||||||
|
// 如果主数据区无效,尝试读取备份区
|
||||||
|
if (!valid) {
|
||||||
|
valid = read_device_data_from_addr(DEVICE_DATA_BACKUP_ADDR, (uint8_t*)&state, sizeof(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 两个存储区都失败,使用默认状态
|
||||||
|
if (!valid) {
|
||||||
|
e_printf("[STORAGE] 存储区数据损坏,使用默认状态\r\n");
|
||||||
|
reset_device_state();
|
||||||
|
save_device_state();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// 更新设备控制状态
|
||||||
|
e_printf("设备状态恢复:\r\n");
|
||||||
|
e_printf("首次启动: %d => %d\r\n", g_device_state.is_first_boot, state.is_first_boot);
|
||||||
|
e_printf("配网状态: %d => %d\r\n", g_device_state.is_bound, state.is_bound);
|
||||||
|
e_printf("总开关: %d => %d\r\n", g_device_state.master_switch, state.master_switch);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&g_device_state, &state, sizeof(device_state_t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存设备状态到 Flash
|
||||||
|
int save_device_state(void) {
|
||||||
|
int ret = 0;
|
||||||
|
device_state_t state;
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
// 准备数据
|
||||||
|
memcpy(&state, &g_device_state, sizeof(device_state_t));
|
||||||
|
// 保存到主存储区
|
||||||
|
ret = write_device_data_to_addr(DEVICE_DATA_FLASH_ADDR, (uint8_t*)&state, sizeof(state));
|
||||||
|
if (ret != HF_SUCCESS) {
|
||||||
|
e_printf("[STORAGE] 写入主存储区失败: %d\r\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存到备份区
|
||||||
|
ret = write_device_data_to_addr(DEVICE_DATA_BACKUP_ADDR, (uint8_t*)&state, sizeof(state));
|
||||||
|
if (ret != HF_SUCCESS) {
|
||||||
|
e_printf("[STORAGE] 写入备份区失败: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
e_printf("[STORAGE] 设备状态保存完成\r\n");
|
||||||
|
return HF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置设备状态为默认值
|
||||||
|
void reset_device_state(void) {
|
||||||
|
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.mode = MODE_NORMAL; // 正常模式
|
||||||
|
|
||||||
|
// 所有开关默认关闭,所有LED默认黄灯
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
g_device_state.switches[i].switch_on = false; // 开关关闭
|
||||||
|
g_device_state.switches[i].led_state = false; // LED黄灯
|
||||||
|
g_device_state.switches[i].physical_key = true; // 按键松开
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[STATE] 设备状态已重置为默认值\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== GPIO配置数据结构 ======================
|
||||||
|
typedef struct {
|
||||||
|
pin_t pin;
|
||||||
|
gpio_direction_t direction;
|
||||||
|
const char* name;
|
||||||
|
} gpio_config_t;
|
||||||
|
|
||||||
|
// 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"},
|
||||||
|
{SWITCH3_GPIO, GPIO_DIRECTION_OUTPUT, "SWITCH3"},
|
||||||
|
{SWITCH4_GPIO, GPIO_DIRECTION_OUTPUT, "SWITCH4"},
|
||||||
|
|
||||||
|
// 物理按键 - 输入
|
||||||
|
{KEY1_GPIO, GPIO_DIRECTION_INPUT, "KEY1"},
|
||||||
|
{KEY2_GPIO, GPIO_DIRECTION_INPUT, "KEY2"},
|
||||||
|
{KEY3_GPIO, GPIO_DIRECTION_INPUT, "KEY3"},
|
||||||
|
{KEY4_GPIO, GPIO_DIRECTION_INPUT, "KEY4"},
|
||||||
|
|
||||||
|
// 面板背光 - 输出
|
||||||
|
{PANEL_LED_GPIO, GPIO_DIRECTION_OUTPUT, "PANEL_LED"}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GPIO_CONFIG_COUNT (sizeof(gpio_configs) / sizeof(gpio_config_t))
|
||||||
|
|
||||||
|
//====================== 硬件控制函数 ======================
|
||||||
|
|
||||||
|
// GPIO 初始化
|
||||||
|
int switch_panel_gpio_init(void) {
|
||||||
|
int ret = HF_SUCCESS;
|
||||||
|
|
||||||
|
// 初始化pinctrl和GPIO
|
||||||
|
uapi_pin_init();
|
||||||
|
// uapi_gpio_init();
|
||||||
|
|
||||||
|
// 使用循环配置所有GPIO
|
||||||
|
for (int i = 0; i < GPIO_CONFIG_COUNT; i++) {
|
||||||
|
const gpio_config_t* config = &gpio_configs[i];
|
||||||
|
|
||||||
|
// 设置为GPIO模式
|
||||||
|
ret = uapi_pin_set_mode(config->pin, PIN_MODE_0);
|
||||||
|
if (ret != HF_SUCCESS) {
|
||||||
|
e_printf("[GPIO] %s pinctrl初始化失败: %d\r\n", config->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置GPIO方向
|
||||||
|
ret = uapi_gpio_set_dir(config->pin, config->direction);
|
||||||
|
if (ret != HF_SUCCESS) {
|
||||||
|
e_printf("[GPIO] %s 设置方向失败: %d\r\n", config->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[GPIO] %s 初始化完成 (方向: %s)\r\n",
|
||||||
|
config->name,
|
||||||
|
config->direction == GPIO_DIRECTION_OUTPUT ? "输出" : "输入");
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[GPIO] 所有GPIO初始化完成 (共%d个)\r\n", GPIO_CONFIG_COUNT);
|
||||||
|
return HF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置开关输出状态
|
||||||
|
void set_switch_output(int switch_id, bool state) {
|
||||||
|
if (switch_id < 0 || switch_id >= SWITCH_COUNT) {
|
||||||
|
e_printf("[HW] 无效的开关ID: %d\r\n", switch_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_t gpio_pin;
|
||||||
|
switch (switch_id) {
|
||||||
|
case 0: gpio_pin = SWITCH1_GPIO; break; // SWITCH1
|
||||||
|
case 1: gpio_pin = SWITCH2_GPIO; break; // SWITCH2
|
||||||
|
case 2: gpio_pin = SWITCH3_GPIO; break; // SWITCH3
|
||||||
|
case 3: gpio_pin = SWITCH4_GPIO; break; // SWITCH4
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置输出状态
|
||||||
|
gpio_level_t level = state ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
|
||||||
|
uapi_gpio_set_val(gpio_pin, level);
|
||||||
|
e_printf("[HW] 开关%d 状态: %s\r\n", switch_id + 1, state ? "开" : "关");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置 LED 指示灯状态
|
||||||
|
void set_led_output(int led_id, led_state_t state) {
|
||||||
|
if (led_id < 0 || led_id >= SWITCH_COUNT) {
|
||||||
|
e_printf("[HW] 无效的LED ID: %d\r\n", led_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_t gpio_pin;
|
||||||
|
switch (led_id) {
|
||||||
|
case 0: gpio_pin = LED1_GPIO; break; // LED1
|
||||||
|
case 1: gpio_pin = LED2_GPIO; break; // LED2
|
||||||
|
case 2: gpio_pin = LED3_GPIO; break; // LED3
|
||||||
|
case 3: gpio_pin = LED4_GPIO; break; // LED4
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置LED状态 (高电平=白灯, 低电平=黄灯)
|
||||||
|
gpio_level_t level = (state == LED_WHITE) ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
|
||||||
|
uapi_gpio_set_val(gpio_pin, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置面板背光状态
|
||||||
|
void set_panel_led(panel_led_state_t state) {
|
||||||
|
// 设置面板背光状态 (高电平=亮黄灯, 低电平=灭灯)
|
||||||
|
gpio_level_t level = (state == PANEL_LED_ON) ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
|
||||||
|
uapi_gpio_set_val(PANEL_LED_GPIO, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取按键输入状态
|
||||||
|
bool get_key_input(int key_id) {
|
||||||
|
if (key_id < 0 || key_id >= SWITCH_COUNT) {
|
||||||
|
return true; // 默认松开状态
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_t gpio_pin;
|
||||||
|
switch (key_id) {
|
||||||
|
case 0: gpio_pin = KEY1_GPIO; break; // KEY1
|
||||||
|
case 1: gpio_pin = KEY2_GPIO; break; // KEY2
|
||||||
|
case 2: gpio_pin = KEY3_GPIO; break; // KEY3
|
||||||
|
case 3: gpio_pin = KEY4_GPIO; break; // KEY4
|
||||||
|
default: return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取输入状态 (低电平=按下, 高电平=松开)
|
||||||
|
gpio_level_t level = uapi_gpio_get_val(gpio_pin);
|
||||||
|
return (level == GPIO_LEVEL_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 设备状态同步函数 ======================
|
||||||
|
|
||||||
|
// 同步硬件状态与软件状态
|
||||||
|
void sync_hardware_state(void) {
|
||||||
|
// 同步所有开关状态
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
set_switch_output(i, g_device_state.switches[i].switch_on);
|
||||||
|
set_led_output(i, g_device_state.switches[i].led_state ? LED_WHITE : LED_YELLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步面板背光状态
|
||||||
|
set_panel_led(g_device_state.panel_led ? PANEL_LED_ON : PANEL_LED_OFF);
|
||||||
|
|
||||||
|
e_printf("[STATE] 硬件状态已同步\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 主程序函数 ======================
|
||||||
|
|
||||||
|
int switch_panel_main(void) {
|
||||||
|
int ret = HF_SUCCESS;
|
||||||
|
|
||||||
|
if (g_initialized) {
|
||||||
|
e_printf("[MAIN] 开关面板已初始化\r\n");
|
||||||
|
return HF_SUCCESS;
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步硬件状态
|
||||||
|
sync_hardware_state();
|
||||||
|
|
||||||
|
// 保存状态更新
|
||||||
|
save_device_state();
|
||||||
|
|
||||||
|
// 配网逻辑:
|
||||||
|
// 1. 如果设备未绑定 且 是第一次启动 -> 直接进入配网
|
||||||
|
// 2. 如果设备未绑定 且 不是第一次启动 -> 等待按键触发配网
|
||||||
|
if (!g_device_state.is_bound) {
|
||||||
|
if (first_boot) {
|
||||||
|
e_printf("[MAIN] 首次启动且未绑定,直接进入配网模式\r\n");
|
||||||
|
enter_config_mode();
|
||||||
|
} else {
|
||||||
|
e_printf("[MAIN] 设备未绑定,等待按键触发配网\r\n");
|
||||||
|
// 配网逻辑将在按键处理函数中实现
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e_printf("[MAIN] 设备已绑定,正常运行\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
e_printf("[MAIN] SORONTEK智能面板初始化完成\r\n");
|
||||||
|
print_device_state();
|
||||||
|
|
||||||
|
return HF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================== 调试函数 ======================
|
||||||
|
|
||||||
|
void print_device_state(void) {
|
||||||
|
e_printf("\r\n===== 设备状态信息 =====\r\n");
|
||||||
|
e_printf("总开关: %s\r\n", g_device_state.master_switch ? "开" : "关");
|
||||||
|
e_printf("面板背光: %s\r\n", g_device_state.panel_led ? "开" : "关");
|
||||||
|
e_printf("绑定状态: %s\r\n", g_device_state.is_bound ? "已绑定" : "未绑定");
|
||||||
|
e_printf("首次启动: %s\r\n", g_device_state.is_first_boot ? "是" : "否");
|
||||||
|
e_printf("工作模式: %s\r\n", get_mode_string(g_device_state.mode));
|
||||||
|
|
||||||
|
for (int i = 0; i < SWITCH_COUNT; i++) {
|
||||||
|
e_printf("开关%d: %s, LED: %s\r\n",
|
||||||
|
i + 1,
|
||||||
|
g_device_state.switches[i].switch_on ? "开" : "关",
|
||||||
|
g_device_state.switches[i].led_state ? "白灯" : "黄灯");
|
||||||
|
}
|
||||||
|
e_printf("=======================\r\n\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* get_mode_string(system_mode_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case MODE_NORMAL: return "正常模式";
|
||||||
|
case MODE_CONFIG: return "配网模式";
|
||||||
|
case MODE_FACTORY_TEST: return "产测模式";
|
||||||
|
case MODE_UNBIND: return "解绑模式";
|
||||||
|
default: return "未知模式";
|
||||||
|
}
|
||||||
|
}
|
@ -265,7 +265,7 @@ target = {
|
|||||||
},
|
},
|
||||||
'ws63-liteos-app-iot': {
|
'ws63-liteos-app-iot': {
|
||||||
'base_target_name': 'target_ws63_app_rom_template',
|
'base_target_name': 'target_ws63_app_rom_template',
|
||||||
# 'liteos_kconfig': 'ws63_iot',
|
'liteos_kconfig': 'ws63_iot', #ekko add for remove indie upgrade
|
||||||
'os': 'liteos',
|
'os': 'liteos',
|
||||||
'defines': [
|
'defines': [
|
||||||
"USE_CMSIS_OS",
|
"USE_CMSIS_OS",
|
||||||
@ -308,7 +308,7 @@ target = {
|
|||||||
"SUPPORT_SOFTAP_NETCFG", # softAP配网
|
"SUPPORT_SOFTAP_NETCFG", # softAP配网
|
||||||
"SUPPORT_BLE_ANCILLAY_NETCFG", # ble辅助配网
|
"SUPPORT_BLE_ANCILLAY_NETCFG", # ble辅助配网
|
||||||
# "SUPPORT_QUICK_NETCFG", # 快速配网
|
# "SUPPORT_QUICK_NETCFG", # 快速配网
|
||||||
"CONFIG_SUPPORT_HILINK_INDIE_UPGRADE",
|
# "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE", #ekko remove for indie upgrade
|
||||||
"CONFIG_DHCPS_GW",
|
"CONFIG_DHCPS_GW",
|
||||||
"_HSF_",
|
"_HSF_",
|
||||||
# "ENABLE_BLE_SCAN" #open ble scan
|
# "ENABLE_BLE_SCAN" #open ble scan
|
||||||
@ -354,10 +354,11 @@ target = {
|
|||||||
'cjson',
|
'cjson',
|
||||||
'xo_trim_port',
|
'xo_trim_port',
|
||||||
'hilink',
|
'hilink',
|
||||||
'app_addr_map',
|
# 'app_addr_map', #ekko remove for indie upgrade
|
||||||
# 'hilinkdevicesdk',
|
'hilinkdevicesdk', #ekko add for remove indie upgrade
|
||||||
# 'hilinkota',
|
'hilinkota', #ekko add for remove indie upgrade
|
||||||
# 'hilinkbtsdk',
|
'hilinkbtsdk', #ekko add for remove indie upgrade
|
||||||
|
# 'hilinkquickcfg', #ekko add for remove indie upgrade
|
||||||
'huks_sdk',
|
'huks_sdk',
|
||||||
'deviceauth',
|
'deviceauth',
|
||||||
'little_fs', 'littlefs_adapt_ws63',
|
'little_fs', 'littlefs_adapt_ws63',
|
||||||
|
47
readme.md
47
readme.md
@ -2,31 +2,6 @@
|
|||||||
|
|
||||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
## Build and Development Commands
|
|
||||||
1. **Build the project**: Run `python build.py` from the root directory.
|
|
||||||
2. **Clean build artifacts**: Run `python build.py clean`.
|
|
||||||
3. **Flash the device**: Use the `hfloader` tool with the appropriate firmware file.
|
|
||||||
|
|
||||||
## Key Codebase Structure
|
|
||||||
1. **Entry Point**: `application/ws63/user_main/app_main.c` contains `user_app_main`, the main entry point for the application.
|
|
||||||
2. **Hilink Integration**:
|
|
||||||
- `application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c` is the Hilink SDK configuration and setup entry.
|
|
||||||
- `application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c` maps physical models to cloud models.
|
|
||||||
3. **Physical Model Control**:
|
|
||||||
- GPIO and LED controls are defined in `application/ws63/hsf`.
|
|
||||||
- Reference implementations are in `refence/LPT26x-HSF-4MB-Hilink_14.2.0.308_20250411`.
|
|
||||||
4. **Device Configuration**:
|
|
||||||
- `build/config/target_config/ws63/config.py` contains build configurations.
|
|
||||||
- `application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h` defines device metadata.
|
|
||||||
|
|
||||||
## Important Notes
|
|
||||||
- **Flash Storage**: Device states (switch, LED, etc.) must be saved to flash immediately after modification.
|
|
||||||
- **Cloud Sync**: Implement logic in `HILINK_NotifyDevStatus` for online/offline state handling.
|
|
||||||
- **Physical and APP Control**: Ensure synchronization between physical button presses and APP controls.
|
|
||||||
|
|
||||||
## Reference Code
|
|
||||||
- Review `refence/LPT26x-HSF-4MB-Hilink_14.2.0.308_20250411` for examples of Hilink integration and device control.
|
|
||||||
|
|
||||||
你是一个资深的物联网嵌入式工程师。这里有一个基于完善的一个智能家居的sdk进行开发的需求,其是基于汉枫(hf)模组+鸿蒙系统(ohos)开发的。
|
你是一个资深的物联网嵌入式工程师。这里有一个基于完善的一个智能家居的sdk进行开发的需求,其是基于汉枫(hf)模组+鸿蒙系统(ohos)开发的。
|
||||||
|
|
||||||
## SDK 相关介绍
|
## SDK 相关介绍
|
||||||
@ -46,15 +21,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
8. indie_upg.md 是关于支持hilink独立升级如何修改代码的说明文档,可供参考
|
8. indie_upg.md 是关于支持hilink独立升级如何修改代码的说明文档,可供参考
|
||||||
|
|
||||||
通过以上信息你已经可以基本了解整个SDK的运作的原理
|
通过以上信息你已经可以基本了解整个SDK的运作的原理
|
||||||
|
目前项目工程是一个已有的项目的代码,你需要在这个基础上进行改造,删除不要的东西。
|
||||||
|
|
||||||
|
## 参考已有产品的的代码
|
||||||
## 参考已有铲平的代码
|
!!这部分非常重要!!!,里面有很多的hilink,配网,和云端交互等的示例,可以帮助你更好的编写代码
|
||||||
!!这部分非常重要!!!,里面有很多的hilink,配网,和云端交互等的示例,可以帮助你更好的编写代码,请你仔细分析!
|
|
||||||
refence/LPT26x-HSF-4MB-Hilink_14.2.0.308_20250411
|
|
||||||
这是此前的一款射灯产品的源码,里面核心的几个文件夹为:
|
这是此前的一款射灯产品的源码,里面核心的几个文件夹为:
|
||||||
refence/LPT26x-HSF-4MB-Hilink_14.2.0.308_20250411/application/ws63/user_main
|
application/ws63/user_main
|
||||||
refence/LPT26x-HSF-4MB-Hilink_14.2.0.308_20250411/application/samples/wifi/ohos_connect/hilink_adapt/product/
|
application/samples/wifi/ohos_connect/hilink_adapt/product/
|
||||||
你可以参考看看里面能够复用的部分!
|
你可以参考看看里面哪些是能够复用的部分。哪些是要删除的
|
||||||
|
|
||||||
## 软件相关的定义如下:
|
## 软件相关的定义如下:
|
||||||
1. 其物理模型2Q4G.json,但是里面的netInfo timer update这几个是hilink内部已经实现无需我们关心,我们只需要关心switch3、switch2、switch1、switch4 switch这几个物理模型。
|
1. 其物理模型2Q4G.json,但是里面的netInfo timer update这几个是hilink内部已经实现无需我们关心,我们只需要关心switch3、switch2、switch1、switch4 switch这几个物理模型。
|
||||||
@ -100,13 +74,20 @@ LED 是整个控制面板的背光灯,高电平亮灯(黄色),低电平灭
|
|||||||
|
|
||||||
## 软件编写规范
|
## 软件编写规范
|
||||||
1. 实现需求需要在application/ws63/user_main另外新建文件夹(命名你根据产品需求定义)实现相关逻辑
|
1. 实现需求需要在application/ws63/user_main另外新建文件夹(命名你根据产品需求定义)实现相关逻辑
|
||||||
|
2. flush操作的api可见 application/ws63/hsf/hfflash.h 里面定义的 HSF_API 修饰的api
|
||||||
|
3. gpio其相关api可见 include/driver/pinctrl.h 和 include/driver/gpio.h。
|
||||||
|
其中 PIN_MODE_0 为输入模式,PIN_MODE_1输出模式
|
||||||
|
GPIO口枚举可见drivers/chips/ws63/include/platform_core_rom.h
|
||||||
|
5. 延时使用msleep
|
||||||
|
6. 定时器使用 uapi_timer_xx 头文件定义在-> include/driver/timer.h
|
||||||
|
7. 线程相关使用 osal_kthread_xx 头文件定义在-> kernel/osal/include/schedule/osal_task.h
|
||||||
|
|
||||||
### SORONTEK智能面板产测:
|
### SORONTEK智能面板产测:
|
||||||
1.由信标发送产测信号
|
1.由信标发送产测信号
|
||||||
=》识别固定的热点名作为进入产测的信号
|
=》识别固定的热点名作为进入产测的信号
|
||||||
2.开关循环:开1-开2-开3-开4-全关-全开-全关
|
2.开关循环:开1-开2-开3-开4-全关-全开-全关
|
||||||
3.每1.5秒执行一个动作
|
3.每1.5秒执行一个动作
|
||||||
4. 需要校验WIFI 信号强度吗?(射灯有此逻辑)
|
4. 需要校验WIFI 信号强度吗
|
||||||
|
|
||||||
### SORONTEK智能面板配网:
|
### SORONTEK智能面板配网:
|
||||||
1. 只有设备处于未绑定状态才能进行配网(出厂或者被APP删除)
|
1. 只有设备处于未绑定状态才能进行配网(出厂或者被APP删除)
|
||||||
|
Reference in New Issue
Block a user