/** * @file protocol.c * @brief this file contains protocol analysis and construct response function when received zigbee module send message * @author qinlang * @date 2022.05.06 * @par email:qinlang.chen@tuya.com * @copyright HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD * @par company * http://www.tuya.com */ #include #include "TM52F1386_bsp.h" #include #include "zigbee.h" #include "uart.h" #include "GLOBAL.h" #include "gpio_ctrl.h" #include "EEPROM.h" #include #include "iap.h" #include #include #include "HLW8110.h" unsigned char string_H16_data[32]; // 16进制字符串 unsigned char hex_data[32]; // 转换后的16进制字节数据 /****************************************************************************** 移植须知: 1:MCU必须在while中直接调用mcu_api.c内的zigbee_uart_service()函数 2:程序正常初始化完成后,建议不进行关串口中断,如必须关中断,关中断时间必须短,关中断会引起串口数据包丢失 3:请勿在中断/定时器中断内调用上报函数 ******************************************************************************/ /****************************************************************************** 第一步:初始化 1:在需要使用到zigbee相关文件的文件中include "zigbee.h" 2:在MCU初始化中调用mcu_api.c文件中的zigbee_protocol_init()函数 3:将MCU串口单字节发送函数填入protocol.c文件中uart_transmit_output函数内,并删除#error 4:在MCU串口接收函数中调用mcu_api.c文件内的uart_receive_input函数,并将接收到的字节作为参数传入 5:单片机进入while循环后调用mcu_api.c文件内的zigbee_uart_service()函数 6:mcu何时开启zigbee模块配网,当zigbee模块查询到mcu的产品信息之后,或者zigbee模块发送了当前网络状态 给到mcu,查询pid信息会在上电5秒之后发送,对接部分zigbee老版本通用对接固件低功耗版本尤其需要注意不要 在第一次确认波特率的时候提前唤醒或者发送串口给zigbee模组,有概率导致zigbee模组波特率存储失败。 7:上电之后,mcu何时上报数据给网关合适,在收到网络状态为已配网,或者接收到读取dp数据的时候。 8: 在mcu ota过程中发送固件内容请求未收到zigbee模块的应答时,需要mcu端做好超时重新请求的处理,和存储image 处理,校验和可以自行设计或者使用参考。 ******************************************************************************/ /****************************************************************************** 1:dp数据点序列类型对照表 **此为自动生成代码,如在开发平台有相关修改请重新下载MCU_SDK** ******************************************************************************/ ///> dp data list, this will be generated by cloud platform #if (defined ZIGBEE_ZTU_T3_SW) && (defined ZIGBEE_3SWITCH_SW) //#ifdef ZIGBEE_ZTU_T3_SW const DOWNLOAD_CMD_S download_cmd[] = { {DPID_SWITCH_1, DP_TYPE_BOOL}, {DPID_SWITCH_2, DP_TYPE_BOOL}, {DPID_SWITCH_3, DP_TYPE_BOOL}, {DPID_RELAY_STATUS, DP_TYPE_ENUM}, {DPID_SWITCH_INCHING, DP_TYPE_STRING}, {DPID_ADD_ELE, DP_TYPE_VALUE}, {DPID_CUR_CURRENT, DP_TYPE_VALUE}, {DPID_CUR_POWER, DP_TYPE_VALUE}, {DPID_CUR_VOLTAGE, DP_TYPE_VALUE}, {DPID_RELAY_STATUS_1, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_2, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_3, DP_TYPE_ENUM}, {DPID_LIGHT_LEVEL, DP_TYPE_ENUM}, {DPID_CUR_CURRENT_2, DP_TYPE_VALUE}, {DPID_CUR_POWER_2, DP_TYPE_VALUE}, {DPID_ADD_ELE_2, DP_TYPE_VALUE}, {DPID_CUR_CURRENT_3, DP_TYPE_VALUE}, {DPID_CUR_POWER_3, DP_TYPE_VALUE}, {DPID_ADD_ELE_3, DP_TYPE_VALUE}, }; #endif #ifdef ZIGBEE_ZTU_T2_SW const DOWNLOAD_CMD_S download_cmd[] = { {DPID_SWITCH_1, DP_TYPE_BOOL}, {DPID_SWITCH_2, DP_TYPE_BOOL}, {DPID_RELAY_STATUS, DP_TYPE_ENUM}, {DPID_SWITCH_INCHING, DP_TYPE_STRING}, {DPID_ADD_ELE, DP_TYPE_VALUE}, {DPID_CUR_CURRENT, DP_TYPE_VALUE}, {DPID_CUR_POWER, DP_TYPE_VALUE}, {DPID_CUR_VOLTAGE, DP_TYPE_VALUE}, {DPID_RELAY_STATUS_1, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_2, DP_TYPE_ENUM}, {DPID_LIGHT_LEVEL, DP_TYPE_ENUM}, {DPID_CUR_CURRENT_2, DP_TYPE_VALUE}, {DPID_CUR_POWER_2, DP_TYPE_VALUE}, {DPID_ADD_ELE_2, DP_TYPE_VALUE}, }; #endif #ifdef ZIGBEE_ZTU_T1_SW const DOWNLOAD_CMD_S download_cmd[] = { {DPID_SWITCH_1, DP_TYPE_BOOL}, {DPID_RELAY_STATUS, DP_TYPE_ENUM}, {DPID_SWITCH_INCHING, DP_TYPE_STRING}, {DPID_ADD_ELE, DP_TYPE_VALUE}, {DPID_CUR_CURRENT, DP_TYPE_VALUE}, {DPID_CUR_POWER, DP_TYPE_VALUE}, {DPID_CUR_VOLTAGE, DP_TYPE_VALUE}, {DPID_RELAY_STATUS_1, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_2, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_3, DP_TYPE_ENUM}, {DPID_LIGHT_LEVEL, DP_TYPE_ENUM}, }; #endif #ifdef ZIGBEE_ZTU_T6_SCENCE_SW const DOWNLOAD_CMD_S download_cmd[] = { {DPID_SCENE_1, DP_TYPE_ENUM}, {DPID_SCENE_2, DP_TYPE_ENUM}, {DPID_SCENE_3, DP_TYPE_ENUM}, {DPID_SCENE_4, DP_TYPE_ENUM}, {DPID_SCENE_5, DP_TYPE_ENUM}, {DPID_SCENE_6, DP_TYPE_ENUM}, {DPID_MODE_1, DP_TYPE_ENUM}, {DPID_MODE_2, DP_TYPE_ENUM}, {DPID_MODE_3, DP_TYPE_ENUM}, {DPID_SWITCH_1, DP_TYPE_BOOL}, {DPID_SWITCH_2, DP_TYPE_BOOL}, {DPID_SWITCH_3, DP_TYPE_BOOL}, {DPID_LIGHT_MODE, DP_TYPE_ENUM}, {DPID_RELAY_STATUS, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_1, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_2, DP_TYPE_ENUM}, {DPID_RELAY_STATUS_3, DP_TYPE_ENUM}, {DPID_SWITCH_INCHING, DP_TYPE_STRING}, {DPID_ADD_ELE, DP_TYPE_VALUE}, {DPID_CUR_VOLTAGE, DP_TYPE_VALUE}, {DPID_CUR_POWER, DP_TYPE_VALUE}, {DPID_CUR_CURRENT, DP_TYPE_VALUE}, {DPID_ADD_ELE_2, DP_TYPE_VALUE}, {DPID_CUR_CURRENT_2, DP_TYPE_VALUE}, {DPID_CUR_POWER_2, DP_TYPE_VALUE}, {DPID_ADD_ELE_3, DP_TYPE_VALUE}, {DPID_CUR_CURRENT_3, DP_TYPE_VALUE}, {DPID_CUR_POWER_3, DP_TYPE_VALUE}, }; #endif /****************************************************************************** 2:串口单字节发送函数 请将MCU串口发送函数填入该函数内,并将接收到的数据作为参数传入串口发送函数 ******************************************************************************/ static void report_mcu_ota_result(unsigned char res); /** * @brief encapsulates a generic send function, developer should use their own function to completing this fuction * @param[in] {value} send signle data * @return void */ ////must modify void uart_transmit_output(unsigned char value) { // static unsigned char buf; // buf = value; // #error "please use your own uart send fuction complete this fuction, exmaple" /* * //demo: * extern void Uart_PutChar(unsigned char value); * Uart_PutChar(value); */ UART0_send(value); } /****************************************************************************** 第二步:实现具体用户函数 1:APP下发数据处理 2:数据上报处理 ******************************************************************************/ /****************************************************************************** 1:所有数据上报处理 当前函数处理全部数据上报(包括可下发/可上报和只上报) 需要用户按照实际情况实现: 1:需要实现可下发/可上报数据点上报 2:需要实现只上报数据点上报 此函数为MCU内部必须调用 用户也可调用此函数实现全部数据上报 ******************************************************************************/ // 自动化生成数据上报函数 /** * @brief Upload all dp information of the system, and realize the synchronization of APP and muc data * @param[in] {void} * @return void */ #ifdef ZIGBEE_ZTU_T1_SW // #ifdef ZIGBEE_ZTU_T3_SW void all_data_update(void) { // #error "mcu must realize function internal function" /* * these fucntion will be generated by cloud platform, but when use these function must reference the function in mcu_api.c */ u08 i = 0; mcu_dp_bool_update(DPID_SWITCH_2, switchState.SWITCH[1]); // BOOL型数据上报; // mcu_dp_bool_update(DPID_SWITCH_1, switchState.SWITCH[0]); // BOOL型数据上报; // mcu_dp_bool_update(DPID_BACKLIGHT_SWITCH, switchState.human); // BOOL型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_1, switchState.relay_status[0]); // 枚举型数据上报; // mcu_dp_enum_update(DPID_RELAY_STATUS_2, switchState.relay_status[1]); // 枚举型数据上报; // mcu_dp_enum_update(DPID_LIGHT_MODE, switchState.led_level); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS, switchState.relay_allstatus); // 枚举型数据上报; /* mcu_dp_string_update(DPID_SWITCH_INCHING,当前点动开关(延时关)指针,当前点动开关(延时关)数据长度); //STRING型数据上报; */ for (i = 0; i < 3; i++) { hex_data[i * 3] = 0xff; hex_data[i * 3 + 1] = 0xff; hex_data[i * 3 + 2] = 0xff; } hex_data[0 * 3] = switchState.plus_mod[1]; hex_data[0 * 3 + 1] = (u08)((switchState.plus_auto_time[1] / 10) >> 8); hex_data[0 * 3 + 2] = (u08)((switchState.plus_auto_time[1] / 10) & 0x00ff); // 实际2号键做1号开关用 HexToDisHex(string_H16_data, hex_data, 9); // 转回16进制字符串 // mcu_dp_string_update(DPID_SWITCH_INCHING, string_H16_data, 18); // 点动开关(延时关)STRING型数据上报; } #endif #ifdef ZIGBEE_ZTU_T2_SW // #ifdef ZIGBEE_ZTU_T3_SW void all_data_update(void) { // #error "mcu must realize function internal function" /* * these fucntion will be generated by cloud platform, but when use these function must reference the function in mcu_api.c */ u08 i = 0; mcu_dp_bool_update(DPID_SWITCH_3, switchState.SWITCH[0]); // BOOL型数据上报; //mcu_dp_bool_update(DPID_SWITCH_2, switchState.SWITCH[1]); // BOOL型数据上报; mcu_dp_bool_update(DPID_SWITCH_1, switchState.SWITCH[2]); // BOOL型数据上报; // mcu_dp_bool_update(DPID_BACKLIGHT_SWITCH, switchState.human); // BOOL型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_1, switchState.relay_status[0]); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_2, switchState.relay_status[1]); // 枚举型数据上报; //mcu_dp_enum_update(DPID_RELAY_STATUS_3, switchState.relay_status[2]); // 枚举型数据上报; // mcu_dp_enum_update(DPID_LIGHT_MODE, switchState.led_level); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS, switchState.relay_allstatus); // 枚举型数据上报; /* mcu_dp_string_update(DPID_SWITCH_INCHING,当前点动开关(延时关)指针,当前点动开关(延时关)数据长度); //STRING型数据上报; */ for (i = 0; i < 3; i++) { hex_data[i * 3] = 0xff; hex_data[i * 3 + 1] = 0xff; hex_data[i * 3 + 2] = 0xff; } hex_data[0 * 3] = switchState.plus_mod[0]; hex_data[0 * 3 + 1] = (u08)((switchState.plus_auto_time[0] / 10) >> 8); hex_data[0 * 3 + 2] = (u08)((switchState.plus_auto_time[0] / 10) & 0x00ff); // 实际3号键做2号开关用 hex_data[1 * 3] = switchState.plus_mod[2]; hex_data[1 * 3 + 1] = (u08)((switchState.plus_auto_time[2] / 10) >> 8); hex_data[1 * 3 + 2] = (u08)((switchState.plus_auto_time[2] / 10) & 0x00ff); // 实际3号键做2号开关用 HexToDisHex(string_H16_data, hex_data, 9); // 转回16进制字符串 // mcu_dp_string_update(DPID_SWITCH_INCHING, string_H16_data, 18); // 点动开关(延时关)STRING型数据上报; } #endif #if (defined ZIGBEE_ZTU_T3_SW) && (defined ZIGBEE_3SWITCH_SW) //#ifdef ZIGBEE_ZTU_T3_SW void all_data_update(void) { // #error "mcu must realize function internal function" /* * these fucntion will be generated by cloud platform, but when use these function must reference the function in mcu_api.c */ u08 i = 0; mcu_dp_bool_update(DPID_SWITCH_3, switchState.SWITCH[0]); // BOOL型数据上报; mcu_dp_bool_update(DPID_SWITCH_2, switchState.SWITCH[1]); // BOOL型数据上报; mcu_dp_bool_update(DPID_SWITCH_1, switchState.SWITCH[2]); // BOOL型数据上报; // mcu_dp_bool_update(DPID_BACKLIGHT_SWITCH, switchState.human); // BOOL型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_1, switchState.relay_status[0]); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_2, switchState.relay_status[1]); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_3, switchState.relay_status[2]); // 枚举型数据上报; //mcu_dp_enum_update(DPID_LIGHT_MODE, switchState.led_level); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS, switchState.relay_allstatus); // 枚举型数据上报; /* mcu_dp_string_update(DPID_SWITCH_INCHING,当前点动开关(延时关)指针,当前点动开关(延时关)数据长度); //STRING型数据上报; */ for (i = 0; i < 3; i++) { hex_data[i * 3] = switchState.plus_mod[i]; hex_data[i * 3 + 1] = (u08)((switchState.plus_auto_time[i] / 10) >> 8); hex_data[i * 3 + 2] = (u08)((switchState.plus_auto_time[i] / 10) & 0x00ff); } HexToDisHex(string_H16_data, hex_data, 9); // 转回16进制字符串 //mcu_dp_string_update(DPID_SWITCH_INCHING, string_H16_data, 18); // 点动开关(延时关)STRING型数据上报; } #endif #ifdef ZIGBEE_ZTU_T6_SCENCE_SW void all_data_update(void) { // #error "mcu must realize function internal function" /* * these fucntion will be generated by cloud platform, but when use these function must reference the function in mcu_api.c */ u08 i = 0; mcu_dp_enum_update(DPID_RELAY_STATUS_1, switchState.relay_status[0]); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_2, switchState.relay_status[1]); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS_3, switchState.relay_status[2]); // 枚举型数据上报; // mcu_dp_enum_update(DPID_LIGHT_MODE, switchState.led_level); // 枚举型数据上报; mcu_dp_enum_update(DPID_RELAY_STATUS, switchState.relay_allstatus); // 枚举型数据上报; mcu_dp_enum_update(DPID_MODE_1, switchState.mod[0]); // 枚举型数据上报; mcu_dp_enum_update(DPID_MODE_2, switchState.mod[1]); // 枚举型数据上报; mcu_dp_enum_update(DPID_MODE_3, switchState.mod[2]); // 枚举型数据上报; if (switchState.mod[2] == 0) mcu_dp_bool_update(DPID_SWITCH_3, switchState.SWITCH[0]); // BOOL型数据上报; if (switchState.mod[1] == 0) mcu_dp_bool_update(DPID_SWITCH_2, switchState.SWITCH[1]); // BOOL型数据上报; if (switchState.mod[0] == 0) mcu_dp_bool_update(DPID_SWITCH_1, switchState.SWITCH[2]); // BOOL型数据上报; // 场景不需要主动上报,APP不需要查询状态 /* mcu_dp_enum_update(DPID_SCENE_1,当前场景1); //枚举型数据上报; mcu_dp_enum_update(DPID_SCENE_2,当前场景2); //枚举型数据上报; mcu_dp_enum_update(DPID_SCENE_3,当前场景3); //枚举型数据上报; mcu_dp_enum_update(DPID_SCENE_4,当前场景4); //枚举型数据上报; mcu_dp_enum_update(DPID_SCENE_5,当前场景5); //枚举型数据上报; mcu_dp_enum_update(DPID_SCENE_6,当前场景6); //枚举型数据上报; */ /* mcu_dp_string_update(DPID_SWITCH_INCHING,当前点动开关(延时关)指针,当前点动开关(延时关)数据长度); //STRING型数据上报; */ // switchState.plus_mod[0] = 1; // switchState.plus_auto_time[0] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 for (i = 0; i < 3; i++) { hex_data[i * 3] = switchState.plus_mod[i]; hex_data[i * 3 + 1] = (u08)((switchState.plus_auto_time[i] / 10) >> 8); hex_data[i * 3 + 2] = (u08)((switchState.plus_auto_time[i] / 10) & 0x00ff); } HexToDisHex(string_H16_data, hex_data, 9); // 转回16进制字符串 // mcu_dp_string_update(DPID_SWITCH_INCHING, string_H16_data, 18); // 点动开关(延时关)STRING型数据上报; } #endif void all_power_data_update(void) //电量数据上报函数 { char i; //test // switchState.dp_add_ele = 100*100;//100 kW·h // switchState.dp_cur_current = 1000;//1000mA // switchState.dp_cur_power = 330*10;//330w // switchState.dp_cur_voltage = 220*10;//220v #ifdef ZIGBEE_ZTU_T1_SW // if((switchState.dp_add_ele[0] !=0)&&((switchState.dp_add_ele[0] - data_dp_add_ele[0])>=1)) // { mcu_dp_value_update(DPID_ADD_ELE,switchState.dp_add_ele[0]); //VALUE型数据上报; if(data_dp_add_ele[0] != switchState.dp_add_ele[0]) { Save_data_ele_flag = 1; } data_dp_add_ele[0] = switchState.dp_add_ele[0]; // } // if((switchState.dp_cur_current[0] != 0)&&(switchState.dp_cur_current[0] != data_dp_cur_current[0])&&(switchState.dp_cur_current[0]<100000)) // { // data_dp_cur_current[0] = switchState.dp_cur_current[0]; mcu_dp_value_update(DPID_CUR_CURRENT,switchState.dp_cur_current[0]); //VALUE型数据上报; // } // if((switchState.dp_cur_power[0] != 0)&&(switchState.dp_cur_power[0] != data_dp_cur_power[0])&&(switchState.dp_cur_power[0]<22000)) // { // data_dp_cur_power[0] = switchState.dp_cur_power[0]; mcu_dp_value_update(DPID_CUR_POWER,switchState.dp_cur_power[0]); //VALUE型数据上报; // } if((switchState.dp_cur_voltage != 0)&&(switchState.dp_cur_voltage != data_dp_cur_voltage)&&(switchState.dp_cur_voltage<2500)) { data_dp_cur_voltage = switchState.dp_cur_voltage; mcu_dp_value_update(DPID_CUR_VOLTAGE,switchState.dp_cur_voltage); //VALUE型数据上报; } #endif #ifdef ZIGBEE_ZTU_T2_SW //第一路数据 // if((switchState.dp_add_ele[0] !=0)&&((switchState.dp_add_ele[0] - data_dp_add_ele[0])>=1)) // { mcu_dp_value_update(DPID_ADD_ELE,switchState.dp_add_ele[0]); //VALUE型数据上报; if(data_dp_add_ele[0] != switchState.dp_add_ele[0]) { Save_data_ele_flag = 1; } data_dp_add_ele[0] = switchState.dp_add_ele[0]; // } // if((switchState.dp_cur_current[0] != 0)&&(switchState.dp_cur_current[0] != data_dp_cur_current[0])&&(switchState.dp_cur_current[0]<100000)) // { // data_dp_cur_current[0] = switchState.dp_cur_current[0]; mcu_dp_value_update(DPID_CUR_CURRENT,switchState.dp_cur_current[0]); //VALUE型数据上报; // } // if((switchState.dp_cur_power[0] != 0)&&(switchState.dp_cur_power[0] != data_dp_cur_power[0])&&(switchState.dp_cur_power[0]<22000)) // { // data_dp_cur_power[0] = switchState.dp_cur_power[0]; mcu_dp_value_update(DPID_CUR_POWER,switchState.dp_cur_power[0]); //VALUE型数据上报; // } if((switchState.dp_cur_voltage != 0)&&(switchState.dp_cur_voltage != data_dp_cur_voltage)&&(switchState.dp_cur_voltage<2500)) { data_dp_cur_voltage = switchState.dp_cur_voltage; mcu_dp_value_update(DPID_CUR_VOLTAGE,switchState.dp_cur_voltage); //VALUE型数据上报; } //第二路数据 // if((switchState.dp_add_ele[1] !=0)&&((switchState.dp_add_ele[1] - data_dp_add_ele[1])>=1)) // { mcu_dp_value_update(DPID_ADD_ELE_2,switchState.dp_add_ele[1]); //VALUE型数据上报; if(data_dp_add_ele[1] != switchState.dp_add_ele[1]) { Save_data_ele_flag = 1; } data_dp_add_ele[1] = switchState.dp_add_ele[1]; // } // if((switchState.dp_cur_current[1] != 0)&&(switchState.dp_cur_current[1] != data_dp_cur_current[1])&&(switchState.dp_cur_current[1]<100000)) // { // data_dp_cur_current[1] = switchState.dp_cur_current[1]; mcu_dp_value_update(DPID_CUR_CURRENT_2,switchState.dp_cur_current[1]); //VALUE型数据上报; // } // if((switchState.dp_cur_power[1] != 0)&&(switchState.dp_cur_power[1] != data_dp_cur_power[1])&&(switchState.dp_cur_power[1]<22000)) // { // data_dp_cur_power[1] = switchState.dp_cur_power[1]; mcu_dp_value_update(DPID_CUR_POWER_2,switchState.dp_cur_power[1]); //VALUE型数据上报; // } #endif #ifdef ZIGBEE_ZTU_T3_SW //第一路数据 // if((switchState.dp_add_ele[0] !=0)&&((switchState.dp_add_ele[0] - data_dp_add_ele[0])>=1)) // { mcu_dp_value_update(DPID_ADD_ELE,switchState.dp_add_ele[0]); //VALUE型数据上报; if(data_dp_add_ele[0] != switchState.dp_add_ele[0]) { Save_data_ele_flag = 1; } data_dp_add_ele[0] = switchState.dp_add_ele[0]; // } // if((switchState.dp_cur_current[0] != 0)&&(switchState.dp_cur_current[0] != data_dp_cur_current[0])&&(switchState.dp_cur_current[0]<100000)) // { // data_dp_cur_current[0] = switchState.dp_cur_current[0]; mcu_dp_value_update(DPID_CUR_CURRENT,switchState.dp_cur_current[0]); //VALUE型数据上报; // } // if((switchState.dp_cur_power[0] != 0)&&(switchState.dp_cur_power[0] != data_dp_cur_power[0])&&(switchState.dp_cur_power[0]<22000)) // { // data_dp_cur_power[0] = switchState.dp_cur_power[0]; mcu_dp_value_update(DPID_CUR_POWER,switchState.dp_cur_power[0]); //VALUE型数据上报; // } if((switchState.dp_cur_voltage != 0)&&(switchState.dp_cur_voltage != data_dp_cur_voltage)&&(switchState.dp_cur_voltage<2500)) { data_dp_cur_voltage = switchState.dp_cur_voltage; mcu_dp_value_update(DPID_CUR_VOLTAGE,switchState.dp_cur_voltage); //VALUE型数据上报; } //第二路数据 // if((switchState.dp_add_ele[1] !=0)&&((switchState.dp_add_ele[1] - data_dp_add_ele[1])>=1)) // { mcu_dp_value_update(DPID_ADD_ELE_2,switchState.dp_add_ele[1]); //VALUE型数据上报; if(data_dp_add_ele[1] != switchState.dp_add_ele[1]) { Save_data_ele_flag = 1; } data_dp_add_ele[1] = switchState.dp_add_ele[1]; // } // if((switchState.dp_cur_current[1] != 0)&&(switchState.dp_cur_current[1] != data_dp_cur_current[1])&&(switchState.dp_cur_current[1]<100000)) // { // data_dp_cur_current[1] = switchState.dp_cur_current[1]; mcu_dp_value_update(DPID_CUR_CURRENT_2,switchState.dp_cur_current[1]); //VALUE型数据上报; // } // if((switchState.dp_cur_power[1] != 0)&&(switchState.dp_cur_power[1] != data_dp_cur_power[1])&&(switchState.dp_cur_power[1]<22000)) // { // data_dp_cur_power[1] = switchState.dp_cur_power[1]; mcu_dp_value_update(DPID_CUR_POWER_2,switchState.dp_cur_power[1]); //VALUE型数据上报; // } //第三路数据 // if((switchState.dp_add_ele[2] !=0)&&((switchState.dp_add_ele[2] - data_dp_add_ele[2])>=1)) // { mcu_dp_value_update(DPID_ADD_ELE_3,switchState.dp_add_ele[2]); //VALUE型数据上报; if(data_dp_add_ele[2] != switchState.dp_add_ele[2]) { Save_data_ele_flag = 1; } data_dp_add_ele[2] = switchState.dp_add_ele[2]; // } // if((switchState.dp_cur_current[2] != 0)&&(switchState.dp_cur_current[2] != data_dp_cur_current[2])&&(switchState.dp_cur_current[2]<100000)) // { // data_dp_cur_current[2] = switchState.dp_cur_current[2]; mcu_dp_value_update(DPID_CUR_CURRENT_3,switchState.dp_cur_current[2]); //VALUE型数据上报; // } // if((switchState.dp_cur_power[2] != 0)&&(switchState.dp_cur_power[2] != data_dp_cur_power[2])&&(switchState.dp_cur_power[2]<22000)) // { // data_dp_cur_power[2] = switchState.dp_cur_power[2]; mcu_dp_value_update(DPID_CUR_POWER_3,switchState.dp_cur_power[2]); //VALUE型数据上报; // } #endif } /****************************************************************************** WARNING!!! 2:所有数据上报处理 自动化代码模板函数,具体请用户自行实现数据处理 ******************************************************************************/ ///> this will realize by cloud platform #ifdef ZIGBEE_ZTU_T6_SCENCE_SW /***************************************************************************** 函数名称 : dp_download_scene_1_handle 功能描述 : 针对DPID_SCENE_1的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_scene_1_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char scene_1; scene_1 = mcu_get_dp_download_enum(value, length); switch (scene_1) { case 0: break; default: break; } // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_SCENE_1, scene_1); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_scene_2_handle 功能描述 : 针对DPID_SCENE_2的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_scene_2_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char scene_2; scene_2 = mcu_get_dp_download_enum(value, length); switch (scene_2) { case 0: break; default: break; } // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_SCENE_2, scene_2); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_scene_3_handle 功能描述 : 针对DPID_SCENE_3的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_scene_3_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char scene_3; scene_3 = mcu_get_dp_download_enum(value, length); switch (scene_3) { case 0: break; default: break; } // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_SCENE_3, scene_3); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_scene_4_handle 功能描述 : 针对DPID_SCENE_4的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_scene_4_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char scene_4; scene_4 = mcu_get_dp_download_enum(value, length); switch (scene_4) { case 0: break; default: break; } // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_SCENE_4, scene_4); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_scene_5_handle 功能描述 : 针对DPID_SCENE_5的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_scene_5_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char scene_5; scene_5 = mcu_get_dp_download_enum(value, length); switch (scene_5) { case 0: break; default: break; } // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_SCENE_5, scene_5); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_scene_6_handle 功能描述 : 针对DPID_SCENE_6的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_scene_6_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char scene_6; scene_6 = mcu_get_dp_download_enum(value, length); switch (scene_6) { case 0: break; default: break; } // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_SCENE_6, scene_6); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_mode_1_handle 功能描述 : 针对DPID_MODE_1的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_mode_1_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char mode_1; mode_1 = mcu_get_dp_download_enum(value, length); switch (mode_1) { case 0: break; case 1: break; default: break; } // add by zzw 20240304 switchState.mod[0] = mode_1; // 开关、场景设置 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[6] = switchState.mod[0]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzw 20240304 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[6] = switchState.mod[0]; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[6] != switchState.mod[0]) // 再次读取不相等,则再次写入 { read_mileage_backup[6] = switchState.mod[0]; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_MODE_1, mode_1); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_mode_2_handle 功能描述 : 针对DPID_MODE_2的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_mode_2_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char mode_2; mode_2 = mcu_get_dp_download_enum(value, length); switch (mode_2) { case 0: break; case 1: break; default: break; } // add by zzw 20240304 switchState.mod[1] = mode_2; // 开关、场景设置 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[7] = switchState.mod[1]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzw 20240304 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[7] = switchState.mod[1]; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[7] != switchState.mod[1]) // 再次读取不相等,则再次写入 { read_mileage_backup[7] = switchState.mod[1]; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_MODE_2, mode_2); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_mode_3_handle 功能描述 : 针对DPID_MODE_3的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_mode_3_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char mode_3; mode_3 = mcu_get_dp_download_enum(value, length); switch (mode_3) { case 0: break; case 1: break; default: break; } // add by zzw 20240304 switchState.mod[2] = mode_3; // 开关、场景设置 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[8] = switchState.mod[2]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzw 20240304 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[8] = switchState.mod[2]; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[8] != switchState.mod[2]) // 再次读取不相等,则再次写入 { read_mileage_backup[8] = switchState.mod[2]; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_MODE_3, mode_3); if (ret == SUCCESS) return SUCCESS; else return ERROR; } #endif /***************************************************************************** 函数名称 : dp_download_switch_1_handle 功能描述 : 针对DPID_SWITCH_1的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_switch_1_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为BOOL unsigned char ret; // 0:off/1:on unsigned char switch_1; switch_1 = mcu_get_dp_download_bool(value, length); if (switch_1 == 0) { // bool off gRelayOnOff &= (~0x01); gLedState = gLedState & (~0x01); // 按键1清除 } else { // bool on gRelayOnOff |= (0x01); gLedState = gLedState | 0x01; // 按键1设置 if (appControlLedEnable) // add by zzw 开灯点亮按键背光10秒 { gRadarKeepTimer = 100; // 10s } if (switchState.plus_mod[0] == 0x01) // 点动开启 { switchState.plus_en[0] = 0x01; switchState.plus_counter[0] = switchState.plus_auto_time[0]; // write_mileage[0] = switchState.plus_en; // iap_eeprom_write(14, write_mileage, 1); // 写入1字节 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[14] = switchState.plus_en[0]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 } } // There should be a report after processing the DP ret = mcu_dp_bool_update(DPID_SWITCH_3, switch_1); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_switch_2_handle 功能描述 : 针对DPID_SWITCH_2的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_switch_2_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为BOOL unsigned char ret; // 0:off/1:on unsigned char switch_2; switch_2 = mcu_get_dp_download_bool(value, length); if (switch_2 == 0) { // bool off gRelayOnOff &= (~0x02); gLedState = gLedState & (~0x02); // 按键1清除 } else { // bool on gRelayOnOff |= (0x02); gLedState = gLedState | 0x02; // 按键2设置 if (appControlLedEnable) // add by zzw 开灯点亮按键背光10秒 { gRadarKeepTimer = 100; // 10s } if (switchState.plus_mod[1] == 0x01) // 点动开启 { switchState.plus_en[1] = 0x01; switchState.plus_counter[1] = switchState.plus_auto_time[1]; // write_mileage[1] = switchState.plus_en; // iap_eeprom_write(15, write_mileage, 1); // 写入1字节 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[15] = switchState.plus_en[1]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 } } // There should be a report after processing the DP ret = mcu_dp_bool_update(DPID_SWITCH_2, switch_2); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_switch_3_handle 功能描述 : 针对DPID_SWITCH_3的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_switch_3_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为BOOL unsigned char ret; // 0:off/1:on unsigned char switch_3; switch_3 = mcu_get_dp_download_bool(value, length); if (switch_3 == 0) { // bool off gRelayOnOff &= (~0x04); gLedState = gLedState & (~0x04); // 按键3清除 } else { // bool on gRelayOnOff |= (0x04); gLedState = gLedState | 0x04; // 按键3设置 if (appControlLedEnable) // add by zzw 开灯点亮按键背光10秒 { gRadarKeepTimer = 100; // 10s } if (switchState.plus_mod[2] == 0x01) // 点动开启 { switchState.plus_en[2] = 0x01; switchState.plus_counter[2] = switchState.plus_auto_time[2]; // write_mileage[2] = switchState.plus_en; // iap_eeprom_write(16, write_mileage, 1); // 写入1字节 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[16] = switchState.plus_en[2]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 } } // There should be a report after processing the DP ret = mcu_dp_bool_update(DPID_SWITCH_1, switch_3); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_relay_status_handle 功能描述 : 针对DPID_RELAY_STATUS的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_relay_status_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char relay_status; relay_status = mcu_get_dp_download_enum(value, length); switch (relay_status) // 全局设置3路的状态 { case 0: break; case 1: break; case 2: break; default: break; } // add by zzw 20240302 switchState.relay_allstatus = relay_status; switchState.relay_status[0] = relay_status; switchState.relay_status[1] = relay_status; switchState.relay_status[2] = relay_status; // iap_eeprom_write(1, write_mileage, 4); // 写入4字节 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[1] = relay_status; write_mileage[2] = relay_status; write_mileage[3] = relay_status; write_mileage[4] = relay_status; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzw 20240302 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[1] = relay_status; write_mileage_backup[2] = relay_status; write_mileage_backup[3] = relay_status; write_mileage_backup[4] = relay_status; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[1] != relay_status) // 再次读取不相等,则再次写入 { read_mileage_backup[1] = relay_status; read_mileage_backup[2] = relay_status; read_mileage_backup[3] = relay_status; read_mileage_backup[4] = relay_status; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_RELAY_STATUS, relay_status); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_light_mode_handle 功能描述 : 针对DPID_LIGHT_MODE的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_light_mode_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char light_mode; light_mode = mcu_get_dp_download_enum(value, length); switch (light_mode) // 枚举范围:Level1,Level2,Level3 { case 0: switchState.led_level = 0; break; case 1: switchState.led_level = 1; break; case 2: switchState.led_level = 2; break; default: break; } iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[5] = switchState.led_level; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[5] = switchState.led_level; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[5] != switchState.led_level) // 再次读取不相等,则再次写入 { read_mileage_backup[5] = switchState.led_level; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_LIGHT_MODE, light_mode); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_backlight_switch_handle 功能描述 : 针对DPID_BACKLIGHT_SWITCH的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_backlight_switch_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为BOOL unsigned char ret; // 0:off/1:on unsigned char backlight_switch; backlight_switch = mcu_get_dp_download_bool(value, length); if (backlight_switch == 0) { // bool off // switchState.bluelight = 0; switchState.human = 0; } else { // bool on // switchState.bluelight = 1; switchState.human = 1; } // add by zzy 20240309 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 // switchState.led_level = write_mileage[5];//重新读取刷新背光亮度值 write_mileage[9] = switchState.human; iap_eeprom_write(0, write_mileage, 30); // 先读,在写入1字节 // add by zzy 20240309 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 switchState.led_level = write_mileage_backup[5]; // 重新读取刷新背光亮度值 write_mileage_backup[9] = switchState.human; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[9] != switchState.human) // 再次读取不相等,则再次写入 { read_mileage_backup[9] = switchState.human; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP // ret = mcu_dp_bool_update(DPID_BACKLIGHT_SWITCH, backlight_switch); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_switch_inching_handle 功能描述 : 针对DPID_SWITCH_INCHING的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_switch_inching_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为STRING unsigned char ret; int i = 0; int j = 0; // 后面两位表示秒数,前面的1字节的0位表示开/关,1开,0关,bit7-bit1表示通道号 // length=0,表示全部删除 //"AQAF"的Base64解码结果是01,00,05 //"AwAF"的Base64解码结果是03,00,05 //"BQAF"的Base64解码结果是05, 00, 05 // STRING type data processing unsigned char string_H16_data[32]; // 16进制字符串 unsigned char string_base64_data[32]; // base64标码字符串 unsigned char hex_data[32]; // 转换后的16进制字节数据 if (length > 12) // 自定义协议,一共18字节 { // 010001ffffff000002,字符串下来就是,1号灯1秒后关,2号没有延时关,3号使能关闭延时时间是2秒 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[20] = 0; write_mileage_backup[21] = 0; write_mileage_backup[22] = 0; write_mileage_backup[23] = 0; write_mileage_backup[24] = 0; write_mileage_backup[25] = 0; write_mileage_backup[26] = 0; write_mileage_backup[27] = 0; write_mileage_backup[28] = 0; // 每次清空数据,重新赋值 switchState.plus_mod[0] = 0; switchState.plus_mod[1] = 0; switchState.plus_mod[2] = 0; // 每次清空数据,重新赋值 DisHexToHex(hex_data, value, 9); // 字符串转16进制数组 #ifdef ZIGBEE_ZTU_T1_SW // 希智账户,3键零火开关 if (hex_data[0] == 0x01) // 开关2使能 { switchState.plus_mod[1] = 1; switchState.plus_auto_time[1] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = hex_data[1]; write_mileage_backup[25] = hex_data[2]; } else if (hex_data[0] == 0x00) // 开关2关闭 { switchState.plus_mod[1] = 0; switchState.plus_auto_time[1] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = hex_data[1]; write_mileage_backup[25] = hex_data[2]; } else { switchState.plus_mod[1] = 0xff; // 清除 write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = 0xff; write_mileage_backup[25] = 0xff; } #endif #ifdef ZIGBEE_ZTU_T2_SW // 希智账户,3键零火开关 if (hex_data[0] == 0x01) // 开关1使能 { switchState.plus_mod[0] = 1; switchState.plus_auto_time[0] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = hex_data[1]; write_mileage_backup[22] = hex_data[2]; } else if (hex_data[0] == 0x00) // 开关1关闭 { switchState.plus_mod[0] = 0; switchState.plus_auto_time[0] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = hex_data[1]; write_mileage_backup[22] = hex_data[2]; } else { switchState.plus_mod[0] = 0xff; // 清除 write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = 0xff; write_mileage_backup[22] = 0xff; } if (hex_data[3] == 0x01) // 开关3使能 { switchState.plus_mod[2] = 1; switchState.plus_auto_time[2] = (hex_data[4] * 256 + hex_data[5]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = hex_data[4]; write_mileage_backup[28] = hex_data[5]; } else if (hex_data[3] == 0x00) // 开关3关闭 { switchState.plus_mod[2] = 0; switchState.plus_auto_time[2] = (hex_data[4] * 256 + hex_data[5]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = hex_data[4]; write_mileage_backup[28] = hex_data[5]; } else { switchState.plus_mod[2] = 0xff; // 清除 write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = 0xff; write_mileage_backup[28] = 0xff; } #endif #if (defined ZIGBEE_ZTU_T3_SW) || (defined ZIGBEE_ZTU_T6_SCENCE_SW) if (hex_data[0] == 0x01) // 开关1使能 { switchState.plus_mod[0] = 1; switchState.plus_auto_time[0] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = hex_data[1]; write_mileage_backup[22] = hex_data[2]; } else if (hex_data[0] == 0x00) // 开关1关闭 { switchState.plus_mod[0] = 0; switchState.plus_auto_time[0] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = hex_data[1]; write_mileage_backup[22] = hex_data[2]; } else { switchState.plus_mod[0] = 0xff; // 清除 write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = 0xff; write_mileage_backup[22] = 0xff; } if (hex_data[3] == 0x01) // 开关2使能 { switchState.plus_mod[1] = 1; switchState.plus_auto_time[1] = (hex_data[4] * 256 + hex_data[5]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = hex_data[4]; write_mileage_backup[25] = hex_data[5]; } else if (hex_data[3] == 0x00) // 开关2关闭 { switchState.plus_mod[1] = 0; switchState.plus_auto_time[1] = (hex_data[4] * 256 + hex_data[5]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = hex_data[4]; write_mileage_backup[25] = hex_data[5]; } else { switchState.plus_mod[1] = 0xff; // 清除 write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = 0xff; write_mileage_backup[25] = 0xff; } if (hex_data[6] == 0x01) // 开关3使能 { switchState.plus_mod[2] = 1; switchState.plus_auto_time[2] = (hex_data[7] * 256 + hex_data[8]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = hex_data[7]; write_mileage_backup[28] = hex_data[8]; } else if (hex_data[6] == 0x00) // 开关3关闭 { switchState.plus_mod[2] = 0; switchState.plus_auto_time[2] = (hex_data[7] * 256 + hex_data[8]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = hex_data[7]; write_mileage_backup[28] = hex_data[8]; } else { switchState.plus_mod[2] = 0xff; // 清除 write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = 0xff; write_mileage_backup[28] = 0xff; } #endif } else // 涂鸦官方标准协议,最大12字节 { // char source[32] = "abc"; // char dest[32]; /*将字符串abc进行base64编码*/ // Base64Encode(dest, source, strlen(source)); // printf("%s\n", dest); /*将字符串abc的编码字符串解码,还原成abc*/ // Base64Decode(source, dest, strlen(dest)); // printf("%s\n", source); iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[20] = 0; write_mileage_backup[21] = 0; write_mileage_backup[22] = 0; write_mileage_backup[23] = 0; write_mileage_backup[24] = 0; write_mileage_backup[25] = 0; write_mileage_backup[26] = 0; write_mileage_backup[27] = 0; write_mileage_backup[28] = 0; // 每次清空数据,重新赋值 switchState.plus_mod[0] = 0; switchState.plus_mod[1] = 0; switchState.plus_mod[2] = 0; if (length == 0) // 清空点动开关 { switchState.plus_mod[0] = 0; switchState.plus_mod[1] = 0; switchState.plus_mod[2] = 0; } else { for (i = 0; i < (length / 4); i++) // 4字符一个数据集 { for (j = 0; j < 4; j++) // 4个字符转换一次 { string_base64_data[j] = value[i * 4 + j]; } // base64_decode_three_bytes(string_base64_data, hex_data); Base64Decode(hex_data, string_base64_data, strlen(string_base64_data)); if (hex_data[0] == 0x01) // 开关1使能 { switchState.plus_mod[0] = 1; switchState.plus_auto_time[0] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = hex_data[1]; write_mileage_backup[22] = hex_data[2]; } else if (hex_data[0] == 0x00) // 开关1关闭 { switchState.plus_mod[0] = 0; write_mileage_backup[20] = switchState.plus_mod[0]; write_mileage_backup[21] = 0; write_mileage_backup[22] = 0; } else if (hex_data[0] == 0x03) // 开关2使能 { switchState.plus_mod[1] = 1; switchState.plus_auto_time[1] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = hex_data[1]; write_mileage_backup[25] = hex_data[2]; } else if (hex_data[0] == 0x02) // 开关2关闭 { switchState.plus_mod[1] = 0; write_mileage_backup[23] = switchState.plus_mod[1]; write_mileage_backup[24] = 0; write_mileage_backup[25] = 0; } else if (hex_data[0] == 0x05) // 开关3使能 { switchState.plus_mod[2] = 1; switchState.plus_auto_time[2] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数 write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = hex_data[1]; write_mileage_backup[28] = hex_data[2]; } else if (hex_data[0] == 0x04) // 开关3关闭 { switchState.plus_mod[2] = 0; write_mileage_backup[26] = switchState.plus_mod[2]; write_mileage_backup[27] = 0; write_mileage_backup[28] = 0; } } } } // add by zzw 20240313 增加eeprom参数配置区 // 点动开关2个字节(使能1,时间2)-20-21-22,-23-24-25,-26-27-28 iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[20] != switchState.plus_mod[0]) // 再次读取不相等,则再次写入 { iap_eeprom_write_backup(0, write_mileage_backup, 30); // } // add by zzw 20240313 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_string_update(DPID_SWITCH_INCHING, value, length); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_relay_status_1_handle 功能描述 : 针对DPID_RELAY_STATUS_1的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_relay_status_1_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char relay_status_1; relay_status_1 = mcu_get_dp_download_enum(value, length); switch (relay_status_1) { case 0: // 断电 // switchState.relay_status[0]=0; break; case 1: // 通电 // switchState.relay_status[0]=1; break; case 2: // 断电记忆 // switchState.relay_status[0]=2; break; default: break; } // add by zzw 20240207 switchState.relay_status[0] = relay_status_1; // add by zzw 20240207 // add by zzy 20240309 iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[2] = switchState.relay_status[0]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzy 20240309 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[2] = switchState.relay_status[0]; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[2] != switchState.relay_status[0]) // 再次读取不相等,则再次写入 { read_mileage_backup[2] = switchState.relay_status[0]; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_RELAY_STATUS_1, relay_status_1); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_relay_status_2_handle 功能描述 : 针对DPID_RELAY_STATUS_2的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_relay_status_2_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char relay_status_2; relay_status_2 = mcu_get_dp_download_enum(value, length); switch (relay_status_2) { case 0: break; case 1: break; case 2: break; default: break; } // add by zzw 20240207 switchState.relay_status[1] = relay_status_2; iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[3] = switchState.relay_status[1]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzw 20240207 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[3] = switchState.relay_status[1]; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[3] != switchState.relay_status[1]) // 再次读取不相等,则再次写入 { read_mileage_backup[3] = switchState.relay_status[1]; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_RELAY_STATUS_2, relay_status_2); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_relay_status_3_handle 功能描述 : 针对DPID_RELAY_STATUS_3的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_relay_status_3_handle(const unsigned char value[], unsigned short length) { // 示例:当前DP类型为ENUM unsigned char ret; unsigned char relay_status_3; relay_status_3 = mcu_get_dp_download_enum(value, length); switch (relay_status_3) { case 0: break; case 1: break; case 2: break; default: break; } // add by zzw 20240207 switchState.relay_status[2] = relay_status_3; iap_eeprom_read(0, write_mileage, 30); // 读取30字节 write_mileage[4] = switchState.relay_status[2]; iap_eeprom_write(0, write_mileage, 30); // 写入1字节 // add by zzw 20240207 // add by zzw 20240312 增加eeprom参数配置区 iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节 write_mileage_backup[4] = switchState.relay_status[2]; iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节 iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节 if (read_mileage_backup[4] != switchState.relay_status[2]) // 再次读取不相等,则再次写入 { read_mileage_backup[4] = switchState.relay_status[2]; iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节 } // add by zzw 20240312 增加eeprom参数配置区 // There should be a report after processing the DP ret = mcu_dp_enum_update(DPID_RELAY_STATUS_3, relay_status_3); if (ret == SUCCESS) return SUCCESS; else return ERROR; } /***************************************************************************** 函数名称 : dp_download_add_ele_handle 功能描述 : 针对DPID_ADD_ELE的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_add_ele_handle(const unsigned char value[], unsigned short length) { //示例:当前DP类型为VALUE unsigned char ret; unsigned long add_ele; add_ele = mcu_get_dp_download_value(value,length); /* //VALUE type data processing */ // switchState.dp_add_ele=value[1]<<8+value[0];//100倍,去除小数的值 //实际值,需要/100,带小数的 //There should be a report after processing the DP ret = mcu_dp_value_update(DPID_ADD_ELE,add_ele); if(ret == SUCCESS) return SUCCESS; else return ERROR; } #ifdef SUPPORT_MCU_RTC_CHECK /** * @brief mcu check local RTC time * @param[in] {time} timestamp * @return void */ void mcu_write_rtctime(unsigned char time[]) { // #error "mcu should realize RTC time wtriting fuction, and delete this line" /* time[0]~time[3]:standard time time[4]~time[7]: Local time */ my_memcpy((void *)timestamp, (const char *)time, 4); // get timestamp zigbee_timestamp_to_time(); /* year = _time.w_year; //year month = _time.w_month; //month date = _time.w_date; //date hour = _time.hour + 8; //hour(8:BeiJing time) min = _time.min; //minute sec = _time.sec; //second */ } #endif /** * @brief Zigbee functional test feedback * @param[in] {void} * @return void */ void zigbee_test_result(void) { // #error "this test is makesure the rf fuction of zigbee module, if test pass or not should do something, mcu should realize" unsigned char rssi = zigbee_uart_rx_buf[DATA_START + 1]; if (zigbee_uart_rx_buf[DATA_START] == 0x01) { if (rssi > 0x3C) { // test sucess the range of rssi is 0% ~ 100% } else { // test failure } } else { // test failure } } /****************************************************************************** WARNING!!! 以下函数用户请勿修改!! ******************************************************************************/ /** * @brief this function will handle uart received frame data * @param[in] {dpid} dp id * @param[in] {value} dp data * @param[in] {length} lenght of dp data * @return handle result */ #ifdef ZIGBEE_ZTU_T1_SW unsigned char dp_download_handle(unsigned char dpid, const unsigned char value[], unsigned short length) { /* only list of function, mcu need realize these fuction*/ unsigned char ret; // 可收到控制信号,说明配网肯定成功 ZG_JoinCounter = 18000; // 入网成功,入网计数器置最大值,180秒 switchState.zigbee_work_state = 1; // 可收到控制信号,说明配网肯定成功 switch (dpid) { case DPID_SWITCH_1: // case DPID_SWITCH_2: // 开关 2处理函数 ret = dp_download_switch_2_handle(value, length); break; case DPID_SWITCH_3: // 开关 3处理函数 ret = dp_download_switch_3_handle(value, length); break; case DPID_RELAY_STATUS: // 上电状态设置处理函数 ret = dp_download_relay_status_handle(value, length); break; case DPID_LIGHT_MODE: // 指示灯状态设置处理函数 ret = dp_download_light_mode_handle(value, length); break; case DPID_BACKLIGHT_SWITCH: // 背光开关处理函数 ret = dp_download_backlight_switch_handle(value, length); break; case DPID_SWITCH_INCHING: // 点动开关(延时关)处理函数 ret = dp_download_switch_inching_handle(value, length); break; case DPID_RELAY_STATUS_1: // 开关1上电状态设置处理函数 ret = dp_download_relay_status_1_handle(value, length); break; case DPID_RELAY_STATUS_2: // 开关2上电状态设置处理函数 ret = dp_download_relay_status_2_handle(value, length); break; case DPID_RELAY_STATUS_3: // 开关3上电状态设置处理函数 ret = dp_download_relay_status_3_handle(value, length); break; default: break; } return ret; } #endif #ifdef ZIGBEE_ZTU_T2_SW unsigned char dp_download_handle(unsigned char dpid, const unsigned char value[], unsigned short length) { /* only list of function, mcu need realize these fuction*/ unsigned char ret; // 可收到控制信号,说明配网肯定成功 ZG_JoinCounter = 18000; // 入网成功,入网计数器置最大值,180秒 switchState.zigbee_work_state = 1; // 可收到控制信号,说明配网肯定成功 switch (dpid) { case DPID_SWITCH_1: // 开关 1处理函数 ret = dp_download_switch_3_handle(value, length); break; case DPID_SWITCH_2: //case DPID_SWITCH_3: // 开关 3处理函数 ret = dp_download_switch_1_handle(value, length); break; case DPID_RELAY_STATUS: // 上电状态设置处理函数 ret = dp_download_relay_status_handle(value, length); break; case DPID_LIGHT_MODE: // 指示灯状态设置处理函数 ret = dp_download_light_mode_handle(value, length); break; case DPID_BACKLIGHT_SWITCH: // 背光开关处理函数 ret = dp_download_backlight_switch_handle(value, length); break; case DPID_SWITCH_INCHING: // 点动开关(延时关)处理函数 ret = dp_download_switch_inching_handle(value, length); break; case DPID_RELAY_STATUS_1: // 开关1上电状态设置处理函数 ret = dp_download_relay_status_1_handle(value, length); break; case DPID_RELAY_STATUS_2: // 开关2上电状态设置处理函数 ret = dp_download_relay_status_2_handle(value, length); break; case DPID_RELAY_STATUS_3: // 开关3上电状态设置处理函数 ret = dp_download_relay_status_3_handle(value, length); break; default: break; } return ret; } #endif //#ifdef ZIGBEE_ZTU_T3_SW #if (defined ZIGBEE_ZTU_T3_SW) && (defined ZIGBEE_3SWITCH_SW) unsigned char dp_download_handle(unsigned char dpid, const unsigned char value[], unsigned short length) { /* only list of function, mcu need realize these fuction*/ unsigned char ret; // 可收到控制信号,说明配网肯定成功 ZG_JoinCounter = 18000; // 入网成功,入网计数器置最大值,180秒 switchState.zigbee_work_state = 1; // 可收到控制信号,说明配网肯定成功 switch (dpid) { case DPID_SWITCH_1: // 开关 1处理函数 ret = dp_download_switch_3_handle(value, length); break; case DPID_SWITCH_2: // 开关 2处理函数 ret = dp_download_switch_2_handle(value, length); break; case DPID_SWITCH_3: // 开关 3处理函数 ret = dp_download_switch_1_handle(value, length); break; case DPID_RELAY_STATUS: // 上电状态设置处理函数 ret = dp_download_relay_status_handle(value, length); break; case DPID_LIGHT_MODE: // 指示灯状态设置处理函数 ret = dp_download_light_mode_handle(value, length); break; case DPID_BACKLIGHT_SWITCH: // 背光开关处理函数 ret = dp_download_backlight_switch_handle(value, length); break; case DPID_SWITCH_INCHING: // 点动开关(延时关)处理函数 ret = dp_download_switch_inching_handle(value, length); break; case DPID_RELAY_STATUS_1: // 开关1上电状态设置处理函数 ret = dp_download_relay_status_1_handle(value, length); break; case DPID_RELAY_STATUS_2: // 开关2上电状态设置处理函数 ret = dp_download_relay_status_2_handle(value, length); break; case DPID_RELAY_STATUS_3: // 开关3上电状态设置处理函数 ret = dp_download_relay_status_3_handle(value, length); break; case DPID_ADD_ELE: //增加电量处理函数 ret = dp_download_add_ele_handle(value,length); default: break; } return ret; } #endif #ifdef ZIGBEE_ZTU_T6_SCENCE_SW unsigned char dp_download_handle(unsigned char dpid, const unsigned char value[], unsigned short length) { /* only list of function, mcu need realize these fuction*/ unsigned char ret; // 可收到控制信号,说明配网肯定成功 ZG_JoinCounter = 18000; // 入网成功,入网计数器置最大值,180秒 switchState.zigbee_work_state = 1; // 有dp控制指令,说明设备肯定在线//add by zzw switch (dpid) { case DPID_SCENE_1: //场景1处理函数 ret = dp_download_scene_1_handle(value,length); break; case DPID_SCENE_2: //场景2处理函数 ret = dp_download_scene_2_handle(value,length); break; case DPID_SCENE_3: //场景3处理函数 ret = dp_download_scene_3_handle(value,length); break; case DPID_SCENE_4: //场景4处理函数 ret = dp_download_scene_4_handle(value,length); break; case DPID_SCENE_5: //场景5处理函数 ret = dp_download_scene_5_handle(value,length); break; case DPID_SCENE_6: //场景6处理函数 ret = dp_download_scene_6_handle(value,length); break; case DPID_MODE_1: //模式1处理函数 ret = dp_download_mode_1_handle(value,length); break; case DPID_MODE_2: //模式2处理函数 ret = dp_download_mode_2_handle(value,length); break; case DPID_MODE_3: //模式3处理函数 ret = dp_download_mode_3_handle(value,length); break; case DPID_SWITCH_1: //开关1处理函数 ret = dp_download_switch_3_handle(value,length); break; case DPID_SWITCH_2: //开关2处理函数 ret = dp_download_switch_2_handle(value,length); break; case DPID_SWITCH_3: //开关3处理函数 ret = dp_download_switch_1_handle(value,length); break; case DPID_LIGHT_MODE: //指示灯亮度处理函数 ret = dp_download_light_mode_handle(value,length); break; case DPID_RELAY_STATUS: //上电状态设置处理函数 ret = dp_download_relay_status_handle(value,length); break; case DPID_RELAY_STATUS_1: //开关1上电状态设置处理函数 ret = dp_download_relay_status_1_handle(value,length); break; case DPID_RELAY_STATUS_2: //开关2上电状态设置处理函数 ret = dp_download_relay_status_2_handle(value,length); break; case DPID_RELAY_STATUS_3: //开关3上电状态设置处理函数 ret = dp_download_relay_status_3_handle(value,length); break; case DPID_SWITCH_INCHING: //点动开关(延时关)处理函数 ret = dp_download_switch_inching_handle(value,length); break; case DPID_ADD_ELE: //增加电量处理函数 break; default: break; } return ret; } #endif /** * @brief get received cmd total number * @param[in] {void} * @return received cmd total number */ unsigned char get_download_cmd_total(void) { return (sizeof(download_cmd) / sizeof(download_cmd[0])); } /** * @brief received zigbee net_work state handle * @param[in] {zigbee_work_state} zigbee current network state * @return void */ void zigbee_work_state_event(unsigned char zigbee_work_state) { unsigned short length = 0; zigbee_uart_write_frame(ZIGBEE_STATE_CMD, length); switch (zigbee_work_state) { case ZIGBEE_NOT_JION: // 设备从在线切换到不在线则报警,脱网报警(离线状态) 慢闪60s 3s一闪烁 if (ZG_Joining == CONDITION_JOINGING_TO_NORMAL) // 入网前几入网阶段不进入报警闪烁,防止入网指令发送后的自动脱网导致闪烁混乱 { switchState.zigbee_work_state = 2; // 脱网报警启动 switchState.time = 6000; // 60秒 ledSetParam(150, 300); // 3s一闪烁 } break; case ZIGBEE_JOIN_GATEWAY: // 新设备入网成功 ZG_JoinCounter = 18000; // 入网成功,入网计数器置最大值,180秒 switchState.zigbee_work_state = 1; break; case ZIGBEE_JOIN_ERROR: // 已经入网设备,发起再次入网,会进入这里 // 配网超时3分钟,触发误触重连,只要APP不操作添加设备确定按键,设备重新回连至上一个账号下 // ZG_JoinCounter = 18000; // 配网结束,入网计数器置最大值,180秒 // switchState.zigbee_work_state = 1; break; case ZIGBEE_JOINING: break; default: break; } } /** * @brief received reset zigbee response * @param[in] {state} response state * @return void */ void mcu_reset_zigbee_event(unsigned char state) { switch (state) { case RESET_ZIGBEE_OK: break; case RESET_ZIGBEE_ERROR: break; default: break; } } /** * @brief check mcu version response * @param[in] {void} * @return void */ void response_mcu_ota_version_event(void) { unsigned short length = 0; length = set_zigbee_uart_byte(length, get_current_mcu_fw_ver()); // current fw version zigbee_uart_write_frame(MCU_OTA_VERSION_CMD, length); } #ifdef SUPPORT_MCU_OTA /** * @brief mcu ota update notify response * @param[in] {offset} data offset * @return void */ void response_mcu_ota_notify_event(unsigned char offset) { unsigned char i = 0; unsigned short length = 0; unsigned char update = 0; unsigned long app_newcode_add = 0; unsigned char j = 0; current_mcu_fw_pid(); // current PID while (i < 8) { ota_fw_info.mcu_ota_pid[i] = zigbee_uart_rx_buf[offset + DATA_START + i]; // ota fw PID i++; } ota_fw_info.mcu_ota_ver = zigbee_uart_rx_buf[offset + DATA_START + 8]; // ota fw version ota_fw_info.mcu_ota_fw_size = zigbee_uart_rx_buf[offset + DATA_START + 9] << 24 | zigbee_uart_rx_buf[offset + DATA_START + 10] << 16 | zigbee_uart_rx_buf[offset + DATA_START + 11] << 8 | zigbee_uart_rx_buf[offset + DATA_START + 12]; // ota fw size ota_fw_info.mcu_ota_checksum = zigbee_uart_rx_buf[offset + DATA_START + 13] << 24 | zigbee_uart_rx_buf[offset + DATA_START + 14] << 16 | zigbee_uart_rx_buf[offset + DATA_START + 15] << 8 | zigbee_uart_rx_buf[offset + DATA_START + 16]; // ota fw checksum if ((!strcmp_barry(&ota_fw_info.mcu_ota_pid[0], ¤t_mcu_pid[0], 8)) && (ota_fw_info.mcu_ota_ver > get_current_mcu_fw_ver() && ota_fw_info.mcu_ota_fw_size > 0)) { // check fw pid and fw version and fw size length = set_zigbee_uart_byte(length, 0x00); // OK update = 1; // 校验通过,可进行固件升级 } else { length = set_zigbee_uart_byte(length, 0x01); // error } ota_fw_info.mcu_current_offset = 0; zigbee_uart_write_frame(MCU_OTA_NOTIFY_CMD, length); // 校验PID一致性,版本号大于当前版本则可执行升级,并给zigbee应答01或00 // add by zzw 升级通知接收成功,第一次调用接收固件命令 if (update) { // zzw ota must add 20240326 OTA 存入标志位 // mcu_ota_fw_request(); // 固件升级,取消直接升级,进入boot升级 // TM52的特性决定了,需要跳转到BOOT去接收OTA数据 update = 0; // 先写入升级的标志再跳转到UBOOT // INFO5地址存储升级标志0x55、0xaa、0x5a CheckBuf[0] = 0x55; CheckBuf[1] = 0xaa; CheckBuf[2] = 0x5a; for (i = 0; i < 8; i++) { CheckBuf[3 + i] = ota_fw_info.mcu_ota_pid[i]; } CheckBuf[11] = ota_fw_info.mcu_ota_ver; for (i = 0; i < 8; i++) { CheckBuf[12 + i] = zigbee_uart_rx_buf[offset + DATA_START + 9 + i]; } // user_write_INFO_byte(INFO5_ADDR, CheckBuf, 20); // while (!com0send_over); //等待uart回复帧发送结束再执行跳转指令 // com0send_over = 0; bsp_delay_ms(5); // 延时5ms等待串口应答结束 EA = 0; // 关闭中断 BOOTV = 0x04; // 设置热复位后跳转到uboot SWCMD = 0x56; // 软件复位 // TM52的特性决定了,需要跳转到BOOT去接收OTA数据 } } /** * @brief received mcu ota data request response * @param[in] {fw_offset} offset of file * @param[in] {data} received data * @return void */ /*void reveived_mcu_ota_data_handle(unsigned int fw_offset, char *data) { //#error "received frame data, should save in flash, mcu should realize this fuction, and delete this line " //未使用 }*/ /** * @brief mcu send ota data request * @param[in] {void} * @return void */ void mcu_ota_fw_request_event(unsigned char offset) { unsigned int fw_offset = 0; char fw_data[FW_SINGLE_PACKET_SIZE] = {-1}; // unsigned char i = 0; unsigned char last_package_len = 0; static unsigned int current_checksum = 0; if (zigbee_uart_rx_buf[offset + DATA_START] == 0x01) // status check return; while (i < 8) { if (current_mcu_pid[i] != zigbee_uart_rx_buf[offset + DATA_START + 1 + i]) // pid check return; i++; } if (ota_fw_info.mcu_ota_ver != zigbee_uart_rx_buf[offset + DATA_START + 9]) // version check return; i = 0; while (i < 4) { fw_offset |= (zigbee_uart_rx_buf[offset + DATA_START + 10 + i] << (24 - i * 8)); // offset i++; } i = 0; if (ota_fw_info.mcu_current_offset == fw_offset) { // if ((ota_fw_info.mcu_ota_fw_size - fw_offset) / FW_SINGLE_PACKET_SIZE != 0) if (((ota_fw_info.mcu_ota_fw_size - fw_offset) / FW_SINGLE_PACKET_SIZE != 0) && (ota_fw_info.mcu_ota_fw_size != (fw_offset + FW_SINGLE_PACKET_SIZE))) // if (((ota_fw_info.mcu_ota_fw_size - fw_offset) / FW_SINGLE_PACKET_SIZE != 0)&&((ota_fw_info.mcu_ota_fw_size - fw_offset) % FW_SINGLE_PACKET_SIZE != 0)) { if (ota_fw_info.mcu_current_offset == 0) { current_checksum = 0; } while (i < FW_SINGLE_PACKET_SIZE) { fw_data[i] = zigbee_uart_rx_buf[offset + DATA_START + 14 + i]; // fw data current_checksum += fw_data[i]; i++; } ota_fw_info.mcu_current_offset += FW_SINGLE_PACKET_SIZE; ota_fw_data_handle(fw_offset, &fw_data[0], FW_SINGLE_PACKET_SIZE); // OTA paket data handle } else { i = 0; // last_package_len = ota_fw_info.mcu_ota_fw_size - fw_offset; if ((ota_fw_info.mcu_ota_fw_size - fw_offset) % FW_SINGLE_PACKET_SIZE != 0) { last_package_len = ota_fw_info.mcu_ota_fw_size - fw_offset; } else { last_package_len = FW_SINGLE_PACKET_SIZE; } while (i < last_package_len) { fw_data[i] = zigbee_uart_rx_buf[offset + DATA_START + 14 + i]; current_checksum += fw_data[i]; i++; } ota_fw_info.mcu_current_offset += last_package_len; if (ota_fw_info.mcu_ota_checksum != current_checksum) { // ota failure report ota failure and clear ota struct mcu_ota_result_report(1); // failed } else { // ota sucess mcu_ota_result_report(0); // seccess } ota_fw_data_handle(fw_offset, &fw_data[0], last_package_len); // OTA paket data handle current_checksum = 0; } } else { // ota request timeout, then restart ota request from ota_fw_info.mcu_ota_fw_size } } static void report_mcu_ota_result(unsigned char res) { unsigned short length; if ((res == 0) || (res == 1)) { length = set_zigbee_uart_byte(length, res); zigbee_uart_write_frame(MCU_OTA_NOTIFY_CMD, length); } } /** * @brief mcu ota data result notify * @param[in] {void} * @return void */ void mcu_ota_result_event(unsigned char offset) { unsigned short k, Ret; u32 temp_buff[256]; unsigned char status = zigbee_uart_rx_buf[offset + DATA_START]; if (status == 0x00) { // 升级成功,用户提示 IAPUpdateFlag = 1; // zzw ota must add /* for (k = 0; k < 256; k++) { temp_buff[k] = flash_word_read(OTA_STATE_DATA_ADD + (4 * k)); // 1.取出程序运行区代码数据 } temp_buff[0] = IAPUpdateFlag; delay_1ms(10); Ret = flash_page_write(OTA_STATE_DATA_ADD, temp_buff); // 2.将取出的运行区代码写入临时区 delay_1ms(20); flash_word_write (OTA_STATE_DATA_ADD,IAPUpdateFlag); delay_1ms(500); NVIC_SystemReset(); // add by zzw 系统复位函数 */ } else if (status == 0x01) { } } /** * @brief mcu ota data handle * @param[in] {fw_offset} frame offset * @param[in] {data} received data * @return void */ void ota_fw_data_handle(unsigned int fw_offset, char *data1, unsigned char data_len) { unsigned short i = 0; unsigned short update = 1; unsigned long app_newcode_add = 0; // 读flash的时候的地址变量,新代码区 unsigned short temp = 0; unsigned long write_data; //"请在该函数处理固件包数据" //"received frame data, should save in flash, mcu should realize this fuction, and delete this line " // 取出数据存入falsh,建议延用‘ota_fw_info’全局变量,不需定义其他全局变量,可维护数据包长度等 if (fw_offset == 0) { // zzw ota must add /*app_newcode_add = OTA_NEW_CODE_START_ADD; fmc_unlock(); for (i = 0; i < 26; i++) { fmc_page_erase(app_newcode_add + i * 1024); } fmc_lock();*/ } OTA_Reciv_Datalen = OTA_Reciv_Datalen + data_len; // zzw ota must add // app_newcode_add = OTA_NEW_CODE_START_ADD + fw_offset; if (data_len == FW_SINGLE_PACKET_SIZE) // 整包数据 { // zzw ota must add /* for (i = 0; i < (FW_SINGLE_PACKET_SIZE / 4); i++) { write_data = 0; write_data = data[i * 4 + 3]; write_data = (write_data << 8) + data[i * 4 + 2]; write_data = (write_data << 8) + data[i * 4 + 1]; write_data = (write_data << 8) + data[i * 4]; flash_word_write(app_newcode_add, write_data); app_newcode_add = app_newcode_add + 4; }*/ } else // 最后一包非整包数据 { temp = data_len % 4; if (temp == 0) { // zzw ota must add /*for (i = 0; i < (data_len / 4); i++) { write_data = 0; write_data = data[i * 4 + 3]; write_data = (write_data << 8) + data[i * 4 + 2]; write_data = (write_data << 8) + data[i * 4 + 1]; write_data = (write_data << 8) + data[i * 4]; flash_word_write(app_newcode_add, write_data); app_newcode_add = app_newcode_add + 4; }*/ } } // if(OTA_Reciv_Datalen == ota_fw_info.mcu_ota_fw_size) //接收数据完成停止获取 // { // update = 0; // } if (update) // 数据存储完毕,继续调用获取数据命令 { mcu_ota_fw_request(); // 固件升级 } // #error "请在该函数处理固件包数据,并删除该行" } #endif #ifdef BEACON_TEST /** * @brief beacon test notify,which used in testing * @param[in] {void} * @return void */ void mcu_received_beacon_test_handle(void) { unsigned short length = 0; length = set_zigbee_uart_byte(length, 0x00); zigbee_uart_write_frame(SEND_BEACON_NOTIFY_CMD, length); // then start test // add by zzw 产测 /*if(burn_in_test_timeout<=300)//开机30S内 { burn_in_test_start=1; //burn_in_test_counter=0; }*/ } #endif #ifdef CHECK_ZIGBEE_NETWORK /** * @brief check zigbee nwkstate,before start join nwk, check nwk if state is not 0x02,can start jion, * else delay 5s * * @param[in] {void} * @return void */ void mcu_check_zigbee_nwk_state(void) { unsigned short length = 0; zigbee_uart_write_frame(CHECK_ZIGBEE_NETWORK_CMD, length); // then start test } #endif void zigbee_notify_factory_new_hanlde(void) //app操作删除设备并清理数据 { unsigned short length = 0; unsigned short i; length = set_zigbee_uart_byte(length, 0x01); zigbee_uart_write_frame(ZIGBEE_FACTORY_NEW_CMD, length); // then start test // add by zzw 20240207 APP删除设备后自动入网开启 ZG_Joining = CONDITION_BEFOR_JOINING_TO_JOINING; // 配网倒计时 ZG_JoinCounter = 0; ledSetParam(6, 12); // 高速闪烁,所有指示灯8Hz闪烁(表现为三位开关三个指示灯都闪烁) // mcu_join_zigbee(); // 发送入网指令 switchState.zigbee_work_state = 0; // 设备被删除 //此处增加删除电量历史数据 for(i = 0; i < 20; i++) { power_data[i] = 0xFF; } user_write_INFO_byte(INFO6_ADDR, power_data, 20); user_write_INFO_byte(INFO7_ADDR, power_data, 20); } #ifdef READ_DP_DATA_NOTIFY /** * @brief when gateway repower or relink clould, or zigbee module join sucess, repower, this commod will notify * mcu, to sys dp data, mcu itself decide whether report. * * @param[in] {void} * @return void */ void read_dp_data_notify_hanlde(void) { unsigned short length = 0; length = set_zigbee_uart_byte(length, 0x01); zigbee_uart_write_frame(ZIGBEE_FACTORY_NEW_CMD, length); // then start test } #endif /* * 函数:HexToDisHex * 功能:将十六进制数转换成十六进制字符形式 * pbDest:存放目标十六进制字符串 * pbSrc:被转化的十六进制数 * nLen:被转化的十六进制数的长度 */ void HexToDisHex(unsigned char *pbDest, unsigned char *pbSrc, int nLen) { unsigned char c0, c1; unsigned char buf[2]; unsigned char *dst = pbDest; unsigned char *src = pbSrc; int index; for (index = 0; index < nLen; index++) { c0 = *src >> 4; if (c0 >= 0x0 && c0 <= 0x9) { buf[0] = c0 - 0 + '0'; } else { buf[0] = c0 - 10 + 'a'; } c1 = *src++ & 0x0F; if (c1 >= 0x0 && c1 <= 0x9) { buf[1] = c1 - 0 + '0'; } else { buf[1] = c1 - 10 + 'a'; } *dst = buf[0]; dst++; *dst = buf[1]; dst++; } } /* * DisHexToHex * 功能:将字符串形式的十六进制数转换成十六进制 * pbDest:存放转换后的十六进制数 * pbSrc:源字符数组,存放要转换的十六进制字符串形式的数据 * nLen:被转化的十六进制数字符串数据的长度 */ void DisHexToHex(unsigned char *pbDest, unsigned char *pbSrc, int nLen) { unsigned char *dst = pbDest; unsigned char *src = pbSrc; unsigned char h1, h2; unsigned char s1, s2; int i; for (i = 0; i < nLen; i++) { h1 = src[2 * i]; h2 = src[2 * i + 1]; s1 = toupper(h1) - 0x30; if (s1 > 9) s1 -= 7; s2 = toupper(h2) - 0x30; if (s2 > 9) s2 -= 7; *dst = (s1 << 4) + s2; dst++; } }