Commit 682c75ca authored by limm's avatar limm

V1.0 VERSION

parent 25f1f17b
/******************************************************************************************************** /********************************************************************************************************
* @file sampleLight.c * @file sampleLight.c
* *
* @brief This is the source file for sampleLight * @brief This is the source file for sampleLight
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#if (__PROJECT_3LIGHT_PANEL_DEMO__) #if (__PROJECT_3LIGHT_PANEL_DEMO__)
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "tl_common.h" #include "tl_common.h"
#include "zb_api.h" #include "zb_api.h"
#include "zcl_include.h" #include "zcl_include.h"
#include "bdb.h" #include "bdb.h"
#include "ota.h" #include "ota.h"
#include "gp.h" #include "gp.h"
#include PROJECT_H #include PROJECT_H
#if ZBHCI_EN #if ZBHCI_EN
#include "zbhci.h" #include "zbhci.h"
#endif #endif
#include "00ikonke_app/general/ikk-tick-handler.h" #include "00ikonke_app/general/ikk-tick-handler.h"
#include "00ikonke_app/general/ikk-network.h" #include "00ikonke_app/general/ikk-network.h"
/********************************************************************** /**********************************************************************
* LOCAL CONSTANTS * LOCAL CONSTANTS
*/ */
/********************************************************************** /**********************************************************************
* TYPEDEFS * TYPEDEFS
*/ */
/********************************************************************** /**********************************************************************
* GLOBAL VARIABLES * GLOBAL VARIABLES
*/ */
app_ctx_t gLightCtx; app_ctx_t gLightCtx;
#ifdef ZCL_OTA #ifdef ZCL_OTA
extern ota_callBack_t sampleLight_otaCb; extern ota_callBack_t sampleLight_otaCb;
//running code firmware information //running code firmware information
ota_preamble_t sampleLight_otaInfo = { ota_preamble_t sampleLight_otaInfo = {
.fileVer = FILE_VERSION, .fileVer = FILE_VERSION,
.imageType = IMAGE_TYPE, .imageType = IMAGE_TYPE,
.manufacturerCode = MANUFACTURER_CODE_TELINK, .manufacturerCode = MANUFACTURER_CODE_TELINK,
}; };
#endif #endif
//Must declare the application call back function which used by ZDO layer //Must declare the application call back function which used by ZDO layer
const zdo_appIndCb_t appCbLst = { const zdo_appIndCb_t appCbLst = {
bdb_zdoStartDevCnf,//start device cnf cb bdb_zdoStartDevCnf,//start device cnf cb
NULL,//reset cnf cb NULL,//reset cnf cb
NULL,//device announce indication cb NULL,//device announce indication cb
sampleLight_leaveIndHandler,//leave ind cb sampleLight_leaveIndHandler,//leave ind cb
NetworkLeaveHandler,//leave cnf cb NetworkLeaveHandler,//leave cnf cb
sampleLight_nwkUpdateIndicateHandler,//nwk update ind cb sampleLight_nwkUpdateIndicateHandler,//nwk update ind cb
NULL,//permit join ind cb NULL,//permit join ind cb
NULL,//nlme sync cnf cb NULL,//nlme sync cnf cb
JoinNetworkHandler,//tc join ind cb JoinNetworkHandler,//tc join ind cb
}; };
/** /**
* @brief Definition for bdb commissioning setting * @brief Definition for bdb commissioning setting
*/ */
bdb_commissionSetting_t g_bdbCommissionSetting = { bdb_commissionSetting_t g_bdbCommissionSetting = {
.linkKey.tcLinkKey.keyType = SS_GLOBAL_LINK_KEY, .linkKey.tcLinkKey.keyType = SS_GLOBAL_LINK_KEY,
.linkKey.tcLinkKey.key = (u8 *)tcLinkKeyCentralDefault, //can use unique link key stored in NV .linkKey.tcLinkKey.key = (u8 *)tcLinkKeyCentralDefault, //can use unique link key stored in NV
.linkKey.distributeLinkKey.keyType = MASTER_KEY, .linkKey.distributeLinkKey.keyType = MASTER_KEY,
.linkKey.distributeLinkKey.key = (u8 *)linkKeyDistributedMaster, //use linkKeyDistributedCertification before testing .linkKey.distributeLinkKey.key = (u8 *)linkKeyDistributedMaster, //use linkKeyDistributedCertification before testing
.linkKey.touchLinkKey.keyType = MASTER_KEY, .linkKey.touchLinkKey.keyType = MASTER_KEY,
.linkKey.touchLinkKey.key = (u8 *)touchLinkKeyMaster, //use touchLinkKeyCertification before testing .linkKey.touchLinkKey.key = (u8 *)touchLinkKeyMaster, //use touchLinkKeyCertification before testing
#if TOUCHLINK_SUPPORT #if TOUCHLINK_SUPPORT
.touchlinkEnable = 1, /* enable touch-link */ .touchlinkEnable = 1, /* enable touch-link */
#else #else
.touchlinkEnable = 0, /* disable touch-link */ .touchlinkEnable = 0, /* disable touch-link */
#endif #endif
.touchlinkChannel = DEFAULT_CHANNEL, /* touch-link default operation channel for target */ .touchlinkChannel = DEFAULT_CHANNEL, /* touch-link default operation channel for target */
.touchlinkLqiThreshold = 0xA0, /* threshold for touch-link scan req/resp command */ .touchlinkLqiThreshold = 0xA0, /* threshold for touch-link scan req/resp command */
}; };
/********************************************************************** /**********************************************************************
* LOCAL VARIABLES * LOCAL VARIABLES
*/ */
ev_timer_event_t *sampleLightAttrsStoreTimerEvt = NULL; ev_timer_event_t *sampleLightAttrsStoreTimerEvt = NULL;
/********************************************************************** /**********************************************************************
* FUNCTIONS * FUNCTIONS
*/ */
/********************************************************************* /*********************************************************************
* @fn stack_init * @fn stack_init
* *
* @brief This function initialize the ZigBee stack and related profile. If HA/ZLL profile is * @brief This function initialize the ZigBee stack and related profile. If HA/ZLL profile is
* enabled in this application, related cluster should be registered here. * enabled in this application, related cluster should be registered here.
* *
* @param None * @param None
* *
* @return None * @return None
*/ */
void stack_init(void) void stack_init(void)
{ {
/* Initialize ZB stack */ /* Initialize ZB stack */
zb_init(); zb_init();
/* Register stack CB */ /* Register stack CB */
zb_zdoCbRegister((zdo_appIndCb_t *)&appCbLst); zb_zdoCbRegister((zdo_appIndCb_t *)&appCbLst);
} }
/********************************************************************* /*********************************************************************
* @fn user_app_init * @fn user_app_init
* *
* @brief This function initialize the application(Endpoint) information for this node. * @brief This function initialize the application(Endpoint) information for this node.
* *
* @param None * @param None
* *
* @return None * @return None
*/ */
extern af_simple_descriptor_t device_simpleDesc[Support_Endpoint_Num]; extern af_simple_descriptor_t device_simpleDesc[Support_Endpoint_Num];
extern zcl_specClusterInfo_t *g_EPClusterAllList[Support_Endpoint_Num]; extern zcl_specClusterInfo_t *g_EPClusterAllList[Support_Endpoint_Num];
extern uint8_t Cluster_Num_List[Support_Endpoint_Num]; extern uint8_t Cluster_Num_List[Support_Endpoint_Num];
void user_app_init(void) void user_app_init(void)
{ {
af_nodeDescManuCodeUpdate(MANUFACTURER_CODE_TELINK); af_nodeDescManuCodeUpdate(MANUFACTURER_CODE_TELINK);
/* Initialize ZCL layer */ /* Initialize ZCL layer */
/* Register Incoming ZCL Foundation command/response messages */ /* Register Incoming ZCL Foundation command/response messages */
zcl_init(sampleLight_zclProcessIncomingMsg); zcl_init(sampleLight_zclProcessIncomingMsg);
/* Initialize or restore attributes, this must before 'zcl_register()' */ /* Initialize or restore attributes, this must before 'zcl_register()' */
//zcl_sampleLightAttrsInit(); //zcl_sampleLightAttrsInit();
for(uint8_t i =0;i< Support_Endpoint_Num;i++) for(uint8_t i =0;i< Support_Endpoint_Num;i++)
{ {
SimpleDesc_Init(fixedEndpoints[i]); SimpleDesc_Init(fixedEndpoints[i]);
/* Register endPoint */ /* Register endPoint */
af_endpointRegister(fixedEndpoints[i], (af_simple_descriptor_t *)&device_simpleDesc[i], zcl_rx_handler, NULL); af_endpointRegister(fixedEndpoints[i], (af_simple_descriptor_t *)&device_simpleDesc[i], zcl_rx_handler, NULL);
/* Register ZCL specific cluster information */ /* Register ZCL specific cluster information */
zcl_register(fixedEndpoints[i], Cluster_Num_List[i], (zcl_specClusterInfo_t *)g_EPClusterAllList[i]); zcl_register(fixedEndpoints[i], Cluster_Num_List[i], (zcl_specClusterInfo_t *)g_EPClusterAllList[i]);
} }
#if AF_TEST_ENABLE
#ifdef ZCL_GREEN_POWER /* Register endPoint */
/* Initialize GP */ u8 status = af_endpointRegister(SAMPLE_TEST_ENDPOINT, (af_simple_descriptor_t *)&sampleTestDesc, afTest_rx_handler, afTest_dataSendConfirm);
gp_init(); printf("af_test regester status =%d\r\n",status);
#endif #endif
#ifdef ZCL_OTA #ifdef ZCL_GREEN_POWER
/* Initialize OTA */ /* Initialize GP */
ota_init(OTA_TYPE_CLIENT, (af_simple_descriptor_t *)&device_simpleDesc[0], &sampleLight_otaInfo, &sampleLight_otaCb); gp_init();
#endif #endif
zcl_reportingTabInit(); #ifdef ZCL_OTA
} /* Initialize OTA */
ota_init(OTA_TYPE_CLIENT, (af_simple_descriptor_t *)&device_simpleDesc[0], &sampleLight_otaInfo, &sampleLight_otaCb);
#endif
void report_handler(void) zcl_reportingTabInit();
{ }
if(zb_isDeviceJoinedNwk()){
if(zcl_reportingEntryActiveNumGet()){
u16 second = 1;//TODO: fix me
void report_handler(void)
reportNoMinLimit(); {
if(zb_isDeviceJoinedNwk()){
//start report timer if(zcl_reportingEntryActiveNumGet()){
reportAttrTimerStart(second); u16 second = 1;//TODO: fix me
}else{
//stop report timer reportNoMinLimit();
//reportAttrTimerStop();
} //start report timer
} reportAttrTimerStart(second);
} }else{
//stop report timer
void app_task(void) //reportAttrTimerStop();
{ }
//app_key_handler(); //lmm deledt }
//localPermitJoinState(); }
if(BDB_STATE_GET() == BDB_STATE_IDLE){
//factroyRst_handler(); void app_task(void)
{
report_handler(); //app_key_handler(); //lmm deledt
//localPermitJoinState();
#if 0/* NOTE: If set to '1', the latest status of lighting will be stored. */ if(BDB_STATE_GET() == BDB_STATE_IDLE){
sampleLightAttrsChk(); //factroyRst_handler();
#endif
} report_handler();
}
#if 0/* NOTE: If set to '1', the latest status of lighting will be stored. */
static void sampleLightSysException(void) sampleLightAttrsChk();
{ #endif
zcl_onOffAttr_save(); }
//zcl_levelAttr_save(); }
//zcl_colorCtrlAttr_save();
iKonkeAfSelfPrint("something wrong ,then system reset"); static void sampleLightSysException(void)
SYSTEM_RESET(); {
//led_on(LED_POWER); zcl_onOffAttr_save();
//while(1); //zcl_levelAttr_save();
} //zcl_colorCtrlAttr_save();
iKonkeAfSelfPrint("something wrong ,then system reset");
SYSTEM_RESET();
/********************************************************************* //led_on(LED_POWER);
* @fn user_init //while(1);
* }
* @brief User level initialization code.
*
* @param isRetention - if it is waking up with ram retention. /*********************************************************************
* * @fn user_init
* @return None *
*/ * @brief User level initialization code.
extern void App_Init(void); *
void user_init(bool isRetention) * @param isRetention - if it is waking up with ram retention.
{ *
(void)isRetention; * @return None
*/
/*Initialize Tick Running*/ extern void App_Init(void);
Tick_Time_Init(); //lmm add for tick event init void user_init(bool isRetention)
{
/* Initialize Stack */ (void)isRetention;
stack_init();
/*Initialize Tick Running*/
/* Initialize user application */ Tick_Time_Init(); //lmm add for tick event init
user_app_init();
/* Initialize Stack */
App_Init(); stack_init();
/* Register except handler for test */ /* Initialize user application */
sys_exceptHandlerRegister(sampleLightSysException); user_app_init();
/* Adjust light state to default attributes*/ App_Init();
//light_adjust(); printf("###########init !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n");
/* User's Task */ /* Register except handler for test */
#if ZBHCI_EN sys_exceptHandlerRegister(sampleLightSysException);
zbhciInit();
ev_on_poll(EV_POLL_HCI, zbhciTask); /* Adjust light state to default attributes*/
#endif //light_adjust();
ev_on_poll(EV_POLL_IDLE, app_task);
/* User's Task */
/* Read the pre-install code from NV */ #if ZBHCI_EN
if(bdb_preInstallCodeLoad(&gLightCtx.tcLinkKey.keyType, gLightCtx.tcLinkKey.key) == RET_OK){ zbhciInit();
g_bdbCommissionSetting.linkKey.tcLinkKey.keyType = gLightCtx.tcLinkKey.keyType; ev_on_poll(EV_POLL_HCI, zbhciTask);
g_bdbCommissionSetting.linkKey.tcLinkKey.key = gLightCtx.tcLinkKey.key; #endif
} ev_on_poll(EV_POLL_IDLE, app_task);
/* Set default reporting configuration */ /* Read the pre-install code from NV */
u8 reportableChange = 0x00; if(bdb_preInstallCodeLoad(&gLightCtx.tcLinkKey.keyType, gLightCtx.tcLinkKey.key) == RET_OK){
for(uint8_t i =0;i< Support_Endpoint_Num;i++) g_bdbCommissionSetting.linkKey.tcLinkKey.keyType = gLightCtx.tcLinkKey.keyType;
{ g_bdbCommissionSetting.linkKey.tcLinkKey.key = gLightCtx.tcLinkKey.key;
status_t status = bdb_defaultReportingCfg(fixedEndpoints[i], fixedProfileIds[i], ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, }
0x0000, 0, (u8 *)&reportableChange);
/* Initialize BDB */ /* Set default reporting configuration */
u8 reportableChange = 0x00;
iKonkeAfSelfPrint("bdb_defaultReportingCfg: index(%d),endpoint(%d),profile(%d) status(%d)\r\n", i,fixedEndpoints[i],fixedProfileIds[i], status); for(uint8_t i =0;i< Support_Endpoint_Num;i++)
} {
u8 result =bdb_init((af_simple_descriptor_t *)&g_EPClusterAllList[0], &g_bdbCommissionSetting, &g_zbDemoBdbCb, 1); status_t status = bdb_defaultReportingCfg(fixedEndpoints[i], fixedProfileIds[i], ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF,
iKonkeAfSelfPrint("bdb_defaultReportingCfg,result = %d\r\n",result); 0x0000, 0, (u8 *)&reportableChange);
} /* Initialize BDB */
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ iKonkeAfSelfPrint("bdb_defaultReportingCfg: index(%d),endpoint(%d),profile(%d) status(%d)\r\n", i,fixedEndpoints[i],fixedProfileIds[i], status);
}
u8 result =bdb_init((af_simple_descriptor_t *)&g_EPClusterAllList[0], &g_bdbCommissionSetting, &g_zbDemoBdbCb, 1);
iKonkeAfSelfPrint("bdb_defaultReportingCfg,result = %d\r\n",result);
}
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */
...@@ -47,12 +47,11 @@ ...@@ -47,12 +47,11 @@
#define _SAMPLE_LIGHT_H_ #define _SAMPLE_LIGHT_H_
#include ENDPOINT_CONFIG_H #include ENDPOINT_CONFIG_H
/********************************************************************** /**********************************************************************
* CONSTANT * CONSTANT
*/ */
#define SAMPLE_LIGHT_ENDPOINT 0x01 #define SAMPLE_LIGHT_ENDPOINT 0x01
#define SAMPLE_TEST_ENDPOINT 0x02 #define SAMPLE_TEST_ENDPOINT 0x06
/********************************************************************** /**********************************************************************
* TYPEDEFS * TYPEDEFS
......
/******************************************************************************************************** /********************************************************************************************************
* @file sampleLightEpCfg.c * @file sampleLightEpCfg.c
* *
* @brief This is the source file for sampleLightEpCfg * @brief This is the source file for sampleLightEpCfg
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#if (__PROJECT_3LIGHT_PANEL_DEMO__) #if (__PROJECT_3LIGHT_PANEL_DEMO__)
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "tl_common.h" #include "tl_common.h"
#include "zcl_include.h" #include "zcl_include.h"
#include PROJECT_H #include PROJECT_H
#include ENDPOINT_CONFIG_H #include ENDPOINT_CONFIG_H
#include "ikk-debug.h" #include "ikk-debug.h"
/********************************************************************** /**********************************************************************
* LOCAL CONSTANTS * LOCAL CONSTANTS
*/ */
#define ZCL_BASIC_MFG_NAME {5,'K','o','n','k','e'} #define ZCL_BASIC_MFG_NAME {5,'K','o','n','k','e'}
#define ZCL_BASIC_MODEL_ID {16,'3','A','F','E','2','8','2','0','0','0','0','6','8','6','2','1'} #define ZCL_BASIC_MODEL_ID {16,'3','A','F','E','2','0','2','0','0','0','0','6','8','6','2','4'}
#ifndef ZCL_BASIC_MFG_NAME #ifndef ZCL_BASIC_MFG_NAME
#define ZCL_BASIC_MFG_NAME {6,'T','E','L','I','N','K'} #define ZCL_BASIC_MFG_NAME {6,'T','E','L','I','N','K'}
#endif #endif
#ifndef ZCL_BASIC_MODEL_ID #ifndef ZCL_BASIC_MODEL_ID
#define ZCL_BASIC_MODEL_ID {8,'T','L','S','R','8','2','x','x'} #define ZCL_BASIC_MODEL_ID {8,'T','L','S','R','8','2','x','x'}
#endif #endif
#ifndef ZCL_BASIC_SW_BUILD_ID #ifndef ZCL_BASIC_SW_BUILD_ID
#define ZCL_BASIC_SW_BUILD_ID {10,'0','1','2','2','0','5','2','0','1','7'} #define ZCL_BASIC_SW_BUILD_ID {10,'0','1','2','2','0','5','2','0','1','7'}
#endif #endif
#ifndef ZCL_FCC0_OPT_ID #ifndef ZCL_FCC0_OPT_ID
#define ZCL_FCC0_OPT_ID {50,'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} #define ZCL_FCC0_OPT_ID {50,'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}
#endif #endif
const uint8_t fixedEndpoints[SUPPORT_MAX_EP] = Support_Endpoint_Array; const uint8_t fixedEndpoints[SUPPORT_MAX_EP] = Support_Endpoint_Array;
const uint16_t fixedProfileIds[SUPPORT_MAX_EP] = FIXED_PROFILE_IDS; const uint16_t fixedProfileIds[SUPPORT_MAX_EP] = FIXED_PROFILE_IDS;
const uint16_t fixedDeviceIds[SUPPORT_MAX_EP] = FIXED_DEVICE_IDS; const uint16_t fixedDeviceIds[SUPPORT_MAX_EP] = FIXED_DEVICE_IDS;
#if COLOR_CCT_SUPPORT #if COLOR_CCT_SUPPORT
#define COLOR_TEMPERATURE_PHYSICAL_MIN 0x00FA//4000K #define COLOR_TEMPERATURE_PHYSICAL_MIN 0x00FA//4000K
#define COLOR_TEMPERATURE_PHYSICAL_MAX 0x01C6//2200K #define COLOR_TEMPERATURE_PHYSICAL_MAX 0x01C6//2200K
#endif #endif
/********************************************************************** /**********************************************************************
* TYPEDEFS * TYPEDEFS
*/ */
/********************************************************************** /**********************************************************************
* GLOBAL VARIABLES * GLOBAL VARIABLES
*/ */
/** /**
* @brief Definition for Incoming cluster / Sever Cluster * @brief Definition for Incoming cluster / Sever Cluster
*/ */
/******************************EP1 INFO**********************************/ /******************************EP1 INFO**********************************/
const u16 EP1_inClusterList[] = const u16 EP1_inClusterList[] =
{ {
ZCL_CLUSTER_GEN_BASIC, ZCL_CLUSTER_GEN_BASIC,
ZCL_CLUSTER_GEN_IDENTIFY, ZCL_CLUSTER_GEN_IDENTIFY,
#ifdef ZCL_GROUP #ifdef ZCL_GROUP
ZCL_CLUSTER_GEN_GROUPS, ZCL_CLUSTER_GEN_GROUPS,
#endif #endif
#ifdef ZCL_SCENE #ifdef ZCL_SCENE
ZCL_CLUSTER_GEN_SCENES, ZCL_CLUSTER_GEN_SCENES,
#endif #endif
#ifdef ZCL_ON_OFF #ifdef ZCL_ON_OFF
ZCL_CLUSTER_GEN_ON_OFF, ZCL_CLUSTER_GEN_ON_OFF,
#endif #endif
#ifdef ZCL_LEVEL_CTRL #ifdef ZCL_LEVEL_CTRL
ZCL_CLUSTER_GEN_LEVEL_CONTROL, ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#endif #endif
#ifdef ZCL_LIGHT_COLOR_CONTROL #ifdef ZCL_LIGHT_COLOR_CONTROL
ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
#endif #endif
#ifdef ZCL_ZLL_COMMISSIONING #ifdef ZCL_ZLL_COMMISSIONING
ZCL_CLUSTER_TOUCHLINK_COMMISSIONING, ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
#endif #endif
#ifdef ZCL_FCC0 #ifdef ZCL_FCC0
ZCL_CLUSTER_PRIVATE_FCC0, ZCL_CLUSTER_PRIVATE_FCC0,
#endif #endif
};
};
/**
/** * @brief Definition for Outgoing cluster / Client Cluster
* @brief Definition for Outgoing cluster / Client Cluster */
*/ const u16 EP1_outClusterList[] =
const u16 EP1_outClusterList[] = {
{ #ifdef ZCL_OTA
#ifdef ZCL_OTA ZCL_CLUSTER_OTA,
ZCL_CLUSTER_OTA, #endif
#endif };
};
/**
/** * @brief Definition for Server cluster number and Client cluster number
* @brief Definition for Server cluster number and Client cluster number */
*/ #define EP1_IN_CLUSTER_NUM (sizeof(EP1_inClusterList)/sizeof(EP1_inClusterList[0]))
#define EP1_IN_CLUSTER_NUM (sizeof(EP1_inClusterList)/sizeof(EP1_inClusterList[0])) #define EP1_OUT_CLUSTER_NUM (sizeof(EP1_outClusterList)/sizeof(EP1_outClusterList[0]))
#define EP1_OUT_CLUSTER_NUM (sizeof(EP1_outClusterList)/sizeof(EP1_outClusterList[0]))
/******************************EP2 INFO**********************************/
/******************************EP2 INFO**********************************/ const u16 EP2_inClusterList[] =
const u16 EP2_inClusterList[] = {
{ ZCL_CLUSTER_GEN_BASIC,
ZCL_CLUSTER_GEN_BASIC, ZCL_CLUSTER_GEN_IDENTIFY,
ZCL_CLUSTER_GEN_IDENTIFY, #ifdef ZCL_GROUP
#ifdef ZCL_GROUP ZCL_CLUSTER_GEN_GROUPS,
ZCL_CLUSTER_GEN_GROUPS, #endif
#endif #ifdef ZCL_SCENE
#ifdef ZCL_SCENE ZCL_CLUSTER_GEN_SCENES,
ZCL_CLUSTER_GEN_SCENES, #endif
#endif #ifdef ZCL_ON_OFF
#ifdef ZCL_ON_OFF ZCL_CLUSTER_GEN_ON_OFF,
ZCL_CLUSTER_GEN_ON_OFF, #endif
#endif #ifdef ZCL_LEVEL_CTRL
#ifdef ZCL_LEVEL_CTRL ZCL_CLUSTER_GEN_LEVEL_CONTROL,
ZCL_CLUSTER_GEN_LEVEL_CONTROL, #endif
#endif #ifdef ZCL_LIGHT_COLOR_CONTROL
#ifdef ZCL_LIGHT_COLOR_CONTROL ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, #endif
#endif #ifdef ZCL_ZLL_COMMISSIONING
#ifdef ZCL_ZLL_COMMISSIONING ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
ZCL_CLUSTER_TOUCHLINK_COMMISSIONING, #endif
#endif };
#ifdef ZCL_FCC0
ZCL_CLUSTER_PRIVATE_FCC0, /**
#endif * @brief Definition for Outgoing cluster / Client Cluster
*/
}; const u16 EP2_outClusterList[] =
{
/** #ifdef ZCL_OTA
* @brief Definition for Outgoing cluster / Client Cluster ZCL_CLUSTER_OTA,
*/ #endif
const u16 EP2_outClusterList[] = };
{
#ifdef ZCL_OTA /**
ZCL_CLUSTER_OTA, * @brief Definition for Server cluster number and Client cluster number
#endif */
}; #define EP2_IN_CLUSTER_NUM (sizeof(EP2_inClusterList)/sizeof(EP2_inClusterList[0]))
#define EP2_OUT_CLUSTER_NUM (sizeof(EP2_outClusterList)/sizeof(EP2_outClusterList[0]))
/**
* @brief Definition for Server cluster number and Client cluster number /******************************EP3 INFO**********************************/
*/
#define EP2_IN_CLUSTER_NUM (sizeof(EP2_inClusterList)/sizeof(EP2_inClusterList[0])) const u16 EP3_inClusterList[] =
#define EP2_OUT_CLUSTER_NUM (sizeof(EP2_outClusterList)/sizeof(EP2_outClusterList[0])) {
ZCL_CLUSTER_GEN_BASIC,
/******************************EP3 INFO**********************************/ ZCL_CLUSTER_GEN_IDENTIFY,
#ifdef ZCL_GROUP
const u16 EP3_inClusterList[] = ZCL_CLUSTER_GEN_GROUPS,
{ #endif
ZCL_CLUSTER_GEN_BASIC, #ifdef ZCL_SCENE
ZCL_CLUSTER_GEN_IDENTIFY, ZCL_CLUSTER_GEN_SCENES,
#ifdef ZCL_GROUP #endif
ZCL_CLUSTER_GEN_GROUPS, #ifdef ZCL_ON_OFF
#endif ZCL_CLUSTER_GEN_ON_OFF,
#ifdef ZCL_SCENE #endif
ZCL_CLUSTER_GEN_SCENES, #ifdef ZCL_LEVEL_CTRL
#endif ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#ifdef ZCL_ON_OFF #endif
ZCL_CLUSTER_GEN_ON_OFF, #ifdef ZCL_LIGHT_COLOR_CONTROL
#endif ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
#ifdef ZCL_LEVEL_CTRL #endif
ZCL_CLUSTER_GEN_LEVEL_CONTROL, #ifdef ZCL_ZLL_COMMISSIONING
#endif ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
#ifdef ZCL_LIGHT_COLOR_CONTROL #endif
ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, };
#endif
#ifdef ZCL_ZLL_COMMISSIONING /**
ZCL_CLUSTER_TOUCHLINK_COMMISSIONING, * @brief Definition for Outgoing cluster / Client Cluster
#endif */
#ifdef ZCL_FCC0 const u16 EP3_outClusterList[] =
ZCL_CLUSTER_PRIVATE_FCC0, {
#endif #ifdef ZCL_OTA
ZCL_CLUSTER_OTA,
}; #endif
};
/**
* @brief Definition for Outgoing cluster / Client Cluster /**
*/ * @brief Definition for Server cluster number and Client cluster number
const u16 EP3_outClusterList[] = */
{ #define EP3_IN_CLUSTER_NUM (sizeof(EP3_inClusterList)/sizeof(EP3_inClusterList[0]))
#ifdef ZCL_OTA #define EP3_OUT_CLUSTER_NUM (sizeof(EP3_outClusterList)/sizeof(EP3_outClusterList[0]))
ZCL_CLUSTER_OTA,
#endif /******************************EP4 INFO**********************************/
}; const u16 EP4_inClusterList[] =
{
/** ZCL_CLUSTER_GEN_BASIC,
* @brief Definition for Server cluster number and Client cluster number ZCL_CLUSTER_GEN_IDENTIFY,
*/ #ifdef ZCL_GROUP
#define EP3_IN_CLUSTER_NUM (sizeof(EP3_inClusterList)/sizeof(EP3_inClusterList[0])) ZCL_CLUSTER_GEN_GROUPS,
#define EP3_OUT_CLUSTER_NUM (sizeof(EP3_outClusterList)/sizeof(EP3_outClusterList[0])) #endif
#ifdef ZCL_SCENE
/******************************EP4 INFO**********************************/ ZCL_CLUSTER_GEN_SCENES,
const u16 EP4_inClusterList[] = #endif
{ #ifdef ZCL_ON_OFF
ZCL_CLUSTER_GEN_BASIC, ZCL_CLUSTER_GEN_ON_OFF,
ZCL_CLUSTER_GEN_IDENTIFY, #endif
#ifdef ZCL_GROUP #ifdef ZCL_LEVEL_CTRL
ZCL_CLUSTER_GEN_GROUPS, ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#endif #endif
#ifdef ZCL_SCENE #ifdef ZCL_LIGHT_COLOR_CONTROL
ZCL_CLUSTER_GEN_SCENES, ZCL_CLUSTER_LIGHTING_COLOR_CONTROL,
#endif #endif
#ifdef ZCL_ON_OFF #ifdef ZCL_ZLL_COMMISSIONING
ZCL_CLUSTER_GEN_ON_OFF, ZCL_CLUSTER_TOUCHLINK_COMMISSIONING,
#endif #endif
#ifdef ZCL_LEVEL_CTRL };
ZCL_CLUSTER_GEN_LEVEL_CONTROL,
#endif /**
#ifdef ZCL_LIGHT_COLOR_CONTROL * @brief Definition for Outgoing cluster / Client Cluster
ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, */
#endif const u16 EP4_outClusterList[] =
#ifdef ZCL_ZLL_COMMISSIONING {
ZCL_CLUSTER_TOUCHLINK_COMMISSIONING, #ifdef ZCL_OTA
#endif ZCL_CLUSTER_OTA,
#ifdef ZCL_FCC0 #endif
ZCL_CLUSTER_PRIVATE_FCC0, };
#endif
/**
}; * @brief Definition for Server cluster number and Client cluster number
*/
/** #define EP4_IN_CLUSTER_NUM (sizeof(EP4_inClusterList)/sizeof(EP4_inClusterList[0]))
* @brief Definition for Outgoing cluster / Client Cluster #define EP4_OUT_CLUSTER_NUM (sizeof(EP4_outClusterList)/sizeof(EP4_outClusterList[0]))
*/
const u16 EP4_outClusterList[] = /**
{ * @brief Definition for simple description for HA profile
#ifdef ZCL_OTA */
ZCL_CLUSTER_OTA, af_simple_descriptor_t EP1_simpleDesc;
#endif af_simple_descriptor_t EP2_simpleDesc;
}; af_simple_descriptor_t EP3_simpleDesc;
af_simple_descriptor_t EP4_simpleDesc;
/** af_simple_descriptor_t device_simpleDesc[Support_Endpoint_Num] ;;
* @brief Definition for Server cluster number and Client cluster number uint8_t Cluster_Num_List[Support_Endpoint_Num];
*/ zcl_specClusterInfo_t *g_EPClusterAllList[Support_Endpoint_Num];
#define EP4_IN_CLUSTER_NUM (sizeof(EP4_inClusterList)/sizeof(EP4_inClusterList[0]))
#define EP4_OUT_CLUSTER_NUM (sizeof(EP4_outClusterList)/sizeof(EP4_outClusterList[0]))
/** /******************************EP4 INFO**********************************/
* @brief Definition for simple description for HA profile #if AF_TEST_ENABLE
*/ /**
af_simple_descriptor_t EP1_simpleDesc; * @brief Definition for Incoming cluster / Sever Cluster
af_simple_descriptor_t EP2_simpleDesc; */
af_simple_descriptor_t EP3_simpleDesc; const u16 sampleTest_inClusterList[] =
af_simple_descriptor_t EP4_simpleDesc; {
af_simple_descriptor_t device_simpleDesc[Support_Endpoint_Num] ;; ZCL_CLUSTER_TELINK_SDK_TEST_REQ,
uint8_t Cluster_Num_List[Support_Endpoint_Num]; ZCL_CLUSTER_TELINK_SDK_TEST_RSP,
zcl_specClusterInfo_t *g_EPClusterAllList[Support_Endpoint_Num]; ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ,
ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP,
0x0001,
};
/******************************EP4 INFO**********************************/
#if AF_TEST_ENABLE
/** /**
* @brief Definition for Incoming cluster / Sever Cluster * @brief Definition for Outgoing cluster / Client Cluster
*/ */
const u16 sampleTest_inClusterList[] = const u16 sampleTest_outClusterList[] =
{ {
ZCL_CLUSTER_TELINK_SDK_TEST_REQ, ZCL_CLUSTER_TELINK_SDK_TEST_REQ,
ZCL_CLUSTER_TELINK_SDK_TEST_RSP, ZCL_CLUSTER_TELINK_SDK_TEST_RSP,
ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ, ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ,
ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP,
}; };
/**
/** * @brief Definition for Server cluster number and Client cluster number
* @brief Definition for Outgoing cluster / Client Cluster */
*/ #define SAMPLE_TEST_IN_CLUSTER_NUM (sizeof(sampleTest_inClusterList)/sizeof(sampleTest_inClusterList[0]))
const u16 sampleTest_outClusterList[] = #define SAMPLE_TEST_OUT_CLUSTER_NUM (sizeof(sampleTest_outClusterList)/sizeof(sampleTest_outClusterList[0]))
{
ZCL_CLUSTER_TELINK_SDK_TEST_REQ, /**
ZCL_CLUSTER_TELINK_SDK_TEST_RSP, * @brief Definition for simple description for HA profile
ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ, */
ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, const af_simple_descriptor_t sampleTestDesc =
}; {
ZDO_PROFILE_ID, /* Application profile identifier */
/** HA_DEV_ONOFF_LIGHT_SWITCH, /* Application device identifier */
* @brief Definition for Server cluster number and Client cluster number SAMPLE_TEST_ENDPOINT, /* Endpoint */
*/ 0, /* Application device version */
#define SAMPLE_TEST_IN_CLUSTER_NUM (sizeof(sampleTest_inClusterList)/sizeof(sampleTest_inClusterList[0])) 0, /* Reserved */
#define SAMPLE_TEST_OUT_CLUSTER_NUM (sizeof(sampleTest_outClusterList)/sizeof(sampleTest_outClusterList[0])) SAMPLE_TEST_IN_CLUSTER_NUM, /* Application input cluster count */
SAMPLE_TEST_OUT_CLUSTER_NUM, /* Application output cluster count */
/** (u16 *)sampleTest_inClusterList, /* Application input cluster list */
* @brief Definition for simple description for HA profile (u16 *)sampleTest_outClusterList, /* Application output cluster list */
*/ };
const af_simple_descriptor_t sampleTestDesc = #endif /* AF_TEST_ENABLE */
{
HA_PROFILE_ID, /* Application profile identifier */
HA_DEV_DIMMABLE_LIGHT, /* Application device identifier */ /* Basic */
SAMPLE_TEST_ENDPOINT, /* Endpoint */ zcl_basicAttr_t g_zcl_basicAttrs =
0, /* Application device version */ {
0, /* Reserved */ .zclVersion = 0x03,
SAMPLE_TEST_IN_CLUSTER_NUM, /* Application input cluster count */ .appVersion = 0x28,
SAMPLE_TEST_OUT_CLUSTER_NUM, /* Application output cluster count */ .stackVersion = 0x02,
(u16 *)sampleTest_inClusterList, /* Application input cluster list */ .hwVersion = 0x20,
(u16 *)sampleTest_outClusterList, /* Application output cluster list */ .manuName = ZCL_BASIC_MFG_NAME,
}; .modelId = ZCL_BASIC_MODEL_ID,
#endif /* AF_TEST_ENABLE */ .powerSource = POWER_SOURCE_MAINS_1_PHASE,
.swBuildId = ZCL_BASIC_SW_BUILD_ID,
.deviceEnable = TRUE,
/* Basic */ };
zcl_basicAttr_t g_zcl_basicAttrs =
{ const zclAttrInfo_t basic_attrTbl[] =
.zclVersion = 0x03, {
.appVersion = 0x28, { ZCL_ATTRID_BASIC_ZCL_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.zclVersion},
.stackVersion = 0x02, { ZCL_ATTRID_BASIC_APP_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.appVersion},
.hwVersion = 0x20, { ZCL_ATTRID_BASIC_STACK_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.stackVersion},
.manuName = ZCL_BASIC_MFG_NAME, { ZCL_ATTRID_BASIC_HW_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.hwVersion},
.modelId = ZCL_BASIC_MODEL_ID, { ZCL_ATTRID_BASIC_MFR_NAME, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)g_zcl_basicAttrs.manuName},
.powerSource = POWER_SOURCE_MAINS_1_PHASE, { ZCL_ATTRID_BASIC_MODEL_ID, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)g_zcl_basicAttrs.modelId},
.swBuildId = ZCL_BASIC_SW_BUILD_ID, { ZCL_ATTRID_BASIC_POWER_SOURCE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.powerSource},
.deviceEnable = TRUE, { ZCL_ATTRID_BASIC_DEV_ENABLED, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.deviceEnable},
}; { ZCL_ATTRID_BASIC_SW_BUILD_ID, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.swBuildId},
const zclAttrInfo_t basic_attrTbl[] = { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
{ };
{ ZCL_ATTRID_BASIC_ZCL_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.zclVersion},
{ ZCL_ATTRID_BASIC_APP_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.appVersion}, #define ZCL_BASIC_ATTR_NUM sizeof(basic_attrTbl) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_BASIC_STACK_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.stackVersion},
{ ZCL_ATTRID_BASIC_HW_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.hwVersion}, #define INDETIFY_DEFAULT1 { 0x0000 /*identifyTime*/ ,\
{ ZCL_ATTRID_BASIC_MFR_NAME, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)g_zcl_basicAttrs.manuName}, }
{ ZCL_ATTRID_BASIC_MODEL_ID, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)g_zcl_basicAttrs.modelId}, #define INDETIFY_DEFAULT2 { 0x0000 /*identifyTime*/ ,\
{ ZCL_ATTRID_BASIC_POWER_SOURCE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.powerSource}, }
{ ZCL_ATTRID_BASIC_DEV_ENABLED, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.deviceEnable}, #define INDETIFY_DEFAULT3 { 0x0000 /*identifyTime*/ ,\
{ ZCL_ATTRID_BASIC_SW_BUILD_ID, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.swBuildId}, }
#define INDETIFY_DEFAULT4 { 0x0000 /*identifyTime*/ ,\
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, }
}; /* Identify */
zcl_identifyAttr_t g_zcl_identifyAttrs[Support_Endpoint_Num] = {INDETIFY_DEFAULT1,INDETIFY_DEFAULT2,INDETIFY_DEFAULT3,INDETIFY_DEFAULT4};
#define ZCL_BASIC_ATTR_NUM sizeof(basic_attrTbl) / sizeof(zclAttrInfo_t)
#define INDETIFY_DEFAULT1 { 0x0000 /*identifyTime*/ ,\ const zclAttrInfo_t identify_attrTbl[] =
} {
#define INDETIFY_DEFAULT2 { 0x0000 /*identifyTime*/ ,\ { ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[0].identifyTime },
}
#define INDETIFY_DEFAULT3 { 0x0000 /*identifyTime*/ ,\ { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
} };
#define INDETIFY_DEFAULT4 { 0x0000 /*identifyTime*/ ,\ const zclAttrInfo_t identify_attrTb2[] =
} {
/* Identify */ { ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[1].identifyTime },
zcl_identifyAttr_t g_zcl_identifyAttrs[Support_Endpoint_Num] = {INDETIFY_DEFAULT1,INDETIFY_DEFAULT2,INDETIFY_DEFAULT3,INDETIFY_DEFAULT4};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t identify_attrTbl[] = const zclAttrInfo_t identify_attrTb3[] =
{ {
{ ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[0].identifyTime }, { ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[2].identifyTime },
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; };
const zclAttrInfo_t identify_attrTb2[] = const zclAttrInfo_t identify_attrTb4[] =
{ {
{ ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[1].identifyTime }, { ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[3].identifyTime },
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; };
const zclAttrInfo_t identify_attrTb3[] =
{ #define ZCL_IDENTIFY_ATTR1_NUM sizeof(identify_attrTbl) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[2].identifyTime }, #define ZCL_IDENTIFY_ATTR2_NUM sizeof(identify_attrTb2) / sizeof(zclAttrInfo_t)
#define ZCL_IDENTIFY_ATTR3_NUM sizeof(identify_attrTb3) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, #define ZCL_IDENTIFY_ATTR4_NUM sizeof(identify_attrTb4) / sizeof(zclAttrInfo_t)
};
const zclAttrInfo_t identify_attrTb4[] = uint8_t g_identifyAttrsNum[Support_Endpoint_Num] = {ZCL_IDENTIFY_ATTR1_NUM,ZCL_IDENTIFY_ATTR2_NUM,ZCL_IDENTIFY_ATTR3_NUM,ZCL_IDENTIFY_ATTR4_NUM};
{
{ ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs[3].identifyTime },
#ifdef ZCL_GROUP
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, /* Group */
}; #define GROUP_DEFAULT1 { 0 /*nameSupport*/ ,\
}
#define ZCL_IDENTIFY_ATTR1_NUM sizeof(identify_attrTbl) / sizeof(zclAttrInfo_t) #define GROUP_DEFAULT2 { 0 /*nameSupport*/ ,\
#define ZCL_IDENTIFY_ATTR2_NUM sizeof(identify_attrTb2) / sizeof(zclAttrInfo_t) }
#define ZCL_IDENTIFY_ATTR3_NUM sizeof(identify_attrTb3) / sizeof(zclAttrInfo_t) #define GROUP_DEFAULT3 { 0 /*nameSupport*/ ,\
#define ZCL_IDENTIFY_ATTR4_NUM sizeof(identify_attrTb4) / sizeof(zclAttrInfo_t) }
#define GROUP_DEFAULT4 { 0 /*nameSupport*/ ,\
uint8_t g_identifyAttrsNum[Support_Endpoint_Num] = {ZCL_IDENTIFY_ATTR1_NUM,ZCL_IDENTIFY_ATTR2_NUM,ZCL_IDENTIFY_ATTR3_NUM,ZCL_IDENTIFY_ATTR4_NUM}; }
zcl_groupAttr_t g_zcl_groupAttrs[Support_Endpoint_Num] = {GROUP_DEFAULT1,GROUP_DEFAULT2,GROUP_DEFAULT3,GROUP_DEFAULT4};
#ifdef ZCL_GROUP
/* Group */ const zclAttrInfo_t group_attrTbl[] =
#define GROUP_DEFAULT1 { 0 /*nameSupport*/ ,\ {
} { ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[0].nameSupport },
#define GROUP_DEFAULT2 { 0 /*nameSupport*/ ,\
} { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
#define GROUP_DEFAULT3 { 0 /*nameSupport*/ ,\ };
} const zclAttrInfo_t group_attrTb2[] =
#define GROUP_DEFAULT4 { 0 /*nameSupport*/ ,\ {
} { ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[1].nameSupport },
zcl_groupAttr_t g_zcl_groupAttrs[Support_Endpoint_Num] = {GROUP_DEFAULT1,GROUP_DEFAULT2,GROUP_DEFAULT3,GROUP_DEFAULT4};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t group_attrTbl[] = const zclAttrInfo_t group_attrTb3[] =
{ {
{ ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[0].nameSupport }, { ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[2].nameSupport },
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; };
const zclAttrInfo_t group_attrTb2[] = const zclAttrInfo_t group_attrTb4[] =
{ {
{ ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[1].nameSupport }, { ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[3].nameSupport },
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; };
const zclAttrInfo_t group_attrTb3[] =
{ #define ZCL_GROUP_ATTR1_NUM sizeof(group_attrTbl[0]) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[2].nameSupport }, #define ZCL_GROUP_ATTR2_NUM sizeof(group_attrTbl[1]) / sizeof(zclAttrInfo_t)
#define ZCL_GROUP_ATTR3_NUM sizeof(group_attrTbl[2]) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, #define ZCL_GROUP_ATTR4_NUM sizeof(group_attrTbl[3]) / sizeof(zclAttrInfo_t)
};
const zclAttrInfo_t group_attrTb4[] = uint8_t g_groupAttrsNum[Support_Endpoint_Num] = {ZCL_GROUP_ATTR1_NUM,ZCL_GROUP_ATTR2_NUM,ZCL_GROUP_ATTR3_NUM,ZCL_GROUP_ATTR4_NUM};
{ #endif
{ ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs[3].nameSupport },
#ifdef ZCL_SCENE
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; #define SCENE_DEFAULT1 { 0 /*sceneCount*/ ,\
0 /*currentScene*/ ,\
#define ZCL_GROUP_ATTR1_NUM sizeof(group_attrTbl[0]) / sizeof(zclAttrInfo_t) 0X0000 /*currentGroup*/ ,\
#define ZCL_GROUP_ATTR2_NUM sizeof(group_attrTbl[1]) / sizeof(zclAttrInfo_t) FALSE /*sceneValid*/ ,\
#define ZCL_GROUP_ATTR3_NUM sizeof(group_attrTbl[2]) / sizeof(zclAttrInfo_t) 0 /*nameSupport*/ }
#define ZCL_GROUP_ATTR4_NUM sizeof(group_attrTbl[3]) / sizeof(zclAttrInfo_t) #define SCENE_DEFAULT2 { 0 /*sceneCount*/ ,\
0 /*currentScene*/ ,\
uint8_t g_groupAttrsNum[Support_Endpoint_Num] = {ZCL_GROUP_ATTR1_NUM,ZCL_GROUP_ATTR2_NUM,ZCL_GROUP_ATTR3_NUM,ZCL_GROUP_ATTR4_NUM}; 0X0000 /*currentGroup*/ ,\
#endif FALSE /*sceneValid*/ ,\
0 /*nameSupport*/ }
#ifdef ZCL_SCENE #define SCENE_DEFAULT3 { 0 /*sceneCount*/ ,\
0 /*currentScene*/ ,\
#define SCENE_DEFAULT1 { 0 /*sceneCount*/ ,\ 0X0000 /*currentGroup*/ ,\
0 /*currentScene*/ ,\ FALSE /*sceneValid*/ ,\
0X0000 /*currentGroup*/ ,\ 0 /*nameSupport*/ }
FALSE /*sceneValid*/ ,\ #define SCENE_DEFAULT4 { 0 /*sceneCount*/ ,\
0 /*nameSupport*/ } 0 /*currentScene*/ ,\
#define SCENE_DEFAULT2 { 0 /*sceneCount*/ ,\ 0X0000 /*currentGroup*/ ,\
0 /*currentScene*/ ,\ FALSE /*sceneValid*/ ,\
0X0000 /*currentGroup*/ ,\ 0 /*nameSupport*/ }
FALSE /*sceneValid*/ ,\ /* Scene */
0 /*nameSupport*/ } zcl_sceneAttr_t g_zcl_sceneAttrs[Support_Endpoint_Num] ={SCENE_DEFAULT1,SCENE_DEFAULT2,SCENE_DEFAULT3,SCENE_DEFAULT4};
#define SCENE_DEFAULT3 { 0 /*sceneCount*/ ,\
0 /*currentScene*/ ,\ const zclAttrInfo_t scene_attrTbl[] =
0X0000 /*currentGroup*/ ,\ {
FALSE /*sceneValid*/ ,\ { ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].sceneCount },
0 /*nameSupport*/ } { ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].currentScene },
#define SCENE_DEFAULT4 { 0 /*sceneCount*/ ,\ { ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].currentGroup },
0 /*currentScene*/ ,\ { ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].sceneValid },
0X0000 /*currentGroup*/ ,\ { ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].nameSupport },
FALSE /*sceneValid*/ ,\
0 /*nameSupport*/ } { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
/* Scene */ };
zcl_sceneAttr_t g_zcl_sceneAttrs[Support_Endpoint_Num] ={SCENE_DEFAULT1,SCENE_DEFAULT2,SCENE_DEFAULT3,SCENE_DEFAULT4}; const zclAttrInfo_t scene_attrTb2[] =
{
const zclAttrInfo_t scene_attrTbl[] = { ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].sceneCount },
{ { ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].currentScene },
{ ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].sceneCount }, { ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].currentGroup },
{ ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].currentScene }, { ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].sceneValid },
{ ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].currentGroup }, { ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].nameSupport },
{ ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].sceneValid },
{ ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[0].nameSupport }, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, const zclAttrInfo_t scene_attrTb3[] =
}; {
const zclAttrInfo_t scene_attrTb2[] = { ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].sceneCount },
{ { ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].currentScene },
{ ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].sceneCount }, { ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].currentGroup },
{ ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].currentScene }, { ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].sceneValid },
{ ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].currentGroup }, { ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].nameSupport },
{ ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].sceneValid },
{ ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[1].nameSupport }, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, const zclAttrInfo_t scene_attrTb4[] =
}; {
const zclAttrInfo_t scene_attrTb3[] = { ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].sceneCount },
{ { ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].currentScene },
{ ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].sceneCount }, { ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].currentGroup },
{ ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].currentScene }, { ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].sceneValid },
{ ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].currentGroup }, { ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].nameSupport },
{ ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].sceneValid },
{ ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[2].nameSupport }, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; #define ZCL_SCENE_ATTR1_NUM sizeof(scene_attrTbl[0]) / sizeof(zclAttrInfo_t)
const zclAttrInfo_t scene_attrTb4[] = #define ZCL_SCENE_ATTR2_NUM sizeof(scene_attrTbl[1]) / sizeof(zclAttrInfo_t)
{ #define ZCL_SCENE_ATTR3_NUM sizeof(scene_attrTbl[2]) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].sceneCount }, #define ZCL_SCENE_ATTR4_NUM sizeof(scene_attrTbl[3]) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].currentScene },
{ ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].currentGroup }, uint8_t g_sceneAttrsNum[Support_Endpoint_Num] ={ZCL_SCENE_ATTR1_NUM,ZCL_SCENE_ATTR2_NUM,ZCL_SCENE_ATTR3_NUM,ZCL_SCENE_ATTR4_NUM};
{ ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].sceneValid }, #endif
{ ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs[3].nameSupport },
#ifdef ZCL_ON_OFF
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, /* On/Off */
}; #define ONOFF_DEFAULT1 { 0x00 /*onOff*/ ,\
1 /*globalSceneControl*/ ,\
#define ZCL_SCENE_ATTR1_NUM sizeof(scene_attrTbl[0]) / sizeof(zclAttrInfo_t) 0X0000 /*onTime*/ ,\
#define ZCL_SCENE_ATTR2_NUM sizeof(scene_attrTbl[1]) / sizeof(zclAttrInfo_t) 0X0000 /*offWaitTime*/ ,\
#define ZCL_SCENE_ATTR3_NUM sizeof(scene_attrTbl[2]) / sizeof(zclAttrInfo_t) ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ }
#define ZCL_SCENE_ATTR4_NUM sizeof(scene_attrTbl[3]) / sizeof(zclAttrInfo_t) #define ONOFF_DEFAULT2 { 0x00 /*onOff*/ ,\
1 /*globalSceneControl*/ ,\
uint8_t g_sceneAttrsNum[Support_Endpoint_Num] ={ZCL_SCENE_ATTR1_NUM,ZCL_SCENE_ATTR2_NUM,ZCL_SCENE_ATTR3_NUM,ZCL_SCENE_ATTR4_NUM}; 0X0000 /*onTime*/ ,\
#endif 0X0000 /*offWaitTime*/ ,\
ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ }
#ifdef ZCL_ON_OFF #define ONOFF_DEFAULT3 { 0x00 /*onOff*/ ,\
/* On/Off */ 1 /*globalSceneControl*/ ,\
#define ONOFF_DEFAULT1 { 0x00 /*onOff*/ ,\ 0X0000 /*onTime*/ ,\
1 /*globalSceneControl*/ ,\ 0X0000 /*offWaitTime*/ ,\
0X0000 /*onTime*/ ,\ ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ }
0X0000 /*offWaitTime*/ ,\ #define ONOFF_DEFAULT4 { 0x00 /*onOff*/ ,\
ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ } 1 /*globalSceneControl*/ ,\
#define ONOFF_DEFAULT2 { 0x00 /*onOff*/ ,\ 0X0000 /*onTime*/ ,\
1 /*globalSceneControl*/ ,\ 0X0000 /*offWaitTime*/ ,\
0X0000 /*onTime*/ ,\ ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ }
0X0000 /*offWaitTime*/ ,\ zcl_onOffAttr_t g_zcl_onOffAttrs[Support_Endpoint_Num] ={ONOFF_DEFAULT1,ONOFF_DEFAULT2,ONOFF_DEFAULT3,ONOFF_DEFAULT4};
ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ }
#define ONOFF_DEFAULT3 { 0x00 /*onOff*/ ,\ const zclAttrInfo_t onOff_attrTbl[] =
1 /*globalSceneControl*/ ,\ {
0X0000 /*onTime*/ ,\ { ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[0].onOff},
0X0000 /*offWaitTime*/ ,\ { ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[0].globalSceneControl},
ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ } { ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[0].onTime},
#define ONOFF_DEFAULT4 { 0x00 /*onOff*/ ,\ { ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[0].offWaitTime},
1 /*globalSceneControl*/ ,\ { ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[0].startUpOnOff},
0X0000 /*onTime*/ ,\
0X0000 /*offWaitTime*/ ,\ { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
ZCL_START_UP_ONOFF_SET_ONOFF_TO_OFF /*offWaitTime*/ } };
zcl_onOffAttr_t g_zcl_onOffAttrs[Support_Endpoint_Num] ={ONOFF_DEFAULT1,ONOFF_DEFAULT2,ONOFF_DEFAULT3,ONOFF_DEFAULT4}; const zclAttrInfo_t onOff_attrTb2[] =
{
const zclAttrInfo_t onOff_attrTbl[] = { ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[1].onOff},
{ { ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[1].globalSceneControl},
{ ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[0].onOff}, { ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[1].onTime},
{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[0].globalSceneControl}, { ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[1].offWaitTime},
{ ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[0].onTime}, { ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[1].startUpOnOff},
{ ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[0].offWaitTime},
{ ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[0].startUpOnOff}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, const zclAttrInfo_t onOff_attrTb3[] =
}; {
const zclAttrInfo_t onOff_attrTb2[] = { ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[2].onOff},
{ { ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[2].globalSceneControl},
{ ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[1].onOff}, { ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[2].onTime},
{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[1].globalSceneControl}, { ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[2].offWaitTime},
{ ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[1].onTime}, { ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[2].startUpOnOff},
{ ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[1].offWaitTime},
{ ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[1].startUpOnOff}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, const zclAttrInfo_t onOff_attrTb4[] =
}; {
const zclAttrInfo_t onOff_attrTb3[] = { ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[3].onOff},
{ { ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[3].globalSceneControl},
{ ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[2].onOff}, { ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[3].onTime},
{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[2].globalSceneControl}, { ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[3].offWaitTime},
{ ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[2].onTime}, { ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[3].startUpOnOff},
{ ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[2].offWaitTime},
{ ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[2].startUpOnOff}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; #define ZCL_ONOFF_ATTR1_NUM sizeof(onOff_attrTbl) / sizeof(zclAttrInfo_t)
const zclAttrInfo_t onOff_attrTb4[] = #define ZCL_ONOFF_ATTR2_NUM sizeof(onOff_attrTb2) / sizeof(zclAttrInfo_t)
{ #define ZCL_ONOFF_ATTR3_NUM sizeof(onOff_attrTb3) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs[3].onOff}, #define ZCL_ONOFF_ATTR4_NUM sizeof(onOff_attrTb4) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs[3].globalSceneControl},
{ ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[3].onTime}, uint8_t g_onoffAttrsNum[Support_Endpoint_Num] ;
{ ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[3].offWaitTime}, #endif
{ ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs[3].startUpOnOff},
#ifdef ZCL_LEVEL_CTRL
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, /* Level */
}; zcl_levelAttr_t g_zcl_levelAttrs =
{
#define ZCL_ONOFF_ATTR1_NUM sizeof(onOff_attrTbl) / sizeof(zclAttrInfo_t) .curLevel = 0xFE,
#define ZCL_ONOFF_ATTR2_NUM sizeof(onOff_attrTb2) / sizeof(zclAttrInfo_t) .remainingTime = 0,
#define ZCL_ONOFF_ATTR3_NUM sizeof(onOff_attrTb3) / sizeof(zclAttrInfo_t) .startUpCurrentLevel = ZCL_START_UP_CURRENT_LEVEL_TO_PREVIOUS,
#define ZCL_ONOFF_ATTR4_NUM sizeof(onOff_attrTb4) / sizeof(zclAttrInfo_t) };
uint8_t g_onoffAttrsNum[Support_Endpoint_Num] ; const zclAttrInfo_t level_attrTbl[] =
#endif {
{ ZCL_ATTRID_LEVEL_CURRENT_LEVEL, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_levelAttrs.curLevel },
#ifdef ZCL_LEVEL_CTRL { ZCL_ATTRID_LEVEL_REMAINING_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_levelAttrs.remainingTime },
/* Level */ { ZCL_ATTRID_LEVEL_START_UP_CURRENT_LEVEL, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_levelAttrs.startUpCurrentLevel },
zcl_levelAttr_t g_zcl_levelAttrs =
{ { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
.curLevel = 0xFE, };
.remainingTime = 0,
.startUpCurrentLevel = ZCL_START_UP_CURRENT_LEVEL_TO_PREVIOUS, #define ZCL_LEVEL_ATTR_NUM sizeof(level_attrTbl) / sizeof(zclAttrInfo_t)
}; #endif
const zclAttrInfo_t level_attrTbl[] = #ifdef ZCL_LIGHT_COLOR_CONTROL
{ /* Color Control */
{ ZCL_ATTRID_LEVEL_CURRENT_LEVEL, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_levelAttrs.curLevel }, zcl_lightColorCtrlAttr_t g_zcl_colorCtrlAttrs =
{ ZCL_ATTRID_LEVEL_REMAINING_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_levelAttrs.remainingTime }, {
{ ZCL_ATTRID_LEVEL_START_UP_CURRENT_LEVEL, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_levelAttrs.startUpCurrentLevel }, .colorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS,
.options = 0,
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, .enhancedColorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS,
}; .colorCapabilities = ZCL_COLOR_CAPABILITIES_BIT_COLOR_TEMPERATURE,
.numOfPrimaries = 0,
#define ZCL_LEVEL_ATTR_NUM sizeof(level_attrTbl) / sizeof(zclAttrInfo_t) #if COLOR_RGB_SUPPORT
#endif .currentHue = 0x00,
.currentSaturation = 0x00,
#ifdef ZCL_LIGHT_COLOR_CONTROL .colorLoopActive = 0x00,
/* Color Control */ .colorLoopDirection = 0x00,
zcl_lightColorCtrlAttr_t g_zcl_colorCtrlAttrs = .colorLoopTime = 0x0019,
{ .colorLoopStartEnhancedHue = 0x2300,
.colorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS, .colorLoopStoredEnhancedHue = 0x0000,
.options = 0, #elif COLOR_CCT_SUPPORT
.enhancedColorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS, .colorTemperatureMireds = COLOR_TEMPERATURE_PHYSICAL_MAX,
.colorCapabilities = ZCL_COLOR_CAPABILITIES_BIT_COLOR_TEMPERATURE, .colorTempPhysicalMinMireds = COLOR_TEMPERATURE_PHYSICAL_MIN,
.numOfPrimaries = 0, .colorTempPhysicalMaxMireds = COLOR_TEMPERATURE_PHYSICAL_MAX,
#if COLOR_RGB_SUPPORT .startUpColorTemperatureMireds = ZCL_START_UP_COLOR_TEMPERATURE_MIREDS_TO_PREVIOUS,
.currentHue = 0x00, #endif
.currentSaturation = 0x00, };
.colorLoopActive = 0x00,
.colorLoopDirection = 0x00, const zclAttrInfo_t lightColorCtrl_attrTbl[] =
.colorLoopTime = 0x0019, {
.colorLoopStartEnhancedHue = 0x2300, { ZCL_ATTRID_COLOR_MODE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorMode },
.colorLoopStoredEnhancedHue = 0x0000, { ZCL_ATTRID_COLOR_OPTIONS, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_colorCtrlAttrs.options },
#elif COLOR_CCT_SUPPORT { ZCL_ATTRID_ENHANCED_COLOR_MODE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.enhancedColorMode },
.colorTemperatureMireds = COLOR_TEMPERATURE_PHYSICAL_MAX, { ZCL_ATTRID_COLOR_CAPABILITIES, ZCL_DATA_TYPE_BITMAP16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorCapabilities },
.colorTempPhysicalMinMireds = COLOR_TEMPERATURE_PHYSICAL_MIN, { ZCL_ATTRID_NUMBER_OF_PRIMARIES, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.numOfPrimaries },
.colorTempPhysicalMaxMireds = COLOR_TEMPERATURE_PHYSICAL_MAX,
.startUpColorTemperatureMireds = ZCL_START_UP_COLOR_TEMPERATURE_MIREDS_TO_PREVIOUS, #if COLOR_RGB_SUPPORT
#endif { ZCL_ATTRID_CURRENT_HUE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentHue },
}; { ZCL_ATTRID_CURRENT_SATURATION, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentSaturation },
{ ZCL_ATTRID_COLOR_LOOP_ACTIVE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopActive },
const zclAttrInfo_t lightColorCtrl_attrTbl[] = { ZCL_ATTRID_COLOR_LOOP_DIRECTION, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopDirection },
{ { ZCL_ATTRID_COLOR_LOOP_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopTime },
{ ZCL_ATTRID_COLOR_MODE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorMode }, { ZCL_ATTRID_COLOR_LOOP_START_ENHANCED_HUE, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorLoopStartEnhancedHue },
{ ZCL_ATTRID_COLOR_OPTIONS, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_colorCtrlAttrs.options }, { ZCL_ATTRID_COLOR_LOOP_STORED_ENHANCED_HUE, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorLoopStoredEnhancedHue },
{ ZCL_ATTRID_ENHANCED_COLOR_MODE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.enhancedColorMode }, #elif COLOR_CCT_SUPPORT
{ ZCL_ATTRID_COLOR_CAPABILITIES, ZCL_DATA_TYPE_BITMAP16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorCapabilities }, { ZCL_ATTRID_COLOR_TEMPERATURE_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorTemperatureMireds },
{ ZCL_ATTRID_NUMBER_OF_PRIMARIES, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.numOfPrimaries }, { ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MIN_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMinMireds },
{ ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MAX_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMaxMireds },
#if COLOR_RGB_SUPPORT { ZCL_ATTRID_START_UP_COLOR_TEMPERATURE_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds },
{ ZCL_ATTRID_CURRENT_HUE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentHue }, #endif
{ ZCL_ATTRID_CURRENT_SATURATION, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentSaturation },
{ ZCL_ATTRID_COLOR_LOOP_ACTIVE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopActive }, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
{ ZCL_ATTRID_COLOR_LOOP_DIRECTION, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopDirection }, };
{ ZCL_ATTRID_COLOR_LOOP_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopTime },
{ ZCL_ATTRID_COLOR_LOOP_START_ENHANCED_HUE, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorLoopStartEnhancedHue }, #define ZCL_COLOR_ATTR_NUM sizeof(lightColorCtrl_attrTbl) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_COLOR_LOOP_STORED_ENHANCED_HUE, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorLoopStoredEnhancedHue }, #endif
#elif COLOR_CCT_SUPPORT
{ ZCL_ATTRID_COLOR_TEMPERATURE_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorTemperatureMireds },
{ ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MIN_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMinMireds }, #ifdef ZCL_FCC0
{ ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MAX_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMaxMireds }, /* FCC0 Attr */
{ ZCL_ATTRID_START_UP_COLOR_TEMPERATURE_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds }, //zcl_privateAttr_t g_zcl_Fcc0Attrs =
#endif //{
// .optdata = ZCL_FCC0_OPT_ID,
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, //};
};
const zclAttrInfo_t fcc0_attrTbl[] =
#define ZCL_COLOR_ATTR_NUM sizeof(lightColorCtrl_attrTbl) / sizeof(zclAttrInfo_t) {
#endif //{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata},
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
#ifdef ZCL_FCC0 };
/* FCC0 Attr */ const zclAttrInfo_t fcc0_attrTb2[] =
//zcl_privateAttr_t g_zcl_Fcc0Attrs = {
//{ //{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata},
// .optdata = ZCL_FCC0_OPT_ID,
//}; { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
};
const zclAttrInfo_t fcc0_attrTbl[] = const zclAttrInfo_t fcc0_attrTb3[] =
{ {
//{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata}, //{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata},
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; };
const zclAttrInfo_t fcc0_attrTb2[] = const zclAttrInfo_t fcc0_attrTb4[] =
{ {
//{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata}, //{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata},
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision},
}; };
const zclAttrInfo_t fcc0_attrTb3[] =
{ #define ZCL_FCC0_ATTR1_NUM sizeof(fcc0_attrTbl) / sizeof(zclAttrInfo_t)
//{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata}, #define ZCL_FCC0_ATTR2_NUM sizeof(fcc0_attrTb2) / sizeof(zclAttrInfo_t)
#define ZCL_FCC0_ATTR3_NUM sizeof(fcc0_attrTb3) / sizeof(zclAttrInfo_t)
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, #define ZCL_FCC0_ATTR4_NUM sizeof(fcc0_attrTb4) / sizeof(zclAttrInfo_t)
};
const zclAttrInfo_t fcc0_attrTb4[] = uint8_t g_fcc0AttrsNum[Support_Endpoint_Num] = {ZCL_FCC0_ATTR1_NUM,ZCL_FCC0_ATTR2_NUM,ZCL_FCC0_ATTR3_NUM,ZCL_FCC0_ATTR4_NUM};
{ #endif
//{ ECA_OPTDATA, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_WRITE | ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_Fcc0Attrs.optdata},
{ ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, zcl_specClusterInfo_t g_EP1ClusterList[] =
}; {
{ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb},
#define ZCL_FCC0_ATTR1_NUM sizeof(fcc0_attrTbl) / sizeof(zclAttrInfo_t) {ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR1_NUM,identify_attrTbl, zcl_identify_register, sampleLight_identifyCb},
#define ZCL_FCC0_ATTR2_NUM sizeof(fcc0_attrTb2) / sizeof(zclAttrInfo_t) #ifdef ZCL_GROUP
#define ZCL_FCC0_ATTR3_NUM sizeof(fcc0_attrTb3) / sizeof(zclAttrInfo_t) {ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR1_NUM, group_attrTbl, zcl_group_register, NULL},
#define ZCL_FCC0_ATTR4_NUM sizeof(fcc0_attrTb4) / sizeof(zclAttrInfo_t) #endif
#ifdef ZCL_SCENE
uint8_t g_fcc0AttrsNum[Support_Endpoint_Num] = {ZCL_FCC0_ATTR1_NUM,ZCL_FCC0_ATTR2_NUM,ZCL_FCC0_ATTR3_NUM,ZCL_FCC0_ATTR4_NUM}; {ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR1_NUM, scene_attrTbl, zcl_scene_register, sampleLight_sceneCb},
#endif #endif
#ifdef ZCL_ON_OFF
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR1_NUM, onOff_attrTbl, zcl_onOff_register, sampleLight_onOffCb},
zcl_specClusterInfo_t g_EP1ClusterList[] = #endif
{ #ifdef ZCL_LEVEL_CTRL
{ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb}, {ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTbl, zcl_level_register, sampleLight_levelCb},
{ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR1_NUM,identify_attrTbl, zcl_identify_register, sampleLight_identifyCb}, #endif
#ifdef ZCL_GROUP #ifdef ZCL_LIGHT_COLOR_CONTROL
{ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR1_NUM, group_attrTbl, zcl_group_register, NULL}, {ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTbl, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif #endif
#ifdef ZCL_SCENE #ifdef ZCL_FCC0
{ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR1_NUM, scene_attrTbl, zcl_scene_register, sampleLight_sceneCb}, {ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR1_NUM, fcc0_attrTbl, NULL, NULL},
#endif #endif
#ifdef ZCL_ON_OFF };
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR1_NUM, onOff_attrTbl, zcl_onOff_register, sampleLight_onOffCb}, u8 EP1_CB_CLUSTER_NUM = (sizeof(g_EP1ClusterList)/sizeof(g_EP1ClusterList[0]));
#endif
#ifdef ZCL_LEVEL_CTRL zcl_specClusterInfo_t g_EP2ClusterList[] =
{ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTbl, zcl_level_register, sampleLight_levelCb}, {
#endif {ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb},
#ifdef ZCL_LIGHT_COLOR_CONTROL {ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR2_NUM,identify_attrTb2, zcl_identify_register, sampleLight_identifyCb},
{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTbl, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb}, #ifdef ZCL_GROUP
#endif {ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR2_NUM, group_attrTb2, zcl_group_register, NULL},
#ifdef ZCL_FCC0 #endif
{ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR1_NUM, fcc0_attrTbl, NULL, NULL}, #ifdef ZCL_SCENE
#endif {ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR2_NUM, scene_attrTb2, zcl_scene_register, sampleLight_sceneCb},
}; #endif
u8 EP1_CB_CLUSTER_NUM = (sizeof(g_EP1ClusterList)/sizeof(g_EP1ClusterList[0])); #ifdef ZCL_ON_OFF
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR2_NUM, onOff_attrTb2, zcl_onOff_register, sampleLight_onOffCb},
zcl_specClusterInfo_t g_EP2ClusterList[] = #endif
{ #ifdef ZCL_LEVEL_CTRL
{ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb}, {ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTb2, zcl_level_register, sampleLight_levelCb},
{ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR2_NUM,identify_attrTb2, zcl_identify_register, sampleLight_identifyCb}, #endif
#ifdef ZCL_GROUP #ifdef ZCL_LIGHT_COLOR_CONTROL
{ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR2_NUM, group_attrTb2, zcl_group_register, NULL}, {ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTb2, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif #endif
#ifdef ZCL_SCENE #ifdef ZCL_FCC0
{ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR2_NUM, scene_attrTb2, zcl_scene_register, sampleLight_sceneCb}, {ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR2_NUM, fcc0_attrTb2, NULL, NULL},
#endif #endif
#ifdef ZCL_ON_OFF };
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR2_NUM, onOff_attrTb2, zcl_onOff_register, sampleLight_onOffCb}, u8 EP2_CB_CLUSTER_NUM = (sizeof(g_EP2ClusterList)/sizeof(g_EP2ClusterList[0]));
#endif
#ifdef ZCL_LEVEL_CTRL zcl_specClusterInfo_t g_EP3ClusterList[] =
{ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTb2, zcl_level_register, sampleLight_levelCb}, {
#endif {ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb},
#ifdef ZCL_LIGHT_COLOR_CONTROL {ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR3_NUM,identify_attrTb3, zcl_identify_register, sampleLight_identifyCb},
{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTb2, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb}, #ifdef ZCL_GROUP
#endif {ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR3_NUM, group_attrTb3, zcl_group_register, NULL},
#ifdef ZCL_FCC0 #endif
{ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR2_NUM, fcc0_attrTb2, NULL, NULL}, #ifdef ZCL_SCENE
#endif {ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR3_NUM, scene_attrTb3, zcl_scene_register, sampleLight_sceneCb},
}; #endif
u8 EP2_CB_CLUSTER_NUM = (sizeof(g_EP2ClusterList)/sizeof(g_EP2ClusterList[0])); #ifdef ZCL_ON_OFF
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR3_NUM, onOff_attrTb3, zcl_onOff_register, sampleLight_onOffCb},
zcl_specClusterInfo_t g_EP3ClusterList[] = #endif
{ #ifdef ZCL_LEVEL_CTRL
{ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb}, {ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTb3, zcl_level_register, sampleLight_levelCb},
{ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR3_NUM,identify_attrTb3, zcl_identify_register, sampleLight_identifyCb}, #endif
#ifdef ZCL_GROUP #ifdef ZCL_LIGHT_COLOR_CONTROL
{ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR3_NUM, group_attrTb3, zcl_group_register, NULL}, {ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTb3, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif #endif
#ifdef ZCL_SCENE #ifdef ZCL_FCC0
{ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR3_NUM, scene_attrTb3, zcl_scene_register, sampleLight_sceneCb}, {ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR3_NUM, fcc0_attrTb3, NULL, NULL},
#endif #endif
#ifdef ZCL_ON_OFF };
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR3_NUM, onOff_attrTb3, zcl_onOff_register, sampleLight_onOffCb}, u8 EP3_CB_CLUSTER_NUM = (sizeof(g_EP3ClusterList)/sizeof(g_EP3ClusterList[0]));
#endif
#ifdef ZCL_LEVEL_CTRL zcl_specClusterInfo_t g_EP4ClusterList[] =
{ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTb3, zcl_level_register, sampleLight_levelCb}, {
#endif {ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb},
#ifdef ZCL_LIGHT_COLOR_CONTROL {ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR4_NUM,identify_attrTb4, zcl_identify_register, sampleLight_identifyCb},
{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTb3, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb}, #ifdef ZCL_GROUP
#endif {ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR3_NUM, group_attrTb4, zcl_group_register, NULL},
#ifdef ZCL_FCC0 #endif
{ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR3_NUM, fcc0_attrTb3, NULL, NULL}, #ifdef ZCL_SCENE
#endif {ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR4_NUM, scene_attrTb4, zcl_scene_register, sampleLight_sceneCb},
}; #endif
u8 EP3_CB_CLUSTER_NUM = (sizeof(g_EP3ClusterList)/sizeof(g_EP3ClusterList[0])); #ifdef ZCL_ON_OFF
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR4_NUM, onOff_attrTb4, zcl_onOff_register, sampleLight_onOffCb},
zcl_specClusterInfo_t g_EP4ClusterList[] = #endif
{ #ifdef ZCL_LEVEL_CTRL
{ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb}, {ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTb4, zcl_level_register, sampleLight_levelCb},
{ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR4_NUM,identify_attrTb4, zcl_identify_register, sampleLight_identifyCb}, #endif
#ifdef ZCL_GROUP #ifdef ZCL_LIGHT_COLOR_CONTROL
{ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR3_NUM, group_attrTb4, zcl_group_register, NULL}, {ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTb4, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif #endif
#ifdef ZCL_SCENE #ifdef ZCL_FCC0
{ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR4_NUM, scene_attrTb4, zcl_scene_register, sampleLight_sceneCb}, {ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR4_NUM, fcc0_attrTb4, NULL, NULL},
#endif #endif
#ifdef ZCL_ON_OFF };
{ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR4_NUM, onOff_attrTb4, zcl_onOff_register, sampleLight_onOffCb}, u8 EP4_CB_CLUSTER_NUM = (sizeof(g_EP4ClusterList)/sizeof(g_EP4ClusterList[0]));
#endif
#ifdef ZCL_LEVEL_CTRL
{ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTb4, zcl_level_register, sampleLight_levelCb}, /**********************************************************************
#endif * FUNCTIONS
#ifdef ZCL_LIGHT_COLOR_CONTROL */
{ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTb4, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb},
#endif void SimpleDesc_Init(uint8_t endpint)
#ifdef ZCL_FCC0 {
{ZCL_CLUSTER_PRIVATE_FCC0, MANUFACTURER_CODE_NONE, ZCL_FCC0_ATTR4_NUM, fcc0_attrTb4, NULL, NULL}, switch(endpint)
#endif {
}; case 1:
u8 EP4_CB_CLUSTER_NUM = (sizeof(g_EP4ClusterList)/sizeof(g_EP4ClusterList[0])); {
EP1_simpleDesc.app_profile_id = fixedProfileIds[0];
EP1_simpleDesc.app_dev_id = fixedDeviceIds[0];
/********************************************************************** EP1_simpleDesc.endpoint = fixedEndpoints[0];
* FUNCTIONS EP1_simpleDesc.app_dev_ver = 1;
*/ EP1_simpleDesc.reserved = 0;
EP1_simpleDesc.app_in_cluster_count = EP1_IN_CLUSTER_NUM;
void SimpleDesc_Init(uint8_t endpint) EP1_simpleDesc.app_out_cluster_count = EP1_OUT_CLUSTER_NUM;
{ EP1_simpleDesc.app_in_cluster_lst = (u16 *)EP1_inClusterList;
switch(endpint) EP1_simpleDesc.app_out_cluster_lst = (u16 *)EP1_outClusterList;
{ device_simpleDesc[0] = EP1_simpleDesc;
case 1: Cluster_Num_List[0] = EP1_CB_CLUSTER_NUM;
{ g_EPClusterAllList[0] = g_EP1ClusterList;
EP1_simpleDesc.app_profile_id = fixedProfileIds[0]; break;
EP1_simpleDesc.app_dev_id = fixedDeviceIds[0]; }
EP1_simpleDesc.endpoint = fixedEndpoints[0]; case 2:
EP1_simpleDesc.app_dev_ver = 1; {
EP1_simpleDesc.reserved = 0; EP2_simpleDesc.app_profile_id = fixedProfileIds[1];
EP1_simpleDesc.app_in_cluster_count = EP1_IN_CLUSTER_NUM; EP2_simpleDesc.app_dev_id = fixedDeviceIds[1];
EP1_simpleDesc.app_out_cluster_count = EP1_OUT_CLUSTER_NUM; EP2_simpleDesc.endpoint = fixedEndpoints[1];
EP1_simpleDesc.app_in_cluster_lst = (u16 *)EP1_inClusterList; EP2_simpleDesc.app_dev_ver = 1;
EP1_simpleDesc.app_out_cluster_lst = (u16 *)EP1_outClusterList; EP2_simpleDesc.reserved = 0;
device_simpleDesc[0] = EP1_simpleDesc; EP2_simpleDesc.app_in_cluster_count = EP2_IN_CLUSTER_NUM;
Cluster_Num_List[0] = EP1_CB_CLUSTER_NUM; EP2_simpleDesc.app_out_cluster_count = EP2_OUT_CLUSTER_NUM;
g_EPClusterAllList[0] = g_EP1ClusterList; EP2_simpleDesc.app_in_cluster_lst = (u16 *)EP2_inClusterList;
break; EP2_simpleDesc.app_out_cluster_lst = (u16 *)EP2_outClusterList;
} device_simpleDesc[1] = EP2_simpleDesc;
case 2: Cluster_Num_List[1] = EP2_CB_CLUSTER_NUM;
{ g_EPClusterAllList[1] = g_EP2ClusterList;
EP2_simpleDesc.app_profile_id = fixedProfileIds[1]; break;
EP2_simpleDesc.app_dev_id = fixedDeviceIds[1]; }
EP2_simpleDesc.endpoint = fixedEndpoints[1]; case 3:
EP2_simpleDesc.app_dev_ver = 1; {
EP2_simpleDesc.reserved = 0; EP3_simpleDesc.app_profile_id = fixedProfileIds[2];
EP2_simpleDesc.app_in_cluster_count = EP2_IN_CLUSTER_NUM; EP3_simpleDesc.app_dev_id = fixedDeviceIds[2];
EP2_simpleDesc.app_out_cluster_count = EP2_OUT_CLUSTER_NUM; EP3_simpleDesc.endpoint = fixedEndpoints[2];
EP2_simpleDesc.app_in_cluster_lst = (u16 *)EP2_inClusterList; EP3_simpleDesc.app_dev_ver = 1;
EP2_simpleDesc.app_out_cluster_lst = (u16 *)EP2_outClusterList; EP3_simpleDesc.reserved = 0;
device_simpleDesc[1] = EP2_simpleDesc; EP3_simpleDesc.app_in_cluster_count = EP3_IN_CLUSTER_NUM;
Cluster_Num_List[1] = EP2_CB_CLUSTER_NUM; EP3_simpleDesc.app_out_cluster_count = EP3_OUT_CLUSTER_NUM;
g_EPClusterAllList[1] = g_EP2ClusterList; EP3_simpleDesc.app_in_cluster_lst = (u16 *)EP3_inClusterList;
break; EP3_simpleDesc.app_out_cluster_lst = (u16 *)EP3_outClusterList;
} device_simpleDesc[2] = EP3_simpleDesc;
case 3: Cluster_Num_List[2] = EP3_CB_CLUSTER_NUM;
{ g_EPClusterAllList[2] = g_EP3ClusterList;
EP3_simpleDesc.app_profile_id = fixedProfileIds[2]; break;
EP3_simpleDesc.app_dev_id = fixedDeviceIds[2]; }
EP3_simpleDesc.endpoint = fixedEndpoints[2]; case 4:
EP3_simpleDesc.app_dev_ver = 1; {
EP3_simpleDesc.reserved = 0; EP4_simpleDesc.app_profile_id = fixedProfileIds[3];
EP3_simpleDesc.app_in_cluster_count = EP3_IN_CLUSTER_NUM; EP4_simpleDesc.app_dev_id = fixedDeviceIds[3];
EP3_simpleDesc.app_out_cluster_count = EP3_OUT_CLUSTER_NUM; EP4_simpleDesc.endpoint = fixedEndpoints[3];
EP3_simpleDesc.app_in_cluster_lst = (u16 *)EP3_inClusterList; EP4_simpleDesc.app_dev_ver = 1;
EP3_simpleDesc.app_out_cluster_lst = (u16 *)EP3_outClusterList; EP4_simpleDesc.reserved = 0;
device_simpleDesc[2] = EP3_simpleDesc; EP4_simpleDesc.app_in_cluster_count = EP4_IN_CLUSTER_NUM;
Cluster_Num_List[2] = EP3_CB_CLUSTER_NUM; EP4_simpleDesc.app_out_cluster_count = EP4_OUT_CLUSTER_NUM;
g_EPClusterAllList[2] = g_EP3ClusterList; EP4_simpleDesc.app_in_cluster_lst = (u16 *)EP4_inClusterList;
break; EP4_simpleDesc.app_out_cluster_lst = (u16 *)EP4_outClusterList;
} device_simpleDesc[3] = EP4_simpleDesc;
case 4: Cluster_Num_List[3] = EP4_CB_CLUSTER_NUM;
{ g_EPClusterAllList[3] = g_EP4ClusterList;
EP4_simpleDesc.app_profile_id = fixedProfileIds[3]; break;
EP4_simpleDesc.app_dev_id = fixedDeviceIds[3]; }
EP4_simpleDesc.endpoint = fixedEndpoints[3]; default:
EP4_simpleDesc.app_dev_ver = 1; break;
EP4_simpleDesc.reserved = 0; }
EP4_simpleDesc.app_in_cluster_count = EP4_IN_CLUSTER_NUM; }
EP4_simpleDesc.app_out_cluster_count = EP4_OUT_CLUSTER_NUM;
EP4_simpleDesc.app_in_cluster_lst = (u16 *)EP4_inClusterList; /*********************************************************************
EP4_simpleDesc.app_out_cluster_lst = (u16 *)EP4_outClusterList; * @fn zcl_onOffAttr_save
device_simpleDesc[3] = EP4_simpleDesc; *
Cluster_Num_List[3] = EP4_CB_CLUSTER_NUM; * @brief
g_EPClusterAllList[3] = g_EP4ClusterList; *
break; * @param None
} *
default: * @return
break; */
} nv_sts_t zcl_onOffAttr_save(void)
} {
nv_sts_t st = NV_SUCC;
/*********************************************************************
* @fn zcl_onOffAttr_save #ifdef ZCL_ON_OFF
* #if NV_ENABLE
* @brief zcl_nv_onOff_t zcl_nv_onOff[Support_Endpoint_Num];
*
* @param None st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
* bool write_falge = false;
* @return if(st == NV_SUCC){
*/ for(uint8_t i=0;i<Support_Endpoint_Num;i++)
nv_sts_t zcl_onOffAttr_save(void) {
{ if((zcl_nv_onOff[i].onOff !=g_zcl_onOffAttrs[i].onOff)||(zcl_nv_onOff[i].startUpOnOff !=g_zcl_onOffAttrs[i].startUpOnOff))
nv_sts_t st = NV_SUCC; {
zcl_nv_onOff[i].onOff = g_zcl_onOffAttrs[i].onOff;
#ifdef ZCL_ON_OFF zcl_nv_onOff[i].startUpOnOff =g_zcl_onOffAttrs[i].startUpOnOff;
#if NV_ENABLE write_falge = true;
zcl_nv_onOff_t zcl_nv_onOff[Support_Endpoint_Num]; }
if(write_falge)
st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff); st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
bool write_falge = false; }
if(st == NV_SUCC){ }else if(st == NV_ITEM_NOT_FOUND){
for(uint8_t i=0;i<Support_Endpoint_Num;i++) for(uint8_t i=0;i<Support_Endpoint_Num;i++)
{ {
if((zcl_nv_onOff[i].onOff !=g_zcl_onOffAttrs[i].onOff)||(zcl_nv_onOff[i].startUpOnOff !=g_zcl_onOffAttrs[i].startUpOnOff)) zcl_nv_onOff[i].onOff = g_zcl_onOffAttrs[i].onOff;
{ zcl_nv_onOff[i].startUpOnOff =g_zcl_onOffAttrs[i].startUpOnOff;
zcl_nv_onOff[i].onOff = g_zcl_onOffAttrs[i].onOff; }
zcl_nv_onOff[i].startUpOnOff =g_zcl_onOffAttrs[i].startUpOnOff; st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
write_falge = true; }
} #else
if(write_falge) st = NV_ENABLE_PROTECT_ERROR;
st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff); #endif
} #endif
}else if(st == NV_ITEM_NOT_FOUND){
for(uint8_t i=0;i<Support_Endpoint_Num;i++) return st;
{ }
zcl_nv_onOff[i].onOff = g_zcl_onOffAttrs[i].onOff;
zcl_nv_onOff[i].startUpOnOff =g_zcl_onOffAttrs[i].startUpOnOff; /*********************************************************************
} * @fn zcl_onOffAttr_restore
st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff); *
} * @brief
#else *
st = NV_ENABLE_PROTECT_ERROR; * @param None
#endif *
#endif * @return
*/
return st; nv_sts_t zcl_onOffAttr_get(void)
} {
nv_sts_t st = NV_SUCC;
/*********************************************************************
* @fn zcl_onOffAttr_restore #ifdef ZCL_ON_OFF
* #if NV_ENABLE
* @brief zcl_nv_onOff_t zcl_nv_onOff[Support_Endpoint_Num];
* st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff);
* @param None if(st == NV_SUCC){
* iKonkeAfSelfPrint("Token Get,zcl_onOffAttr_get::\r\n");
* @return for(uint8_t i=0;i<Support_Endpoint_Num;i++)
*/ {
nv_sts_t zcl_onOffAttr_get(void) g_zcl_onOffAttrs[i].onOff = zcl_nv_onOff[i].onOff;
{ g_zcl_onOffAttrs[i].startUpOnOff = zcl_nv_onOff[i].startUpOnOff;
nv_sts_t st = NV_SUCC; iKonkeAfSelfPrint("ep(%d)state%d ",i+1,g_zcl_onOffAttrs[i].onOff);
}
#ifdef ZCL_ON_OFF iKonkeAfSelfPrint("\r\n");
#if NV_ENABLE
zcl_nv_onOff_t zcl_nv_onOff[Support_Endpoint_Num]; }
st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff), (u8*)zcl_nv_onOff); #else
if(st == NV_SUCC){ st = NV_ENABLE_PROTECT_ERROR;
iKonkeAfSelfPrint("Token Get,zcl_onOffAttr_get::\r\n"); #endif
for(uint8_t i=0;i<Support_Endpoint_Num;i++) #endif
{
g_zcl_onOffAttrs[i].onOff = zcl_nv_onOff[i].onOff; return st;
g_zcl_onOffAttrs[i].startUpOnOff = zcl_nv_onOff[i].startUpOnOff; }
iKonkeAfSelfPrint("ep(%d)state%d ",i+1,g_zcl_onOffAttrs[i].onOff);
} #endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */
iKonkeAfSelfPrint("\r\n");
}
#else
st = NV_ENABLE_PROTECT_ERROR;
#endif
#endif
return st;
}
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */
#ifndef __IKONKE_ENDPOINT_CONFIG_H___ #ifndef __IKONKE_ENDPOINT_CONFIG_H___
#define __IKONKE_ENDPOINT_CONFIG_H___ #define __IKONKE_ENDPOINT_CONFIG_H___
#include "types.h" #include "types.h"
/** /**
* @brief Defined for basic cluster attributes * @brief Defined for basic cluster attributes
*/ */
#define SUPPORT_MAX_EP 6 #define SUPPORT_MAX_EP 6
#define Support_Endpoint_Array {1 ,2 ,3 ,4 } #define Support_Endpoint_Array {1 ,2 ,3 ,4 }
#define Support_Endpoint_Num 4 #define Support_Endpoint_Num 4
// Array of profile ids // Array of profile ids
#define FIXED_PROFILE_IDS { 260, 260, 260, 260 } #define FIXED_PROFILE_IDS { 260, 260, 260, 260 }
// Array of device ids // Array of device ids
#define FIXED_DEVICE_IDS { HA_DEV_ONOFF_LIGHT_SWITCH, HA_DEV_ONOFF_LIGHT_SWITCH, HA_DEV_ONOFF_LIGHT_SWITCH, HA_DEV_ONOFF_LIGHT_SWITCH } #define FIXED_DEVICE_IDS { HA_DEV_ONOFF_LIGHT_SWITCH, HA_DEV_ONOFF_LIGHT_SWITCH, HA_DEV_ONOFF_LIGHT_SWITCH, HA_DEV_ONOFF_LIGHT_SWITCH }
typedef struct{ typedef struct{
u8 zclVersion; u8 zclVersion;
u8 appVersion; u8 appVersion;
u8 stackVersion; u8 stackVersion;
u8 hwVersion; u8 hwVersion;
u8 manuName[24]; u8 manuName[24];
u8 modelId[24]; u8 modelId[24];
u8 swBuildId[24]; u8 swBuildId[24];
u8 powerSource; u8 powerSource;
u8 deviceEnable; u8 deviceEnable;
}zcl_basicAttr_t; }zcl_basicAttr_t;
/** /**
* @brief Defined for identify cluster attributes * @brief Defined for identify cluster attributes
*/ */
typedef struct{ typedef struct{
u16 identifyTime; u16 identifyTime;
}zcl_identifyAttr_t; }zcl_identifyAttr_t;
/** /**
* @brief Defined for group cluster attributes * @brief Defined for group cluster attributes
*/ */
typedef struct{ typedef struct{
u8 nameSupport; u8 nameSupport;
}zcl_groupAttr_t; }zcl_groupAttr_t;
/** /**
* @brief Defined for scene cluster attributes * @brief Defined for scene cluster attributes
*/ */
typedef struct{ typedef struct{
u8 sceneCount; u8 sceneCount;
u8 currentScene; u8 currentScene;
u8 nameSupport; u8 nameSupport;
bool sceneValid; bool sceneValid;
u16 currentGroup; u16 currentGroup;
}zcl_sceneAttr_t; }zcl_sceneAttr_t;
/** /**
* @brief Defined for on/off cluster attributes * @brief Defined for on/off cluster attributes
*/ */
typedef struct{ typedef struct{
u16 onTime; u16 onTime;
u16 offWaitTime; u16 offWaitTime;
u8 startUpOnOff; u8 startUpOnOff;
bool onOff; bool onOff;
bool globalSceneControl; bool globalSceneControl;
}zcl_onOffAttr_t; }zcl_onOffAttr_t;
/** /**
* @brief Defined for level cluster attributes * @brief Defined for level cluster attributes
*/ */
typedef struct{ typedef struct{
u16 remainingTime; u16 remainingTime;
u8 curLevel; u8 curLevel;
u8 startUpCurrentLevel; u8 startUpCurrentLevel;
}zcl_levelAttr_t; }zcl_levelAttr_t;
/** /**
* @brief Defined for color control cluster attributes * @brief Defined for color control cluster attributes
*/ */
typedef struct{ typedef struct{
u8 colorMode; u8 colorMode;
u8 options; u8 options;
u8 enhancedColorMode; u8 enhancedColorMode;
u8 numOfPrimaries; u8 numOfPrimaries;
u16 colorCapabilities; u16 colorCapabilities;
#if COLOR_RGB_SUPPORT #if COLOR_RGB_SUPPORT
u8 currentHue; u8 currentHue;
u8 currentSaturation; u8 currentSaturation;
u8 colorLoopActive; u8 colorLoopActive;
u8 colorLoopDirection; u8 colorLoopDirection;
u16 colorLoopTime; u16 colorLoopTime;
u16 colorLoopStartEnhancedHue; u16 colorLoopStartEnhancedHue;
u16 colorLoopStoredEnhancedHue; u16 colorLoopStoredEnhancedHue;
#elif COLOR_CCT_SUPPORT #elif COLOR_CCT_SUPPORT
u16 colorTemperatureMireds; u16 colorTemperatureMireds;
u16 colorTempPhysicalMinMireds; u16 colorTempPhysicalMinMireds;
u16 colorTempPhysicalMaxMireds; u16 colorTempPhysicalMaxMireds;
u16 startUpColorTemperatureMireds; u16 startUpColorTemperatureMireds;
#endif #endif
}zcl_lightColorCtrlAttr_t; }zcl_lightColorCtrlAttr_t;
extern const uint8_t fixedEndpoints[SUPPORT_MAX_EP] ; extern const uint8_t fixedEndpoints[SUPPORT_MAX_EP] ;
extern const uint16_t fixedProfileIds[SUPPORT_MAX_EP]; extern const uint16_t fixedProfileIds[SUPPORT_MAX_EP];
extern const uint16_t fixedDeviceIds[SUPPORT_MAX_EP]; extern const uint16_t fixedDeviceIds[SUPPORT_MAX_EP];
/* Attributes */ /* Attributes */
extern zcl_basicAttr_t g_zcl_basicAttrs; extern zcl_basicAttr_t g_zcl_basicAttrs;
extern zcl_identifyAttr_t g_zcl_identifyAttrs[]; extern zcl_identifyAttr_t g_zcl_identifyAttrs[];
extern zcl_groupAttr_t g_zcl_groupAttrs[]; extern zcl_groupAttr_t g_zcl_groupAttrs[];
extern zcl_sceneAttr_t g_zcl_sceneAttrs[]; extern zcl_sceneAttr_t g_zcl_sceneAttrs[];
extern zcl_onOffAttr_t g_zcl_onOffAttrs[]; extern zcl_onOffAttr_t g_zcl_onOffAttrs[];
#ifdef ZCL_LEVEL_CTRL #ifdef ZCL_LEVEL_CTRL
extern zcl_levelAttr_t g_zcl_levelAttrs; extern zcl_levelAttr_t g_zcl_levelAttrs;
extern zcl_lightColorCtrlAttr_t g_zcl_colorCtrlAttrs; extern zcl_lightColorCtrlAttr_t g_zcl_colorCtrlAttrs;
#define zcl_levelAttrGet(ep) &g_zcl_levelAttrs #define zcl_levelAttrGet(ep) &g_zcl_levelAttrs
#define zcl_colorAttrGet(ep) &g_zcl_colorCtrlAttrs #define zcl_colorAttrGet(ep) &g_zcl_colorCtrlAttrs
#endif #endif
#define zcl_sceneAttrGet(ep) &g_zcl_sceneAttrs[ep-1] #define zcl_sceneAttrGet(ep) &g_zcl_sceneAttrs[ep-1]
#define zcl_onoffAttrGet(ep) &g_zcl_onOffAttrs[ep-1] #define zcl_onoffAttrGet(ep) &g_zcl_onOffAttrs[ep-1]
void SimpleDesc_Init(uint8_t endpint); #define zcl_BasicAttrGet() &g_zcl_basicAttrs
nv_sts_t zcl_onOffAttr_get(void);
nv_sts_t zcl_onOffAttr_save(void); void SimpleDesc_Init(uint8_t endpint);
#endif nv_sts_t zcl_onOffAttr_get(void);
nv_sts_t zcl_onOffAttr_save(void);
#endif
/******************************************************************************************************** /********************************************************************************************************
* @file app_cfg.h * @file app_cfg.h
* *
* @brief This is the header file for app_cfg * @brief This is the header file for app_cfg
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#pragma once #pragma once
/* Enable C linkage for C++ Compilers: */ /* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
/********************************************************************** /**********************************************************************
* Version configuration * Version configuration
*/ */
#include "ikk-config.h" #include "ikk-config.h"
/********************************************************************** /**********************************************************************
* Product Information * Product Information
*/ */
/* Debug mode config */ /* Debug mode config */
#define UART_PRINTF_MODE 1 #define UART_PRINTF_MODE 1
#define USB_PRINTF_MODE 0 #define USB_PRINTF_MODE 0
/* HCI interface */ /* HCI interface */
#define ZBHCI_UART 0 #define ZBHCI_UART 0
/* RGB or CCT */ /* RGB or CCT */
#define COLOR_RGB_SUPPORT 0 #define COLOR_RGB_SUPPORT 0
#define COLOR_CCT_SUPPORT 0 #define COLOR_CCT_SUPPORT 0
/* BDB */ /* BDB */
#define TOUCHLINK_SUPPORT 0 #define TOUCHLINK_SUPPORT 0
#define FIND_AND_BIND_SUPPORT 0 #define FIND_AND_BIND_SUPPORT 0
#define CLOCK_SYS_CLOCK_HZ 48000000 #define CLOCK_SYS_CLOCK_HZ 48000000
/* Voltage detect module */ /* Voltage detect module */
#define VOLTAGE_DETECT_ENABLE 0 #define VOLTAGE_DETECT_ENABLE 0
/* Watch dog module */ /* Watch dog module */
#define MODULE_WATCHDOG_ENABLE 0 #define MODULE_WATCHDOG_ENABLE 0
/* UART module */ /* UART module */
#if ZBHCI_UART #if ZBHCI_UART
#define MODULE_UART_ENABLE 1 #define MODULE_UART_ENABLE 1
#endif #endif
#if (ZBHCI_USB_PRINT || ZBHCI_USB_CDC || ZBHCI_USB_HID || ZBHCI_UART) #if (ZBHCI_USB_PRINT || ZBHCI_USB_CDC || ZBHCI_USB_HID || ZBHCI_UART)
#define ZBHCI_EN 1 #define ZBHCI_EN 1
#endif #endif
/********************************************************************** /**********************************************************************
* ZCL cluster support setting * ZCL cluster support setting
*/ */
#define ZCL_ON_OFF_SUPPORT 1 #define ZCL_ON_OFF_SUPPORT 1
#define ZCL_LEVEL_CTRL_SUPPORT 0 #define ZCL_LEVEL_CTRL_SUPPORT 0
#if (COLOR_RGB_SUPPORT || COLOR_CCT_SUPPORT) #if (COLOR_RGB_SUPPORT || COLOR_CCT_SUPPORT)
#define ZCL_LIGHT_COLOR_CONTROL_SUPPORT 0 #define ZCL_LIGHT_COLOR_CONTROL_SUPPORT 0
#endif #endif
#define ZCL_GROUP_SUPPORT 1 #define ZCL_GROUP_SUPPORT 1
#define ZCL_SCENE_SUPPORT 1 #define ZCL_SCENE_SUPPORT 1
#define ZCL_OTA_SUPPORT 1 #define ZCL_OTA_SUPPORT 1
#define ZCL_PRIVATE_CLUSTER_FCC0_SUPPORT 1 #define ZCL_PRIVATE_CLUSTER_FCC0_SUPPORT 1
#if TOUCHLINK_SUPPORT #if TOUCHLINK_SUPPORT
#define ZCL_ZLL_COMMISSIONING_SUPPORT 1 #define ZCL_ZLL_COMMISSIONING_SUPPORT 1
#endif #endif
#define AF_TEST_ENABLE 0 #define AF_TEST_ENABLE 0
// UART // UART
#if ZBHCI_UART #if ZBHCI_UART
#error please configurate uart PIN!!!!!! #error please configurate uart PIN!!!!!!
#endif #endif
// DEBUG // DEBUG
#if UART_PRINTF_MODE #if UART_PRINTF_MODE
#define DEBUG_INFO_TX_PIN GPIO_PA2//print #define DEBUG_INFO_TX_PIN GPIO_PA1//print
#endif #endif
/********************************************************************** /**********************************************************************
* Stack configuration * Stack configuration
*/ */
/** /**
* @brief Working channel * @brief Working channel
* Valid value: 11 ~ 26 * Valid value: 11 ~ 26
*/ */
#define DEFAULT_CHANNEL 20 #define DEFAULT_CHANNEL 20
/** /**
* @brief Security * @brief Security
*/ */
#define SECURITY_ENABLE 1 #define SECURITY_ENABLE 1
/** /**
* @brief NVRAM * @brief NVRAM
*/ */
#define NV_ENABLE 1 #define NV_ENABLE 1
/********************************************************************** /**********************************************************************
* Following parameter need user to adjust according the app requirement * Following parameter need user to adjust according the app requirement
*/ */
/** /**
* @brief ZCL: MAX number of cluster list, in cluster number add + out cluster number * @brief ZCL: MAX number of cluster list, in cluster number add + out cluster number
* *
*/ */
#define ZCL_CLUSTER_NUM_MAX 30 #define ZCL_CLUSTER_NUM_MAX 50
/** /**
* @brief ZCL: maximum number for zcl reporting table * @brief ZCL: maximum number for zcl reporting table
* *
*/ */
#define ZCL_REPORTING_TABLE_NUM 4 #define ZCL_REPORTING_TABLE_NUM 4
/** /**
* @brief ZCL: maximum number for zcl scene table * @brief ZCL: maximum number for zcl scene table
* *
*/ */
#define ZCL_SCENE_TABLE_NUM 8 #define ZCL_SCENE_TABLE_NUM 8
/** /**
* @brief APS: MAX number of groups size in the group table * @brief APS: MAX number of groups size in the group table
* In each group entry, there is 8 endpoints existed. * In each group entry, there is 8 endpoints existed.
*/ */
#define APS_GROUP_TABLE_NUM 8 #define APS_GROUP_TABLE_NUM 8
/** /**
* @brief APS: MAX number of binding table size * @brief APS: MAX number of binding table size
*/ */
#define APS_BINDING_TABLE_NUM 8 #define APS_BINDING_TABLE_NUM 8
/********************************************************************** /**********************************************************************
* Following configuration will calculated automatically * Following configuration will calculated automatically
*/ */
/** /**
Auto definition for the role Auto definition for the role
*/ */
#if (COORDINATOR) #if (COORDINATOR)
#define ZB_ROUTER_ROLE 1 #define ZB_ROUTER_ROLE 1
#define ZB_COORDINATOR_ROLE 1 #define ZB_COORDINATOR_ROLE 1
#elif (ROUTER) #elif (ROUTER)
#define ZB_ROUTER_ROLE 1 #define ZB_ROUTER_ROLE 1
#elif (END_DEVICE) #elif (END_DEVICE)
#define ZB_ED_ROLE 1 #define ZB_ED_ROLE 1
#endif #endif
#if ZB_ROUTER_ROLE #if ZB_ROUTER_ROLE
#define GP_SUPPORT_ENABLE 1 #define GP_SUPPORT_ENABLE 1
#endif #endif
#if (SECURITY_ENABLE) #if (SECURITY_ENABLE)
#define ZB_SECURITY #define ZB_SECURITY
#endif #endif
/********************************************************************** /**********************************************************************
* EV configuration * EV configuration
*/ */
typedef enum{ typedef enum{
EV_POLL_ED_DETECT, EV_POLL_ED_DETECT,
EV_POLL_HCI, EV_POLL_HCI,
EV_POLL_IDLE, EV_POLL_IDLE,
EV_POLL_MAX, EV_POLL_MAX,
}ev_poll_e; }ev_poll_e;
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif
#ifndef __IKONKE_CONFIG_H___ #ifndef __IKONKE_CONFIG_H___
#define __IKONKE_CONFIG_H___ #define __IKONKE_CONFIG_H___
#include "types.h" #include "types.h"
/*Dsp: product model id */ /*Dsp: product model id */
#define PRODUCT_MODEL "KK-PA-M10X" #define PRODUCT_MODEL "KK-PA-M10X"
/*Dsp: APP Version */ /*Dsp: APP Version */
#define FIRMWARE_VER 0x20 #define FIRMWARE_VER 0x20
/*Dsp: Stack Version */ /*Dsp: Stack Version */
#define STACK_VER 0x11 #define STACK_VER 0x11
/*Dsp: HARDWARE_VER */ /*Dsp: HARDWARE_VER */
#define HARDWARE_VERSION 0x20 #define HARDWARE_VERSION 0x20
/*Dsp: MANUFATURE NAME */ /*Dsp: MANUFATURE NAME */
#define MANUFATURE_NAME "Konke" #define MANUFATURE_NAME "Konke"
/*Dsp: MODEL_ID */ /*Dsp: MODEL_ID */
#define MODEL_ID 0x3AFE101000068624 #define MODEL_ID 0x00068624
/*Dsp: OTA_IMAGE_TYPE */ /*Dsp: OTA_IMAGE_TYPE */
#define OTA_IMAGE_TYPE 65000 #define OTA_IMAGE_TYPE 65000
/*Dsp: OTA_FIRMVERSION */ /*Dsp: OTA_FIRMVERSION */
#define OTA_FIRMVERSION 0x20 #define OTA_FIRMVERSION 0x20
/*Dsp: MANUFATURE_CODE */ /*Dsp: MANUFATURE_CODE */
#define MANUFATURE_CODE 0x1268 #define MANUFATURE_CODE 0x1268
/*Dsp: OTA_HARDWARE_VER */ /*Dsp: OTA_HARDWARE_VER */
#define OTA_HARDWARE_VER 0x20 #define OTA_HARDWARE_VER 0x20
#define MANUFACTURER_CODE_TELINK 0x1268 #define MANUFACTURER_CODE_TELINK 0x1268
#define IMAGE_TYPE 65000 #define IMAGE_TYPE 65000
#define FILE_VERSION 0x10 #define FILE_VERSION 0x10
#include "../common/comm_cfg.h" #include "../common/comm_cfg.h"
/* Pre-compiled link configuration. */ /* Pre-compiled link configuration. */
#define IS_BOOT_LOADER_IMAGE 0 #define IS_BOOT_LOADER_IMAGE 0
#define RESV_FOR_APP_RAM_CODE_SIZE 0 #define RESV_FOR_APP_RAM_CODE_SIZE 0
#define IMAGE_OFFSET APP_IMAGE_ADDR #define IMAGE_OFFSET APP_IMAGE_ADDR
#define ENDPOINT_CONFIG_H "3LightPanelDemo_endpoint_config.h" #define ENDPOINT_CONFIG_H "3LightPanelDemo_endpoint_config.h"
#define PROJECT_H "3LightPanelDemo.h" #define PROJECT_H "3LightPanelDemo.h"
#endif #endif
#include "user.h" #include "user.h"
#include PROJECT_H #include PROJECT_H
#include "ikk-token.h" #include "ikk-token.h"
#include "ikk-opt-tunnel.h" #include "ikk-opt-tunnel.h"
#include "ikk-factory-test.h" #include "ikk-factory-test.h"
#include "ikk-cluster.h" #include "ikk-cluster.h"
#include "ikk-pwm.h" #include "ikk-pwm.h"
#include "ikk-timer.h" #include "ikk-timer.h"
#include "ikk-uart.h" #include "ikk-uart.h"
#include "ikk-relay.h" #include "ikk-relay.h"
#include "ikk-led.h" #include "ikk-led.h"
#include "ikk-ota.h" #include "ikk-ota.h"
#include "ikk-command.h"
#define ZERO_PIN GPIO_PA0 #include "ikk-common-utils.h"
#include "ikk-interpan.h"
#define RELAY1_PIN GPIO_PC1 #include "ikk-pwm.h"
#define RELAY2_PIN GPIO_PC4 #define ZERO_PIN GPIO_PA0
#define RELAY3_PIN GPIO_PC6
#define RELAY4_PIN GPIO_PC5 #define RELAY1_PIN GPIO_PC0
#define RELAY2_PIN GPIO_PC4
#define LED_RADAR_PIN GPIO_PD2 #define RELAY3_PIN GPIO_PC6
#define LED1_PIN GPIO_PB6 #define RELAY4_PIN GPIO_PC5
#define LED2_PIN GPIO_PA5
#define LED3_PIN GPIO_PD4 #define LED_RADAR_PIN GPIO_PD4
#define LED4_PIN GPIO_PB4 #define LED1_PIN GPIO_PB5
#define LED2_PIN GPIO_PA4
#define KEY_SYS_PIN GPIO_PD7 #define LED3_PIN GPIO_PD2
#define KEY1_PIN GPIO_PC7 #define LED4_PIN GPIO_PA3
#define KEY2_PIN GPIO_PB5
#define KEY3_PIN GPIO_PD3 #define KEY_SYS_PIN GPIO_PD7
#define KEY4_PIN GPIO_PA3 #define KEY1_PIN GPIO_PC7
#define RADAR_PIN GPIO_PC0 #define KEY2_PIN GPIO_PB4
#define KEY3_PIN GPIO_PD3
#define KEY4_PIN GPIO_PA6
#define SYS_BUTTON_LONG_PRESS_TIME_MS (5 * 1000) #define RADAR_PIN GPIO_PC1
#define DELAY_REPORT_DATA_AFTER_NWK_JOINED_MS (3 * 1000)
#define HEART_RAND_MIN_NUM (240 * 1000) #define UART_TX_PIN GPIO_PB7
#define HEART_RAND_MAX_NUM (300 * 1000) #define UART_RX_PIN GPIO_PB1
#define SYS_BUTTON_LONG_PRESS_TIME_MS (5 * 1000)
#define LED_SLOW_BLINK_ON_TIME_MS 500 #define DELAY_REPORT_DATA_AFTER_NWK_JOINED_MS (3 * 1000)
#define LED_SLOW_BLINK_OFF_TIME_MS 500
#define LED_FAST_BLINK_ON_TIME_MS 200 #define HEART_RAND_MIN_NUM (240 * 1000)
#define LED_FAST_BLINK_OFF_TIME_MS 200 #define HEART_RAND_MAX_NUM (300 * 1000)
#define LED_SLOW_BLINK_CONTINUE_TIME_MS (60 * 1000) #define LED_SLOW_BLINK_ON_TIME_MS 500
#define LED_FAST_BLINK_CONTINUE_TIME_MS (5 * 1000) #define LED_SLOW_BLINK_OFF_TIME_MS 500
#define LED_FAST_BLINK_ON_TIME_MS 200
#define MIN_JOINED_NWK_DELAY_TIME_MS (7 * 1000) //重新上电后最短时间,用于判断是否随机延时10~40S上报心跳和CMEI和ISN #define LED_FAST_BLINK_OFF_TIME_MS 200
#define RAND_MIN_NUM (3 * 1000) //最小随机数,单位MS #define LED_SLOW_BLINK_CONTINUE_TIME_MS (60 * 1000)
#define RAND_MAX_NUM (6 * 1000) //最大随机数 #define LED_FAST_BLINK_CONTINUE_TIME_MS (5 * 1000)
#define REPORT_ATTR_MAX_RAND_NUM (7 * 1000) //场景下发控制后随机最大延时上报状态,状态改变后SDK会主动上报 #define MIN_JOINED_NWK_DELAY_TIME_MS (7 * 1000) //重新上电后最短时间,用于判断是否随机延时10~40S上报心跳和CMEI和ISN
#define REPORT_ATTR_MIN_RAND_NUM (2.5 * 1000) //场景下发控制后随机最小延时上报状态
#define RAND_MIN_NUM (3 * 1000) //最小随机数,单位MS
#define RAND_MAX_NUM (6 * 1000) //最大随机数
#define CHECKED_ZERO_DELAY_ON_TIME_MS (6000)//因继电器会有延时,检测到零点后,按键开关或命令下发开关延时去开的时间,
#define CHECKED_ZERO_DELAY_OFF_TIME_MS (5970)//因继电器会有延时,检测到零点后,按键开关或命令下发开关延时去关的时间, #define REPORT_ATTR_MAX_RAND_NUM (7 * 1000) //场景下发控制后随机最大延时上报状态,状态改变后SDK会主动上报
//join nwk timeout #define REPORT_ATTR_MIN_RAND_NUM (2.5 * 1000) //场景下发控制后随机最小延时上报状态
#define NWK_STEERING_TIMEOUT_MS (60 * 1000)
#define HEART_DEBUG 0 #define CHECKED_ZERO_DELAY_ON_TIME_MS (6000)//因继电器会有延时,检测到零点后,按键开关或命令下发开关延时去开的时间,
#if HEART_DEBUG #define CHECKED_ZERO_DELAY_OFF_TIME_MS (5970)//因继电器会有延时,检测到零点后,按键开关或命令下发开关延时去关的时间,
#define HEARTBEAT_TIME_MS (20 * 1000) //join nwk timeout
#else #define NWK_STEERING_TIMEOUT_MS (60 * 1000)
#define HEARTBEAT_TIME_MS kGetRandNum(HEART_RAND_MIN_NUM, HEART_RAND_MAX_NUM)
#endif #define HEART_DEBUG 0
#if HEART_DEBUG
#define RADAR_ON_TIME_MS 10000 #define HEARTBEAT_TIME_MS (20 * 1000)
#define SENSOR_LONG_PRESS_TIME_MS 200 #else
#define MAX_FIRST_USER_KEY_LEAVE_NWK_INTERVAL_TIME_MS (14 * 1000)//第一个按键长按两次退网最大间隔时间 #define HEARTBEAT_TIME_MS kGetRandNum(HEART_RAND_MIN_NUM, HEART_RAND_MAX_NUM)
#endif
typedef enum {KEY_SYS_ID = 1,KEY1_ID, KEY2_ID, KEY3_ID, KEY4_ID , RADAR_ID}KEY_ID_ENUM;
typedef enum {LED_RADAR_ID = 1,LED1_ID, LED2_ID, LED3_ID, LED4_ID, LED_ALL_ID}LED_ID_ENUM; #define RADAR_ON_TIME_MS 10000
typedef enum {RELAY_CHANNEL1_ID=1, RELAY_CHANNEL2_ID, RELAY_CHANNEL3_ID, RELAY_CHANNEL4_ID, RELAY_ALL_ID}RELAY_ID_ENUM; #define SENSOR_LONG_PRESS_TIME_MS 200
#define MAX_FIRST_USER_KEY_LEAVE_NWK_INTERVAL_TIME_MS (14 * 1000)//第一个按键长按两次退网最大间隔时间
#define GET_LED_ID(endpoint) (endpoint == 1?LED1_ID:(endpoint == 2?LED2_ID:(endpoint == 3?LED3_ID:LED4_ID)))
#define GET_ENDPOINT(led_id) (led_id == LED1_ID?1:(led_id == LED2_ID?2:(led_id == LED3_ID?3:4))) typedef enum {KEY_SYS_ID = 1,KEY1_ID, KEY2_ID, KEY3_ID, KEY4_ID , RADAR_ID}KEY_ID_ENUM;
#define GET_LED_ID_BY_ENDPOINT(endpoint, max_endpint) (endpoint <= max_endpint?GET_LED_ID(endpoint):LED_UNKNOW_ID) typedef enum {LED_RADAR_ID = 1,LED1_ID, LED2_ID, LED3_ID, LED4_ID, LED_ALL_ID}LED_ID_ENUM;
// BUTTONs CONFIG typedef enum {RELAY_CHANNEL1_ID=1, RELAY_CHANNEL2_ID, RELAY_CHANNEL3_ID, RELAY_CHANNEL4_ID, RELAY_ALL_ID}RELAY_ID_ENUM;
BtnConfSt g_btnConfList[] = {
{KEY_SYS_ID, KEY_SYS_PIN, EBP_HIGH, false, true, SYS_BUTTON_LONG_PRESS_TIME_MS}, // Key1 #define GET_LED_ID(endpoint) (endpoint == 1?LED1_ID:(endpoint == 2?LED2_ID:(endpoint == 3?LED3_ID:LED4_ID)))
{KEY1_ID, KEY1_PIN, EBP_HIGH, false, true, SYS_BUTTON_LONG_PRESS_TIME_MS}, // Key2 #define GET_ENDPOINT(led_id) (led_id == LED1_ID?1:(led_id == LED2_ID?2:(led_id == LED3_ID?3:4)))
{KEY2_ID, KEY2_PIN, EBP_HIGH, false, false, 0xffffffff}, // Key2 #define GET_LED_ID_BY_ENDPOINT(endpoint, max_endpint) (endpoint <= max_endpint?GET_LED_ID(endpoint):LED_UNKNOW_ID)
{KEY3_ID, KEY3_PIN, EBP_HIGH, false, false, 0xffffffff}, // Key2 // BUTTONs CONFIG
{KEY4_ID, KEY4_PIN, EBP_HIGH, false, false, 0xffffffff}, // Key2 BtnConfSt g_btnConfList[] = {
}; {KEY_SYS_ID, KEY_SYS_PIN, EBP_HIGH, false, true, SYS_BUTTON_LONG_PRESS_TIME_MS}, // Key1
// LEDs CONFIG {KEY1_ID, KEY1_PIN, EBP_HIGH, false, true, SYS_BUTTON_LONG_PRESS_TIME_MS}, // Key2
LedConfSt g_ledConfList[] = { {KEY2_ID, KEY2_PIN, EBP_HIGH, false, false, 0xffffffff}, // Key2
{(uint8_t)LED_RADAR_ID, 1, {LED_RADAR_PIN, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH }, {KEY3_ID, KEY3_PIN, EBP_HIGH, false, false, 0xffffffff}, // Key2
{(uint8_t)LED1_ID, 1, {LED1_PIN, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH }, {KEY4_ID, KEY4_PIN, EBP_HIGH, false, false, 0xffffffff}, // Key2
{(uint8_t)LED2_ID, 1, {LED2_PIN, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH }, };
{(uint8_t)LED3_ID, 1, {LED3_PIN, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH }, // LEDs CONFIG
{(uint8_t)LED4_ID, 1, {LED4_PIN, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH }, LedConfSt g_ledConfList[] = {
{(uint8_t)LED_ALL_ID, 4, {LED1_PIN, PWM_UNKNOW_ID, LED2_PIN, PWM_UNKNOW_ID, LED3_PIN, PWM_UNKNOW_ID, LED4_PIN, PWM_UNKNOW_ID}, ELP_HIGH }, {(uint8_t)LED_RADAR_ID, 1, {LED_RADAR_PIN, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH },
}; {(uint8_t)LED1_ID, 1, {LED1_PIN, PWM1_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH },
PwmConfSt g_pwmConfList[] = { {(uint8_t)LED2_ID, 1, {LED2_PIN, PWM2_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH },
{PWM1_ID, {LED1_PIN, KK_PWM_CC0}}, // {(uint8_t)LED3_ID, 1, {LED3_PIN, PWM3_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH },
{PWM2_ID, {LED2_PIN, KK_PWM_CC1}}, // {(uint8_t)LED4_ID, 1, {LED4_PIN, PWM4_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID, PIN_UNKNOW, PWM_UNKNOW_ID}, ELP_HIGH },
{PWM3_ID, {LED3_PIN, KK_PWM_CC2}}, // {(uint8_t)LED_ALL_ID, 4, {LED1_PIN, PWM1_ID, LED2_PIN, PWM2_ID, LED3_PIN, PWM3_ID, LED4_PIN, PWM4_ID}, ELP_HIGH },
{PWM4_ID, {LED4_PIN, KK_PWM_CC3}}, // };
}; PwmConfSt g_pwmConfList[] = {
{PWM1_ID, {LED1_PIN, KK_PWM_CC0}}, //
{PWM2_ID, {LED2_PIN, KK_PWM_CC1}}, //
// ZERO-ACCESS CONFIG {PWM3_ID, {LED3_PIN, KK_PWM_CC2}}, //
RelayChannelConfSt g_relayConfList[] = { {PWM4_ID, {LED4_PIN, KK_PWM_CC3}}, //
{RELAY_CHANNEL1_ID, 1, {RELAY1_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel1 };
{RELAY_CHANNEL2_ID, 1, {RELAY2_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel2
{RELAY_CHANNEL3_ID, 1, {RELAY3_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel3
{RELAY_CHANNEL4_ID, 1, {RELAY4_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel3 // ZERO-ACCESS CONFIG
{RELAY_ALL_ID, 4, {RELAY1_PIN, RELAY2_PIN, RELAY3_PIN, RELAY4_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, //ALL RelayChannelConfSt g_relayConfList[] = {
}; {RELAY_CHANNEL1_ID, 1, {RELAY1_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel1
{RELAY_CHANNEL2_ID, 1, {RELAY2_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel2
//老化配置 {RELAY_CHANNEL3_ID, 1, {RELAY3_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel3
FactoryTestConfSt g_factoryTestConfList[] = { {RELAY_CHANNEL4_ID, 1, {RELAY4_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, // Channel3
{KEY_SYS_ID, LONG_PRESS_1_TIMES, MECHANICAL_KEY_LONG_PRESS_TIME_MS}, {RELAY_ALL_ID, 4, {RELAY1_PIN, RELAY2_PIN, RELAY3_PIN, RELAY4_PIN, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW, PIN_UNKNOW}, EZAP_HIGH }, //ALL
{KEY1_ID, LONG_PRESS_1_TIMES, MECHANICAL_KEY_LONG_PRESS_TIME_MS}, };
};
BindObjSt cluster_obj_list[] = { //老化配置
{ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 1}, FactoryTestConfSt g_factoryTestConfList[] = {
{ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 2}, {KEY_SYS_ID, LONG_PRESS_1_TIMES, MECHANICAL_KEY_LONG_PRESS_TIME_MS},
{ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 3}, {KEY1_ID, LONG_PRESS_1_TIMES, MECHANICAL_KEY_LONG_PRESS_TIME_MS},
{ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 4}, };
}; BindObjSt cluster_obj_list[] = {
{ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 1},
uint32_t u32PeroidIntervalMS = 2*1000; {ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 2},
bool Human_body_induction_flag = false; {ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 3},
static bool power_on_sync[4] = {false,false,false,false}; {ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, 4},
};
//非控客网关首次数据是否上报标志
static bool g_bIsNotKonkeGatewayFirstReportedFlg = false;
static uint8_t g_u8CurrentHeartEndpoint = 1; void pOnOffAttributeChangeCallback(uint8_t endpoint,uint16_t cluster,uint16_t attribute,uint8_t *data,uint8_t data_type);
static uint8_t g_ucRelayIdBuff[] = {RELAY_CHANNEL1_ID, RELAY_CHANNEL2_ID, RELAY_CHANNEL3_ID, RELAY_CHANNEL4_ID, RELAY_ALL_ID};
void JoinCompleteCallback(NwkJoinCompltEnum nwkcomplt ); AttributeChangeConfSt attribte_change_list[] = {
void kUserNetworkStatusNotify(NwkStatusEnum nwkst ); {ZCL_CLUSTER_GEN_ON_OFF, pOnOffAttributeChangeCallback},
void kUserNetworkExitCompleteCallback(void); };
void kUserOnOffClusterOnOffStatusCallback(uint8_t endpoint, OnOffStatusEnum estatus );; uint32_t u32PeroidIntervalMS = 2*1000;
kk_err_t kUserOODMessageIncoming(uint8_t channel, uint8_t opcode, uint8_t args_in_out[], uint8_t *length_in_out ); bool Human_body_induction_flag = false;
static bool power_on_sync[4] = {false,false,false,false};
void kUserButtonAcitonCallback(unsigned char button_id, BtnActionEnum action );
void kUserLedActionDoneCallback(unsigned char id); static uint8_t g_u8NoDisturbModeMinLevel = 0x01;
void kUserPwmActionDoneCallback(unsigned char id, PwmGradientDirectionEnum opt); static uint8_t g_u8NoDisturbModeMaxLevel = 0x64;
#if Z30_DEVICE_AGING_ENABLE //非控客网关首次数据是否上报标志
void kUserFactorTestPollCallback(FactoryTestStatusEnum status); static bool g_bIsNotKonkeGatewayFirstReportedFlg = false;
#endif static uint8_t g_u8CurrentHeartEndpoint = 1;
static uint8_t g_ucRelayIdBuff[] = {RELAY_CHANNEL1_ID, RELAY_CHANNEL2_ID, RELAY_CHANNEL3_ID, RELAY_CHANNEL4_ID, RELAY_ALL_ID};
#if Z30_DEVICE_OTA_ENABLE void JoinCompleteCallback(NwkJoinCompltEnum nwkcomplt );
void kOTAMoudleUserCallback(OTAStatusEnum status); void kUserNetworkStatusNotify(NwkStatusEnum nwkst );
#endif void kUserNetworkExitCompleteCallback(void);
void kUserOnOffClusterOnOffStatusCallback(uint8_t endpoint, OnOffStatusEnum estatus );;
kk_err_t kUserOODMessageIncoming(uint8_t channel, uint8_t opcode, uint8_t args_in_out[], uint8_t *length_in_out );
void kUserRelayLedCallback(RelayStatusSt status);
void kRadarDetectInit(void); void kUserButtonAcitonCallback(unsigned char button_id, BtnActionEnum action );
void kRadarLedTragger(void); void kUserLedActionDoneCallback(unsigned char id);
static void kSetLedStatus(LED_ID_ENUM id); void kUserPwmActionDoneCallback(unsigned char id, PwmGradientDirectionEnum opt);
#if UART_ENABLE #if Z30_DEVICE_AGING_ENABLE
void UartMsgProcessHandle(UMsgNodeSt *pMsgNode); void kUserFactorTestPollCallback(FactoryTestStatusEnum status);
bool MsgCRC16(uint8_t *pdat, int length ); #endif
uint16_t check_sum( uint8_t* msg, uint8_t len);
uint8_t uart_send(void); #if Z30_DEVICE_OTA_ENABLE
#endif void kOTAMoudleUserCallback(OTAStatusEnum status);
void Test(void ); #endif
static ev_timer_event_t *kkSystemSetUpEvent = NULL; #define UART_ENABLE false
s32 kkSystemSetUpEventHandler(void *arg ); void kUserRelayLedCallback(RelayStatusSt status);
//void pOnOffClusterAttributeChangeCallback(uint8_t endpoint,uint16_t cluster,uint16_t attribute,uint8_t len,uint8_t *data); void kRadarDetectInit(void);
// void kRadarLedTragger(void);
//AttributeChangeConfSt g_ClusterAttributeConfList[] = { static void kSetLedStatus(LED_ID_ENUM id);
// {ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, pOnOffClusterAttributeChangeCallback}, #if UART_ENABLE
//}; void UartMsgProcessHandle(UMsgNodeSt *pMsgNode);
#define UART_ENABLE false bool MsgCRC16(uint8_t *pdat, int length );
static void kLEDOnAction(LED_ID_ENUM led_id); uint16_t check_sum( uint8_t* msg, uint8_t len);
static void kLEDOffAction(LED_ID_ENUM led_id); uint8_t uart_send(void);
void App_Init(void) #endif
{ void Test(void );
iKonkeAfSelfPrint("\r\n************************************************\r\n");
iKonkeAfSelfPrint("\r\n****************APP Init***********************\r\n"); static ev_timer_event_t *kkSystemSetUpEvent = NULL;
// iKonkeAfSelfPrint("xxx Reboot Reason: R-INFO(0x%x: %p), R-EXTEND(0x%x: %p) xxx\r\n" s32 kkSystemSetUpEventHandler(void *arg );
// , halGetResetInfo(), halGetResetString() void kUserInterPanMsgInComingPaser(UMsgNodeSt *pMsgNode);
// , halGetExtendedResetInfo(), halGetExtendedResetString()); void pOnOffClusterAttributeChangeCallback(uint8_t endpoint,uint16_t cluster,uint16_t attribute,uint8_t len,uint8_t *data);
// iKonkeAfSelfPrint("xxx Network Status: %d, systime: %d xxx\r\n", emberAfNetworkState()
// , halCommonGetInt32uMillisecondTick()); AttributeChangeConfSt g_ClusterAttributeConfList[] = {
iKonkeAfSelfPrint("\r\n************************************************\r\n"); {ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, pOnOffClusterAttributeChangeCallback},
#if 1 };
kk_err_t err = kBtnModuleInit(g_btnConfList, sizeof(g_btnConfList) / sizeof(BtnConfSt), kUserButtonAcitonCallback);
if( err != KET_OK ) { static void kLEDOnAction(LED_ID_ENUM led_id);
iKonkeAfSelfPrint("Err: Button Module Init failed(%d)!!\r\n", err); static void kLEDOffAction(LED_ID_ENUM led_id);
} void App_Init(void)
#endif {
#if 0 iKonkeAfSelfPrint("\r\n************************************************\r\n");
err = kPwmModuleInit(g_pwmConfList, sizeof(g_pwmConfList)/sizeof(PwmConfSt), kUserPwmActionDoneCallback); iKonkeAfSelfPrint("\r\n****************APP Init***********************\r\n");
if( err != KET_OK ) { // iKonkeAfSelfPrint("xxx Reboot Reason: R-INFO(0x%x: %p), R-EXTEND(0x%x: %p) xxx\r\n"
iKonkeAfSelfPrint("Err: PWM Module Init failed(%d)!!\r\n", err); // , halGetResetInfo(), halGetResetString()
} // , halGetExtendedResetInfo(), halGetExtendedResetString());
#endif // iKonkeAfSelfPrint("xxx Network Status: %d, systime: %d xxx\r\n", emberAfNetworkState()
err = kLedModuleInit(g_ledConfList, sizeof(g_ledConfList) / sizeof(LedConfSt), kUserLedActionDoneCallback); // , halCommonGetInt32uMillisecondTick());
if( err != KET_OK ) { iKonkeAfSelfPrint("\r\n************************************************\r\n");
iKonkeAfSelfPrint("Err: Led Module Init failed(%d)!!\r\n", err); #if 1
} kk_err_t err = kBtnModuleInit(g_btnConfList, sizeof(g_btnConfList) / sizeof(BtnConfSt), kUserButtonAcitonCallback);
err = kRelayModuleInit(ZERO_PIN, CHECKED_ZERO_DELAY_ON_TIME_MS, CHECKED_ZERO_DELAY_OFF_TIME_MS \ if( err != KET_OK ) {
, EZAP_LOW, g_relayConfList, sizeof(g_relayConfList)/sizeof(RelayChannelConfSt), kUserRelayLedCallback); iKonkeAfSelfPrint("Err: Button Module Init failed(%d)!!\r\n", err);
if( err != KET_OK ) { }
iKonkeAfSelfPrint("Err: Led Module Init failed(%d)!!\r\n", err); #endif
} #if 1
#if UART_ENABLE err = kPwmModuleInit(g_pwmConfList, sizeof(g_pwmConfList)/sizeof(PwmConfSt), kUserPwmActionDoneCallback);
uint8_t recv_header[] = {0xAA,0X55}; if( err != KET_OK ) {
err = kUartModuleInit(UART_TX_PIN,UART_RX_PIN,115200,PARITY_NONE,STOP_BIT_ONE,recv_header,2,2,5,MsgCRC16,UartMsgProcessHandle,true ); iKonkeAfSelfPrint("Err: PWM Module Init failed(%d)!!\r\n", err);
#endif }
#endif
kNwkModuleInit(cluster_obj_list,sizeof(cluster_obj_list) / sizeof(cluster_obj_list[0]), kUserNetworkStatusNotify, kUserNetworkExitCompleteCallback); err = kLedModuleInit(g_ledConfList, sizeof(g_ledConfList) / sizeof(LedConfSt), kUserLedActionDoneCallback);
if( err != KET_OK ) {
#if Z30_DEVICE_OTA_ENABLE iKonkeAfSelfPrint("Err: Led Module Init failed(%d)!!\r\n", err);
kOTAMoudleInit(kOTAMoudleUserCallback, LED_ALL_ID); }
#endif err = kRelayModuleInit(ZERO_PIN, CHECKED_ZERO_DELAY_ON_TIME_MS, CHECKED_ZERO_DELAY_OFF_TIME_MS \
#if Z30_DEVICE_AGING_ENABLE , EZAP_LOW, g_relayConfList, sizeof(g_relayConfList)/sizeof(RelayChannelConfSt), kUserRelayLedCallback);
kFactoryTestInit(kUserFactorTestPollCallback, g_factoryTestConfList, sizeof(g_factoryTestConfList)/ sizeof(FactoryTestConfSt)); if( err != KET_OK ) {
#endif iKonkeAfSelfPrint("Err: Led Module Init failed(%d)!!\r\n", err);
// init the private cluster protocol module. }
err = kOptTunnelModuleInit(kUserOODMessageIncoming); #if UART_ENABLE
if( err != KET_OK ) { uint8_t recv_header[] = {0xAA,0X55};
iKonkeAfSelfPrint("Err: kUserOODMessageIncoming Register Failed(%d)!!\r\n", err); err = kUartModuleInit(UART_TX_PIN,UART_RX_PIN,115200,PARITY_NONE,STOP_BIT_ONE,recv_header,2,3,6,MsgCRC16,UartMsgProcessHandle,true );
} #endif
// ZCL
kZclOnOffClusterServerInit(kUserOnOffClusterOnOffStatusCallback); kNwkModuleInit(cluster_obj_list,sizeof(cluster_obj_list) / sizeof(cluster_obj_list[0]), kUserNetworkStatusNotify, kUserNetworkExitCompleteCallback);
if(!ev_timer_exist(kkSystemSetUpEvent)) {
kkSystemSetUpEvent = TL_ZB_TIMER_SCHEDULE(kkSystemSetUpEventHandler, NULL, 20); #if Z30_DEVICE_OTA_ENABLE
} kOTAMoudleInit(kOTAMoudleUserCallback, LED_ALL_ID);
//start radar detect event #endif
kRadarDetectInit(); #if Z30_DEVICE_AGING_ENABLE
kFactoryTestInit(kUserFactorTestPollCallback, g_factoryTestConfList, sizeof(g_factoryTestConfList)/ sizeof(FactoryTestConfSt));
kZclClusterPermitReportTableInit(cluster_obj_list, sizeof(cluster_obj_list) / sizeof(BindObjSt)); #endif
//注册属性改变回调 // init the private cluster protocol module.
//ClusterAttributeChangeCallbackRegister(g_ClusterAttributeConfList,sizeof(g_ClusterAttributeConfList)/sizeof(AttributeChangeConfSt)); err = kOptTunnelModuleInit(kUserOODMessageIncoming);
//重写attribute if( err != KET_OK ) {
Update_Local_Attribute_Info(); iKonkeAfSelfPrint("Err: kUserOODMessageIncoming Register Failed(%d)!!\r\n", err);
}
} // //注册属性改变回调
ikkAttributeChangeCallbackRegister(attribte_change_list,sizeof(attribte_change_list)/sizeof(attribte_change_list[0]));
void Test(void ) kZclOnOffClusterServerInit(kUserOnOffClusterOnOffStatusCallback);
{ if(!ev_timer_exist(kkSystemSetUpEvent)) {
kkSystemSetUpEvent = TL_ZB_TIMER_SCHEDULE(kkSystemSetUpEventHandler, NULL, 50);
} }
//start radar detect event
static bool kClustePeriodReportCheckIsSet(uint8_t endpoint) kRadarDetectInit();
{
uint16_t u16MinTimeMS = 0; kZclClusterPermitReportTableInit(cluster_obj_list, sizeof(cluster_obj_list) / sizeof(BindObjSt));
uint16_t u16MaxTimeMS = 0;
if (endpoint <= Support_Endpoint_Num){ }
bool status = kkClusterGetReportingPeriod(endpoint,ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, &u16MinTimeMS, &u16MaxTimeMS);
if (status == true){ void Test(void )
if (u16MaxTimeMS > 0){ {
return true;
} }
} void kUserNetworkExitCompleteCallback()
} {
return false;
} SYSTEM_RESET();
}
void JoinCompleteCallback(NwkJoinCompltEnum nwkcomplt ) static bool kClustePeriodReportCheckIsSet(uint8_t endpoint)
{ {
iKonkeAfSelfPrint("#########JoinCompleteCallback = %d\r\n", nwkcomplt); uint16_t u16MinTimeMS = 0;
switch(nwkcomplt) { uint16_t u16MaxTimeMS = 0;
case (EJC_JOIN_FAILED ): if (endpoint <= Support_Endpoint_Num){
{ bool status = kkClusterGetReportingPeriod(endpoint,ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, &u16MinTimeMS, &u16MaxTimeMS);
LED_OPT_OFF(LED_ALL_ID); if (status == true){
kUserNetworkExitCompleteCallback(); if (u16MaxTimeMS > 0){
break; return true;
} }
case (EJC_JOIN_SUCCEED): }
{ }
return false;
break; }
}
default: break; void JoinCompleteCallback(NwkJoinCompltEnum nwkcomplt )
} {
} iKonkeAfSelfPrint("#########JoinCompleteCallback = %d\r\n", nwkcomplt);
void kUserNetworkStatusNotify(NwkStatusEnum nwkst ) switch(nwkcomplt) {
{ case (EJC_JOIN_FAILED ):
iKonkeAfSelfPrint("#############################kUserNetworkStatusNotify = %d\r\n", nwkst); {
switch(nwkst) { LED_OPT_OFF(LED_ALL_ID);
case (ENS_ONLINE ): break;
{ }
uint32_t randTimeMS = DELAY_REPORT_DATA_AFTER_NWK_JOINED_MS; case (EJC_JOIN_SUCCEED):
//power on after joined network {
uint32_t currentTimeMS = clock_time();
if ( currentTimeMS < MIN_JOINED_NWK_DELAY_TIME_MS){ break;
randTimeMS = kGetRandNum(RAND_MIN_NUM, RAND_MAX_NUM); }
}else { default: break;
// kPwmOptTrigger(PWM4_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000); }
// kPwmOptTrigger(PWM3_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000); }
// kPwmOptTrigger(PWM2_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000);
// kPwmOptTrigger(PWM1_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000); void kUserNetworkStatusNotify(NwkStatusEnum nwkst )
//kLedOptTrigger(LED_ALL_ID, 0, 0, 0, LED_OFF, LED_IGNORE); {
} iKonkeAfSelfPrint("#############################kUserNetworkStatusNotify = %d\r\n", nwkst);
if (kIsKonkeRemoteGateway() != true){ switch(nwkst) {
g_bIsNotKonkeGatewayFirstReportedFlg = false; case (ENS_ONLINE ):
} {
kSetLedStatus(LED_ALL_ID); uint32_t randTimeMS = DELAY_REPORT_DATA_AFTER_NWK_JOINED_MS;
kNwkScheduleTaskRegister(randTimeMS); //power on after joined network
iKonkeAfSelfPrint("Joined Network RandTime(%dms) CurrentTime(%ld)\r\n", randTimeMS, currentTimeMS); uint32_t currentTimeMS = clock_time()/16/1000;
break; kSetLedStatus(LED_ALL_ID);
}
case (ENS_JOINING): if ( currentTimeMS < MIN_JOINED_NWK_DELAY_TIME_MS){
{ randTimeMS = kGetRandNum(RAND_MIN_NUM, RAND_MAX_NUM);
kLedOptTrigger(LED_ALL_ID, LED_SLOW_BLINK_ON_TIME_MS, LED_SLOW_BLINK_OFF_TIME_MS, \ }else {
LED_SLOW_BLINK_CONTINUE_TIME_MS/(LED_SLOW_BLINK_ON_TIME_MS+LED_SLOW_BLINK_OFF_TIME_MS), LED_ON, LED_IGNORE); kPwmOptTrigger(PWM4_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000);
break; kPwmOptTrigger(PWM3_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000);
} kPwmOptTrigger(PWM2_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000);
case (ENS_LEAVED): kPwmOptTrigger(PWM1_ID, PWM_TIMER_MAX_DUTY_CYCLE_NUM, 0, 5*1000);
{ //kLedOptTrigger(LED_ALL_ID, 0, 0, 0, LED_OFF, LED_IGNORE);
iKonkeAfSelfPrint("#####Enter Leave\r\n"); }
kLedOptTrigger((uint8_t)LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS \ if (kIsKonkeRemoteGateway() != true){
,LED_FAST_BLINK_CONTINUE_TIME_MS/(LED_FAST_BLINK_ON_TIME_MS+LED_FAST_BLINK_ON_TIME_MS), LED_ON, LED_IGNORE); g_bIsNotKonkeGatewayFirstReportedFlg = false;
//关闭勿扰模式 }
kSetIndicatorNotDisturbModeFlg(false);
kNwkScheduleTaskRegister(randTimeMS);
break; iKonkeAfSelfPrint("Joined Network RandTime(%dms) CurrentTime(%d)\r\n", randTimeMS, currentTimeMS);
} break;
default: }
{ case (ENS_JOINING):
break; {
} kLedOptTrigger(LED_ALL_ID, LED_SLOW_BLINK_ON_TIME_MS, LED_SLOW_BLINK_OFF_TIME_MS, \
} LED_SLOW_BLINK_CONTINUE_TIME_MS/(LED_SLOW_BLINK_ON_TIME_MS+LED_SLOW_BLINK_OFF_TIME_MS), LED_ON, LED_IGNORE);
} break;
//on off 属性改变后的回调函数,一般用来操作继电器,过零检测,如果没有过零检测可以在这里同步LED状态 }
void kUserOnOffClusterOnOffStatusCallback(uint8_t endpoint, OnOffStatusEnum estatus ) case (ENS_LEAVED):
{ {
iKonkeAfSelfPrint("OnOff-status: endpoint(%d), estatus(%d)\r\n", endpoint, estatus); iKonkeAfSelfPrint("#####Enter Leave\r\n");
kRadarLedTragger(); kLedOptTrigger((uint8_t)LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS \
switch(endpoint) { ,LED_FAST_BLINK_CONTINUE_TIME_MS/(LED_FAST_BLINK_ON_TIME_MS+LED_FAST_BLINK_ON_TIME_MS), LED_ON, LED_IGNORE);
case (1): //关闭勿扰模式
{ kSetIndicatorNotDisturbModeFlg(false);
if(estatus == EOOS_OFF)
LED_OPT_OFF(LED1_ID); break;
else }
LED_OPT_ON(LED1_ID); default:
kRelayChannelOpt(RELAY_CHANNEL1_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON); {
break; break;
} }
case (2): }
{ }
if(estatus == EOOS_OFF)
LED_OPT_OFF(LED2_ID); void pOnOffAttributeChangeCallback(uint8_t endpoint,uint16_t cluster,uint16_t attribute,uint8_t *data,uint8_t data_type)
else {
LED_OPT_ON(LED2_ID); if((cluster == ZCL_CLUSTER_GEN_ON_OFF)&&(attribute == ZCL_ATTRID_ONOFF)&&(data_type == ZCL_DATA_TYPE_BOOLEAN))
kRelayChannelOpt(RELAY_CHANNEL2_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON); {
break; OnOffStatusEnum estatus = *data;
} kUserOnOffClusterOnOffStatusCallback(endpoint,estatus);
case (3): iKonkeAfSelfPrint("#####pOnOffAttributeChangeCallback,endpont = %d,value = %d\r\n",endpoint,estatus);
{ }
if(estatus == EOOS_OFF) }
LED_OPT_OFF(LED3_ID); //on off 属性改变后的回调函数,一般用来操作继电器,过零检测,如果没有过零检测可以在这里同步LED状态
else void kUserOnOffClusterOnOffStatusCallback(uint8_t endpoint, OnOffStatusEnum estatus )
LED_OPT_ON(LED3_ID); {
kRelayChannelOpt(RELAY_CHANNEL3_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON); iKonkeAfSelfPrint("OnOff-status: endpoint(%d), estatus(%d)\r\n", endpoint, estatus);
break; kRadarLedTragger();
} switch(endpoint) {
case (4): case (1):
{ {
if(estatus == EOOS_OFF) kRelayChannelOpt(RELAY_CHANNEL1_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON);
LED_OPT_OFF(LED4_ID); break;
else }
LED_OPT_ON(LED4_ID); case (2):
kRelayChannelOpt(RELAY_CHANNEL4_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON); {
break; kRelayChannelOpt(RELAY_CHANNEL2_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON);
} break;
default: break; }
} case (3):
kZclOnOffClusterServerOnOffControl(endpoint, estatus); {
kRelayChannelOpt(RELAY_CHANNEL3_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON);
} break;
void kUserButtonAcitonCallback(unsigned char button_id, BtnActionEnum action ) }
{ case (4):
iKonkeAfSelfPrint("kUserButton: ButtonId(%d), Action(%d)\r\n", button_id, action); {
if ( kGetFactoryTestStatus() == FTS_AGING_8HOU || kGetFactoryTestStatus() == FTS_AGING_DONE \ kRelayChannelOpt(RELAY_CHANNEL4_ID,estatus == EOOS_OFF? EZAO_OFF : EZAO_ON);
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \ break;
|| kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS \ }
|| kNwkIsExiting() == true){ default: break;
//未老化完成,单击按键不操作继电器 }
return; kZclOnOffClusterServerOnOffControl(endpoint, estatus);
}
switch(button_id) }
{
case KEY_SYS_ID: //sys botton uint8_t Key_Press_Test_Flag[5] = {0};
{ void kUserButtonAcitonCallback(unsigned char button_id, BtnActionEnum action )
switch(action) {
{ iKonkeAfSelfPrint("kUserButton: ButtonId(%d), Action(%d),%d\r\n", button_id, action,kGetFactoryTestStatus());
case EBA_CLICK: if ( kGetFactoryTestStatus() == FTS_AGING_4HOU || kGetFactoryTestStatus() == FTS_AGING_DONE \
{ || kGetFactoryTestStatus() == FTS_AGING_WAITING \
if(kNwkGetCurrentStatus() == ENS_ONLINE) || kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS \
kLedOptTrigger(LED_ALL_ID,200,200,1,LED_OFF,LED_IGNORE); //绿灯闪烁一次 || kNwkIsExiting() == true){
else if(kNwkGetCurrentStatus() == ENS_LEAVED) //未老化完成,单击按键不操作继电器
{ return;
kNwkFactoryReset(false); }
kNwkJoiningStart(NWK_STEERING_TIMEOUT_MS,JoinCompleteCallback); //开启组网 switch(button_id)
} {
} case KEY_SYS_ID: //sys botton
break; {
case EBA_LONGPRESS: switch(action)
{ {
if(kNwkGetCurrentStatus() == ENS_ONLINE) case EBA_CLICK:
{ {
kNwkFactoryReset(true); Key_Press_Test_Flag[0] = 1;
iKonkeAfSelfPrint("Start Leave...........\r\n"); if( kNwkGetCurrentStatus() == ENS_ONLINE ) { // report connected!
}
} if (kLedIsBlinking(LED_ALL_ID) != true)
break; kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 1, LED_ON, LED_OFF);
default: kOptTunnelOODReport(0, 0XCD, NULL, 0);
break; }
} else if(kNwkGetCurrentStatus() == ENS_LEAVED)
break; {
} kNwkFactoryReset(false);
case KEY1_ID: kNwkJoiningStart(NWK_STEERING_TIMEOUT_MS,JoinCompleteCallback); //开启组网
{ }
if(action == EBA_CLICK) }
{ break;
iKonkeAfSelfPrint("KEY 1 PRESS!!!\r\n"); case EBA_LONGPRESS:
OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(1)? EOOC_OFF : EOOC_ON; {
kZclClusterSetPermitReportInfo(1,0x0006,true,false); if(kNwkGetCurrentStatus() == ENS_ONLINE)
kZclOnOffClusterServerOnOffControl(1, state); {
kRelayChannelOpt(RELAY_CHANNEL1_ID,kZclOnOffClusterServerOnOffGet(1)? EZAO_ON : EZAO_OFF); kNwkFactoryReset(true);
// iKonkeAfSelfPrint("Get onoff (%d),%d\r\n", pOnOff->onOff, pOnOff->startUpOnOff); iKonkeAfSelfPrint("Start Leave...........\r\n");
}else if (action == EBA_LONGPRESS){ }
if (kNwkIsExiting() == true){ }
iKonkeAfSelfPrint("#####NWK is exiting\r\n"); break;
return; default:
} break;
}
static bool firstLongPressFlg = false; break;
if (kNwkGetCurrentStatus() == ENS_ONLINE){ }
static uint32_t lastTimeMS = 0; case KEY1_ID:
uint32_t currentTimeMS = clock_time(); {
if (firstLongPressFlg != true \ if(action == EBA_CLICK)
|| (currentTimeMS - lastTimeMS >= MAX_FIRST_USER_KEY_LEAVE_NWK_INTERVAL_TIME_MS)){ {
firstLongPressFlg = true; iKonkeAfSelfPrint("KEY 1 PRESS!!!\r\n");
lastTimeMS = currentTimeMS; Key_Press_Test_Flag[1] = 1;
if ( kGetOTAStatus() == OTA_NORMAL){ OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(1)? EOOC_OFF : EOOC_ON;
kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 1, LED_ON, LED_OFF); kZclClusterSetPermitReportInfo(1,0x0006,true,false);
} //afTest_dataSendDemo();
}else { kZclOnOffClusterServerOnOffControl(1, state);
//second times long press }else if (action == EBA_LONGPRESS){
if (currentTimeMS - lastTimeMS < MAX_FIRST_USER_KEY_LEAVE_NWK_INTERVAL_TIME_MS){ if (kNwkIsExiting() == true){
//关闭黄色LED iKonkeAfSelfPrint("#####NWK is exiting\r\n");
// LED_OPT_OFF(LED_SYS_ID); return;
//leave nwk }
if (kNwkGetCurrentStatus() != ENS_JOINING){
kNwkFactoryReset(true); static bool firstLongPressFlg = false;
} if (kNwkGetCurrentStatus() == ENS_ONLINE){
} static uint32_t lastTimeMS = 0;
firstLongPressFlg = false; uint32_t currentTimeMS = clock_time()/16/1000;
} if (firstLongPressFlg != true \
}else if (kNwkGetCurrentStatus() == ENS_LEAVED){ || (currentTimeMS - lastTimeMS >= MAX_FIRST_USER_KEY_LEAVE_NWK_INTERVAL_TIME_MS)){
//开始组网 firstLongPressFlg = true;
kNwkFactoryReset(false); lastTimeMS = currentTimeMS;
//steering timeout can be set if ( kGetOTAStatus() == OTA_NORMAL){
iKonkeAfSelfPrint("#####Start Steering\r\n"); kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 1, LED_ON, LED_OFF);
kNwkJoiningStart(NWK_STEERING_TIMEOUT_MS, JoinCompleteCallback); }
} }else {
} //second times long press
break; if (currentTimeMS - lastTimeMS < MAX_FIRST_USER_KEY_LEAVE_NWK_INTERVAL_TIME_MS){
} //关闭黄色LED
case (KEY2_ID): // LED_OPT_OFF(LED_SYS_ID);
{ //leave nwk
if (action == EBA_CLICK){ if (kNwkGetCurrentStatus() != ENS_JOINING){
//restore report attribute immediately kNwkFactoryReset(true);
iKonkeAfSelfPrint("KEY 2 PRESS!!!\r\n"); }
OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(2)? EOOC_OFF : EOOC_ON; }
kZclClusterSetPermitReportInfo(2,0x0006,true,false); firstLongPressFlg = false;
kZclOnOffClusterServerOnOffControl(2, state); }
kRelayChannelOpt(RELAY_CHANNEL2_ID,kZclOnOffClusterServerOnOffGet(2)? EZAO_ON : EZAO_OFF); }else if (kNwkGetCurrentStatus() == ENS_LEAVED){
} //开始组网
break; kNwkFactoryReset(false);
} //steering timeout can be set
case (KEY3_ID): iKonkeAfSelfPrint("#####Start Steering\r\n");
{ kNwkJoiningStart(NWK_STEERING_TIMEOUT_MS, JoinCompleteCallback);
if (action == EBA_CLICK){ }
//restore report attribute immediately }
iKonkeAfSelfPrint("KEY 3 PRESS!!!\r\n"); break;
OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(3)? EOOC_OFF : EOOC_ON; }
kZclClusterSetPermitReportInfo(3,0x0006,true,false); case (KEY2_ID):
kZclOnOffClusterServerOnOffControl(3, state); {
kRelayChannelOpt(RELAY_CHANNEL3_ID,kZclOnOffClusterServerOnOffGet(3)? EZAO_ON : EZAO_OFF); if (action == EBA_CLICK){
} //restore report attribute immediately
break; iKonkeAfSelfPrint("KEY 2 PRESS!!!\r\n");
} Key_Press_Test_Flag[2] = 1;
case (KEY4_ID): OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(2)? EOOC_OFF : EOOC_ON;
{ kZclClusterSetPermitReportInfo(2,0x0006,true,false);
if (action == EBA_CLICK){ kZclOnOffClusterServerOnOffControl(2, state);
//restore report attribute immediately }
iKonkeAfSelfPrint("KEY 4 PRESS!!!\r\n"); break;
OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(4)? EOOC_OFF : EOOC_ON; }
kZclClusterSetPermitReportInfo(4,0x0006,true,false); case (KEY3_ID):
kZclOnOffClusterServerOnOffControl(4, state); {
kRelayChannelOpt(RELAY_CHANNEL4_ID,kZclOnOffClusterServerOnOffGet(4)? EZAO_ON : EZAO_OFF); if (action == EBA_CLICK){
} //restore report attribute immediately
break; iKonkeAfSelfPrint("KEY 3 PRESS!!!\r\n");
} Key_Press_Test_Flag[3] = 1;
default: OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(3)? EOOC_OFF : EOOC_ON;
break; kZclClusterSetPermitReportInfo(3,0x0006,true,false);
} kZclOnOffClusterServerOnOffControl(3, state);
} }
//过零检测后继电器操作完成,同步LED状态,不是过零操作继电器也是到这里操作LED break;
void kUserRelayLedCallback(RelayStatusSt status) }
{ case (KEY4_ID):
iKonkeAfSelfPrint("#########kUserZaLedCallback channel(%d) opt(%d)\r\n", status.u8RelayChannelId, status.opt); {
if (action == EBA_CLICK){
if (/*kPwmIsChanging(PWM1_ID) == true ||*/ kLedIsBlinking(LED_ALL_ID) == true \ //restore report attribute immediately
|| kNwkGetCurrentStatus() == ENS_JOINING) iKonkeAfSelfPrint("KEY 4 PRESS!!!\r\n");
{ Key_Press_Test_Flag[4] = 1;
return; OnOffCtrlEnum state = kZclOnOffClusterServerOnOffGet(4)? EOOC_OFF : EOOC_ON;
} kZclClusterSetPermitReportInfo(4,0x0006,true,false);
kZclOnOffClusterServerOnOffControl(4, state);
switch (status.u8RelayChannelId) }
{ break;
case RELAY_CHANNEL1_ID: }
if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[0] == true \ default:
|| kGetFactoryTestStatus() == FTS_AGING_8HOU \ break;
|| kGetFactoryTestStatus() == FTS_AGING_DONE \ }
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \ }
|| kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){ //过零检测后继电器操作完成,同步LED状态,不是过零操作继电器也是到这里操作LED
power_on_sync[0] = false; void kUserRelayLedCallback(RelayStatusSt status)
if (status.opt == EZAO_OFF){ {
kLEDOffAction(LED1_ID); iKonkeAfSelfPrint("#########kUserZaLedCallback channel(%d) opt(%d)\r\n", status.u8RelayChannelId, status.opt);
}else if (status.opt == EZAO_ON){
kLEDOnAction(LED1_ID); if (/*kPwmIsChanging(PWM1_ID) == true ||*/ kLedIsBlinking(LED_ALL_ID) == true \
} || kNwkGetCurrentStatus() == ENS_JOINING)
}else if (kNwkGetCurrentStatus() == ENS_LEAVED \ {
|| kNwkGetCurrentStatus() == ENS_OFFLINE){ return;
kLedOptTrigger(LED1_ID, LED_FAST_BLINK_ON_TIME_MS, \ }
LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_IGNORE);
} switch (status.u8RelayChannelId)
break; {
case RELAY_CHANNEL2_ID: case RELAY_CHANNEL1_ID:
if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[1] == true \ if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[0] == true \
|| kGetFactoryTestStatus() == FTS_AGING_8HOU \ || kGetFactoryTestStatus() == FTS_AGING_4HOU \
|| kGetFactoryTestStatus() == FTS_AGING_DONE \ || kGetFactoryTestStatus() == FTS_AGING_DONE \
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \ || kGetFactoryTestStatus() == FTS_AGING_WAITING \
|| kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){ || kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){
power_on_sync[1] = false; power_on_sync[0] = false;
if (status.opt == EZAO_OFF){ if (status.opt == EZAO_OFF){
kLEDOffAction(LED2_ID); kLEDOffAction(LED1_ID);
}else if (status.opt == EZAO_ON){ }else if (status.opt == EZAO_ON){
kLEDOnAction(LED2_ID); kLEDOnAction(LED1_ID);
} }
}else if (kNwkGetCurrentStatus() == ENS_LEAVED \ }else if (kNwkGetCurrentStatus() == ENS_LEAVED \
|| kNwkGetCurrentStatus() == ENS_OFFLINE){ || kNwkGetCurrentStatus() == ENS_OFFLINE){
kLedOptTrigger(LED2_ID, LED_FAST_BLINK_ON_TIME_MS, \ if(kZclOnOffClusterServerOnOffGet(1)== EOOC_OFF)
LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_IGNORE); kLedOptTrigger(LED1_ID, LED_FAST_BLINK_ON_TIME_MS, \
} LED_FAST_BLINK_OFF_TIME_MS, 3, EOOC_OFF, EOOC_OFF);
break; else
case RELAY_CHANNEL3_ID: kLedOptTrigger(LED1_ID, LED_FAST_BLINK_ON_TIME_MS, \
if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[2] == true \ LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_ON);
|| kGetFactoryTestStatus() == FTS_AGING_8HOU \ }
|| kGetFactoryTestStatus() == FTS_AGING_DONE \ break;
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \ case RELAY_CHANNEL2_ID:
|| kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){ if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[1] == true \
power_on_sync[2] = false; || kGetFactoryTestStatus() == FTS_AGING_4HOU \
if (status.opt == EZAO_OFF){ || kGetFactoryTestStatus() == FTS_AGING_DONE \
kLEDOffAction(LED3_ID); || kGetFactoryTestStatus() == FTS_AGING_WAITING \
}else if (status.opt == EZAO_ON){ || kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){
kLEDOnAction(LED3_ID); power_on_sync[1] = false;
} if (status.opt == EZAO_OFF){
}else if (kNwkGetCurrentStatus() == ENS_LEAVED \ kLEDOffAction(LED2_ID);
|| kNwkGetCurrentStatus() == ENS_OFFLINE){ }else if (status.opt == EZAO_ON){
kLedOptTrigger(LED3_ID, LED_FAST_BLINK_ON_TIME_MS, \ kLEDOnAction(LED2_ID);
LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_IGNORE); }
} }else if (kNwkGetCurrentStatus() == ENS_LEAVED \
break; || kNwkGetCurrentStatus() == ENS_OFFLINE){
case RELAY_CHANNEL4_ID: if(kZclOnOffClusterServerOnOffGet(2)== EOOC_OFF)
if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[3] == true \ kLedOptTrigger(LED2_ID, LED_FAST_BLINK_ON_TIME_MS, \
|| kGetFactoryTestStatus() == FTS_AGING_8HOU \ LED_FAST_BLINK_OFF_TIME_MS, 3, EOOC_OFF, EOOC_OFF);
|| kGetFactoryTestStatus() == FTS_AGING_DONE \ else
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \ kLedOptTrigger(LED2_ID, LED_FAST_BLINK_ON_TIME_MS, \
|| kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){ LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_ON);
power_on_sync[3] = false; }
if (status.opt == EZAO_OFF){ break;
kLEDOffAction(LED4_ID); case RELAY_CHANNEL3_ID:
}else if (status.opt == EZAO_ON){ if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[2] == true \
kLEDOnAction(LED4_ID); || kGetFactoryTestStatus() == FTS_AGING_4HOU \
} || kGetFactoryTestStatus() == FTS_AGING_DONE \
}else if (kNwkGetCurrentStatus() == ENS_LEAVED \ || kGetFactoryTestStatus() == FTS_AGING_WAITING \
|| kNwkGetCurrentStatus() == ENS_OFFLINE){ || kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){
kLedOptTrigger(LED4_ID, LED_FAST_BLINK_ON_TIME_MS, \ power_on_sync[2] = false;
LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_IGNORE); if (status.opt == EZAO_OFF){
} kLEDOffAction(LED3_ID);
break; }else if (status.opt == EZAO_ON){
kLEDOnAction(LED3_ID);
default: }
iKonkeAfSelfPrint("###Erro: Relay Channel is invalid\r\n"); }else if (kNwkGetCurrentStatus() == ENS_LEAVED \
break; || kNwkGetCurrentStatus() == ENS_OFFLINE){
} if(kZclOnOffClusterServerOnOffGet(3)== EOOC_OFF)
} kLedOptTrigger(LED3_ID, LED_FAST_BLINK_ON_TIME_MS, \
//ota升级失败或入网成功和失败后LED闪烁完成后处理,需要根据不同产品来修改 LED_FAST_BLINK_OFF_TIME_MS, 3, EOOC_OFF, EOOC_OFF);
static void kSetLedStatus(LED_ID_ENUM id) else
{ kLedOptTrigger(LED3_ID, LED_FAST_BLINK_ON_TIME_MS, \
//恢复继电器的LED状态 LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_ON);
if (id == LED_ALL_ID) }
{ break;
kLedOptTrigger(LED_ALL_ID, 0, 0, 0, LED_OFF, LED_IGNORE); case RELAY_CHANNEL4_ID:
for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){ if (kNwkGetCurrentStatus() == ENS_ONLINE || power_on_sync[3] == true \
if (kLedIsBlinking(GET_LED_ID_BY_ENDPOINT(i, Support_Endpoint_Num)) == false){ || kGetFactoryTestStatus() == FTS_AGING_4HOU \
if ((kZclOnOffClusterServerOnOffGet(i) == EOOS_ON)&&(!kGetIndicatorNotDisturbModeFlg())){ || kGetFactoryTestStatus() == FTS_AGING_DONE \
kLEDOnAction(GET_LED_ID_BY_ENDPOINT(i, Support_Endpoint_Num)); || kGetFactoryTestStatus() == FTS_AGING_WAITING \
}else { || kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){
kLEDOffAction(GET_LED_ID_BY_ENDPOINT(i, Support_Endpoint_Num)); power_on_sync[3] = false;
} if (status.opt == EZAO_OFF){
} kLEDOffAction(LED4_ID);
} }else if (status.opt == EZAO_ON){
}else if (id == LED1_ID || id == LED2_ID || id == LED3_ID || id == LED4_ID){ kLEDOnAction(LED4_ID);
if (kLedIsBlinking(id) == false){ }
if ((kZclOnOffClusterServerOnOffGet(GET_ENDPOINT(id)) == EOOS_ON)&&(!kGetIndicatorNotDisturbModeFlg())){ }else if (kNwkGetCurrentStatus() == ENS_LEAVED \
kLEDOnAction(id); || kNwkGetCurrentStatus() == ENS_OFFLINE){
}else { if(kZclOnOffClusterServerOnOffGet(4)== EOOC_OFF)
kLEDOffAction(id); kLedOptTrigger(LED4_ID, LED_FAST_BLINK_ON_TIME_MS, \
} LED_FAST_BLINK_OFF_TIME_MS, 3, EOOC_OFF, EOOC_OFF);
} else
} kLedOptTrigger(LED4_ID, LED_FAST_BLINK_ON_TIME_MS, \
} LED_FAST_BLINK_OFF_TIME_MS, 3, LED_ON, LED_ON);
//固定事件,目前用于心跳上报 }
s32 kUserScheduleTaskHandler(void *arg) break;
{
iKonkeAfSelfPrint("##########kUserScheduleTaskHandlerCallback!!\r\n"); default:
if (kIsKonkeRemoteGateway() == true){ iKonkeAfSelfPrint("###Erro: Relay Channel is invalid\r\n");
kOptTunnelCommonReport(ECA_OPTDATA); break;
return HEARTBEAT_TIME_MS; }
}else { }
if (cluster_obj_list[0].cluster != CLUSTER_UNKNOW){ //add by zbw
if (cluster_obj_list[0].cluster == ZCL_CLUSTER_GEN_POWER_CFG){ void kUserPwmActionDoneCallback(unsigned char id, PwmGradientDirectionEnum opt)
//kBatteryMonitorReadADC(true); {
}else { switch(id)
//add by maozj 20200512 report on off status {
if ((g_bIsNotKonkeGatewayFirstReportedFlg )&& kClustePeriodReportCheckIsSet(g_u8CurrentHeartEndpoint)== true){ case PWM1_ID:
//网关设置过report interval,使用SDK的report kSetLedStatus(LED1_ID);
//kNwkScheduleTaskStop(SCHEDULE_ALLOPT_ID); break;
}else { case PWM2_ID:
kOptTunnelReportingPlagiarizeOriginal(g_u8CurrentHeartEndpoint, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF); kSetLedStatus(LED2_ID);
} break;
} case PWM3_ID:
} kSetLedStatus(LED3_ID);
g_u8CurrentHeartEndpoint++; break;
if (g_u8CurrentHeartEndpoint > Support_Endpoint_Num){ case PWM4_ID:
g_bIsNotKonkeGatewayFirstReportedFlg = true; kSetLedStatus(LED4_ID);
g_u8CurrentHeartEndpoint = 1; break;
//repeat overwrite heartbeat report time default:
return HEARTBEAT_TIME_MS; break;
}else { }
return 1000;
} }
} //ota升级失败或入网成功和失败后LED闪烁完成后处理,需要根据不同产品来修改
static void kSetLedStatus(LED_ID_ENUM id)
return HEARTBEAT_TIME_MS; {
} if (id != LED_ALL_ID){
//LED闪烁完成,可以用来恢复继电器的LED状态 kPwmClearGradientCounterById(id - 1);
void kUserLedActionDoneCallback(unsigned char id) }else{
{ kPwmClearGradientCounterById(PWM1_ID);
iKonkeAfSelfPrint("##############kUserLedActionDoneCallback id(%d)nwk(%d)##################\r\n", id,kNwkGetCurrentStatus()); kPwmClearGradientCounterById(PWM2_ID);
kSetLedStatus(id); kPwmClearGradientCounterById(PWM3_ID);
} kPwmClearGradientCounterById(PWM4_ID);
void kUserPwmActionDoneCallback(unsigned char id, PwmGradientDirectionEnum opt) }
{ //恢复继电器的LED状态
iKonkeAfSelfPrint("####kUserPwmActionDoneCallback id(%d)opt(%d)##################\r\n", id,opt); if (id == LED_ALL_ID)
{
} kLedOptTrigger(LED_ALL_ID, 0, 0, 0, LED_OFF, LED_IGNORE);
//网关场景控制下发后的属性延时上报处理,可以根据不同场景cluster修改 for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){
/* DESP: recall scene rand delay report Attribute set if (kLedIsBlinking(GET_LED_ID_BY_ENDPOINT(i, Support_Endpoint_Num)) == false){
* Auth: maozj.20191224. if ((kZclOnOffClusterServerOnOffGet(i) == EOOS_ON)&&(!kGetIndicatorNotDisturbModeFlg())){
* */ kLEDOnAction(GET_LED_ID_BY_ENDPOINT(i, Support_Endpoint_Num));
void kZclClusterRecallSceneCallback(uint8_t endpoint, uint16_t cluster, uint8_t command_id, bool reportEnable, bool sceneRecallFlg) }else {
{ kLEDOffAction(GET_LED_ID_BY_ENDPOINT(i, Support_Endpoint_Num));
iKonkeAfSelfPrint("####kZclClusterRecallSceneCallback ep(%d)cluster(%d)command_id(%d),reportEnable(%d),sceneRecallFlg(%d)\r\n"); }
if((cluster == ZCL_CLUSTER_GEN_ON_OFF)&&(command_id == ZCL_CMD_SCENE_RECALL_SCENE)) }
{ }
kZclClusterSetPermitReportInfo(endpoint,ZCL_CLUSTER_GEN_ON_OFF,false,true); }else if (id == LED1_ID || id == LED2_ID || id == LED3_ID || id == LED4_ID){
} iKonkeAfSelfPrint("###kSetLedStatus:%d,%d,%d\r\n",kLedIsBlinking(id),kZclOnOffClusterServerOnOffGet(GET_ENDPOINT(id)),kGetIndicatorNotDisturbModeFlg());
} if (kLedIsBlinking(id) == false){
if ((kZclOnOffClusterServerOnOffGet(GET_ENDPOINT(id)) == EOOS_ON)&&(!kGetIndicatorNotDisturbModeFlg())){
kLEDOnAction(id);
static ev_timer_event_t *kEndpoint1DelayReport = NULL; }else {
static ev_timer_event_t *kEndpoint2DelayReport = NULL; kLEDOffAction(id);
static ev_timer_event_t *kEndpoint3DelayReport = NULL; }
static ev_timer_event_t *kEndpoint4DelayReport = NULL; }
static s32 kEndpoint1DelayReportAttrEventHandler(void *arg) }
{ }
iKonkeAfSelfPrint("######kEndpoint1DelayReportAttrEventHandler\r\n" ); //固定事件,目前用于心跳上报
kZclClusterSetPermitReportInfo(1, ZCL_CLUSTER_GEN_ON_OFF, true, false); s32 kUserScheduleTaskHandler(void *arg)
kOptTunnelReportingPlagiarizeOriginal(1, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF); {
return -1; iKonkeAfSelfPrint("##########kUserScheduleTaskHandlerCallback!!\r\n");
} if (kIsKonkeRemoteGateway() == true){
static s32 kEndpoint2DelayReportAttrEventHandler(void *arg) kOptTunnelCommonReport(ECA_OPTDATA);
{ return HEARTBEAT_TIME_MS;
iKonkeAfSelfPrint("######kEndpoint2DelayReportAttrEventHandler\r\n" ); }else {
kZclClusterSetPermitReportInfo(2, ZCL_CLUSTER_GEN_ON_OFF, true, false); if (cluster_obj_list[0].cluster != CLUSTER_UNKNOW){
kOptTunnelReportingPlagiarizeOriginal(2, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF); if (cluster_obj_list[0].cluster == ZCL_CLUSTER_GEN_POWER_CFG){
return -1; //kBatteryMonitorReadADC(true);
} }else {
static s32 kEndpoint3DelayReportAttrEventHandler(void *arg) //add by maozj 20200512 report on off status
{ if ((g_bIsNotKonkeGatewayFirstReportedFlg )&& kClustePeriodReportCheckIsSet(g_u8CurrentHeartEndpoint)== true){
iKonkeAfSelfPrint("######kEndpoint3DelayReportAttrEventHandler\r\n" ); //网关设置过report interval,使用SDK的report
kZclClusterSetPermitReportInfo(3, ZCL_CLUSTER_GEN_ON_OFF, true, false); //kNwkScheduleTaskStop(SCHEDULE_ALLOPT_ID);
kOptTunnelReportingPlagiarizeOriginal(3, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF); }else {
return -1; kOptTunnelReportingPlagiarizeOriginal(g_u8CurrentHeartEndpoint, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF);
} }
static s32 kEndpoint4DelayReportAttrEventHandler(void *arg) }
{ }
iKonkeAfSelfPrint("######kEndpoint4DelayReportAttrEventHandler\r\n" ); g_u8CurrentHeartEndpoint++;
kZclClusterSetPermitReportInfo(4, ZCL_CLUSTER_GEN_ON_OFF, true, false); if (g_u8CurrentHeartEndpoint > Support_Endpoint_Num){
kOptTunnelReportingPlagiarizeOriginal(4, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF); g_bIsNotKonkeGatewayFirstReportedFlg = true;
return -1; g_u8CurrentHeartEndpoint = 1;
} //repeat overwrite heartbeat report time
//网关场景控制下发后的属性延时上报处理,可以根据不同场景cluster修改 return HEARTBEAT_TIME_MS;
/* DESP: recall scene rand delay report Attribute set }else {
* Auth: maozj.20191224. return 1000;
* */ }
bool kZclClusterReportChangeCallback(uint8_t endpoint, uint16_t clusterId, uint16_t attributeId) }
{
ZclReportTableSt zclReportInfo; return HEARTBEAT_TIME_MS;
bool status = kZclClusterGetPermitReportInfo(endpoint,clusterId,&zclReportInfo); }
iKonkeAfSelfPrint("######kZclClusterReportChangeCallback status(%d)ep(%d)enable(%d)scene(%d)\r\n", //LED闪烁完成,可以用来恢复继电器的LED状态
status, endpoint, zclReportInfo.reportEnable, zclReportInfo.sceneRecallFlg ); void kUserLedActionDoneCallback(unsigned char id)
if (status == true){ {
if (zclReportInfo.reportEnable != true && zclReportInfo.sceneRecallFlg == true){ iKonkeAfSelfPrint("##############kUserLedActionDoneCallback id(%d)nwk(%d)##################\r\n", id,kNwkGetCurrentStatus());
uint32_t randDelayTimeMS = kGetRandNum(REPORT_ATTR_MIN_RAND_NUM, REPORT_ATTR_MAX_RAND_NUM); kSetLedStatus(id);
if (endpoint == 1){ }
if(!ev_timer_exist(kEndpoint1DelayReport)) { //网关场景控制下发后的属性延时上报处理,可以根据不同场景cluster修改
kEndpoint1DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint1DelayReportAttrEventHandler, NULL, randDelayTimeMS); /* DESP: recall scene rand delay report Attribute set
} * Auth: maozj.20191224.
}else if (endpoint == 2){ * */
if(!ev_timer_exist(kEndpoint2DelayReport)) { void kZclClusterRecallSceneCallback(uint8_t endpoint, uint16_t cluster, uint8_t command_id, bool reportEnable, bool sceneRecallFlg)
kEndpoint2DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint2DelayReportAttrEventHandler, NULL, randDelayTimeMS); {
} iKonkeAfSelfPrint("####kZclClusterRecallSceneCallback ep(%d)cluster(%d)command_id(%d),reportEnable(%d),sceneRecallFlg(%d)\r\n");
}else if (endpoint == 3){ if((cluster == ZCL_CLUSTER_GEN_ON_OFF)&&(command_id == ZCL_CMD_SCENE_RECALL_SCENE))
if(!ev_timer_exist(kEndpoint3DelayReport)) { {
kEndpoint3DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint3DelayReportAttrEventHandler, NULL, randDelayTimeMS); kZclClusterSetPermitReportInfo(endpoint,ZCL_CLUSTER_GEN_ON_OFF,false,true);
} }
} }
else if (endpoint == 4){
if(!ev_timer_exist(kEndpoint4DelayReport)) {
kEndpoint3DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint4DelayReportAttrEventHandler, NULL, randDelayTimeMS); static ev_timer_event_t *kEndpoint1DelayReport = NULL;
} static ev_timer_event_t *kEndpoint2DelayReport = NULL;
} static ev_timer_event_t *kEndpoint3DelayReport = NULL;
//有多控绑定发给其它子设备, 不发给网关 static ev_timer_event_t *kEndpoint4DelayReport = NULL;
// if( kZclNodeIsBindNotGatewayIeeeAddress(endpoint, ZCL_ON_OFF_CLUSTER_ID) == true) { static s32 kEndpoint1DelayReportAttrEventHandler(void *arg)
// iKonkeAfSelfPrint("Multi Control\r\n"); {
// kZclClusterSetPermitReportInfo(endpoint, true, false, false, true); iKonkeAfSelfPrint("######kEndpoint1DelayReportAttrEventHandler\r\n" );
// kOptTunnelReportingPlagiarizeOriginal(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER); kZclClusterSetPermitReportInfo(1, ZCL_CLUSTER_GEN_ON_OFF, true, false);
// //kZclClusterConditionallySendReport(endpoint, ZCL_ON_OFF_CLUSTER_ID, false, true); kOptTunnelReportingPlagiarizeOriginal(1, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF);
// } return -1;
//不直接上报,随机延时上报 }
return false; static s32 kEndpoint2DelayReportAttrEventHandler(void *arg)
} {
} iKonkeAfSelfPrint("######kEndpoint2DelayReportAttrEventHandler\r\n" );
kZclClusterSetPermitReportInfo(2, ZCL_CLUSTER_GEN_ON_OFF, true, false);
kOptTunnelReportingPlagiarizeOriginal(2, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF);
return true; return -1;
} }
kk_err_t kUserOODMessageIncoming(uint8_t channel, uint8_t opcode, uint8_t args_in_out[], uint8_t *length_in_out ) static s32 kEndpoint3DelayReportAttrEventHandler(void *arg)
{ {
if( NULL == args_in_out || NULL == length_in_out ) { iKonkeAfSelfPrint("######kEndpoint3DelayReportAttrEventHandler\r\n" );
return KET_ERR_INVALID_POINTER; kZclClusterSetPermitReportInfo(3, ZCL_CLUSTER_GEN_ON_OFF, true, false);
} kOptTunnelReportingPlagiarizeOriginal(3, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF);
return -1;
iKonkeAfSelfPrint("OOD-INCOMING: channel(%d), opcode(%x)--\r\n", channel, opcode); }
for(int index = 0; index < *length_in_out; ++index ) { static s32 kEndpoint4DelayReportAttrEventHandler(void *arg)
iKonkeAfSelfPrint("%x ", args_in_out[index]); {
} iKonkeAfSelfPrint("######kEndpoint4DelayReportAttrEventHandler\r\n" );
iKonkeAfSelfPrint("--------------------------------------\r\n"); kZclClusterSetPermitReportInfo(4, ZCL_CLUSTER_GEN_ON_OFF, true, false);
kOptTunnelReportingPlagiarizeOriginal(4, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF);
switch(opcode) { return -1;
case (0x00): // get the device snap. }
{ //网关场景控制下发后的属性延时上报处理,可以根据不同场景cluster修改
args_in_out[0] = 0x00; /* DESP: recall scene rand delay report Attribute set
args_in_out[1] = kZclOnOffClusterServerOnOffGet(1); * Auth: maozj.20191224.
args_in_out[2] = kZclOnOffClusterServerOnOffGet(2); * */
args_in_out[3] = kZclOnOffClusterServerOnOffGet(3); bool kZclClusterReportChangeCallback(uint8_t endpoint, uint16_t clusterId, uint16_t attributeId)
args_in_out[4] = kZclOnOffClusterServerOnOffGet(4); {
args_in_out[5] = kGetIndicatorNotDisturbModeFlg(); ZclReportTableSt zclReportInfo;
iKonkeAfSelfPrint("OOOOOOPCODE: 1(%d), 2(%d), 3(%d),4(%d),5(%d)\r\n", args_in_out[1], args_in_out[2], args_in_out[3],args_in_out[4],args_in_out[5]); bool status = kZclClusterGetPermitReportInfo(endpoint,clusterId,&zclReportInfo);
*length_in_out = 6; iKonkeAfSelfPrint("######kZclClusterReportChangeCallback status(%d)ep(%d)enable(%d)scene(%d)\r\n",
break; status, endpoint, zclReportInfo.reportEnable, zclReportInfo.sceneRecallFlg );
} if (status == true){
case (0xFE): if (zclReportInfo.reportEnable != true && zclReportInfo.sceneRecallFlg == true){
{ uint32_t randDelayTimeMS = kGetRandNum(REPORT_ATTR_MIN_RAND_NUM, REPORT_ATTR_MAX_RAND_NUM);
//set disturb mode if (endpoint == 1){
uint8_t mode = args_in_out[0]; if(!ev_timer_exist(kEndpoint1DelayReport)) {
if (mode != 0x00 && mode != 0x01){ kEndpoint1DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint1DelayReportAttrEventHandler, NULL, randDelayTimeMS);
args_in_out[0] = ERR_NO_COMMAND_FORMAT; }
}else { }else if (endpoint == 2){
//存储勿扰标志 if(!ev_timer_exist(kEndpoint2DelayReport)) {
kSetIndicatorNotDisturbModeFlg(mode); kEndpoint2DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint2DelayReportAttrEventHandler, NULL, randDelayTimeMS);
////State Sync//// }
if (kLedIsBlinking(LED_ALL_ID) != true) { }else if (endpoint == 3){
kSetLedStatus(LED_ALL_ID); if(!ev_timer_exist(kEndpoint3DelayReport)) {
} kEndpoint3DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint3DelayReportAttrEventHandler, NULL, randDelayTimeMS);
args_in_out[0] = ERR_NO_NONE; }
} }
iKonkeAfSelfPrint("Disturb Mode(%d)\r\n", mode); else if (endpoint == 4){
args_in_out[1] = mode; if(!ev_timer_exist(kEndpoint4DelayReport)) {
*length_in_out = 2; kEndpoint3DelayReport = TL_ZB_TIMER_SCHEDULE(kEndpoint4DelayReportAttrEventHandler, NULL, randDelayTimeMS);
break; }
} }
case (0xFF): //有多控绑定发给其它子设备, 不发给网关
{ // if( kZclNodeIsBindNotGatewayIeeeAddress(endpoint, ZCL_ON_OFF_CLUSTER_ID) == true) {
uint8_t permitJoinTimeS = args_in_out[0]; //unit:s // iKonkeAfSelfPrint("Multi Control\r\n");
iKonkeAfSelfPrint("###Opcode is channel(%d) JoinPermitTime(0x%X)!!\r\n",channel, permitJoinTimeS); // kZclClusterSetPermitReportInfo(endpoint, true, false, false, true);
//路由协同组网,黄灯闪烁(OTA升级)时不协同组网闪灯 // kOptTunnelReportingPlagiarizeOriginal(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER);
if (kLedIsBlinking(LED_ALL_ID) != true // //kZclClusterConditionallySendReport(endpoint, ZCL_ON_OFF_CLUSTER_ID, false, true);
&& permitJoinTimeS != 0 // }
&& kNwkGetCurrentStatus() != ENS_JOINING){ //不直接上报,随机延时上报
iKonkeAfSelfPrint("####LED Blink\r\n"); return false;
kLedOptTrigger(LED_ALL_ID, LED_SLOW_BLINK_ON_TIME_MS, LED_SLOW_BLINK_OFF_TIME_MS, }
permitJoinTimeS * 1000/(LED_SLOW_BLINK_ON_TIME_MS+LED_SLOW_BLINK_OFF_TIME_MS), LED_ON, LED_OFF); else if(!zclReportInfo.reportEnable)
}else if (kLedIsBlinking(LED2_ID) == true {
&& permitJoinTimeS == 0 return false;
&& kNwkGetCurrentStatus() != ENS_JOINING){ }
kLedOptTrigger(LED_ALL_ID, 0, 0, 0, LED_OFF, LED_IGNORE); }
// kLEDOffAction(LED_ALL_ID);
kSetLedStatus(LED_ALL_ID);
} return true;
return KET_NO_RESPONSE; }
} kk_err_t kUserOODMessageIncoming(uint8_t channel, uint8_t opcode, uint8_t args_in_out[], uint8_t *length_in_out )
{
default: { if( NULL == args_in_out || NULL == length_in_out ) {
iKonkeAfSelfPrint("Err: opcode is not exist(%d:%X)!!\r\n", channel, opcode); return KET_ERR_INVALID_POINTER;
args_in_out[0] = ERR_NO_OPCODE; }
*length_in_out = 1;
break; iKonkeAfSelfPrint("OOD-INCOMING: channel(%d), opcode(%x)--\r\n", channel, opcode);
} for(int index = 0; index < *length_in_out; ++index ) {
} iKonkeAfSelfPrint("%x ", args_in_out[index]);
}
return KET_OK; iKonkeAfSelfPrint("--------------------------------------\r\n");
}
switch(opcode) {
case (0x00): // get the device snap.
static void kLEDOffAction(LED_ID_ENUM led_id) {
{ args_in_out[0] = 0x00;
iKonkeAfSelfPrint("LED_Off_Action LED_ID (%d).\r\n", led_id); args_in_out[1] = kZclOnOffClusterServerOnOffGet(1);
LED_OPT_OFF(led_id); args_in_out[2] = kZclOnOffClusterServerOnOffGet(2);
} args_in_out[3] = kZclOnOffClusterServerOnOffGet(3);
args_in_out[4] = kZclOnOffClusterServerOnOffGet(4);
static void kLEDOnAction(LED_ID_ENUM led_id) args_in_out[5] = kGetIndicatorNotDisturbModeFlg();
{ iKonkeAfSelfPrint("OOOOOOPCODE: 1(%d), 2(%d), 3(%d),4(%d),5(%d)\r\n", args_in_out[1], args_in_out[2], args_in_out[3],args_in_out[4],args_in_out[5]);
iKonkeAfSelfPrint("LED_ON_Action LED_ID (%d).\r\n", led_id); *length_in_out = 6;
LED_OPT_ON(led_id); break;
} }
//芯片上电后延时操作事件,一般处理继电器状态恢复或者禁用SWD口作为普通IO,也用来根据gpio读取电平修改同一类型的不同型号 case (0xFE):
/* DESP: system setup delay callback handler, called once. {
* Auth: dingmz_frc.20190628. //set disturb mode
* */ uint8_t mode = args_in_out[0];
s32 kkSystemSetUpEventHandler(void *arg ) if (mode != 0x00 && mode != 0x01){
{ args_in_out[0] = ERR_NO_COMMAND_FORMAT;
bool relayStatusBuffer[Support_Endpoint_Num] = {false, false,false,false}; }else {
nv_sts_t st = zcl_onOffAttr_get(); //存储勿扰标志
kSetIndicatorNotDisturbModeFlg(mode);
for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){ ////State Sync////
if(st == NV_SUCC) if (kLedIsBlinking(LED_ALL_ID) != true) {
{ kSetLedStatus(LED_ALL_ID);
relayStatusBuffer[i-1] = g_zcl_onOffAttrs[i-1].onOff; }
} args_in_out[0] = ERR_NO_NONE;
power_on_sync[i - 1] = true; }
iKonkeAfSelfPrint("###########EP(%d), status(%d)\r\n", i, relayStatusBuffer[i-1]); iKonkeAfSelfPrint("Disturb Mode(%d)\r\n", mode);
kZclClusterSetPermitReportInfo(i,CLUSTER_ONOFF_ID, false, false); args_in_out[1] = mode;
kZclOnOffClusterServerOnOffSet(i,relayStatusBuffer[i-1]); *length_in_out = 2;
kZclClusterSetPermitReportInfo(i,CLUSTER_ONOFF_ID, false, false); break;
}
kRelayChannelOpt(i == 1?RELAY_CHANNEL1_ID:(i == 2?RELAY_CHANNEL2_ID:(i == 3?RELAY_CHANNEL3_ID:RELAY_CHANNEL4_ID)) \ case (0xFF):
,relayStatusBuffer[i-1] == false? EZAO_OFF : EZAO_ON); {
uint8_t permitJoinTimeS = args_in_out[0]; //unit:s
} iKonkeAfSelfPrint("###Opcode is channel(%d) JoinPermitTime(0x%X)!!\r\n",channel, permitJoinTimeS);
return -1; //路由协同组网,黄灯闪烁(OTA升级)时不协同组网闪灯
} if (kLedIsBlinking(LED_ALL_ID) != true
&& permitJoinTimeS != 0
&& kNwkGetCurrentStatus() != ENS_JOINING){
//退网5S快闪结束后的回调函数,一般用于面板、插座和窗帘面板退网完成后在全部关闭时复位 iKonkeAfSelfPrint("####LED Blink\r\n");
void kUserNetworkExitCompleteCallback(void) kLedOptTrigger(LED_ALL_ID, LED_SLOW_BLINK_ON_TIME_MS, LED_SLOW_BLINK_OFF_TIME_MS,
{ permitJoinTimeS * 1000/(LED_SLOW_BLINK_ON_TIME_MS+LED_SLOW_BLINK_OFF_TIME_MS), LED_ON, LED_OFF);
iKonkeAfSelfPrint("##############kUserNetworkExitCompleteCallback(%d)##################\r\n"); }else if (kLedIsBlinking(LED2_ID) == true
bool bIsAllOffFlg = true; && permitJoinTimeS == 0
for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){ && kNwkGetCurrentStatus() != ENS_JOINING){
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(i); kLedOptTrigger(LED_ALL_ID, 0, 0, 0, LED_OFF, LED_IGNORE);
if (pOnOff->onOff){ // kLEDOffAction(LED_ALL_ID);
bIsAllOffFlg = false; kSetLedStatus(LED_ALL_ID);
break; }
} return KET_NO_RESPONSE;
} }
if (bIsAllOffFlg == true){
SYSTEM_RESET(); default: {
} iKonkeAfSelfPrint("Err: opcode is not exist(%d:%X)!!\r\n", channel, opcode);
} args_in_out[0] = ERR_NO_OPCODE;
*length_in_out = 1;
#if Z30_DEVICE_AGING_ENABLE break;
//老化的轮询回调函数,一般用于实现老化期间的LED闪烁或继电器翻转,也可以只LED闪烁 }
void kUserFactorTestPollCallback(FactoryTestStatusEnum status) }
{
iKonkeAfSelfPrint("##############kUserFactorTestPollCallback status(%d)##################\r\n", status); return KET_OK;
static RelayOptEnum eRelayStatus = EZAO_OFF; }
switch(status)
{
case FTS_NORMAL: static void kLEDOffAction(LED_ID_ENUM led_id)
break; {
case FTS_START: iKonkeAfSelfPrint("LED_Off_Action LED_ID (%d).\r\n", led_id);
//没有老化完需先都清除网络 kLedOptTrigger(led_id, 0, 0, 0, LED_OFF, LED_IGNORE);
break; if (kGetIndicatorNotDisturbModeFlg() == false){
case FTS_AGING_15MIN: iKonkeAfSelfPrint("is not NotDisturbMode.\r\n");
break; switch (led_id)
case FTS_AGING_8HOU_START: {
//关闭所有的蓝色LED,有可能之前蓝灯闪烁了 case LED1_ID:
LED_OPT_OFF(LED_ALL_ID); {
LED_OPT_OFF(LED_RADAR_ID); kPwmDriverhandler(kPwmGetIndexByID(PWM1_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100) );
//同步所有的LED和继电器 break;
for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){ }
kRelayChannelOpt(g_ucRelayIdBuff[i-1], EZAO_OFF); case LED2_ID:
} {
eRelayStatus = EZAO_ON; kPwmDriverhandler(kPwmGetIndexByID(PWM2_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100) );
break; break;
case FTS_AGING_8HOU: }
//翻转继电器,LED也会同步 case LED3_ID:
eRelayStatus = eRelayStatus == EZAO_ON?EZAO_OFF:EZAO_ON; {
if (eRelayStatus == EZAO_ON){ kPwmDriverhandler(kPwmGetIndexByID(PWM3_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100));
LED_OPT_ON(LED_RADAR_ID); break;
}else{ }
LED_OPT_OFF(LED_RADAR_ID); case LED4_ID:
} {
for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){ kPwmDriverhandler(kPwmGetIndexByID(PWM4_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100));
kRelayChannelOpt(g_ucRelayIdBuff[i-1], eRelayStatus); break;
} }
break; case LED_ALL_ID:
case FTS_AGING_DONE: {
//老化结束后,打开所有的LED和继电器 kPwmDriverhandler(kPwmGetIndexByID(PWM1_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100));
LED_OPT_ON(LED_RADAR_ID); kPwmDriverhandler(kPwmGetIndexByID(PWM2_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100));
for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){ kPwmDriverhandler(kPwmGetIndexByID(PWM3_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100));
kRelayChannelOpt(g_ucRelayIdBuff[i-1], EZAO_ON); kPwmDriverhandler(kPwmGetIndexByID(PWM4_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMinLevel * 65535) / 100));
} break;
eRelayStatus = EZAO_ON; }
//如果有单独系统LED也需要都点亮 default:
// LED_OPT_ON(LED_SYS_ID); break;
break; }
case FTS_AGING_FORCE_EXIT: }
iKonkeAfSelfPrint("############## FactoryTestSatus is FTS_AGING_FORCE_EXIT\r\n"); }
//按键强制退老化,快闪
kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, BLINK_DEAD, LED_ON, LED_IGNORE); static void kLEDOnAction(LED_ID_ENUM led_id)
break; {
case FTS_AGING_WAITING: iKonkeAfSelfPrint("LED_ON_Action LED_ID (%d).\r\n", led_id);
break; kLedOptTrigger(led_id, 0, 0, 0, LED_OFF, LED_IGNORE);
case FTS_AGING_FIRST_LONG_PRESSED: if (kGetIndicatorNotDisturbModeFlg() == false){
//快闪一次,指示第一次长按有效 iKonkeAfSelfPrint("is not NotDisturbMode.\r\n");
kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 1, LED_ON, LED_IGNORE); switch (led_id)
break; {
case FTS_AGING_FORCE_REBOOT: case LED1_ID:
SYSTEM_RESET(); {
break; kPwmDriverhandler(kPwmGetIndexByID(PWM1_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
default: break;
iKonkeAfSelfPrint("##############Erro: FactoryTestSatus is not exist\r\n"); }
break; case LED2_ID:
} {
} kPwmDriverhandler(kPwmGetIndexByID(PWM2_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
#endif break;
}
#if Z30_DEVICE_OTA_ENABLE case LED3_ID:
//如果初始化OTA增加callback这里处理,否则使用ota模块的默认callback,就不在这里 {
void kOTAMoudleUserCallback(OTAStatusEnum status) kPwmDriverhandler(kPwmGetIndexByID(PWM3_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
{ break;
#if 0 }
static bool flg = false; //防止网关断电后,ota失败后会间隔快闪 case LED4_ID:
iKonkeAfSelfPrint("##############kOTAMoudleUserCallback status(%d)##################\r\n", status); {
switch(status) kPwmDriverhandler(kPwmGetIndexByID(PWM4_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
{ break;
case OTA_NORMAL: }
break; case LED_ALL_ID:
case OTA_START: {
//关闭所有蓝色LED kPwmDriverhandler(kPwmGetIndexByID(PWM1_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
// LED_OPT_OFF(LED_ALL_ID); kPwmDriverhandler(kPwmGetIndexByID(PWM2_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
kLedOptTrigger(LED_ALL_ID, 2 * LED_FAST_BLINK_ON_TIME_MS, 14 * LED_FAST_BLINK_ON_TIME_MS,\ kPwmDriverhandler(kPwmGetIndexByID(PWM3_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
OTA_UPGRADE__CONTINUE_MAX_TIME_MS /(2 * LED_FAST_BLINK_ON_TIME_MS + 14 * LED_FAST_BLINK_ON_TIME_MS), LED_ON, LED_ON); kPwmDriverhandler(kPwmGetIndexByID(PWM4_ID), ELP_ANY, (uint16_t)(((uint32_t)g_u8NoDisturbModeMaxLevel * 65535) / 100) );
kSetOTAStatus(OTA_START); break;
flg = false; }
break; default:
case OTA_DOWNLOAD_DONE: break;
{ }
uint8_t buffer[] = {"Konke download disable watchdog.....\r\n"}; }
//不能注释掉, 不然无法禁用看门狗,导致第二次连续升级卡死,认为这里是相当于加了延时 }
emberSerialWriteData((uint8_t)APP_SERIAL, buffer, strlen((char *)buffer)); //芯片上电后延时操作事件,一般处理继电器状态恢复或者禁用SWD口作为普通IO,也用来根据gpio读取电平修改同一类型的不同型号
halInternalDisableWatchDog(MICRO_DISABLE_WATCH_DOG_KEY);//add by maozj 20190308文件快下载好后禁用看门狗 /* DESP: system setup delay callback handler, called once.
kSetOTAStatus(OTA_DOWNLOAD_DONE); * Auth: dingmz_frc.20190628.
break; * */
} s32 kkSystemSetUpEventHandler(void *arg )
case OTA_VERITY_SUCCEED: {
{ bool relayStatusBuffer[Support_Endpoint_Num] = {false, false,false,false};
//校验成功,记录继电器状态,需要复位后恢复继电器状态 nv_sts_t st = zcl_onOffAttr_get();
//saveRelayStatusWhenOtaSucceed(relayTotalNum);
//uint8_t relayStatus = 1; for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){
//halCommonSetToken(TOKEN_OTA_RELAY_STATUS, &relayStatus); if(st == NV_SUCC)
//常亮5S {
kLedOptTrigger(LED_ALL_ID, 25 * LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_ON_TIME_MS, 1, LED_ON, LED_ON); relayStatusBuffer[i-1] = g_zcl_onOffAttrs[i-1].onOff;
kSetOTAStatus(OTA_NORMAL); }
break; power_on_sync[i - 1] = true;
} iKonkeAfSelfPrint("###########EP(%d), status(%d)\r\n", i, relayStatusBuffer[i-1]);
case OTA_FAILED: kZclClusterSetPermitReportInfo(i,CLUSTER_ONOFF_ID, false, false);
{ kZclOnOffClusterServerOnOffSet(i,relayStatusBuffer[i-1]);
if (flg != true){ kZclClusterSetPermitReportInfo(i,CLUSTER_ONOFF_ID, false, false);
halInternalWatchDogEnabled(); //使能看门狗
emberAfOtaStorageClearTempDataCallback(); kRelayChannelOpt(i == 1?RELAY_CHANNEL1_ID:(i == 2?RELAY_CHANNEL2_ID:(i == 3?RELAY_CHANNEL3_ID:RELAY_CHANNEL4_ID)) \
kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_ON_TIME_MS,\ ,relayStatusBuffer[i-1] == false? EZAO_OFF : EZAO_ON);
LED_FAST_BLINK_CONTINUE_TIME_MS /(LED_FAST_BLINK_ON_TIME_MS + LED_FAST_BLINK_ON_TIME_MS), LED_ON, LED_ON);
kSetOTAStatus(OTA_NORMAL); }
//uint8_t status = 0; //重写attribute
//halCommonSetToken(TOKEN_OTA_RELAY_STATUS, &status); Update_Local_Attribute_Info();
//emAfOtaClientStop(); //刚加上, 未测试,防止网关断电后,一直request 5分钟 #if UART_ENABLE
} kInterPanMoudleInit(kUserInterPanMsgInComingPaser);
flg = true; #endif
break; return -1;
} }
default:
iKonkeAfSelfPrint("##############Err: OTA status is not exist\r\n"); #if Z30_DEVICE_AGING_ENABLE
break; //老化的轮询回调函数,一般用于实现老化期间的LED闪烁或继电器翻转,也可以只LED闪烁
} void kUserFactorTestPollCallback(FactoryTestStatusEnum status)
{
#endif iKonkeAfSelfPrint("##############kUserFactorTestPollCallback status(%d)##################\r\n", status);
} static RelayOptEnum eRelayStatus = EZAO_OFF;
#endif switch(status)
static ev_timer_event_t *kRadarCheckEventControl = NULL; {
static ev_timer_event_t *kRadarControlLedEvent = NULL; case FTS_NORMAL:
break;
case FTS_START:
s32 kRadarCheckEventHandler(void *arg) //没有老化完需先都清除网络
{ break;
if (kGetFactoryTestStatus() == FTS_AGING_8HOU \ case FTS_AGING_15MIN:
|| kGetFactoryTestStatus() == FTS_AGING_DONE \ break;
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \ case FTS_AGING_4HOU_START:
|| kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){ //关闭所有的蓝色LED,有可能之前蓝灯闪烁了
return 0; LED_OPT_OFF(LED_ALL_ID);
} LED_OPT_OFF(LED_RADAR_ID);
//同步所有的LED和继电器
static uint8_t Radar_count = 0; for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){
if (gpio_read(RADAR_PIN)){ kRelayChannelOpt(g_ucRelayIdBuff[i-1], EZAO_OFF);
Radar_count ++; }
}else{ eRelayStatus = EZAO_ON;
Radar_count = 0; break;
} case FTS_AGING_4HOU:
//翻转继电器,LED也会同步
if (Radar_count >= 2){ eRelayStatus = eRelayStatus == EZAO_ON?EZAO_OFF:EZAO_ON;
// iKonkeAfSelfPrint("Radar Action.\r\n"); if (eRelayStatus == EZAO_ON){
Human_body_induction_flag = true; LED_OPT_ON(LED_RADAR_ID);
Radar_count = 0; }else{
kRadarLedTragger(); LED_OPT_OFF(LED_RADAR_ID);
} }
return 0; for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){
} kRelayChannelOpt(g_ucRelayIdBuff[i-1], eRelayStatus);
}
s32 kRadarLedEventHandler(void *arg) break;
{ case FTS_AGING_DONE:
if (kGetFactoryTestStatus() == FTS_AGING_8HOU \ //老化结束后,打开所有的LED和继电器
|| kGetFactoryTestStatus() == FTS_AGING_DONE \ LED_OPT_ON(LED_RADAR_ID);
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \ for (uint8_t i = 1; i <= Support_Endpoint_Num; i++){
|| kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){ kRelayChannelOpt(g_ucRelayIdBuff[i-1], EZAO_ON);
return 0; }
} eRelayStatus = EZAO_ON;
//如果有单独系统LED也需要都点亮
bool OnOffFlag = false; // LED_OPT_ON(LED_SYS_ID);
break;
OnOffFlag |= kZclOnOffClusterServerOnOffGet(1) == EOOS_ON?true:false; case FTS_AGING_FORCE_EXIT:
//iKonkeAfSelfPrint("OnOffFlag by endpoint1 : (%d).\r\n",OnOffFlag); iKonkeAfSelfPrint("############## FactoryTestSatus is FTS_AGING_FORCE_EXIT\r\n");
OnOffFlag |= kZclOnOffClusterServerOnOffGet(2) == EOOS_ON?true:false; //按键强制退老化,快闪
//iKonkeAfSelfPrint("OnOffFlag by endpoint2 : (%d).\r\n",OnOffFlag); kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, BLINK_DEAD, LED_ON, LED_IGNORE);
OnOffFlag |= kZclOnOffClusterServerOnOffGet(3) == EOOS_ON?true:false; break;
//iKonkeAfSelfPrint("OnOffFlag by endpoint3 : (%d).\r\n",OnOffFlag); case FTS_AGING_WAITING:
OnOffFlag |= kZclOnOffClusterServerOnOffGet(4) == EOOS_ON?true:false; break;
//iKonkeAfSelfPrint("OnOffFlag by endpoint4 : (%d).\r\n",OnOffFlag); case FTS_AGING_FIRST_LONG_PRESSED:
//快闪一次,指示第一次长按有效
if (OnOffFlag == true){ kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_OFF_TIME_MS, 1, LED_ON, LED_IGNORE);
kLedOptTrigger(LED_RADAR_ID, 0, 0, 0, LED_ON, LED_IGNORE); break;
Human_body_induction_flag = false; case FTS_AGING_FORCE_REBOOT:
}else if (Human_body_induction_flag == true){ SYSTEM_RESET();
kLedOptTrigger(LED_RADAR_ID, RADAR_ON_TIME_MS, 0, 1, LED_ON, LED_OFF); break;
Human_body_induction_flag = false; default:
}else{ iKonkeAfSelfPrint("##############Erro: FactoryTestSatus is not exist\r\n");
kLedOptTrigger(LED_RADAR_ID, RADAR_ON_TIME_MS, 0, 1, LED_ON, LED_OFF); break;
} }
return -1; }
} #endif
void kRadarDetectInit(void)
{ #if Z30_DEVICE_OTA_ENABLE
if(!ev_timer_exist(kRadarCheckEventControl)) { //如果初始化OTA增加callback这里处理,否则使用ota模块的默认callback,就不在这里
kRadarCheckEventControl = TL_ZB_TIMER_SCHEDULE(kRadarCheckEventHandler, NULL, 100); void kOTAMoudleUserCallback(OTAStatusEnum status)
} {
GPIO_INPUT_SET(RADAR_PIN,PM_PIN_UP_DOWN_FLOAT); #if 0
} static bool flg = false; //防止网关断电后,ota失败后会间隔快闪
void kRadarLedTragger(void) iKonkeAfSelfPrint("##############kOTAMoudleUserCallback status(%d)##################\r\n", status);
{ switch(status)
if(!ev_timer_exist(kRadarControlLedEvent)){ {
TL_ZB_TIMER_CANCEL(&kRadarControlLedEvent); case OTA_NORMAL:
} break;
kRadarControlLedEvent = TL_ZB_TIMER_SCHEDULE(kRadarLedEventHandler, NULL, 1); case OTA_START:
//关闭所有蓝色LED
} // LED_OPT_OFF(LED_ALL_ID);
kLedOptTrigger(LED_ALL_ID, 2 * LED_FAST_BLINK_ON_TIME_MS, 14 * LED_FAST_BLINK_ON_TIME_MS,\
#if UART_ENABLE OTA_UPGRADE__CONTINUE_MAX_TIME_MS /(2 * LED_FAST_BLINK_ON_TIME_MS + 14 * LED_FAST_BLINK_ON_TIME_MS), LED_ON, LED_ON);
uint8_t uart_send(void) kSetOTAStatus(OTA_START);
{ flg = false;
UMsgNodeSt MsgNode; break;
uint8_t i = 0; case OTA_DOWNLOAD_DONE:
memset(&MsgNode,0,sizeof(UMsgNodeSt)); {
MsgNode.buffer[i++] = 0xAA; uint8_t buffer[] = {"Konke download disable watchdog.....\r\n"};
MsgNode.buffer[i++] = 0X55; //不能注释掉, 不然无法禁用看门狗,导致第二次连续升级卡死,认为这里是相当于加了延时
MsgNode.buffer[i++] = 0X05; emberSerialWriteData((uint8_t)APP_SERIAL, buffer, strlen((char *)buffer));
MsgNode.buffer[i++] = 0x01; halInternalDisableWatchDog(MICRO_DISABLE_WATCH_DOG_KEY);//add by maozj 20190308文件快下载好后禁用看门狗
MsgNode.buffer[i++] = 0X02; kSetOTAStatus(OTA_DOWNLOAD_DONE);
MsgNode.buffer[i++] = 0X03; break;
MsgNode.buffer[i++] = 0X04; }
MsgNode.buffer[i++] = 0X05; case OTA_VERITY_SUCCEED:
{
//校验成功,记录继电器状态,需要复位后恢复继电器状态
uint16_t crc = check_sum(&MsgNode.buffer[0], MsgNode.buffer[2]+3); //saveRelayStatusWhenOtaSucceed(relayTotalNum);
MsgNode.buffer[i++] = crc>>8; //uint8_t relayStatus = 1;
MsgNode.buffer[i++] = crc; //halCommonSetToken(TOKEN_OTA_RELAY_STATUS, &relayStatus);
MsgNode.length = i; //常亮5S
kLedOptTrigger(LED_ALL_ID, 25 * LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_ON_TIME_MS, 1, LED_ON, LED_ON);
// setting for matcher content. kSetOTAStatus(OTA_NORMAL);
break;
MsgNode.matcher[0] = 0XAA; }
MsgNode.matcher[0] = 0X55; case OTA_FAILED:
MsgNode.matcher_offset = 4; {
MsgNode.matcher_n = 2; if (flg != true){
halInternalWatchDogEnabled(); //使能看门狗
MsgNode.sent_try = 3; emberAfOtaStorageClearTempDataCallback();
kLedOptTrigger(LED_ALL_ID, LED_FAST_BLINK_ON_TIME_MS, LED_FAST_BLINK_ON_TIME_MS,\
return kUartMsgSent(&MsgNode); LED_FAST_BLINK_CONTINUE_TIME_MS /(LED_FAST_BLINK_ON_TIME_MS + LED_FAST_BLINK_ON_TIME_MS), LED_ON, LED_ON);
} kSetOTAStatus(OTA_NORMAL);
void UartMsgProcessHandle(UMsgNodeSt *pMsgNode ) //uint8_t status = 0;
{ //halCommonSetToken(TOKEN_OTA_RELAY_STATUS, &status);
if( NULL == pMsgNode ) { //emAfOtaClientStop(); //刚加上, 未测试,防止网关断电后,一直request 5分钟
return ; }
} flg = true;
break;
#if 1 // Just for debug }
iKonkeAfSelfPrint("\r\nUartMsgProcessHandle,MSG INCOMING[%d]:\r\n", pMsgNode->length); default:
iKonkeAfSelfPrintBuffer(pMsgNode->buffer, pMsgNode->length); iKonkeAfSelfPrint("##############Err: OTA status is not exist\r\n");
iKonkeAfSelfPrint("\r\n--------------------\r\n"); break;
#endif }
}
uint16_t check_sum( uint8_t* msg, uint8_t len) #endif
{ }
uint16_t crc = 0xFFFF; #endif
uint16_t i, j = 0; static ev_timer_event_t *kRadarCheckEventControl = NULL;
static ev_timer_event_t *kRadarControlLedEvent = NULL;
for (i = 0; i < len; i++)
{
for (j = 0; j < 8; j++) s32 kRadarCheckEventHandler(void *arg)
{ {
uint8_t c15 = (uint8_t)((crc >> 15 & 1) == 1); if (kGetFactoryTestStatus() == FTS_AGING_4HOU \
uint8_t bit = (uint8_t)((msg[i] >> (7 - j) & 1) == 1); || kGetFactoryTestStatus() == FTS_AGING_DONE \
|| kGetFactoryTestStatus() == FTS_AGING_WAITING \
crc <<= 1; || kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){
return 0;
if (c15 ^ bit) }
{
crc ^= 0x1021; static uint8_t Radar_count = 0;
} if (gpio_read(RADAR_PIN)){
} Radar_count ++;
} }else{
return crc; Radar_count = 0;
} }
bool MsgCRC16(uint8_t *pdat, int length )
{ if (Radar_count >= 2){
uint16_t crc_data = 0; // iKonkeAfSelfPrint("Radar Action.\r\n");
uint8_t CRC_H = 0; Human_body_induction_flag = true;
uint8_t CRC_L = 0; Radar_count = 0;
kRadarLedTragger();
if((NULL == pdat) || (length < 9)){ }
return false; return 0;
} }
crc_data = check_sum(&pdat[3], pdat[2]);
CRC_H = (crc_data>>8) & 0xff; s32 kRadarLedEventHandler(void *arg)
CRC_L = crc_data & 0xff; {
iKonkeAfSelfPrint("\r\nMsgCRC16,%d,%d\r\n",CRC_H,CRC_L); if (kGetFactoryTestStatus() == FTS_AGING_4HOU \
if((pdat[length - 1] == CRC_L) && (pdat[length - 2]== CRC_H)) || kGetFactoryTestStatus() == FTS_AGING_DONE \
{ || kGetFactoryTestStatus() == FTS_AGING_WAITING \
return true; || kGetFactoryTestStatus() == FTS_AGING_WAITING_SECOND_PRESS){
} return 0;
}
return false;
} bool OnOffFlag = false;
#endif
OnOffFlag |= kZclOnOffClusterServerOnOffGet(1) == EOOS_ON?true:false;
//iKonkeAfSelfPrint("OnOffFlag by endpoint1 : (%d).\r\n",OnOffFlag);
OnOffFlag |= kZclOnOffClusterServerOnOffGet(2) == EOOS_ON?true:false;
//iKonkeAfSelfPrint("OnOffFlag by endpoint2 : (%d).\r\n",OnOffFlag);
OnOffFlag |= kZclOnOffClusterServerOnOffGet(3) == EOOS_ON?true:false;
//iKonkeAfSelfPrint("OnOffFlag by endpoint3 : (%d).\r\n",OnOffFlag);
OnOffFlag |= kZclOnOffClusterServerOnOffGet(4) == EOOS_ON?true:false;
//iKonkeAfSelfPrint("OnOffFlag by endpoint4 : (%d).\r\n",OnOffFlag);
if (OnOffFlag == true){
kLedOptTrigger(LED_RADAR_ID, 0, 0, 0, LED_ON, LED_IGNORE);
Human_body_induction_flag = false;
}else if (Human_body_induction_flag == true){
kLedOptTrigger(LED_RADAR_ID, RADAR_ON_TIME_MS, 0, 1, LED_ON, LED_OFF);
Human_body_induction_flag = false;
}else{
kLedOptTrigger(LED_RADAR_ID, RADAR_ON_TIME_MS, 0, 1, LED_ON, LED_OFF);
}
return -1;
}
void kRadarDetectInit(void)
{
if(!ev_timer_exist(kRadarCheckEventControl)) {
kRadarCheckEventControl = TL_ZB_TIMER_SCHEDULE(kRadarCheckEventHandler, NULL, 100);
}
GPIO_INPUT_SET(RADAR_PIN,PM_PIN_UP_DOWN_FLOAT);
}
void kRadarLedTragger(void)
{
if(!ev_timer_exist(kRadarControlLedEvent)){
TL_ZB_TIMER_CANCEL(&kRadarControlLedEvent);
}
kRadarControlLedEvent = TL_ZB_TIMER_SCHEDULE(kRadarLedEventHandler, NULL, 1);
}
#if UART_ENABLE
uint8_t uart_send(void)
{
UMsgNodeSt MsgNode;
uint8_t i = 0;
memset(&MsgNode,0,sizeof(UMsgNodeSt));
MsgNode.buffer[i++] = 0xAA;
MsgNode.buffer[i++] = 0X55;
MsgNode.buffer[i++] = 0X05;
MsgNode.buffer[i++] = 0x01;
MsgNode.buffer[i++] = 0X02;
MsgNode.buffer[i++] = 0X03;
MsgNode.buffer[i++] = 0X04;
MsgNode.buffer[i++] = 0X05;
uint16_t crc = check_sum(&MsgNode.buffer[0], MsgNode.buffer[2]+3);
MsgNode.buffer[i++] = crc>>8;
MsgNode.buffer[i++] = crc;
MsgNode.length = i;
// setting for matcher content.
MsgNode.matcher[0] = 0XAA;
MsgNode.matcher[0] = 0X55;
MsgNode.matcher_offset = 4;
MsgNode.matcher_n = 2;
MsgNode.sent_try = 3;
return kUartMsgSent(&MsgNode);
}
void UartMsgProcessHandle(UMsgNodeSt *pMsgNode )
{
uint16_t opcode;
uint16_t frameLenth = 0;
uint8_t *args_in;
uint8_t reply_control_field;
DataField_st send_buf;
if( NULL == pMsgNode ) {
return ;
}
#if 1 // Just for debug
iKonkeAfSelfPrint("\r\n-- RTT MSG INCOMING[%d]:\r\n", pMsgNode->length);
iKonkeAfSelfPrintBuffer(pMsgNode->buffer, pMsgNode->length);
iKonkeAfSelfPrint("\r\n--------------------\r\n");
#endif
// check SOF
if ((pMsgNode->buffer[0] != 0xAA) || (pMsgNode->buffer[1] != 0x55)) {
return ;
}
frameLenth = UINT16_HL(pMsgNode->buffer[2], pMsgNode->buffer[3]);
// check for parsable packets
if( pMsgNode->length < 10 /* Minimum Packet Length */ ) {
iKonkeAfSelfPrint("Err: Unparsable Packets!!\r\n");
return ;
}
opcode = ((uint16_t)pMsgNode->buffer[9] << 8) | (uint16_t)(pMsgNode->buffer[10]);
args_in = &pMsgNode->buffer[8];
send_buf.seq = UINT16_HL(pMsgNode->buffer[5],pMsgNode->buffer[6] );
send_buf.u8ChannelID = args_in[0];
send_buf.u16Opcode = opcode;
iKonkeAfSelfPrint("opcode(%d)\r\n", opcode);
reply_control_field = Z_TO_H_NO_ACK;
switch(opcode){
case UART_MSG_READ_DEVICE_SNAP_OPCODE:
case UART_MSG_JOIN_NWK_REQUEST_OPCODE:
case UART_MSG_LEAVE_NWK_REQUEST_OPCODE:
case UART_MSG_QUERY_NWK_STATUS_REQUEST_OPCODE:
case UART_MSG_NWK_STATUS_NOTIFY_OPCODE:
case UART_MSG_READ_ATTRIBUTE_REQUEST_OPCODE:
case UART_MSG_WRITE_ATTRIBUTE_REQUEST_OPCODE:
case UART_MSG_WRITE_CMEI_CODE_OPCODE:
case UART_MSG_READ_CMEI_CODE_OPCODE:
case UART_MSG_WRITE_ISN_CODE_OPCODE:
case UART_MSG_READ_ISN_CODE_OPCODE:
case UART_MSG_ZCL_COMMAND_REQUEST_OPCODE:
case UART_MSG_BIND_REQUEST_OPCODE:
case UART_MSG_WRITE_INSTALL_CODE_OPCODE:
case UART_MSG_READ_INSTALL_CODE_OPCODE:
case UART_MSG_WRITE_MAC_CODE_OPCODE:
case UART_MSG_READ_MAC_CODE_OPCODE:
case UART_MSG_WRITE_MOUDLE_ID_OPCODE:
case UART_MSG_READ_MOUDLE_ID_OPCODE:
case UART_MSG_READ_DEV_RSSI_OPCODE:
case UART_MSG_WRITE_AGING_TIME_OPCODE:
case UART_MSG_READ_AGING_TIME_OPCODE:
case UART_MSG_WRITE_INTERPAN_PARA_OPCODE:
case UART_MSG_READ_INTERPAN_PARA_OPCODE:
reply_control_field = Z_TO_H_NO_ACK;
kCmdGeneralMsgPaser(pMsgNode, ECOM_PORT_UART, &send_buf);
break;
case UART_MSG_QUERY_INFO_OPCODE:
case UART_MSG_QUERY_DEVICE_VERSION_OPCODE:
case UART_MSG_QUERY_DEVICE_INFO_OPCODE:
case UART_MSG_CONFIG_DEVICE_SLEEP_OPCODE:
case UART_MSG_EXIT_FACTORY_TEST_OPCODE:
case UART_MSG_QUERY_SWITCH_ONOFF_OPCODE:
case UART_MSG_QUERY_FACTORY_INFO_OPCODE:
case UART_MSG_ENTER_FACTORY_TEST_OPCODE:
case UART_MSG_ONOFF_SWITCH_OPCODE:
kkFactoryMsgInComingPaser(pMsgNode, ECOM_PORT_UART, &send_buf);
break;
default:
send_buf.u8ARG[0] = ERR_NOT_EXIST;
send_buf.u8ArgLen = 1;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
kCmdMsgDataSentByPort(reply_control_field, send_buf, false, ECOM_PORT_UART);
}
/* DESP: rtt command message incoming and process interface.
* Auth: kkk.20210222.
* */
void kUserInterPanMsgInComingPaser(UMsgNodeSt *pMsgNode)
{
uint16_t opcode;
uint16_t frameLenth = 0;
uint16_t crc16DataIn = 0;
uint16_t crc16Value = 0;
uint8_t *args_in;
uint8_t reply_control_field;
DataField_st send_buf;
if( NULL == pMsgNode ) {
return ;
}
#if 0 // Just for debug
iKonkeAfSelfPrint("\r\n-- InterPan MSG INCOMING[%d]:\r\n", pMsgNode->length);
iKonkeAfSelfPrintBuffer(pMsgNode->buffer, pMsgNode->length);
iKonkeAfSelfPrint("\r\n--------------------\r\n");
#endif
// check SOF
if ((pMsgNode->buffer[0] != 0xAA) || (pMsgNode->buffer[1] != 0x55)) {
return ;
}
frameLenth = UINT16_HL(pMsgNode->buffer[2], pMsgNode->buffer[3]);
// check CRC16
crc16Value = kCmdGetMsgCrc16Value(&pMsgNode->buffer[4], frameLenth);
crc16DataIn = UINT16_HL(pMsgNode->buffer[pMsgNode->length - 2], pMsgNode->buffer[pMsgNode->length - 1]);
if (crc16Value != crc16DataIn) {
iKonkeAfSelfPrint("Err: CRC(%d)(%d)\r\n", crc16Value, crc16DataIn);
return ;
}
// check for parsable packets
if( pMsgNode->length < 10 /* Minimum Packet Length */ ) {
iKonkeAfSelfPrint("Err: Unparsable Packets!!\r\n");
return ;
}
opcode = ((uint16_t)pMsgNode->buffer[9] << 8) | (uint16_t)(pMsgNode->buffer[10]);
args_in = &pMsgNode->buffer[8];
send_buf.seq = UINT16_HL(pMsgNode->buffer[5],pMsgNode->buffer[6] );
send_buf.u8ChannelID = args_in[0];
send_buf.u16Opcode = opcode;
iKonkeAfSelfPrint("opcode(%d)\r\n", opcode);
switch(opcode){
case UART_MSG_READ_DEVICE_SNAP_OPCODE:
case UART_MSG_JOIN_NWK_REQUEST_OPCODE:
case UART_MSG_LEAVE_NWK_REQUEST_OPCODE:
case UART_MSG_QUERY_NWK_STATUS_REQUEST_OPCODE:
case UART_MSG_NWK_STATUS_NOTIFY_OPCODE:
case UART_MSG_READ_ATTRIBUTE_REQUEST_OPCODE:
case UART_MSG_WRITE_ATTRIBUTE_REQUEST_OPCODE:
case UART_MSG_WRITE_CMEI_CODE_OPCODE:
case UART_MSG_READ_CMEI_CODE_OPCODE:
case UART_MSG_WRITE_ISN_CODE_OPCODE:
case UART_MSG_READ_ISN_CODE_OPCODE:
case UART_MSG_ZCL_COMMAND_REQUEST_OPCODE:
case UART_MSG_BIND_REQUEST_OPCODE:
case UART_MSG_WRITE_INSTALL_CODE_OPCODE:
case UART_MSG_READ_INSTALL_CODE_OPCODE:
case UART_MSG_WRITE_MAC_CODE_OPCODE:
case UART_MSG_READ_MAC_CODE_OPCODE:
case UART_MSG_WRITE_MOUDLE_ID_OPCODE:
case UART_MSG_READ_MOUDLE_ID_OPCODE:
case UART_MSG_READ_DEV_RSSI_OPCODE:
case UART_MSG_WRITE_AGING_TIME_OPCODE:
case UART_MSG_READ_AGING_TIME_OPCODE:
case UART_MSG_WRITE_INTERPAN_PARA_OPCODE:
case UART_MSG_READ_INTERPAN_PARA_OPCODE:
kCmdGeneralMsgPaser(pMsgNode, ECOM_PORT_INTERPAN, &send_buf);
break;
case UART_MSG_QUERY_INFO_OPCODE:
case UART_MSG_QUERY_DEVICE_VERSION_OPCODE:
case UART_MSG_QUERY_DEVICE_INFO_OPCODE:
case UART_MSG_CONFIG_DEVICE_SLEEP_OPCODE:
case UART_MSG_EXIT_FACTORY_TEST_OPCODE:
case UART_MSG_QUERY_FACTORY_INFO_OPCODE:
case UART_MSG_QUERY_SWITCH_ONOFF_OPCODE:
case UART_MSG_ENTER_FACTORY_TEST_OPCODE:
case UART_MSG_ONOFF_SWITCH_OPCODE:
kkFactoryMsgInComingPaser(pMsgNode, ECOM_PORT_INTERPAN, &send_buf);
break;
default:
send_buf.u8ARG[0] = ERR_NOT_EXIST;
send_buf.u8ArgLen = 1;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
reply_control_field = Z_TO_H_NO_ACK;
kCmdMsgDataSentByPort(reply_control_field, send_buf, false, ECOM_PORT_INTERPAN);
}
uint16_t check_sum( uint8_t* msg, uint8_t len)
{
uint16_t crc = 0xFFFF;
uint16_t i, j = 0;
for (i = 0; i < len; i++)
{
for (j = 0; j < 8; j++)
{
uint8_t c15 = (uint8_t)((crc >> 15 & 1) == 1);
uint8_t bit = (uint8_t)((msg[i] >> (7 - j) & 1) == 1);
crc <<= 1;
if (c15 ^ bit)
{
crc ^= 0x1021;
}
}
}
return crc;
}
bool MsgCRC16(uint8_t *pdat, int length )
{
uint16_t crc_data = 0;
uint8_t CRC_H = 0;
uint8_t CRC_L = 0;
if((NULL == pdat) || (length < 9)){
return false;
}
crc_data = check_sum(&pdat[4], pdat[3]);
CRC_H = (crc_data>>8) & 0xff;
CRC_L = crc_data & 0xff;
//iKonkeAfSelfPrint("\r\nMsgCRC16,%d,%d\r\n",CRC_H,CRC_L);
if((pdat[length - 1] == CRC_L) && (pdat[length - 2]== CRC_H))
{
return true;
}
return false;
}
#endif
/******************************************************************************************************** /********************************************************************************************************
* @file zb_afTestCb.c * @file zb_afTestCb.c
* *
* @brief This is the source file for zb_afTestCb * @brief This is the source file for zb_afTestCb
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#if (__PROJECT_3LIGHT_PANEL_DEMO__) #if (__PROJECT_3LIGHT_PANEL_DEMO__)
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "tl_common.h" #include "tl_common.h"
#include "zb_api.h" #include "zb_api.h"
#include "zcl_include.h" #include "zcl_include.h"
#include PROJECT_H #include PROJECT_H
#if ZBHCI_EN #if ZBHCI_EN
#include "zbhci.h" #include "zbhci.h"
#endif #endif
#include "ikk-debug.h"
#if AF_TEST_ENABLE #if AF_TEST_ENABLE
/********************************************************************** /**********************************************************************
* LOCAL CONSTANTS * LOCAL CONSTANTS
*/ */
/********************************************************************** /**********************************************************************
* TYPEDEFS * TYPEDEFS
*/ */
/********************************************************************** /**********************************************************************
* LOCAL FUNCTIONS * LOCAL FUNCTIONS
*/ */
/********************************************************************** /**********************************************************************
* GLOBAL VARIABLES * GLOBAL VARIABLES
*/ */
/********************************************************************** /**********************************************************************
* LOCAL VARIABLES * LOCAL VARIABLES
*/ */
u16 g_afTest_rcvReqCnt = 0; u16 g_afTest_rcvReqCnt = 0;
/********************************************************************** /**********************************************************************
* FUNCTIONS * FUNCTIONS
*/ */
static void afTest_testReqPrc(apsdeDataInd_t *pApsdeInd) static void afTest_testReqPrc(apsdeDataInd_t *pApsdeInd)
{ {
epInfo_t dstEp; epInfo_t dstEp;
TL_SETSTRUCTCONTENT(dstEp, 0); TL_SETSTRUCTCONTENT(dstEp, 0);
dstEp.dstEp = pApsdeInd->indInfo.src_ep; dstEp.dstEp = pApsdeInd->indInfo.src_ep;
dstEp.profileId = pApsdeInd->indInfo.profile_id; dstEp.profileId = pApsdeInd->indInfo.profile_id;
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP; dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr; dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr;
u8 dataLen = 50; u8 dataLen = 50;
u8 *pBuf = (u8 *)ev_buf_allocate(dataLen); u8 *pBuf = (u8 *)ev_buf_allocate(dataLen);
if(pBuf){ if(pBuf){
u8 *pData = pBuf; u8 *pData = pBuf;
*pData++ = LO_UINT16(g_afTest_rcvReqCnt); *pData++ = LO_UINT16(g_afTest_rcvReqCnt);
*pData++ = HI_UINT16(g_afTest_rcvReqCnt); *pData++ = HI_UINT16(g_afTest_rcvReqCnt);
for(u8 i = 0; i < dataLen - 2; i++){ for(u8 i = 0; i < dataLen - 2; i++){
*pData++ = i; *pData++ = i;
} }
u8 apsCnt = 0; u8 apsCnt = 0;
#if ZBHCI_EN #if ZBHCI_EN
zbhciTx(ZCL_CLUSTER_TELINK_SDK_TEST_RSP, pApsdeInd->asduLen, (u8 *)pApsdeInd->asdu); zbhciTx(ZCL_CLUSTER_TELINK_SDK_TEST_RSP, pApsdeInd->asduLen, (u8 *)pApsdeInd->asdu);
#else #else
af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_RSP, dataLen, pBuf, &apsCnt); af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_RSP, dataLen, pBuf, &apsCnt);
#endif #endif
ev_buf_free(pBuf); ev_buf_free(pBuf);
} }
} }
static void afTest_testClearReqPrc(apsdeDataInd_t *pApsdeInd) static void afTest_testClearReqPrc(apsdeDataInd_t *pApsdeInd)
{ {
epInfo_t dstEp; epInfo_t dstEp;
TL_SETSTRUCTCONTENT(dstEp, 0); TL_SETSTRUCTCONTENT(dstEp, 0);
dstEp.dstEp = pApsdeInd->indInfo.src_ep; dstEp.dstEp = pApsdeInd->indInfo.src_ep;
dstEp.profileId = pApsdeInd->indInfo.profile_id; dstEp.profileId = pApsdeInd->indInfo.profile_id;
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP; dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr; dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr;
u8 st = SUCCESS;
u8 st = SUCCESS;
u8 apsCnt = 0;
u8 apsCnt = 0; af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, 1, &st, &apsCnt);
af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, 1, &st, &apsCnt);
} }
void afTest_rx_handler(void *arg) static void afTest_dataSendDemo(apsdeDataInd_t *pApsdeInd)
{ {
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg; epInfo_t dstEp;
TL_SETSTRUCTCONTENT(dstEp, 0);
switch(pApsdeInd->indInfo.cluster_id){
case ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ: dstEp.dstAddrMode = APS_LONG_DSTADDR_WITHEP;
g_afTest_rcvReqCnt = 0; dstEp.dstEp = pApsdeInd->indInfo.src_ep;
afTest_testClearReqPrc(pApsdeInd); memcpy(dstEp.dstAddr.extAddr,pApsdeInd->indInfo.src_ext_addr,8);
break; dstEp.profileId = HA_PROFILE_ID;
case ZCL_CLUSTER_TELINK_SDK_TEST_REQ: dstEp.txOptions = APS_TX_OPT_INTRA_PAN;
g_afTest_rcvReqCnt++; dstEp.radius = 0;
afTest_testReqPrc(pApsdeInd);
break; u8 apsCnt = 0;
case ZCL_CLUSTER_TELINK_SDK_TEST_RSP:
u8 asdu[] = {0xAA, 0x55, 0x00, 0x08, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0d, 0x00, 0xF3, 0xD0};
break; u8 asdulength = sizeof(asdu);
default: //af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, 0x0001, asdulength, asdu, &apsCnt);
break; printf("afTest_Receive--------------ok!!\r\n");
} }
/* Must be free here. */
ev_buf_free((u8 *)arg); void afTest_rx_handler(void *arg)
} {
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
void afTest_dataSendConfirm(void *arg)
{ iKonkeAfSelfPrint("interpan data received,data len =%d\r\n",pApsdeInd->indInfo.asduLength);
// apsdeDataConf_t *pApsDataCnf = (apsdeDataConf_t *)arg; iKonkeAfSelfPrintBuffer(pApsdeInd->indInfo.asdu,pApsdeInd->indInfo.asduLength);
switch(pApsdeInd->indInfo.cluster_id){
} case ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ:
g_afTest_rcvReqCnt = 0;
#endif /* AF_TEST_ENABLE */ afTest_testClearReqPrc(pApsdeInd);
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ break;
case ZCL_CLUSTER_TELINK_SDK_TEST_REQ:
g_afTest_rcvReqCnt++;
afTest_testReqPrc(pApsdeInd);
break;
case ZCL_CLUSTER_TELINK_SDK_TEST_RSP:
break;
// case ZCL_CLUSTER_PRIVATE_FCC0:
// {
// afTest_dataSendDemo(pApsdeInd);
// break;
// }
default:
break;
}
/* Must be free here. */
ev_buf_free((u8 *)arg);
}
void afTest_dataSendConfirm(void *arg)
{
apsdeDataConf_t *pApsDataCnf = (apsdeDataConf_t *)arg;
printf("afTest_dataSendConfirm,dest ep = %d\r\n!!\r\n",pApsDataCnf->dstEndpoint);
}
#endif /* AF_TEST_ENABLE */
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */
#include "../general/ikk-tick-handler.h" #include "../general/ikk-tick-handler.h"
#include "ikk-button.h" #include "ikk-button.h"
#include "../general/ikk-debug.h" #include "../general/ikk-debug.h"
#define BTN_UNUSED_ID BTN_UNKNOW_ID #define BTN_UNUSED_ID BTN_UNKNOW_ID
#define BTN_UNKNOW_INTNO 0XFF #define BTN_UNKNOW_INTNO 0XFF
//modify by maozj 20200303 //modify by maozj 20200303
#define BTN_CALLBACK_MAXN (3) #define BTN_CALLBACK_MAXN (3)
#define SYS_BUTTON_DEFAULT_INDEX 0 //system key defalut index add by maozj 20200313 #define SYS_BUTTON_DEFAULT_INDEX 0 //system key defalut index add by maozj 20200313
#define INVALID_TIME_BETWEEN_SYS_BTN_MS 300 #define INVALID_TIME_BETWEEN_SYS_BTN_MS 300
#define SYS_BTN_FILTER_TIME_MS 100 #define SYS_BTN_FILTER_TIME_MS 100
// Button jitter timeslot // Button jitter timeslot
#define BUTTON_JITTER_SLOT 0 // MS #define BUTTON_JITTER_SLOT 0 // MS
// Double click timeslot. // Double click timeslot.
#define DCLICK_SLOT_DEF 350 // MS #define DCLICK_SLOT_DEF 350 // MS
typedef enum { EBS_UNKNOW = 0, EBS_RELEASED, EBS_PRESSED }BtnStatusEnum; typedef enum { EBS_UNKNOW = 0, EBS_RELEASED, EBS_PRESSED }BtnStatusEnum;
//Ĭ0Ϊϵͳ //Ĭ0Ϊϵͳ
//add by maozj 20200313 repair short press other key will effect system key //add by maozj 20200313 repair short press other key will effect system key
//static uint8_t g_u8TimeMS = 0; //static uint8_t g_u8TimeMS = 0;
static uint8_t g_u8BtnNum = 0; static uint8_t g_u8BtnNum = 0;
static BtnConfSt g_stBtnConfList[BTN_SUPPORT_MAXN]; static BtnConfSt g_stBtnConfList[BTN_SUPPORT_MAXN];
// button interrupt mapping table // button interrupt mapping table
static uint8_t g_u8BtnIrqMapp[BTN_SUPPORT_MAXN]; static uint8_t g_u8BtnIrqMapp[BTN_SUPPORT_MAXN];
// CALLBACs // CALLBACs
pBtnActionCallback g_pBtnActionCallback[BTN_CALLBACK_MAXN] = {NULL}; pBtnActionCallback g_pBtnActionCallback[BTN_CALLBACK_MAXN] = {NULL};
typedef struct { typedef struct {
BtnActionEnum eAction; // aciton enum BtnActionEnum eAction; // aciton enum
uint32_t u32ActStamp; // action occur timestamp uint32_t u32ActStamp; // action occur timestamp
uint32_t u32ActDuration;// press duration uint32_t u32ActDuration;// press duration
}ActionRecordSt; }ActionRecordSt;
// button click detection controller // button click detection controller
typedef struct { typedef struct {
ActionRecordSt sOldAct; ActionRecordSt sOldAct;
ActionRecordSt sNewAct; ActionRecordSt sNewAct;
uint32_t stamp; uint32_t stamp;
BtnActionEnum status; BtnActionEnum status;
BtnActionEnum lastStatus; BtnActionEnum lastStatus;
bool bValidAction; bool bValidAction;
bool bLongPressed;//add by maozj 20200226 bool bLongPressed;//add by maozj 20200226
uint32_t u32BtnPressedTimeCount; uint32_t u32BtnPressedTimeCount;
uint32_t u32CountDownCounter; uint32_t u32CountDownCounter;
bool bStartDect; bool bStartDect;
}ClickDetectCtrllerSt; }ClickDetectCtrllerSt;
static ClickDetectCtrllerSt g_stClickDetectCtrller[BTN_SUPPORT_MAXN]; static ClickDetectCtrllerSt g_stClickDetectCtrller[BTN_SUPPORT_MAXN];
//add by maozj //add by maozj
#define BTN_PRESSED_POLL_TIME_MS (1000) #define BTN_PRESSED_POLL_TIME_MS (1000)
/* DESP: the button[index0] input mode interface. /* DESP: the button[index0] input mode interface.
* Auth: mengmengli_frc.20200523. * Auth: mengmengli_frc.20200523.
* */ * */
static void Set_GPIO_Input(u32 pin,GPIO_PullTypeDef mode) static void Set_GPIO_Input(u32 pin,GPIO_PullTypeDef mode)
{ {
drv_gpio_func_set(pin); drv_gpio_func_set(pin);
drv_gpio_output_en(pin, 0); //enable output drv_gpio_output_en(pin, 0); //enable output
drv_gpio_input_en(pin, 1); //disable input drv_gpio_input_en(pin, 1); //disable input
drv_gpio_up_down_resistor(pin, mode); drv_gpio_up_down_resistor(pin, mode);
} }
/* DESP: the button[index0] active callback interface. /* DESP: the button[index0] active callback interface.
* Auth: mengmengli_frc.20200523. * Auth: mengmengli_frc.20200523.
* */ * */
//static uint8_t kBtnGetButtonIndexByIrqNO(uint8_t irq_no ) //static uint8_t kBtnGetButtonIndexByIrqNO(uint8_t irq_no )
//{ //{
// for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) { // for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) {
// if( g_stBtnConfList[index].u8ButtonId != BTN_UNUSED_ID ) { // if( g_stBtnConfList[index].u8ButtonId != BTN_UNUSED_ID ) {
// if( g_u8BtnIrqMapp[index] == irq_no ) { // if( g_u8BtnIrqMapp[index] == irq_no ) {
// return index; // return index;
// } // }
// }else { // }else {
// break; // break;
// } // }
// } // }
// //
// return 0XFF; // return 0XFF;
//} //}
/* DESP: the button[index0] active callback interface. /* DESP: the button[index0] active callback interface.
* Auth: maozj.20200325. * Auth: maozj.20200325.
* */ * */
uint8_t kBtnGetButtonIndexById(uint8_t button_id ) uint8_t kBtnGetButtonIndexById(uint8_t button_id )
{ {
for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) { for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) {
if( g_stBtnConfList[index].u8ButtonId == button_id ) { if( g_stBtnConfList[index].u8ButtonId == button_id ) {
return index; return index;
} }
} }
return 0XFF; return 0XFF;
} }
/* DESP: Check whether all keys have stopped action detection. /* DESP: Check whether all keys have stopped action detection.
* Auth: dingmz_frc.20191107. * Auth: dingmz_frc.20191107.
* */ * */
bool kBtnModuleActionIsGoing(void ) bool kBtnModuleActionIsGoing(void )
{ {
for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) { for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) {
if( g_stBtnConfList[index].u8ButtonId != BTN_UNUSED_ID ) { if( g_stBtnConfList[index].u8ButtonId != BTN_UNUSED_ID ) {
if( g_stClickDetectCtrller[index].u32CountDownCounter > 0 ) { if( g_stClickDetectCtrller[index].u32CountDownCounter > 0 ) {
return true; return true;
} }
}else { }else {
break; break;
} }
} }
return false; return false;
} }
/* DESP: Register button action callback notification function. /* DESP: Register button action callback notification function.
* Auth: dingmz_frc.20191107. * Auth: dingmz_frc.20191107.
* */ * */
kk_err_t kBtnaIRQCallbackRegister(pBtnActionCallback callback ) kk_err_t kBtnaIRQCallbackRegister(pBtnActionCallback callback )
{ {
if( NULL == callback ) { if( NULL == callback ) {
return KET_ERR_INVALID_PARAM; return KET_ERR_INVALID_PARAM;
} }
int valid_index = BTN_CALLBACK_MAXN; int valid_index = BTN_CALLBACK_MAXN;
for(int index = 0; index < BTN_CALLBACK_MAXN; ++index ) { for(int index = 0; index < BTN_CALLBACK_MAXN; ++index ) {
if( g_pBtnActionCallback[index] == callback ) { if( g_pBtnActionCallback[index] == callback ) {
valid_index = index; valid_index = index;
break; break;
}else if((g_pBtnActionCallback[index] == NULL) && (valid_index == BTN_CALLBACK_MAXN)) { }else if((g_pBtnActionCallback[index] == NULL) && (valid_index == BTN_CALLBACK_MAXN)) {
valid_index = index; valid_index = index;
} }
} }
if( valid_index < BTN_CALLBACK_MAXN ) { if( valid_index < BTN_CALLBACK_MAXN ) {
g_pBtnActionCallback[valid_index] = callback; g_pBtnActionCallback[valid_index] = callback;
return KET_OK; return KET_OK;
} }
return KET_ERR_INSUFFICIENT_SPACE; return KET_ERR_INSUFFICIENT_SPACE;
} }
/* DESP: Recall all registered buttons action callback interface. /* DESP: Recall all registered buttons action callback interface.
* Auth: dingmz_frc.20191107. * Auth: dingmz_frc.20191107.
* */ * */
void kBtnaIRQCallbackRecall(unsigned char btnIndex, BtnActionEnum action ) void kBtnaIRQCallbackRecall(unsigned char btnIndex, BtnActionEnum action )
{ {
for(int index = 0; index < BTN_CALLBACK_MAXN; ++index ) { for(int index = 0; index < BTN_CALLBACK_MAXN; ++index ) {
if( g_pBtnActionCallback[index] != NULL ) { if( g_pBtnActionCallback[index] != NULL ) {
g_pBtnActionCallback[index](btnIndex, action); g_pBtnActionCallback[index](btnIndex, action);
}else { }else {
break; break;
} }
} }
} }
//static uint8_t state_change_flg[BTN_SUPPORT_MAXN] = {1,1,1,1,1,1,1,1}; //static uint8_t state_change_flg[BTN_SUPPORT_MAXN] = {1,1,1,1,1,1,1,1};
//void kBtnModuleActionDetectCallback_self(void ) //void kBtnModuleActionDetectCallback_self(void )
//{ //{
// static uint32_t key_count[BTN_SUPPORT_MAXN] = {0}; // static uint32_t key_count[BTN_SUPPORT_MAXN] = {0};
// for(int index = 0; index < 2; index++ ) { // for(int index = 0; index < 2; index++ ) {
// // check button status // // check button status
// unsigned int gpio_st = gpio_read(g_stBtnConfList[index].pin); // unsigned int gpio_st = gpio_read(g_stBtnConfList[index].pin);
// if(gpio_st == g_stBtnConfList[index].eActionPolarity) // if(gpio_st == g_stBtnConfList[index].eActionPolarity)
// { // {
// if(key_count[index] < 0xffffffff) // if(key_count[index] < 0xffffffff)
// key_count[index]++; // key_count[index]++;
// //
// if( (g_stBtnConfList[index].bSupportPressedSend)&&(key_count[index] >= MS2COUNT(g_stBtnConfList[index].u32LongPressDuration) ) ) // if( (g_stBtnConfList[index].bSupportPressedSend)&&(key_count[index] >= MS2COUNT(g_stBtnConfList[index].u32LongPressDuration) ) )
// { // {
// if(g_stClickDetectCtrller[index].lastStatus != EBA_LONGPRESS) // if(g_stClickDetectCtrller[index].lastStatus != EBA_LONGPRESS)
// { // {
// iKonkeAfSelfPrint("Button Id = %d,Long Press!!\r\n", index); // iKonkeAfSelfPrint("Button Id = %d,Long Press!!\r\n", index);
// g_stClickDetectCtrller[index].status = EBA_LONGPRESS; // g_stClickDetectCtrller[index].status = EBA_LONGPRESS;
// } // }
// } // }
// else if(key_count[index] >= MS2COUNT(60)) // else if(key_count[index] >= MS2COUNT(60))
// { // {
// if(g_stClickDetectCtrller[index].lastStatus != EBA_PRESSED) // if(g_stClickDetectCtrller[index].lastStatus != EBA_PRESSED)
// { // {
// iKonkeAfSelfPrint("Button Id = %d,Pressed!!\r\n", index); // iKonkeAfSelfPrint("Button Id = %d,Pressed!!\r\n", index);
// g_stClickDetectCtrller[index].status = EBA_PRESSED; // g_stClickDetectCtrller[index].status = EBA_PRESSED;
// } // }
// } // }
// //
// } // }
// else // else
// { // {
// if( (key_count[index]>= MS2COUNT(60))&&(key_count[index] < MS2COUNT(g_stBtnConfList[index].u32LongPressDuration)) ) // if( (key_count[index]>= MS2COUNT(60))&&(key_count[index] < MS2COUNT(g_stBtnConfList[index].u32LongPressDuration)) )
// { // {
// iKonkeAfSelfPrint("Button Id = %d,Sigal Click!!\r\n", index); // iKonkeAfSelfPrint("Button Id = %d,Sigal Click!!\r\n", index);
// g_stClickDetectCtrller[index].status = EBA_CLICK; // g_stClickDetectCtrller[index].status = EBA_CLICK;
// } // }
// key_count[index] = 0; // key_count[index] = 0;
// } // }
// if(g_stClickDetectCtrller[index].lastStatus != g_stClickDetectCtrller[index].status) // if(g_stClickDetectCtrller[index].lastStatus != g_stClickDetectCtrller[index].status)
// { // {
// kBtnaIRQCallbackRecall(g_stBtnConfList[index].u8ButtonId, g_stClickDetectCtrller[index].status); // kBtnaIRQCallbackRecall(g_stBtnConfList[index].u8ButtonId, g_stClickDetectCtrller[index].status);
// g_stClickDetectCtrller[index].lastStatus = g_stClickDetectCtrller[index].status ; // g_stClickDetectCtrller[index].lastStatus = g_stClickDetectCtrller[index].status ;
// } // }
// } // }
//} //}
/* DESP: Button module action detection task callback interface. /* DESP: Button module action detection task callback interface.
* Auth: dingmz_frc.20191107. * Auth: dingmz_frc.20191107.
* */ * */
void kBtnModuleActionDetectCallback(void ) void kBtnModuleActionDetectCallback(void )
{ {
static uint32_t key_count[BTN_SUPPORT_MAXN] = {0}; static uint32_t key_count[BTN_SUPPORT_MAXN] = {0};
for(int index = 0; index < g_u8BtnNum; index++ ) for(int index = 0; index < g_u8BtnNum; index++ )
{ {
// check button status // check button status
unsigned int gpio_st = (gpio_read(g_stBtnConfList[index].pin)>0)? 1:0;; unsigned int gpio_st = (gpio_read(g_stBtnConfList[index].pin)>0)? 1:0;;
if(gpio_st == g_stBtnConfList[index].eActionPolarity) if(gpio_st == g_stBtnConfList[index].eActionPolarity)
{ {
if(key_count[index] < 0xffffffff) if(key_count[index] < 0xffffffff)
key_count[index]++; key_count[index]++;
if( (g_stBtnConfList[index].bSupportPressedSend)&&(key_count[index] >= MS2COUNT(g_stBtnConfList[index].u32LongPressDuration) ) ) if( (g_stBtnConfList[index].bSupportPressedSend)&&(key_count[index] >= MS2COUNT(g_stBtnConfList[index].u32LongPressDuration) ) )
{ {
if(g_stClickDetectCtrller[index].lastStatus != EBA_LONGPRESS) if(g_stClickDetectCtrller[index].lastStatus != EBA_LONGPRESS)
{ {
iKonkeAfSelfPrint("Button Id = %d,Long Press!!\r\n", index); iKonkeAfSelfPrint("Button Id = %d,Long Press!!\r\n", index);
g_stClickDetectCtrller[index].status = EBA_LONGPRESS; g_stClickDetectCtrller[index].status = EBA_LONGPRESS;
} }
} }
else if(key_count[index] >= MS2COUNT(60)) else if(key_count[index] >= MS2COUNT(60))
{ {
if(g_stClickDetectCtrller[index].lastStatus != EBA_PRESSED) if(g_stClickDetectCtrller[index].lastStatus != EBA_PRESSED)
{ {
iKonkeAfSelfPrint("Button Id = %d,Pressed!!\r\n", index); iKonkeAfSelfPrint("Button Id = %d,Pressed!!\r\n", index);
g_stClickDetectCtrller[index].status = EBA_PRESSED; g_stClickDetectCtrller[index].status = EBA_PRESSED;
} }
} }
} }
else else
{ {
if( (key_count[index]>= MS2COUNT(60))&&(key_count[index] < MS2COUNT(g_stBtnConfList[index].u32LongPressDuration)) ) if( (key_count[index]>= MS2COUNT(60))&&(key_count[index] < MS2COUNT(g_stBtnConfList[index].u32LongPressDuration)) )
{ {
iKonkeAfSelfPrint("Button Id = %d,Sigal Click!!\r\n", index); iKonkeAfSelfPrint("Button Id = %d,Sigal Click!!\r\n", index);
g_stClickDetectCtrller[index].status = EBA_CLICK; g_stClickDetectCtrller[index].status = EBA_CLICK;
} }
else if(key_count[index]>= MS2COUNT(60)) else if(key_count[index]>= MS2COUNT(60))
g_stClickDetectCtrller[index].status = EBA_RELEASED; g_stClickDetectCtrller[index].status = EBA_RELEASED;
key_count[index] = 0; key_count[index] = 0;
} }
if(g_stClickDetectCtrller[index].lastStatus != g_stClickDetectCtrller[index].status) if(g_stClickDetectCtrller[index].lastStatus != g_stClickDetectCtrller[index].status)
{ {
kBtnaIRQCallbackRecall(g_stBtnConfList[index].u8ButtonId, g_stClickDetectCtrller[index].status); kBtnaIRQCallbackRecall(g_stBtnConfList[index].u8ButtonId, g_stClickDetectCtrller[index].status);
g_stClickDetectCtrller[index].lastStatus = g_stClickDetectCtrller[index].status ; g_stClickDetectCtrller[index].lastStatus = g_stClickDetectCtrller[index].status ;
} }
} }
} }
/* DESP: the button[index0] active callback interface. /* DESP: the button[index0] active callback interface.
* Auth: dingmz_frc.20191107. * Auth: dingmz_frc.20191107.
* */ * */
//static void kBtnaIRQCallback(uint8_t irq_no ) //static void kBtnaIRQCallback(uint8_t irq_no )
//{ //{
// uint8_t button_index = kBtnGetButtonIndexByIrqNO(irq_no); // uint8_t button_index = kBtnGetButtonIndexByIrqNO(irq_no);
// static bool flg = false; // static bool flg = false;
// static BtnConfSt stBtnConfList[BTN_SUPPORT_MAXN] ; // static BtnConfSt stBtnConfList[BTN_SUPPORT_MAXN] ;
// //
// if( button_index != 0XFF ) { // if( button_index != 0XFF ) {
// //iKonkeAfSelfPrint("BUTTON Actived[%d]: ButtonID(%d)!\r\n", button_index, g_stBtnConfList[button_index].u8ButtonId); // //iKonkeAfSelfPrint("BUTTON Actived[%d]: ButtonID(%d)!\r\n", button_index, g_stBtnConfList[button_index].u8ButtonId);
// //
// // trigger running button click detection. // // trigger running button click detection.
// g_stClickDetectCtrller[button_index].status = EBS_PRESSED; // g_stClickDetectCtrller[button_index].status = EBS_PRESSED;
// g_stClickDetectCtrller[button_index].stamp = clock_time(); // g_stClickDetectCtrller[button_index].stamp = clock_time();
// //g_stClickDetectCtrller[button_index].bValidAction = false; // //g_stClickDetectCtrller[button_index].bValidAction = false;
// //g_stClickDetectCtrller[button_index].bLongPressed = false;//add by maozj 20200226 // //g_stClickDetectCtrller[button_index].bLongPressed = false;//add by maozj 20200226
// g_stClickDetectCtrller[button_index].u32BtnPressedTimeCount = 0; //add by maozj 20200226 // g_stClickDetectCtrller[button_index].u32BtnPressedTimeCount = 0; //add by maozj 20200226
// g_stClickDetectCtrller[button_index].u32CountDownCounter // g_stClickDetectCtrller[button_index].u32CountDownCounter
// = (g_stBtnConfList[button_index].u32LongPressDuration + 1000) / TICK_LOOP_NMS; // = (g_stBtnConfList[button_index].u32LongPressDuration + 1000) / TICK_LOOP_NMS;
// //g_stClickDetectCtrller[button_index].bStartDect = false; // //g_stClickDetectCtrller[button_index].bStartDect = false;
// g_stClickDetectCtrller[button_index].lastStatus = EBS_UNKNOW; // g_stClickDetectCtrller[button_index].lastStatus = EBS_UNKNOW;
// if (flg != true){ // if (flg != true){
// flg = true; // flg = true;
// memcpy(stBtnConfList, g_stBtnConfList, sizeof(stBtnConfList)); // memcpy(stBtnConfList, g_stBtnConfList, sizeof(stBtnConfList));
// } // }
// //
// //change irq ege // //change irq ege
// if (stBtnConfList[button_index].eActionPolarity == EBP_BOTH){ // if (stBtnConfList[button_index].eActionPolarity == EBP_BOTH){
// bool status = gpio_read(g_stBtnConfList[button_index].pin); // bool status = gpio_read(g_stBtnConfList[button_index].pin);
// g_stBtnConfList[button_index].eActionPolarity = status?EBP_HIGH:EBP_LOW; // g_stBtnConfList[button_index].eActionPolarity = status?EBP_HIGH:EBP_LOW;
// } // }
// kTickRunnningTrigger(); // kTickRunnningTrigger();
// } // }
//} //}
/* DESP: single Button instance register interface. /* DESP: single Button instance register interface.
* Auth: dingmz_frc.20191108. modify by maozj 20200326 * Auth: dingmz_frc.20191108. modify by maozj 20200326
* */ * */
kk_err_t kBtnRegister(uint8_t id, uint32_t pin, BtnPolarityEnum ePolarity, bool bSupportDClick, bool bSupportPressedSend, uint32_t u32LongPressDuration ) kk_err_t kBtnRegister(uint8_t id, uint32_t pin, BtnPolarityEnum ePolarity, bool bSupportDClick, bool bSupportPressedSend, uint32_t u32LongPressDuration )
{ {
if( BTN_UNKNOW_ID == id || BTN_ALLOPT_ID == id ) { if( BTN_UNKNOW_ID == id || BTN_ALLOPT_ID == id ) {
return KET_ERR_INVALID_PARAM; return KET_ERR_INVALID_PARAM;
} }
int valid_index = BTN_SUPPORT_MAXN; int valid_index = BTN_SUPPORT_MAXN;
kk_err_t err = KET_OK; kk_err_t err = KET_OK;
for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) { for(int index = 0; index < BTN_SUPPORT_MAXN; ++index ) {
if( g_stBtnConfList[index].u8ButtonId == id ) { if( g_stBtnConfList[index].u8ButtonId == id ) {
valid_index = index; valid_index = index;
break; break;
}else if((valid_index == BTN_SUPPORT_MAXN) && (g_stBtnConfList[index].u8ButtonId == BTN_UNUSED_ID)) { }else if((valid_index == BTN_SUPPORT_MAXN) && (g_stBtnConfList[index].u8ButtonId == BTN_UNUSED_ID)) {
valid_index = index; valid_index = index;
} }
} }
if( valid_index < BTN_SUPPORT_MAXN ) { // GET A VALID CHUNK. if( valid_index < BTN_SUPPORT_MAXN ) { // GET A VALID CHUNK.
memset(&g_stClickDetectCtrller[valid_index], 0, sizeof(g_stClickDetectCtrller[valid_index])); memset(&g_stClickDetectCtrller[valid_index], 0, sizeof(g_stClickDetectCtrller[valid_index]));
g_stBtnConfList[valid_index].u8ButtonId = id; g_stBtnConfList[valid_index].u8ButtonId = id;
g_stBtnConfList[valid_index].pin = pin; g_stBtnConfList[valid_index].pin = pin;
g_stBtnConfList[valid_index].eActionPolarity = ePolarity; g_stBtnConfList[valid_index].eActionPolarity = ePolarity;
g_stBtnConfList[valid_index].bSupportDClick = bSupportDClick; g_stBtnConfList[valid_index].bSupportDClick = bSupportDClick;
g_stBtnConfList[valid_index].bSupportPressedSend = bSupportPressedSend;//add by maozj 20200326 g_stBtnConfList[valid_index].bSupportPressedSend = bSupportPressedSend;//add by maozj 20200326
g_stBtnConfList[valid_index].u32LongPressDuration = u32LongPressDuration; g_stBtnConfList[valid_index].u32LongPressDuration = u32LongPressDuration;
iKonkeAfSelfPrint("BTN_REGISTER: id(%d),pin(%d), intno(%d), eActionPolarity(%d), bDclick(%d), longSlot(%d)\r\n" iKonkeAfSelfPrint("BTN_REGISTER: id(%d),pin(%d), intno(%d), eActionPolarity(%d), bDclick(%d), longSlot(%d)\r\n"
, g_stBtnConfList[valid_index].u8ButtonId,g_stBtnConfList[valid_index].pin, g_u8BtnIrqMapp[valid_index] , g_stBtnConfList[valid_index].u8ButtonId,g_stBtnConfList[valid_index].pin, g_u8BtnIrqMapp[valid_index]
, g_stBtnConfList[valid_index].eActionPolarity, g_stBtnConfList[valid_index].bSupportDClick , g_stBtnConfList[valid_index].eActionPolarity, g_stBtnConfList[valid_index].bSupportDClick
, g_stBtnConfList[valid_index].u32LongPressDuration , g_stBtnConfList[valid_index].u32LongPressDuration
); );
#if (Z30_DEVICE_DTYPE == Z30_DEVICE_ZED_SLEEPY) #if (Z30_DEVICE_DTYPE == Z30_DEVICE_ZED_SLEEPY)
GPIO_Mode_TypeDef mode = gpioModeInput; GPIO_Mode_TypeDef mode = gpioModeInput;
#else #else
GPIO_PullTypeDef mode = PM_PIN_UP_DOWN_FLOAT; GPIO_PullTypeDef mode = PM_PIN_UP_DOWN_FLOAT;
//GPIO_Mode_TypeDef mode = gpioModeInput; //GPIO_Mode_TypeDef mode = gpioModeInput;
#endif #endif
Set_GPIO_Input(g_stBtnConfList[valid_index].pin,mode); Set_GPIO_Input(g_stBtnConfList[valid_index].pin,mode);
}else { }else {
err = KET_ERR_INSUFFICIENT_SPACE; err = KET_ERR_INSUFFICIENT_SPACE;
} }
return err; return err;
} }
/* DESP: button module Initialize configuration interface. /* DESP: button module Initialize configuration interface.
* Note: Button initialization interface supports one-time registration of multiple buttons! * Note: Button initialization interface supports one-time registration of multiple buttons!
* Auth: dingmz_frc.20191107. * Auth: dingmz_frc.20191107.
* */ * */
kk_err_t kBtnModuleInit(BtnConfSt *btnlist, unsigned char btn_number, pBtnActionCallback pBtnActionCallback ) kk_err_t kBtnModuleInit(BtnConfSt *btnlist, unsigned char btn_number, pBtnActionCallback pBtnActionCallback )
{ {
kk_err_t err = KET_OK; kk_err_t err = KET_OK;
memset(g_u8BtnIrqMapp, BTN_UNKNOW_INTNO, sizeof(g_u8BtnIrqMapp)); memset(g_u8BtnIrqMapp, BTN_UNKNOW_INTNO, sizeof(g_u8BtnIrqMapp));
memset(g_stBtnConfList, BTN_UNUSED_ID, sizeof(g_stBtnConfList)); memset(g_stBtnConfList, BTN_UNUSED_ID, sizeof(g_stBtnConfList));
if( btnlist && (btn_number > 0)) { if( btnlist && (btn_number > 0)) {
btn_number = (btn_number < BTN_SUPPORT_MAXN)?btn_number:BTN_SUPPORT_MAXN; btn_number = (btn_number < BTN_SUPPORT_MAXN)?btn_number:BTN_SUPPORT_MAXN;
for(int index = 0; index < btn_number; ++index ) { for(int index = 0; index < btn_number; ++index ) {
err = kBtnRegister(btnlist[index].u8ButtonId, btnlist[index].pin, btnlist[index].eActionPolarity err = kBtnRegister(btnlist[index].u8ButtonId, btnlist[index].pin, btnlist[index].eActionPolarity
, btnlist[index].bSupportDClick, btnlist[index].bSupportPressedSend,btnlist[index].u32LongPressDuration); , btnlist[index].bSupportDClick, btnlist[index].bSupportPressedSend,btnlist[index].u32LongPressDuration);
} }
kBtnaIRQCallbackRegister(pBtnActionCallback); kBtnaIRQCallbackRegister(pBtnActionCallback);
} }
g_u8BtnNum = btn_number; g_u8BtnNum = btn_number;
return err; return err;
} }
#include "ikk-pwm.h" #include "ikk-pwm.h"
#include "tl_common.h" #include "tl_common.h"
#include "ikk-led.h" #include "ikk-led.h"
#include "../general/ikk-debug.h" #include "../general/ikk-debug.h"
#define PWM_UNUSED_ID PWM_UNKNOW_ID #define PWM_UNUSED_ID PWM_UNKNOW_ID
#define PWM_TICK_LOOP_NMS 10 // MS #define PWM_TICK_LOOP_NMS 10 // MS
// led controller // led controller
static struct tag_pwm_controller_st { static struct tag_pwm_controller_st {
uint32_t actionCounter; //event couter uint32_t actionCounter; //event couter
uint32_t intervalDutyCycle; //+ / - every times uint32_t intervalDutyCycle; //+ / - every times
uint32_t durationMs; uint32_t durationMs;
uint16_t startDutyCycle; uint16_t startDutyCycle;
uint16_t endDutyCycle; uint16_t endDutyCycle;
uint16_t startDutyCycleValue; uint16_t startDutyCycleValue;
PwmGpioSt gpioInfo; PwmGpioSt gpioInfo;
}g_stPwmCtrller[PWM_OBJS_SUPPORT_MAXN]; }g_stPwmCtrller[PWM_OBJS_SUPPORT_MAXN];
static PwmGpioListSt stPWM_Mutex_Info[] = PWM_TLSR8258_INFO_INIT; static PwmGpioListSt stPWM_Mutex_Info[] = PWM_TLSR8258_INFO_INIT;
static PwmConfSt g_stPwmConfList[PWM_OBJS_SUPPORT_MAXN]; static PwmConfSt g_stPwmConfList[PWM_OBJS_SUPPORT_MAXN];
static uint8_t g_u8PwmChannelNum = 0; static uint8_t g_u8PwmChannelNum = 0;
pPwmActionDoneCallback g_pPwmActionDoneCallback = NULL; pPwmActionDoneCallback g_pPwmActionDoneCallback = NULL;
static bool Pwm_Tick_Detect_Running_Flag = false; static bool Pwm_Tick_Detect_Running_Flag = false;
static ev_timer_event_t *Tick_Pwm_TimerEvt = NULL; static ev_timer_event_t *Tick_Pwm_TimerEvt = NULL;
static s32 kPwmGradientChangeEventHandler(void *data); static s32 kPwmGradientChangeEventHandler(void *data);
static PwmChannelEnum Get_PWM_CHANNEL_FROM_PIN(uint32_t pin) static PwmChannelEnum Get_PWM_CHANNEL_FROM_PIN(uint32_t pin)
{ {
for(uint8_t index = 0;index < PWM_OBJS_SUPPORT_MAXN;index++ ) for(uint8_t index = 0;index < PWM_OBJS_SUPPORT_MAXN;index++ )
for(uint8_t i = 0;i<2;i++) for(uint8_t i = 0;i<2;i++)
for(uint8_t j=0;j< stPWM_Mutex_Info[index].gpioinfo[i].vaild_num;j++) for(uint8_t j=0;j< stPWM_Mutex_Info[index].gpioinfo[i].vaild_num;j++)
if(stPWM_Mutex_Info[index].gpioinfo[i].pin[j] == pin) if(stPWM_Mutex_Info[index].gpioinfo[i].pin[j] == pin)
return stPWM_Mutex_Info[index].pwmChannel; return stPWM_Mutex_Info[index].pwmChannel;
return 0xff; return 0xff;
} }
static GPIO_FuncTypeDef Get_PIN_FUNC_By_PIN(uint32_t pin) static GPIO_FuncTypeDef Get_PIN_FUNC_By_PIN(uint32_t pin)
{ {
for(uint8_t index = 0;index < PWM_OBJS_SUPPORT_MAXN;index++ ) for(uint8_t index = 0;index < PWM_OBJS_SUPPORT_MAXN;index++ )
for(uint8_t i = 0;i<2;i++) for(uint8_t i = 0;i<2;i++)
for(uint8_t j=0;j< stPWM_Mutex_Info[index].gpioinfo[i].vaild_num;j++) for(uint8_t j=0;j< stPWM_Mutex_Info[index].gpioinfo[i].vaild_num;j++)
if(stPWM_Mutex_Info[index].gpioinfo[i].pin[j] == pin) if(stPWM_Mutex_Info[index].gpioinfo[i].pin[j] == pin)
return stPWM_Mutex_Info[index].gpioinfo[i].Pin_Funs; return stPWM_Mutex_Info[index].gpioinfo[i].Pin_Funs;
return 0xff; return 0xff;
} }
void pwmSetDuty(u8 ch, u16 dutycycle) void pwmSetDuty(u8 ch, u16 dutycycle)
{ {
uint32_t ticksPerPeriod = CLOCK_SYS_CLOCK_HZ / PWM_FREQUENCY; uint32_t ticksPerPeriod = CLOCK_SYS_CLOCK_HZ / PWM_FREQUENCY;
u32 cmp_tick = ((u32)dutycycle * ticksPerPeriod) / ( PWM_TIMER_MAX_DUTY_CYCLE_NUM); u32 cmp_tick = ((u32)dutycycle * ticksPerPeriod) / ( PWM_TIMER_MAX_DUTY_CYCLE_NUM);
drv_pwm_cfg(ch, (u16)cmp_tick, ticksPerPeriod); drv_pwm_cfg(ch, (u16)cmp_tick, ticksPerPeriod);
} }
/* DESP: get the pwm index by led_id. /* DESP: get the pwm index by led_id.
* Auth: maozj.20200211. * Auth: maozj.20200211.
* */ * */
uint8_t kPwmGetIndexByID(uint8_t pwm_id ) uint8_t kPwmGetIndexByID(uint8_t pwm_id )
{ {
for(int index = 0; index < g_u8PwmChannelNum; ++index ) { for(int index = 0; index < g_u8PwmChannelNum; ++index ) {
iKonkeAfSelfPrint("####kPwmGetIndexByID index[%d] pwm_id[%d]\r\n",index, g_stPwmConfList[index].u8PwmId); //iKonkeAfSelfPrint("####kPwmGetIndexByID index[%d] pwm_id[%d]\r\n",index, g_stPwmConfList[index].u8PwmId);
if( g_stPwmConfList[index].u8PwmId != PWM_UNUSED_ID ) { if( g_stPwmConfList[index].u8PwmId != PWM_UNUSED_ID ) {
if( g_stPwmConfList[index].u8PwmId == pwm_id ) { if( g_stPwmConfList[index].u8PwmId == pwm_id ) {
return index; return index;
} }
} }
else break; else break;
} }
return 0XFF; return 0XFF;
} }
/* DESP: registration the system pwm driver processing function interface. /* DESP: registration the system pwm driver processing function interface.
Auth: maozj.20200211. Auth: maozj.20200211.
*/ */
void kPwmDriverhandler(uint8_t pwm_index, PwmGradientDirectionEnum st, uint16_t value) void kPwmDriverhandler(uint8_t pwm_index, PwmGradientDirectionEnum st, uint16_t value)
{ {
Pwm_Tick_Detect_Running_Flag = false; Pwm_Tick_Detect_Running_Flag = false;
if (pwm_index >= g_u8PwmChannelNum){ if (pwm_index >= g_u8PwmChannelNum){
iKonkeAfSelfPrint("####kPwmDriverhandler index is too large\r\n"); iKonkeAfSelfPrint("####kPwmDriverhandler index is too large\r\n");
return; return;
} }
iKonkeAfSelfPrint("######kPwmDriverhandler index(%d), direction(%d), value(%d)\r\n", pwm_index, st, value); //iKonkeAfSelfPrint("######kPwmDriverhandler index(%d), direction(%d), value(%d)\r\n", pwm_index, st, value);
switch(st) { switch(st) {
case (ELP_MIN): case (ELP_MIN):
{ {
pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,PWM_TIMER_MIN_DUTY_CYCLE_NUM); pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,PWM_TIMER_MIN_DUTY_CYCLE_NUM);
break; break;
} }
case (ELP_MID): case (ELP_MID):
{ {
pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,PWM_TIMER_MID_DUTY_CYCLE_NUM); pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,PWM_TIMER_MID_DUTY_CYCLE_NUM);
break; break;
} }
case (ELP_ANY): case (ELP_ANY):
{ {
//must use param[value] when pwm set a value //must use param[value] when pwm set a value
pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,value); pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,value);
break; break;
} }
case (ELP_MAX): case (ELP_MAX):
{ {
pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,PWM_TIMER_MAX_DUTY_CYCLE_NUM); pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,PWM_TIMER_MAX_DUTY_CYCLE_NUM);
break; break;
} }
case (ELP_TO_BRIGHT): case (ELP_TO_BRIGHT):
case (ELP_TO_DARKEN): case (ELP_TO_DARKEN):
{ {
break; break;
} }
default: break; default: break;
} }
} }
/* DESP: Check whether all pwm have stopped action detection. /* DESP: Check whether all pwm have stopped action detection.
* Auth: maozj.20200211. * Auth: maozj.20200211.
* */ * */
bool kPwmGradientChangeIsGoing(void ) bool kPwmGradientChangeIsGoing(void )
{ {
for(int pwm_index = 0; pwm_index < g_u8PwmChannelNum; ++pwm_index ) { for(int pwm_index = 0; pwm_index < g_u8PwmChannelNum; ++pwm_index ) {
if( g_stPwmCtrller[pwm_index].actionCounter > 0 ) { if( g_stPwmCtrller[pwm_index].actionCounter > 0 ) {
return true; return true;
} }
//else break; //else break;
} }
return false; return false;
} }
/* DESP: Check if the specified pwm is changing. /* DESP: Check if the specified pwm is changing.
* Auth: maozj.20200211. * Auth: maozj.20200211.
* */ * */
bool kPwmIsChanging(uint8_t pwm_id ) bool kPwmIsChanging(uint8_t pwm_id )
{ {
uint8_t pwm_index = kPwmGetIndexByID(pwm_id); uint8_t pwm_index = kPwmGetIndexByID(pwm_id);
if( pwm_index != 0XFF ) { if( pwm_index != 0XFF ) {
return (g_stPwmCtrller[pwm_index].actionCounter > 0); return (g_stPwmCtrller[pwm_index].actionCounter > 0);
} }
return false; return false;
} }
/* DESP: Indicator lamp behavior control interface. /* DESP: Indicator lamp behavior control interface.
Auth: dingmz_frc.20191108. Auth: dingmz_frc.20191108.
*/ */
void kPwmOptTrigger(uint8_t id, uint32_t start_value, uint32_t end_value, uint32_t duration_time ) void kPwmOptTrigger(uint8_t id, uint32_t start_value, uint32_t end_value, uint32_t duration_time )
{ {
uint8_t pwm_index = kPwmGetIndexByID(id); uint8_t pwm_index = kPwmGetIndexByID(id);
if( pwm_index == 0XFF || (start_value == end_value) ) { if( pwm_index == 0XFF || (start_value == end_value) ) {
iKonkeAfSelfPrint("#####PWM value is invalid index(%d)id(%d)start(%d)end(%d) \r\n", pwm_index, id, start_value, end_value); iKonkeAfSelfPrint("#####PWM value is invalid index(%d)id(%d)start(%d)end(%d) \r\n", pwm_index, id, start_value, end_value);
return ; return ;
} }
iKonkeAfSelfPrint("PWM_TRIGGER: pwm_index[%d], id(%d), start_value(%d), end_value(%d), times(%d)\r\n", iKonkeAfSelfPrint("PWM_TRIGGER: pwm_index[%d], id(%d), start_value(%d), end_value(%d), times(%d)\r\n",
pwm_index, id, start_value, end_value, duration_time); pwm_index, id, start_value, end_value, duration_time);
g_stPwmCtrller[pwm_index].actionCounter = duration_time / PWM_TICK_LOOP_NMS; g_stPwmCtrller[pwm_index].actionCounter = duration_time / PWM_TICK_LOOP_NMS;
g_stPwmCtrller[pwm_index].intervalDutyCycle = absSub(start_value,end_value) \ g_stPwmCtrller[pwm_index].intervalDutyCycle = absSub(start_value,end_value) \
/ g_stPwmCtrller[pwm_index].actionCounter; / g_stPwmCtrller[pwm_index].actionCounter;
g_stPwmCtrller[pwm_index].startDutyCycle = start_value; g_stPwmCtrller[pwm_index].startDutyCycle = start_value;
g_stPwmCtrller[pwm_index].endDutyCycle = end_value; g_stPwmCtrller[pwm_index].endDutyCycle = end_value;
g_stPwmCtrller[pwm_index].startDutyCycleValue = start_value; g_stPwmCtrller[pwm_index].startDutyCycleValue = start_value;
memcpy(&g_stPwmCtrller[pwm_index].gpioInfo, &g_stPwmConfList[pwm_index].gpioInfo, sizeof(PwmGpioListSt)); memcpy(&g_stPwmCtrller[pwm_index].gpioInfo, &g_stPwmConfList[pwm_index].gpioInfo, sizeof(PwmGpioSt));
iKonkeAfSelfPrint("action (%d) , interval[%d]\r\n",g_stPwmCtrller[pwm_index].actionCounter,g_stPwmCtrller[pwm_index].intervalDutyCycle); iKonkeAfSelfPrint("action (%d) , interval[%d]\r\n",g_stPwmCtrller[pwm_index].actionCounter,g_stPwmCtrller[pwm_index].intervalDutyCycle);
pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,start_value); pwmSetDuty(g_stPwmConfList[pwm_index].gpioInfo.pwmChannel,start_value);
if(!Pwm_Tick_Detect_Running_Flag) { if(!Pwm_Tick_Detect_Running_Flag) {
Pwm_Tick_Detect_Running_Flag = true; Pwm_Tick_Detect_Running_Flag = true;
} }
} }
/* DESP: single LED instance register interface. /* DESP: single LED instance register interface.
* Auth: dingmz_frc.20191108. * Auth: dingmz_frc.20191108.
* */ * */
kk_err_t kPwmRegister(uint8_t pwm_id, PwmGpioSt gpioInfo ) kk_err_t kPwmRegister(uint8_t pwm_id, PwmGpioSt gpioInfo )
{ {
if( PWM_UNKNOW_ID == pwm_id || PWM_ALLOPT_ID == pwm_id ) { if( PWM_UNKNOW_ID == pwm_id || PWM_ALLOPT_ID == pwm_id ) {
return KET_ERR_INVALID_PARAM; return KET_ERR_INVALID_PARAM;
} }
int valid_index = PWM_OBJS_SUPPORT_MAXN; int valid_index = PWM_OBJS_SUPPORT_MAXN;
kk_err_t err = KET_OK; kk_err_t err = KET_OK;
for(int index = 0; index < PWM_OBJS_SUPPORT_MAXN; ++index ) { for(int index = 0; index < PWM_OBJS_SUPPORT_MAXN; ++index ) {
if( g_stPwmConfList[index].u8PwmId == pwm_id ) { if( g_stPwmConfList[index].u8PwmId == pwm_id ) {
valid_index = index; valid_index = index;
break; break;
}else if((valid_index == PWM_OBJS_SUPPORT_MAXN) && (g_stPwmConfList[index].u8PwmId == PWM_UNUSED_ID)) { }else if((valid_index == PWM_OBJS_SUPPORT_MAXN) && (g_stPwmConfList[index].u8PwmId == PWM_UNUSED_ID)) {
valid_index = index; valid_index = index;
} }
} }
uint8_t channel = Get_PWM_CHANNEL_FROM_PIN(gpioInfo.pin); uint8_t channel = Get_PWM_CHANNEL_FROM_PIN(gpioInfo.pin);
if(channel == 0xff) if(channel == 0xff)
{ {
iKonkeAfSelfPrint("pin (%d) not support pwm function!\r\n",gpioInfo.pin); iKonkeAfSelfPrint("pin (%d) not support pwm function!\r\n",gpioInfo.pin);
return KET_ERR_CONTENT_MISMATCH; return KET_ERR_CONTENT_MISMATCH;
} }
if( valid_index < PWM_OBJS_SUPPORT_MAXN ) { if( valid_index < PWM_OBJS_SUPPORT_MAXN ) {
memset(&g_stPwmCtrller[valid_index], 0, sizeof(g_stPwmCtrller[valid_index])); memset(&g_stPwmCtrller[valid_index], 0, sizeof(g_stPwmCtrller[valid_index]));
g_stPwmConfList[valid_index].u8PwmId = pwm_id; g_stPwmConfList[valid_index].u8PwmId = pwm_id;
g_stPwmConfList[valid_index].gpioInfo.pin = gpioInfo.pin; g_stPwmConfList[valid_index].gpioInfo.pin = gpioInfo.pin;
g_stPwmConfList[valid_index].gpioInfo.pwmChannel = channel; g_stPwmConfList[valid_index].gpioInfo.pwmChannel = channel;
gpio_set_func(g_stPwmConfList[valid_index].gpioInfo.pin,Get_PIN_FUNC_By_PIN(gpioInfo.pin)); gpio_set_func(g_stPwmConfList[valid_index].gpioInfo.pin,Get_PIN_FUNC_By_PIN(gpioInfo.pin));
iKonkeAfSelfPrint("PWM_REGISTER:index(%d),id(%d), pwmChannel(%d)\r\n",valid_index, g_stPwmConfList[valid_index].u8PwmId iKonkeAfSelfPrint("PWM_REGISTER:index(%d),id(%d), pwmChannel(%d)\r\n",valid_index, g_stPwmConfList[valid_index].u8PwmId
, g_stPwmConfList[valid_index].gpioInfo.pwmChannel); , g_stPwmConfList[valid_index].gpioInfo.pwmChannel);
pwmSetDuty(g_stPwmConfList[valid_index].gpioInfo.pwmChannel,0); pwmSetDuty(g_stPwmConfList[valid_index].gpioInfo.pwmChannel,0);
drv_pwm_start(g_stPwmConfList[valid_index].gpioInfo.pwmChannel); drv_pwm_start(g_stPwmConfList[valid_index].gpioInfo.pwmChannel);
}else { }else {
err = KET_ERR_INSUFFICIENT_SPACE; err = KET_ERR_INSUFFICIENT_SPACE;
} }
return err; return err;
} }
/* DESP: led control module Initialize configuration interface. /* DESP: led control module Initialize configuration interface.
* Note: Led initialization interface supports one-time registration of multiple LEDs! * Note: Led initialization interface supports one-time registration of multiple LEDs!
* Auth: dingmz_frc.20191108. * Auth: dingmz_frc.20191108.
* */ * */
kk_err_t kPwmModuleInit(PwmConfSt pwmlist[], unsigned char pwm_number, pPwmActionDoneCallback pCallback) kk_err_t kPwmModuleInit(PwmConfSt pwmlist[], unsigned char pwm_number, pPwmActionDoneCallback pCallback)
{ {
kk_err_t err = KET_OK; kk_err_t err = KET_OK;
memset(g_stPwmConfList, PWM_UNUSED_ID, sizeof(g_stPwmConfList)); memset(g_stPwmConfList, PWM_UNUSED_ID, sizeof(g_stPwmConfList));
memset(g_stPwmCtrller, 0, sizeof(g_stPwmCtrller)); memset(g_stPwmCtrller, 0, sizeof(g_stPwmCtrller));
if(pwmlist && (pwm_number > 0)) { if(pwmlist && (pwm_number > 0)) {
g_u8PwmChannelNum = (pwm_number < PWM_OBJS_SUPPORT_MAXN)?pwm_number:PWM_OBJS_SUPPORT_MAXN; g_u8PwmChannelNum = (pwm_number < PWM_OBJS_SUPPORT_MAXN)?pwm_number:PWM_OBJS_SUPPORT_MAXN;
for(int index = 0; index < g_u8PwmChannelNum; ++index ) { for(int index = 0; index < g_u8PwmChannelNum; ++index ) {
err = kPwmRegister(pwmlist[index].u8PwmId, pwmlist[index].gpioInfo); err = kPwmRegister(pwmlist[index].u8PwmId, pwmlist[index].gpioInfo);
} }
} }
//init callback function when led blink over //init callback function when led blink over
g_pPwmActionDoneCallback = pCallback; g_pPwmActionDoneCallback = pCallback;
//init software timer //init software timer
if(Tick_Pwm_TimerEvt){ if(Tick_Pwm_TimerEvt){
TL_ZB_TIMER_CANCEL(&Tick_Pwm_TimerEvt); TL_ZB_TIMER_CANCEL(&Tick_Pwm_TimerEvt);
} }
Tick_Pwm_TimerEvt = TL_ZB_TIMER_SCHEDULE(kPwmGradientChangeEventHandler, NULL, PWM_TICK_LOOP_NMS); Tick_Pwm_TimerEvt = TL_ZB_TIMER_SCHEDULE(kPwmGradientChangeEventHandler, NULL, PWM_TICK_LOOP_NMS);
return err; return err;
} }
static s32 kPwmGradientChangeEventHandler(void *data) static s32 kPwmGradientChangeEventHandler(void *data)
{ {
if(!Pwm_Tick_Detect_Running_Flag) if(!Pwm_Tick_Detect_Running_Flag)
return 0; return 0;
for (uint8_t i = 0; i < g_u8PwmChannelNum; i++){ for (uint8_t i = 0; i < g_u8PwmChannelNum; i++){
if (g_stPwmCtrller[i].actionCounter > 0){ if (g_stPwmCtrller[i].actionCounter > 0){
if (g_stPwmCtrller[i].startDutyCycle > g_stPwmCtrller[i].endDutyCycle){ if (g_stPwmCtrller[i].startDutyCycle > g_stPwmCtrller[i].endDutyCycle){
g_stPwmCtrller[i].actionCounter--; g_stPwmCtrller[i].actionCounter--;
g_stPwmCtrller[i].startDutyCycleValue -= g_stPwmCtrller[i].intervalDutyCycle; g_stPwmCtrller[i].startDutyCycleValue -= g_stPwmCtrller[i].intervalDutyCycle;
pwmSetDuty(g_stPwmCtrller[i].gpioInfo.pwmChannel,g_stPwmCtrller[i].startDutyCycleValue); pwmSetDuty(g_stPwmCtrller[i].gpioInfo.pwmChannel,g_stPwmCtrller[i].startDutyCycleValue);
} else if (g_stPwmCtrller[i].startDutyCycle < g_stPwmCtrller[i].endDutyCycle){ } else if (g_stPwmCtrller[i].startDutyCycle < g_stPwmCtrller[i].endDutyCycle){
g_stPwmCtrller[i].actionCounter--; g_stPwmCtrller[i].actionCounter--;
g_stPwmCtrller[i].startDutyCycleValue += g_stPwmCtrller[i].intervalDutyCycle; g_stPwmCtrller[i].startDutyCycleValue += g_stPwmCtrller[i].intervalDutyCycle;
pwmSetDuty(g_stPwmCtrller[i].gpioInfo.pwmChannel,g_stPwmCtrller[i].startDutyCycleValue); pwmSetDuty(g_stPwmCtrller[i].gpioInfo.pwmChannel,g_stPwmCtrller[i].startDutyCycleValue);
} }
iKonkeAfSelfPrint("BREATH index(%d)channel(%d) count(%d),%d\r\n", i,g_stPwmCtrller[i].gpioInfo.pwmChannel, g_stPwmCtrller[i].actionCounter,g_stPwmCtrller[i].startDutyCycleValue); //iKonkeAfSelfPrint("BREATH index(%d)channel(%d) count(%d),%d\r\n", i,g_stPwmCtrller[i].gpioInfo.pwmChannel, g_stPwmCtrller[i].actionCounter,g_stPwmCtrller[i].startDutyCycleValue);
//PWM_IDص //PWM_IDص
if (g_stPwmCtrller[i].actionCounter == 0){ if (g_stPwmCtrller[i].actionCounter == 0){
//may be end duty cycle not equal, restore end duty cycle //may be end duty cycle not equal, restore end duty cycle
pwmSetDuty(g_stPwmCtrller[i].gpioInfo.pwmChannel,g_stPwmCtrller[i].endDutyCycle); pwmSetDuty(g_stPwmCtrller[i].gpioInfo.pwmChannel,g_stPwmCtrller[i].endDutyCycle);
if (g_pPwmActionDoneCallback){ if (g_pPwmActionDoneCallback){
PwmGradientDirectionEnum opt = ELP_OPT_DEFAULT; PwmGradientDirectionEnum opt = ELP_OPT_DEFAULT;
if (g_stPwmCtrller[i].startDutyCycle > g_stPwmCtrller[i].endDutyCycle){ if (g_stPwmCtrller[i].startDutyCycle > g_stPwmCtrller[i].endDutyCycle){
opt = ELP_TO_DARKEN; opt = ELP_TO_DARKEN;
}else if (g_stPwmCtrller[i].startDutyCycle < g_stPwmCtrller[i].endDutyCycle){ }else if (g_stPwmCtrller[i].startDutyCycle < g_stPwmCtrller[i].endDutyCycle){
opt = ELP_TO_BRIGHT; opt = ELP_TO_BRIGHT;
} }
if (opt != ELP_OPT_DEFAULT){ if (opt != ELP_OPT_DEFAULT){
//user custom implement //user custom implement
g_pPwmActionDoneCallback(g_stPwmConfList[i].u8PwmId, opt); g_pPwmActionDoneCallback(g_stPwmConfList[i].u8PwmId, opt);
} }
} }
} }
} }
} }
return 0; return 0;
} }
/* DESP: clear pwm gradient counter interface by pwm id.
void PWM_Test(uint8_t data) * Auth: maozj.20200212.
{ * */
// gpio_set_func(GPIO_PB3,AS_PWM0_N); bool kPwmClearGradientCounterById(uint8_t pwm_id)
// if(data == 1) {
// pwmSetDuty(0,60000); if (pwm_id == PWM_UNUSED_ID){
// else iKonkeAfSelfPrint("#Err: kPwmClearGradientCounterById pwm id is invalid\r\n");
// pwmSetDuty(0,0); return false;
// drv_pwm_start(0); }
// for(uint8_t index = 0;index < PWM_OBJS_SUPPORT_MAXN;index++ )
// { for (int index = 0; index < PWM_OBJS_SUPPORT_MAXN; ++index ) {
// iKonkeAfSelfPrint("stPWM_Mutex_Info(%d)\r\n",index); //iKonkeAfSelfPrint("####kPwmGetIndexByID index[%d] pwm_id[%d]\r\n",index, g_stPwmConfList[index].u8PwmId);
// for(uint8_t i = 0;i<2;i++)
// { if (g_stPwmConfList[index].u8PwmId == pwm_id) {
// iKonkeAfSelfPrint("gpio(%d),num = %d\r\n",i,stPWM_Mutex_Info[index].gpioinfo[i].vaild_num); iKonkeAfSelfPrint("###kPwmClearGradientCounterById success index(%d) id(%d)\r\n", index, pwm_id);
// for(uint8_t j=0;j< stPWM_Mutex_Info[index].gpioinfo[i].vaild_num;j++) g_stPwmCtrller[index].actionCounter = 0;
// { return true;
// iKonkeAfSelfPrint("gpio(%d)\r\n",stPWM_Mutex_Info[index].gpioinfo[i].pin[j]); }
// } }
// }
// } return false;
}
}
void PWM_Test(uint8_t data)
{
// gpio_set_func(GPIO_PB3,AS_PWM0_N);
// if(data == 1)
// pwmSetDuty(0,60000);
// else
// pwmSetDuty(0,0);
// drv_pwm_start(0);
// for(uint8_t index = 0;index < PWM_OBJS_SUPPORT_MAXN;index++ )
// {
// iKonkeAfSelfPrint("stPWM_Mutex_Info(%d)\r\n",index);
// for(uint8_t i = 0;i<2;i++)
// {
// iKonkeAfSelfPrint("gpio(%d),num = %d\r\n",i,stPWM_Mutex_Info[index].gpioinfo[i].vaild_num);
// for(uint8_t j=0;j< stPWM_Mutex_Info[index].gpioinfo[i].vaild_num;j++)
// {
// iKonkeAfSelfPrint("gpio(%d)\r\n",stPWM_Mutex_Info[index].gpioinfo[i].pin[j]);
// }
// }
// }
}
...@@ -89,7 +89,7 @@ kk_err_t kPwmModuleInit(PwmConfSt pwmlist[], unsigned char pwm_number, pPwmActio ...@@ -89,7 +89,7 @@ kk_err_t kPwmModuleInit(PwmConfSt pwmlist[], unsigned char pwm_number, pPwmActio
*/ */
void kPwmOptTrigger(uint8_t id, uint32_t start_value, uint32_t end_value, uint32_t duration_time ); void kPwmOptTrigger(uint8_t id, uint32_t start_value, uint32_t end_value, uint32_t duration_time );
bool kPwmClearGradientCounterById(uint8_t pwm_id);
void PWM_Test(uint8_t data); void PWM_Test(uint8_t data);
......
#include "ikk-uart.h" #include "ikk-uart.h"
#include "../general/ikk-debug.h" #include "../general/ikk-debug.h"
__attribute__((aligned(4))) uint8_t dma_uartTxBuf[UMSG_NODE_SIZE] = {0}; __attribute__((aligned(4))) uint8_t dma_uartTxBuf[UMSG_NODE_SIZE] = {0};
__attribute__((aligned(4))) uint8_t dma_uartRxBuf[UART_RECEIVER_CACHE_SIZE] = {0}; __attribute__((aligned(4))) uint8_t dma_uartRxBuf[UART_RECEIVER_CACHE_SIZE] = {0};
// Serial Data Sending Time Cycle Period // Serial Data Sending Time Cycle Period
#define UART_SENTLOOP_INTV 35 // unit:ms #define UART_SENTLOOP_INTV 35 // unit:ms
// Serial Data retry Sending Time Cycle Period // Serial Data retry Sending Time Cycle Period
#define UART_SENTRETRY_INTERVAL 500 // unit:ms #define UART_SENTRETRY_INTERVAL 500 // unit:ms
// Serial Data Receiving Time Cycle Period // Serial Data Receiving Time Cycle Period
#define UART_RECVLOOP_INTV 25 // unit:ms #define UART_RECVLOOP_INTV 25 // unit:ms
// Waitting times for Serial Receiving Data // Waitting times for Serial Receiving Data
#define UART_RECV_TIMEOUT 3000// unit:ms #define UART_RECV_TIMEOUT 3000// unit:ms
// uart message recv queue // uart message recv queue
UMsgQueueSt g_uMsgRecvQueue,g_uMsgSentQueue; UMsgQueueSt g_uMsgRecvQueue,g_uMsgSentQueue;
// uart manager instance // uart manager instance
UartManagerSt g_uManagerInsc; UartManagerSt g_uManagerInsc;
static ev_timer_event_t *ikkUartSentLoopCheckEventEvt = NULL; static ev_timer_event_t *ikkUartSentLoopCheckEventEvt = NULL;
static ev_timer_event_t *ikkUartRecvLoopCheckEventEvt = NULL; static ev_timer_event_t *ikkUartRecvLoopCheckEventEvt = NULL;
static void dma_uartRcvHandler(void); static void dma_uartRcvHandler(void);
static s32 ikkUartSentLoopCheckEventHandler(void *arg ); static s32 ikkUartSentLoopCheckEventHandler(void *arg );
static s32 ikkUartRecvLoopCheckEventHandler(void *arg ); static s32 ikkUartRecvLoopCheckEventHandler(void *arg );
// //
//void ikkUartRecvLoopCheckEventHandler(void ); //void ikkUartRecvLoopCheckEventHandler(void );
// //
/* DESP: serial usart driver init interface. /* DESP: serial usart driver init interface.
* PARAM[recv_header]: Recognition Sequence of recv effective data frame header and detection of Data Frame start. * PARAM[recv_header]: Recognition Sequence of recv effective data frame header and detection of Data Frame start.
* PARAM[recv_header_n]: the length of recv data frame header. * PARAM[recv_header_n]: the length of recv data frame header.
* PARAM[buffer_len_index]: the length of paload. * PARAM[buffer_len_index]: the length of paload.
* PARAM[addtional_len]: the length of added * PARAM[addtional_len]: the length of added
* PARAM[pfunc_crc]: CRC function. * PARAM[pfunc_crc]: CRC function.
* PARAM[pfunc_incoming]: Callback function when valid data frame is detected, provided by youself. * PARAM[pfunc_incoming]: Callback function when valid data frame is detected, provided by youself.
* PARAM[bSleepSupport]: support for sleepy device function. * PARAM[bSleepSupport]: support for sleepy device function.
* Auth: dingmz_frc.20190620. * Auth: dingmz_frc.20190620.
* */ * */
kk_err_t kUartModuleInit(GPIO_PinTypeDef Txpin,GPIO_PinTypeDef Rxpin, uint32_t rate, UART_ParityTypeDef parity, UART_StopBitTypeDef stopBits kk_err_t kUartModuleInit(GPIO_PinTypeDef Txpin,GPIO_PinTypeDef Rxpin, uint32_t rate, UART_ParityTypeDef parity, UART_StopBitTypeDef stopBits
, uint8_t recv_header[], uint8_t recv_header_n,uint8_t buffer_len_index,uint8_t addtional_len , uint8_t recv_header[], uint8_t recv_header_n,uint8_t buffer_len_index,uint8_t addtional_len
, PFUNC_CRC pfunc_crc, PFUNC_INCOMING_CALLBACK pfunc_incoming , PFUNC_CRC pfunc_crc, PFUNC_INCOMING_CALLBACK pfunc_incoming
, bool bSleepSupport ) , bool bSleepSupport )
{ {
if((0 == recv_header_n) || (NULL == pfunc_crc) || (NULL == pfunc_incoming)) { if((0 == recv_header_n) || (NULL == pfunc_crc) || (NULL == pfunc_incoming)) {
return KET_ERR_INVALID_PARAM; return KET_ERR_INVALID_PARAM;
} }
if( recv_header_n > sizeof(g_uManagerInsc.recv_header)) { if( recv_header_n > sizeof(g_uManagerInsc.recv_header)) {
return KET_ERR_INVALID_PARAM; return KET_ERR_INVALID_PARAM;
} }
kk_err_t err = KET_OK; kk_err_t err = KET_OK;
g_uManagerInsc.Rxpin = Rxpin; g_uManagerInsc.Rxpin = Rxpin;
g_uManagerInsc.Txpin = Txpin; g_uManagerInsc.Txpin = Txpin;
memcpy(g_uManagerInsc.recv_header, recv_header, recv_header_n); memcpy(g_uManagerInsc.recv_header, recv_header, recv_header_n);
g_uManagerInsc.recv_header_n = recv_header_n; g_uManagerInsc.recv_header_n = recv_header_n;
g_uManagerInsc.buffer_len_index = buffer_len_index; g_uManagerInsc.buffer_len_index = buffer_len_index;
g_uManagerInsc.additional_len = addtional_len; g_uManagerInsc.additional_len = addtional_len;
g_uManagerInsc.pfunc_crc = pfunc_crc; g_uManagerInsc.pfunc_crc = pfunc_crc;
g_uManagerInsc.pfunc_incoming = pfunc_incoming; g_uManagerInsc.pfunc_incoming = pfunc_incoming;
g_uManagerInsc.bSleepSupport = bSleepSupport; g_uManagerInsc.bSleepSupport = bSleepSupport;
g_uManagerInsc.u16SleepCounter = UART_RECV_TIMEOUT / UART_RECVLOOP_INTV; g_uManagerInsc.u16SleepCounter = UART_RECV_TIMEOUT / UART_RECVLOOP_INTV;
drv_uart_pin_set(Txpin, Rxpin); drv_uart_pin_set(Txpin, Rxpin);
drv_uart_init_self(rate,parity,stopBits, dma_uartRxBuf, sizeof(dma_uartRxBuf)/sizeof(u8), dma_uartRcvHandler); drv_uart_init_self(rate,parity,stopBits, dma_uartRxBuf, sizeof(dma_uartRxBuf)/sizeof(u8), dma_uartRcvHandler);
//regesiter send time tick //regesiter send time tick
if(ikkUartSentLoopCheckEventEvt){ if(ikkUartSentLoopCheckEventEvt){
TL_ZB_TIMER_CANCEL(&ikkUartSentLoopCheckEventEvt); TL_ZB_TIMER_CANCEL(&ikkUartSentLoopCheckEventEvt);
} }
ikkUartSentLoopCheckEventEvt = TL_ZB_TIMER_SCHEDULE(ikkUartSentLoopCheckEventHandler, NULL, UART_SENTLOOP_INTV); ikkUartSentLoopCheckEventEvt = TL_ZB_TIMER_SCHEDULE(ikkUartSentLoopCheckEventHandler, NULL, UART_SENTLOOP_INTV);
//regesiter recv time tick //regesiter recv time tick
if(ikkUartRecvLoopCheckEventEvt){ if(ikkUartRecvLoopCheckEventEvt){
TL_ZB_TIMER_CANCEL(&ikkUartRecvLoopCheckEventEvt); TL_ZB_TIMER_CANCEL(&ikkUartRecvLoopCheckEventEvt);
} }
ikkUartRecvLoopCheckEventEvt = TL_ZB_TIMER_SCHEDULE(ikkUartRecvLoopCheckEventHandler, NULL, UART_RECVLOOP_INTV); ikkUartRecvLoopCheckEventEvt = TL_ZB_TIMER_SCHEDULE(ikkUartRecvLoopCheckEventHandler, NULL, UART_RECVLOOP_INTV);
//reset g_uMsgSentQueue,g_uMsgSentQueue buff //reset g_uMsgSentQueue,g_uMsgSentQueue buff
memset(&g_uMsgSentQueue,0,sizeof(UMsgQueueSt)); memset(&g_uMsgSentQueue,0,sizeof(UMsgQueueSt));
memset(&g_uMsgRecvQueue,0,sizeof(UMsgQueueSt)); memset(&g_uMsgRecvQueue,0,sizeof(UMsgQueueSt));
return err; return err;
} }
/* DESP: serial usart message data sent interface. /* DESP: serial usart message data sent interface.
Auth: dingmz_frc.20190627. Auth: dingmz_frc.20190627.
*/ */
kk_err_t MsgSent(uint8_t *buffer, uint8_t length ) kk_err_t MsgSent(uint8_t *buffer, uint8_t length )
{ {
#if 1 // Just for debug #if 1 // Just for debug
iKonkeAfSelfPrint("\r\n-- MSG SENT[%d]:\r\n", length); iKonkeAfSelfPrint("\r\n-- MSG SENT[%d]:\r\n", length);
iKonkeAfSelfPrintBuffer(buffer, length); iKonkeAfSelfPrintBuffer(buffer, length);
#endif #endif
return ((drv_uart_tx_start(buffer, length))?KET_OK:KET_ERR_UNKNOW); return ((drv_uart_tx_start(buffer, length))?KET_OK:KET_ERR_UNKNOW);
} }
/* DESP: message header sniffer. /* DESP: message header sniffer.
Auth: dingmz_frc.20190601. Auth: dingmz_frc.20190601.
*/ */
static bool MsgHeaderSniffer(uint8_t org_data ) static bool MsgHeaderSniffer(uint8_t org_data )
{ {
if( g_uManagerInsc.header_chunk_index < g_uManagerInsc.recv_header_n ) { if( g_uManagerInsc.header_chunk_index < g_uManagerInsc.recv_header_n ) {
g_uManagerInsc.header_chunk[g_uManagerInsc.header_chunk_index++] = org_data; g_uManagerInsc.header_chunk[g_uManagerInsc.header_chunk_index++] = org_data;
}else { // shift... }else { // shift...
int index = 0; int index = 0;
for( ; index < (g_uManagerInsc.recv_header_n - 1); ++index ) { for( ; index < (g_uManagerInsc.recv_header_n - 1); ++index ) {
g_uManagerInsc.header_chunk[index] = g_uManagerInsc.header_chunk[index + 1]; g_uManagerInsc.header_chunk[index] = g_uManagerInsc.header_chunk[index + 1];
} }
g_uManagerInsc.header_chunk[index] = org_data; g_uManagerInsc.header_chunk[index] = org_data;
} }
bool _bfound = false; bool _bfound = false;
if( g_uManagerInsc.header_chunk_index == g_uManagerInsc.recv_header_n ) { if( g_uManagerInsc.header_chunk_index == g_uManagerInsc.recv_header_n ) {
if( memcmp(g_uManagerInsc.header_chunk, g_uManagerInsc.recv_header, g_uManagerInsc.recv_header_n) == 0 ) { if( memcmp(g_uManagerInsc.header_chunk, g_uManagerInsc.recv_header, g_uManagerInsc.recv_header_n) == 0 ) {
_bfound = true; _bfound = true;
} }
} }
return _bfound; return _bfound;
} }
// //
/* DESP: pop msg from the head of buffer queue chunk. /* DESP: pop msg from the head of buffer queue chunk.
Auth: dingmz_frc.20190626. Auth: dingmz_frc.20190626.
*/ */
static UMsgNodeSt *PopMsg(QueueEm eQ ) static UMsgNodeSt *PopMsg(QueueEm eQ )
{ {
UMsgQueueSt *pQ = (eQ == EQU_RECV)?(&g_uMsgRecvQueue):(&g_uMsgSentQueue); UMsgQueueSt *pQ = (eQ == EQU_RECV)?(&g_uMsgRecvQueue):(&g_uMsgSentQueue);
return (pQ->counter?(&(pQ->node[0])):NULL); return (pQ->counter?(&(pQ->node[0])):NULL);
} }
/* DESP: push msg to buffer queue chunk . /* DESP: push msg to buffer queue chunk .
Auth: dingmz_frc.20180626. Auth: dingmz_frc.20180626.
*/ */
static kk_err_t PushMsg(QueueEm eQ, UMsgNodeSt *pNode ) static kk_err_t PushMsg(QueueEm eQ, UMsgNodeSt *pNode )
{ {
if( NULL == pNode ) { if( NULL == pNode ) {
return KET_ERR_INVALID_PARAM; return KET_ERR_INVALID_PARAM;
} }
kk_err_t err = KET_OK; kk_err_t err = KET_OK;
UMsgQueueSt *pQ = (eQ == EQU_RECV)?(&g_uMsgRecvQueue):(&g_uMsgSentQueue); UMsgQueueSt *pQ = (eQ == EQU_RECV)?(&g_uMsgRecvQueue):(&g_uMsgSentQueue);
if( pQ->counter < UMSG_NODE_MAX ) { if( pQ->counter < UMSG_NODE_MAX ) {
memcpy(&pQ->node[pQ->counter], pNode, sizeof(UMsgNodeSt)); memcpy(&pQ->node[pQ->counter], pNode, sizeof(UMsgNodeSt));
pQ->counter++; pQ->counter++;
}else { }else {
err = KET_ERR_NO_PERMISSIONS; err = KET_ERR_NO_PERMISSIONS;
} }
return err; return err;
} }
/* DESP: Remove Msg from Specified position[index base 0]. /* DESP: Remove Msg from Specified position[index base 0].
Auth: dingmz_frc.20180430. Auth: dingmz_frc.20180430.
*/ */
static kk_err_t RemoveMsg(QueueEm eQ, uint8_t index_pos ) static kk_err_t RemoveMsg(QueueEm eQ, uint8_t index_pos )
{ {
kk_err_t err = KET_OK; kk_err_t err = KET_OK;
UMsgQueueSt *pQ = (eQ == EQU_RECV)?(&g_uMsgRecvQueue):(&g_uMsgSentQueue); UMsgQueueSt *pQ = (eQ == EQU_RECV)?(&g_uMsgRecvQueue):(&g_uMsgSentQueue);
if( index_pos < pQ->counter ) { if( index_pos < pQ->counter ) {
for(int index = index_pos; index < (pQ->counter - 1); ++index ) { for(int index = index_pos; index < (pQ->counter - 1); ++index ) {
memcpy(&(pQ->node[index]), &(pQ->node[index + 1]), sizeof(UMsgNodeSt)); memcpy(&(pQ->node[index]), &(pQ->node[index + 1]), sizeof(UMsgNodeSt));
} }
pQ->counter--; pQ->counter--;
}else { }else {
err = KET_ERR_NON_EXIST; err = KET_ERR_NON_EXIST;
} }
return err; return err;
} }
/* DESP: serial usart msg sending loop check handler. /* DESP: serial usart msg sending loop check handler.
* Auth: dingmz_frc.20190702. * Auth: dingmz_frc.20190702.
* */ * */
static s32 ikkUartSentLoopCheckEventHandler(void *arg ) static s32 ikkUartSentLoopCheckEventHandler(void *arg )
{ {
UMsgNodeSt *pMsgNode = PopMsg(EQU_SENT); UMsgNodeSt *pMsgNode = PopMsg(EQU_SENT);
if( pMsgNode ) { if( pMsgNode ) {
// check if the message is valid. // check if the message is valid.
if( pMsgNode->sent_try > 0 ) { if( pMsgNode->sent_try > 0 ) {
MsgSent(pMsgNode->buffer, pMsgNode->length); MsgSent(pMsgNode->buffer, pMsgNode->length);
--pMsgNode->sent_try; --pMsgNode->sent_try;
} }
else { else {
// delete msg form head when invaild! // delete msg form head when invaild!
RemoveMsg(EQU_SENT, 0); RemoveMsg(EQU_SENT, 0);
} }
} }
return 0; return 0;
} }
/* DESP: serial usart msg receiving loop check handler. /* DESP: serial usart msg receiving loop check handler.
* Auth: dingmz_frc.20190626. * Auth: dingmz_frc.20190626.
* */ * */
static s32 ikkUartRecvLoopCheckEventHandler(void *arg ) static s32 ikkUartRecvLoopCheckEventHandler(void *arg )
{ {
UMsgNodeSt *pMsgNode = PopMsg(EQU_RECV), *pMsgSending = PopMsg(EQU_SENT); UMsgNodeSt *pMsgNode = PopMsg(EQU_RECV), *pMsgSending = PopMsg(EQU_SENT);
if( pMsgNode ) { if( pMsgNode ) {
bool bDispatchEnable = true; bool bDispatchEnable = true;
// reset the recving timeout counter. // reset the recving timeout counter.
g_uManagerInsc.u16SleepCounter = UART_RECV_TIMEOUT / UART_RECVLOOP_INTV; g_uManagerInsc.u16SleepCounter = UART_RECV_TIMEOUT / UART_RECVLOOP_INTV;
// Does the matching message send a response for the specified message? // Does the matching message send a response for the specified message?
if( pMsgSending ) { if( pMsgSending ) {
iKonkeAfSelfPrint("match: org(%X:%X), des(%X:%X)\r\n" iKonkeAfSelfPrint("match: org(%X:%X), des(%X:%X)\r\n"
, pMsgNode->buffer[pMsgSending->matcher_offset], pMsgNode->buffer[pMsgSending->matcher_offset + 1] , pMsgNode->buffer[pMsgSending->matcher_offset], pMsgNode->buffer[pMsgSending->matcher_offset + 1]
, pMsgSending->matcher[0], pMsgSending->matcher[1]); , pMsgSending->matcher[0], pMsgSending->matcher[1]);
if( memcmp(pMsgNode->buffer + pMsgSending->matcher_offset, pMsgSending->matcher, pMsgSending->matcher_n) == 0 ) { if( memcmp(pMsgNode->buffer + pMsgSending->matcher_offset, pMsgSending->matcher, pMsgSending->matcher_n) == 0 ) {
pMsgSending->sent_try = 0; pMsgSending->sent_try = 0;
// need to dispatch? // need to dispatch?
if( !pMsgSending->bRspNeedtoDispatch ) { if( !pMsgSending->bRspNeedtoDispatch ) {
bDispatchEnable = false; bDispatchEnable = false;
} }
} }
} }
if((bDispatchEnable) && (g_uManagerInsc.pfunc_incoming)) { if((bDispatchEnable) && (g_uManagerInsc.pfunc_incoming)) {
g_uManagerInsc.pfunc_incoming(pMsgNode); g_uManagerInsc.pfunc_incoming(pMsgNode);
} }
// Remove the Msg form head; // Remove the Msg form head;
RemoveMsg(EQU_RECV, 0); RemoveMsg(EQU_RECV, 0);
} }
return 0; return 0;
} }
/* DESP: serial usart message data sent interface. /* DESP: serial usart message data sent interface.
* Note: Actively sending data requiring detection and retransmitting needs to join the sending queue, * Note: Actively sending data requiring detection and retransmitting needs to join the sending queue,
* But the ACK packet is sent only once. * But the ACK packet is sent only once.
Auth: dingmz_frc.20190627. Auth: dingmz_frc.20190627.
*/ */
kk_err_t kUartMsgSent(UMsgNodeSt *pMsgNode ) kk_err_t kUartMsgSent(UMsgNodeSt *pMsgNode )
{ {
kk_err_t err = KET_ERR_UNKNOW; kk_err_t err = KET_ERR_UNKNOW;
if( pMsgNode->sent_try > 0 ) { if( pMsgNode->sent_try > 0 ) {
err = PushMsg(EQU_SENT, pMsgNode); err = PushMsg(EQU_SENT, pMsgNode);
}else { }else {
err = MsgSent(pMsgNode->buffer, pMsgNode->length); err = MsgSent(pMsgNode->buffer, pMsgNode->length);
} }
return err; return err;
} }
static void dma_uartRcvHandler(void) static void dma_uartRcvHandler(void)
{ {
static UMsgNodeSt MsgNode; static UMsgNodeSt MsgNode;
bool recving = false; bool recving = false;
uint8_t head_index = 0; uint8_t head_index = 0;
uint32_t len = *dma_uartRxBuf; uint32_t len = *dma_uartRxBuf;
// iKonkeAfSelfPrint("#############dma_uartRcvHandler,recv data len = %d \r\n",len); iKonkeAfSelfPrint("#############dma_uartRcvHandler,recv data len = %d \r\n",len);
// iKonkeAfSelfPrintBuffer(dma_uartRxBuf+4,len); iKonkeAfSelfPrintBuffer(dma_uartRxBuf+4,len);
memset(&MsgNode,0,sizeof(UMsgNodeSt)); memset(&MsgNode,0,sizeof(UMsgNodeSt));
for(uint8_t i = 0;i< len;i++) for(uint8_t i = 0;i< len;i++)
{ {
// find the message header // find the message header
if( recving == false ) { if( recving == false ) {
if( MsgHeaderSniffer(dma_uartRxBuf[i+4]) ) { if( MsgHeaderSniffer(dma_uartRxBuf[i+4]) ) {
recving = true; recving = true;
head_index = i+4-g_uManagerInsc.recv_header_n +1; head_index = i+4-g_uManagerInsc.recv_header_n +1;
//muster tell this pack data total length //muster tell this pack data total length
MsgNode.length = dma_uartRxBuf[head_index+g_uManagerInsc.buffer_len_index]+g_uManagerInsc.additional_len; MsgNode.length = dma_uartRxBuf[head_index+g_uManagerInsc.buffer_len_index]+g_uManagerInsc.additional_len;
//iKonkeAfSelfPrint("#############bufferlen = %d, addtional len = %d \r\n",dma_uartRxBuf[head_index+g_uManagerInsc.buffer_len_index],g_uManagerInsc.additional_len); //iKonkeAfSelfPrint("#############bufferlen = %d, addtional len = %d \r\n",dma_uartRxBuf[head_index+g_uManagerInsc.buffer_len_index],g_uManagerInsc.additional_len);
} }
}else { }else {
if( MsgNode.length < UMSG_NODE_SIZE ) if( MsgNode.length < UMSG_NODE_SIZE )
memcpy(MsgNode.buffer,dma_uartRxBuf+head_index,MsgNode.length); memcpy(MsgNode.buffer,dma_uartRxBuf+head_index,MsgNode.length);
// push to msg queue when crc succeed. // push to msg queue when crc succeed.
if( g_uManagerInsc.pfunc_crc(MsgNode.buffer, MsgNode.length)) { if( g_uManagerInsc.pfunc_crc(MsgNode.buffer, MsgNode.length)) {
// process; // process;
PushMsg(EQU_RECV, &MsgNode); PushMsg(EQU_RECV, &MsgNode);
} }
recving = false; recving = false;
} }
} }
} }
#if 0 #if 0
#define UART_TX_PIN GPIO_PC2 #define UART_TX_PIN GPIO_PC2
#define UART_RX_PIN GPIO_PC3 #define UART_RX_PIN GPIO_PC3
//__attribute__((aligned(4))) u8 moduleTest_uartTxBuf[32] = {0xAA,0x55,0x05,0x01,0x02,0x03,0x04,0x05,0x93,0x04}; //__attribute__((aligned(4))) u8 moduleTest_uartTxBuf[32] = {0xAA,0x55,0x05,0x01,0x02,0x03,0x04,0x05,0x93,0x04};
//__attribute__((aligned(4))) u8 moduleTest_uartRxBuf[128] = {0}; //__attribute__((aligned(4))) u8 moduleTest_uartRxBuf[128] = {0};
void module_test_uartRcvHandler(void){ void module_test_uartRcvHandler(void){
iKonkeAfSelfPrint("#############33module_test_uartRcvHandler,recv data is \r\n"); iKonkeAfSelfPrint("#############33module_test_uartRcvHandler,recv data is \r\n");
iKonkeAfSelfPrintBuffer(moduleTest_uartRxBuf,50); iKonkeAfSelfPrintBuffer(moduleTest_uartRxBuf,50);
} }
void UART_TEST(void) void UART_TEST(void)
{ {
drv_uart_pin_set(UART_TX_PIN, UART_RX_PIN); drv_uart_pin_set(UART_TX_PIN, UART_RX_PIN);
drv_uart_init_self(115200,PARITY_NONE,STOP_BIT_ONE, moduleTest_uartRxBuf, sizeof(moduleTest_uartRxBuf)/sizeof(u8), module_test_uartRcvHandler); drv_uart_init_self(115200,PARITY_NONE,STOP_BIT_ONE, moduleTest_uartRxBuf, sizeof(moduleTest_uartRxBuf)/sizeof(u8), module_test_uartRcvHandler);
if(drv_uart_tx_start(moduleTest_uartTxBuf, 10) == 1) if(drv_uart_tx_start(moduleTest_uartTxBuf, 10) == 1)
WaitMs(1000); WaitMs(1000);
} }
#endif #endif
#ifndef __IKONKE_MODULE_UART_H_______________________________ #ifndef __IKONKE_MODULE_UART_H_______________________________
#define __IKONKE_MODULE_UART_H_______________________________ #define __IKONKE_MODULE_UART_H_______________________________
#include "../general/ikk-module-def.h" #include "../general/ikk-module-def.h"
#include "drv_uart.h" #include "drv_uart.h"
// MSG BUFFER OF NODE MAXLENGTH // MSG BUFFER OF NODE MAXLENGTH
#define UMSG_NODE_SIZE 32 #define UMSG_NODE_SIZE 96
// Maximum number of message nodes in the queue // Maximum number of message nodes in the queue
#define UMSG_NODE_MAX 4 #define UMSG_NODE_MAX 4
// Maximum Cache Length of Message Receiver // Maximum Cache Length of Message Receiver
#define UART_RECEIVER_CACHE_SIZE 128 #define UART_RECEIVER_CACHE_SIZE 128
// //
typedef enum { EQU_RECV = 0, EQU_SENT }QueueEm; typedef enum { EQU_RECV = 0, EQU_SENT }QueueEm;
// uart recv/send buffer node // uart recv/send buffer node
typedef struct tag_uart_message_node { typedef struct tag_uart_message_node {
unsigned char buffer[UMSG_NODE_SIZE]; unsigned char buffer[UMSG_NODE_SIZE];
unsigned char length; uint16_t length;
// just for sending, Used to match instruction responses. For example, according to the instruction opcode! // just for sending, Used to match instruction responses. For example, according to the instruction opcode!
unsigned char matcher[4]; unsigned char matcher[4];
unsigned char matcher_offset; unsigned char matcher_offset;
unsigned char matcher_n; unsigned char matcher_n;
// just for sending, need to dispatch the response message? // just for sending, need to dispatch the response message?
bool bRspNeedtoDispatch; bool bRspNeedtoDispatch;
// Attempt to send number of times, decreases to 0 when invalid!!! // Attempt to send number of times, decreases to 0 when invalid!!!
unsigned char sent_try; unsigned char sent_try;
}UMsgNodeSt; unsigned char *ack;
unsigned char ack_length;
typedef struct tag_uart_message_queue { }UMsgNodeSt;
UMsgNodeSt node[UMSG_NODE_MAX];
unsigned char counter; typedef struct tag_uart_message_queue {
}UMsgQueueSt; UMsgNodeSt node[UMSG_NODE_MAX];
unsigned char counter;
typedef bool (*PFUNC_CRC)(uint8_t *pdat, int length ); }UMsgQueueSt;
typedef void (*PFUNC_INCOMING_CALLBACK)(UMsgNodeSt *pMsgNode );
typedef bool (*PFUNC_CRC)(uint8_t *pdat, int length );
typedef struct tag_uart_manager_st { typedef void (*PFUNC_INCOMING_CALLBACK)(UMsgNodeSt *pMsgNode );
GPIO_PinTypeDef Rxpin;
GPIO_PinTypeDef Txpin; typedef struct tag_uart_manager_st {
GPIO_PinTypeDef Rxpin;
uint8_t recv_header[4]; GPIO_PinTypeDef Txpin;
uint8_t recv_header_n;
// head detection assistant chunk! uint8_t recv_header[4];
uint8_t header_chunk[4]; uint8_t recv_header_n;
uint8_t header_chunk_index; // head detection assistant chunk!
uint8_t header_chunk[4];
// length occupy index,0xff is valided! uint8_t header_chunk_index;
uint8_t buffer_len_index;
uint8_t additional_len; // length occupy index,0xff is valided!
uint8_t buffer_len_index;
PFUNC_CRC pfunc_crc; uint8_t additional_len;
PFUNC_INCOMING_CALLBACK pfunc_incoming;
// support for sleepy device. when waking up, the serial port receives automatically, PFUNC_CRC pfunc_crc;
// and after receiving, it sleeps actively. PFUNC_INCOMING_CALLBACK pfunc_incoming;
bool bSleepSupport; // support for sleepy device. when waking up, the serial port receives automatically,
// support for sleepy device. the countdown ends and goes to sleep! // and after receiving, it sleeps actively.
uint16_t u16SleepCounter; bool bSleepSupport;
}UartManagerSt; // support for sleepy device. the countdown ends and goes to sleep!
uint16_t u16SleepCounter;
kk_err_t kUartMsgSent(UMsgNodeSt *pMsgNode ); }UartManagerSt;
/* DESP: serial usart driver init interface.
* PARAM[recv_header]: Recognition Sequence of recv effective data frame header and detection of Data Frame start. kk_err_t kUartMsgSent(UMsgNodeSt *pMsgNode );
* PARAM[recv_header_n]: the length of recv data frame header. /* DESP: serial usart driver init interface.
* PARAM[buffer_len_index]: the length of paload. * PARAM[recv_header]: Recognition Sequence of recv effective data frame header and detection of Data Frame start.
* PARAM[addtional_len]: the length of added * PARAM[recv_header_n]: the length of recv data frame header.
* PARAM[pfunc_crc]: CRC function. * PARAM[buffer_len_index]: the length of paload.
* PARAM[pfunc_incoming]: Callback function when valid data frame is detected, provided by youself. * PARAM[addtional_len]: the length of added
* PARAM[bSleepSupport]: support for sleepy device function. * PARAM[pfunc_crc]: CRC function.
* Auth: dingmz_frc.20190620. * PARAM[pfunc_incoming]: Callback function when valid data frame is detected, provided by youself.
* */ * PARAM[bSleepSupport]: support for sleepy device function.
kk_err_t kUartModuleInit(GPIO_PinTypeDef Txpin,GPIO_PinTypeDef Rxpin, uint32_t rate, UART_ParityTypeDef parity, UART_StopBitTypeDef stopBits * Auth: dingmz_frc.20190620.
, uint8_t recv_header[], uint8_t recv_header_n,uint8_t buffer_len_index,uint8_t addtional_len * */
, PFUNC_CRC pfunc_crc, PFUNC_INCOMING_CALLBACK pfunc_incoming kk_err_t kUartModuleInit(GPIO_PinTypeDef Txpin,GPIO_PinTypeDef Rxpin, uint32_t rate, UART_ParityTypeDef parity, UART_StopBitTypeDef stopBits
, bool bSleepSupport ); , uint8_t recv_header[], uint8_t recv_header_n,uint8_t buffer_len_index,uint8_t addtional_len
, PFUNC_CRC pfunc_crc, PFUNC_INCOMING_CALLBACK pfunc_incoming
#if 0 , bool bSleepSupport );
void UART_TEST(void);
#endif #if 0
void UART_TEST(void);
#endif
#endif
#endif
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "ikk-cluster.h" #include "ikk-cluster.h"
#include "ikk-debug.h" #include "ikk-debug.h"
#include "ikk-config.h" #include "ikk-config.h"
#include "ikk-network.h" #include "ikk-network.h"
#include "ikk-token.h" #include "ikk-token.h"
#include "zcl.h" #include "zcl.h"
#include PROJECT_H #include PROJECT_H
#define ENDPOINT_MAXN 5 #define ENDPOINT_MAXN 5
#define CLUSTER_MAXN 5 #define CLUSTER_MAXN 5
static uint8_t g_tmp_buffer[64] = { 0 }; static uint8_t g_tmp_buffer[64] = { 0 };
pOnOffClusterOnOffStatusCallback g_pfOnOffStatusCallback = NULL; pOnOffClusterOnOffStatusCallback g_pfOnOffStatusCallback = NULL;
//static pClusterAttributeChangeCallback pOnOffClusterCallback = NULL; static pClusterAttributeChangeCallback pOnOffClusterCallback = NULL;
//static pClusterAttributeChangeCallback pLevelClusterCallback = NULL; //static pClusterAttributeChangeCallback pLevelClusterCallback = NULL;
//static pClusterAttributeChangeCallback pColorClusterCallback = NULL; //static pClusterAttributeChangeCallback pColorClusterCallback = NULL;
static status_t WriteServerAttribute(u8 endpoint, u16 clusterId,uint8_t attributeID,uint8_t* dataPtr, uint8_t data_type); static status_t WriteServerAttribute(u8 endpoint, u16 clusterId,uint8_t attributeID,uint8_t* dataPtr, uint8_t data_type);
typedef struct { typedef struct {
ZclReportTableSt g_stZclReportPermitList[ENDPOINT_MAXN * CLUSTER_MAXN]; ZclReportTableSt g_stZclReportPermitList[ENDPOINT_MAXN * CLUSTER_MAXN];
uint8_t size; uint8_t size;
}ZclClusterReportTableSt; }ZclClusterReportTableSt;
static ZclClusterReportTableSt g_stZclClusterReportPermitTable; static ZclClusterReportTableSt g_stZclClusterReportPermitTable;
//bool kZclOnOffClusterServerOnOffGet(uint8_t endpoint) void kZclOnOffClusterServerOnOffSet(uint8_t endpoint,bool onoff)
//{ {
// uint8_t status; WriteServerAttribute(endpoint,CLUSTER_ONOFF_ID,ZCL_ATTRID_ONOFF,(uint8_t*)&onoff,ZCL_DATA_TYPE_BOOLEAN);
// zclAttrInfo_t *onoff = zcl_attrRead(endpoint,ZCL_CLUSTER_GEN_ON_OFF,ZCL_ATTRID_ONOFF,&status); // zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(endpoint);
// //
// iKonkeAfSelfPrint("kZclOnOffClusterServerOnOffGet:status(%d), endpoint(%d), status(%d)\r\n",status, endpoint, onoff->data[0]); // pOnOff->onOff = onoff;
// iKonkeAfSelfPrint("kZclOnOffClusterServerOnOffGet:id(%d), type(%d), access(%d)\r\n",onoff->id, onoff->type, onoff->access); zcl_onOffAttr_save();
// }
// return onoff->data[0]; /* DESP: on-off cluster control operate.
//} * Auth: dingmz_frc.20191112.
bool kZclOnOffClusterServerOnOffGet(uint8_t endpoint) * */
{ kk_err_t kZclOnOffClusterServerOnOffControl(uint8_t endpoint, OnOffCtrlEnum ctrlopt )
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(endpoint); {
bool setValue = kZclOnOffClusterServerOnOffGet(endpoint);
return pOnOff->onOff; iKonkeAfSelfPrint("OnOffControl: endpoint(%d), opt(%d),last state = %d\r\n", endpoint, ctrlopt,setValue);
} if(ctrlopt == EOOC_TOGGLE)
void kZclOnOffClusterServerOnOffSet(uint8_t endpoint,bool onoff) setValue = !setValue;
{ else if(ctrlopt == EOOC_ON)
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(endpoint); setValue = 1;
else
pOnOff->onOff = onoff; setValue = 0;
zcl_onOffAttr_save(); kZclOnOffClusterServerOnOffSet(endpoint,setValue);
} if( kNwkGetCurrentStatus() == ENS_ONLINE ) {
/* DESP: on-off cluster control operate. // check binding table
* Auth: dingmz_frc.20191112. kk_err_t err = kNwkClusterBindingObjIsOK(endpoint, CLUSTER_ONOFF_ID);
* */ if( err == KET_ERR_NON_EXIST ) {
kk_err_t kZclOnOffClusterServerOnOffControl(uint8_t endpoint, OnOffCtrlEnum ctrlopt ) kNwkClusterBindingTrigger();
{ }
bool setValue = kZclOnOffClusterServerOnOffGet(endpoint); }
iKonkeAfSelfPrint("OnOffControl: endpoint(%d), opt(%d),last state = %d\r\n", endpoint, ctrlopt,setValue);
if(ctrlopt == EOOC_TOGGLE) return KET_OK;
setValue = !setValue; }
else if(ctrlopt == EOOC_ON) bool kZclOnOffClusterServerOnOffGet(uint8_t endpoint)
setValue = 1; {
else status_t status ;
setValue = 0; zclAttrInfo_t *pOnOff = zcl_attrRead(endpoint,CLUSTER_ONOFF_ID,ZCL_ATTRID_ONOFF,&status);
return (status == ZCL_STA_SUCCESS )? (pOnOff->data[0]): (0);
kZclOnOffClusterServerOnOffSet(endpoint,setValue); }
if( kNwkGetCurrentStatus() == ENS_ONLINE ) {
// check binding table
kk_err_t err = kNwkClusterBindingObjIsOK(endpoint, CLUSTER_ONOFF_ID); static status_t WriteServerAttribute(u8 endpoint, u16 clusterId,uint8_t attributeID,uint8_t* dataPtr, uint8_t data_type)
if( err == KET_ERR_NON_EXIST ) { {
kNwkClusterBindingTrigger(); zclWriteRec_t attr_data;
} attr_data.attrID = attributeID;
} attr_data.dataType = data_type;
u16 dataLen = zcl_getAttrSize(data_type, dataPtr);
return KET_OK; attr_data.attrData = dataPtr;
}
iKonkeAfSelfPrint("##WriteServerAttribute cluster =%d,attr = %d,len=%d :\r\n",clusterId,attr_data.attrID,dataLen);
if(dataLen == 1)
iKonkeAfSelfPrint("##data=%d:\r\n",*dataPtr);
static status_t WriteServerAttribute(u8 endpoint, u16 clusterId,uint8_t attributeID,uint8_t* dataPtr, uint8_t data_type) else
{ iKonkeAfSelfPrintBuffer(dataPtr,dataLen);
zclWriteRec_t attr_data; return zcl_attrWrite(endpoint,clusterId,&attr_data,true);
attr_data.attrID = attributeID; }
attr_data.dataType = data_type; bool Get_Model_ID(uint8_t *ModeID)
u16 dataLen = zcl_getAttrSize(data_type, dataPtr); {
memcpy(attr_data.attrData,dataPtr,dataLen); status_t status ;
zclAttrInfo_t *pAttrInfo = zcl_attrRead(1,ZCL_CLUSTER_GEN_BASIC,ZCL_ATTRID_BASIC_MODEL_ID,&status);
// iKonkeAfSelfPrint("##WriteServerAttribute attr =%x,attr = %x,len=%d :\r\n",clusterId,attr_data.attrID,dataLen); if(status == ZCL_STA_SUCCESS )
// iKonkeAfSelfPrint("##DataBuffer len = %d,data=%x-%x:\r\n",dataLen,attr_data.attrData[1],attr_data.attrData[2]); {
// iKonkeAfSelfPrintBuffer(attr_data.attrData,attr_data.attrData[0]+1); uint8_t len = pAttrInfo->data[0];
return zcl_attrWrite(endpoint,clusterId,&attr_data,false); if((ModeID)&&(len >0)&&(pAttrInfo->type == ZCL_DATA_TYPE_CHAR_STR))
} {
uint8_t temp[16] = {0};
memcpy(ModeID,&pAttrInfo->data[1],len); //Get ASCII Data
static status_t Rewrite_Modeid(uint8_t *modeid,uint8_t software,uint8_t hardware) if((len >0)&&(len %2 == 0))
{ {
uint8_t Modeid_Temp[] = "3AFE101003008611" ; kUtilsStr2Hex(ModeID,temp,len);
uint8_t temp[6]; memcpy(ModeID,temp,len/2);
uint8_t dest_temp[20]; iKonkeAfSelfPrint("##Trans Data Buffer Len =%d:\r\n",len);
status_t status = ZCL_STA_SUCCESS; iKonkeAfSelfPrintBuffer(ModeID,8);
return true;
temp[0] = software; }
temp[1] = hardware; }
temp[2] = modeid[3]; }
temp[3] = modeid[2]; return false;
temp[4] = modeid[1]; }
temp[5] = modeid[0];
for(uint8_t i = 0;i<6;i++)
{ static status_t Rewrite_Modeid(uint8_t *modeid,uint8_t software,uint8_t hardware)
uint8_t high_byte = (temp[i]>>4)&0x0f; {
uint8_t low_byte = temp[i]&0x0f; uint8_t Modeid_Temp[] = "3AFE101003008611" ;
if( ( high_byte >= 0)&&( high_byte <= 9) ) uint8_t temp[6];
{ uint8_t dest_temp[20];
dest_temp[2*i] = high_byte +'0'; status_t status = ZCL_STA_SUCCESS;
}
else temp[0] = software;
{ temp[1] = hardware;
dest_temp[2*i] = high_byte -10 +'A'; temp[2] = modeid[3];
} temp[3] = modeid[2];
temp[4] = modeid[1];
if( (low_byte >= 0)&&(low_byte <= 9) ) temp[5] = modeid[0];
{
dest_temp[2*i +1] = low_byte +'0'; for(uint8_t i = 0;i<6;i++)
} {
else uint8_t high_byte = (temp[i]>>4)&0x0f;
{ uint8_t low_byte = temp[i]&0x0f;
dest_temp[2*i +1] = low_byte -10 +'A'; if( ( high_byte >= 0)&&( high_byte <= 9) )
} {
} dest_temp[2*i] = high_byte +'0';
memcpy(&Modeid_Temp[4],dest_temp,12); }
memmove(&g_tmp_buffer[1],Modeid_Temp,16); //дʼֵ else
g_tmp_buffer[0] = 16; {
g_tmp_buffer[0+ 2+16] = '0'; dest_temp[2*i] = high_byte -10 +'A';
}
status = WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_MODEL_ID ,(uint8_t*)g_tmp_buffer,ZCL_DATA_TYPE_CHAR_STR);
if(status != ZCL_STA_SUCCESS) if( (low_byte >= 0)&&(low_byte <= 9) )
{ {
iKonkeAfSelfPrint("write modeidid failed status = %d :\r\n",status); dest_temp[2*i +1] = low_byte +'0';
return status; }
} else
status = WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_APP_VER ,(uint8_t*)&software,ZCL_DATA_TYPE_UINT8); {
if(status != ZCL_STA_SUCCESS) dest_temp[2*i +1] = low_byte -10 +'A';
{ }
iKonkeAfSelfPrint("write app version failed status = %d :\r\n",status); }
return status; memcpy(&Modeid_Temp[4],dest_temp,12);
} memmove(&g_tmp_buffer[1],Modeid_Temp,16); //дʼֵ
//iKonkeAfSelfPrint("write app version status = %d :\r\n",status); g_tmp_buffer[0] = 16;
status = WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_HW_VER ,(uint8_t*)&hardware,ZCL_DATA_TYPE_UINT8); g_tmp_buffer[0+ 2+16] = '0';
if(status != ZCL_STA_SUCCESS)
{ uint8_t *data = MODEL_ID_TOKEN_GET();
iKonkeAfSelfPrint("write hard version failed status = %d :\r\n",status); if(!All_Same_Data(&data[1],0xff,32))
return status; memcpy(g_tmp_buffer,data,data[0]+1);
}
return status; status = WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_MODEL_ID ,(uint8_t*)g_tmp_buffer,ZCL_DATA_TYPE_CHAR_STR);
} if(status != ZCL_STA_SUCCESS)
static status_t Rewrite_ManufactureName(void) {
{ iKonkeAfSelfPrint("write modeidid failed status = %d :\r\n",status);
uint8_t manuName[] = MANUFATURE_NAME; return status;
g_tmp_buffer[0] = strlen((const char *)manuName); }
strcpy((char*)&g_tmp_buffer[1],(const char*)manuName); status = WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_APP_VER ,(uint8_t*)&software,ZCL_DATA_TYPE_UINT8);
status_t status = ZCL_STA_SUCCESS; if(status != ZCL_STA_SUCCESS)
status =WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_MFR_NAME ,(uint8_t*)g_tmp_buffer,ZCL_DATA_TYPE_CHAR_STR); {
if(status != ZCL_STA_SUCCESS) iKonkeAfSelfPrint("write app version failed status = %d :\r\n",status);
{ return status;
iKonkeAfSelfPrint("write mfg name failed status = %d :\r\n",status); }
return status; //iKonkeAfSelfPrint("write app version status = %d :\r\n",status);
} status = WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_HW_VER ,(uint8_t*)&hardware,ZCL_DATA_TYPE_UINT8);
return status; if(status != ZCL_STA_SUCCESS)
} {
iKonkeAfSelfPrint("write hard version failed status = %d :\r\n",status);
void Update_Local_Attribute_Info(void) return status;
{ }
uint32_t modeid = (uint32_t)MODEL_ID; return status;
Rewrite_Modeid((uint8_t *)&modeid,FIRMWARE_VER,HARDWARE_VERSION); }
Rewrite_ManufactureName(); static status_t Rewrite_ManufactureName(void)
} {
uint8_t manuName[] = MANUFATURE_NAME;
g_tmp_buffer[0] = strlen((const char *)manuName);
strcpy((char*)&g_tmp_buffer[1],(const char*)manuName);
status_t status = ZCL_STA_SUCCESS;
status =WriteServerAttribute(1, ZCL_CLUSTER_GEN_BASIC, ZCL_ATTRID_BASIC_MFR_NAME ,(uint8_t*)g_tmp_buffer,ZCL_DATA_TYPE_CHAR_STR);
if(status != ZCL_STA_SUCCESS)
{
iKonkeAfSelfPrint("write mfg name failed status = %d :\r\n",status);
return status;
// }
//static typedef struct{ return status;
// zcl_basicAttr_t basicAttrs_temp; }
// zcl_identifyAttr_t identifyAttrs_temp
// zcl_onOffAttr_t onOffAttrs_temp; void Update_Local_Attribute_Info(void)
// zcl_onOffAttr_t levelAttrs_temp; {
//}AttrListST; uint32_t modeid = (uint32_t)MODEL_ID;
//static AttrListST Attr_List_Value[MAX_ATTR_CHANGE_SUPPORT_NUMS] ; Rewrite_Modeid((uint8_t *)&modeid,FIRMWARE_VER,HARDWARE_VERSION);
//void ClusterAttributeChangeCallbackRegister(AttributeChangeConfSt *ConfSt,unint8_t num) Rewrite_ManufactureName();
//{ }
// for(uint8_t i=0;i<num;i++)
// {
// if(i > MAX_ATTR_CHANGE_SUPPORT_NUMS)
// {
// iKonkeAfSelfPrint("attribute change callback totals number beyond!!\r\n");
// break;
// } typedef struct{
// switch(ConfSt[i]->cluster) zcl_basicAttr_t basicAttrs_temp;
// { zcl_identifyAttr_t identifyAttrs_temp;
// case ZCL_CLUSTER_GEN_ON_OFF: zcl_onOffAttr_t onOffAttrs_temp;
// { zcl_levelAttr_t levelAttrs_temp;
// if(ConfSt[i]->attribute == ZCL_ATTRID_ONOFF) }AttrListST;
// { static AttrListST Attr_List_Value[MAX_ATTR_CHANGE_SUPPORT_NUMS] ;
// pOnOffClusterCallback = ConfSt[i]->change_callback; void ikkAttributeChangeCallbackRegister(AttributeChangeConfSt *ConfSt,uint8_t num)
// } {
// } for(uint8_t i=0;i<MAX_ATTR_CHANGE_SUPPORT_NUMS;i++)
// break; {
// case ZCL_CLUSTER_GEN_LEVEL_CONTROL: if(i > MAX_ATTR_CHANGE_SUPPORT_NUMS)
// { {
// if(ConfSt[i]->attribute == ZCL_ATTRID_LEVEL_CURRENT_LEVEL) iKonkeAfSelfPrint("attribute change callback totals number beyond!!\r\n");
// pLevelClusterCallback = ConfSt[i]->change_callback; break;
// } }
// break; switch(ConfSt->cluster)
// default: {
// break; case ZCL_CLUSTER_GEN_ON_OFF:
// } {
// } pOnOffClusterCallback = ConfSt->change_callback;
//// memcpy(&Attr_List_Value.basicAttrs_temp,&g_zcl_basicAttrs,sizeof(zcl_basicAttr_t)); }
//// memcpy(&Attr_List_Value.identifyAttrs_temp,&g_zcl_identifyAttrs,sizeof(zcl_basicAttr_t)); break;
//// memcpy(&Attr_List_Value.onOffAttrs_temp,&g_zcl_onOffAttrs,sizeof(zcl_basicAttr_t)); // case ZCL_CLUSTER_GEN_LEVEL_CONTROL:
//// memcpy(&Attr_List_Value.levelAttrs_temp,&g_zcl_levelAttrs,sizeof(zcl_basicAttr_t)); // {
//} // pLevelClusterCallback = ConfSt->change_callback;
// }
// break;
default:
void AttributeValueCheck(void) break;
{ }
// if((Attr_List_Value.onOffAttrs_temp.onOff !=g_zcl_onOffAttrs.onOff)&&(pOnOffClusterCallback)) }
// { }
// pOnOffClusterCallback(1,ZCL_CLUSTER_GEN_ON_OFF,ZCL_ATTRID_ONOFF,g_zcl_onOffAttrs.onOff,1,g_zcl_onOffAttrs.onOff);
// void AttributeValueCheckCallback(void)
// {
// } for(uint8_t i = 0;i<Support_Endpoint_Num;i++)
{
if(memcmp((uint8_t*)&Attr_List_Value[i].onOffAttrs_temp,(uint8_t*)&g_zcl_onOffAttrs[i],sizeof(zcl_onOffAttr_t)) )
{
if(Attr_List_Value[i].onOffAttrs_temp.onOff != g_zcl_onOffAttrs[i].onOff)
{
if(pOnOffClusterCallback)
pOnOffClusterCallback(i+1,ZCL_CLUSTER_GEN_ON_OFF,ZCL_ATTRID_ONOFF,(uint8_t *)&g_zcl_onOffAttrs[i].onOff,ZCL_DATA_TYPE_BOOLEAN);
}
memcpy((uint8_t*)&Attr_List_Value[i].onOffAttrs_temp,(uint8_t*)&g_zcl_onOffAttrs[i],sizeof(zcl_onOffAttr_t));
}
}
} }
bool kIsKonkeRemoteGateway(void) bool kIsKonkeRemoteGateway(void)
{ {
return MFG_Code_Get() == MANUFACTURER_CODE_TELINK; return MFG_Code_Get() == MANUFACTURER_CODE_TELINK;
} }
bool kkClusterGetReportingPeriod(uint8_t endpoint, uint16_t cluster_id, uint16_t attribute_id,uint16_t *min_interval, uint16_t *max_interval ) bool kkClusterGetReportingPeriod(uint8_t endpoint, uint16_t cluster_id, uint16_t attribute_id,uint16_t *min_interval, uint16_t *max_interval )
{ {
uint8_t index = 0; uint8_t index = 0;
for(index = 0; index < ZCL_REPORTING_TABLE_NUM; index++){ for(index = 0; index < ZCL_REPORTING_TABLE_NUM; index++){
reportCfgInfo_t *pEntry = &reportingTab.reportCfgInfo[index]; reportCfgInfo_t *pEntry = &reportingTab.reportCfgInfo[index];
if( pEntry->used&& if( pEntry->used&&
pEntry->endPoint== endpoint && pEntry->endPoint== endpoint &&
pEntry->clusterID == cluster_id && pEntry->clusterID == cluster_id &&
pEntry->attrID== attribute_id ) pEntry->attrID== attribute_id )
{ {
*min_interval = pEntry->minInterval; *min_interval = pEntry->minInterval;
*max_interval = pEntry->maxInterval; *max_interval = pEntry->maxInterval;
return true; return true;
} }
} }
return false; return false;
} }
//table init //table init
void kZclClusterPermitReportTableInit(BindObjSt clusterBindList[], uint8_t size) void kZclClusterPermitReportTableInit(BindObjSt clusterBindList[], uint8_t size)
{ {
if (clusterBindList == NULL || size == 0 || size >= ENDPOINT_MAXN * CLUSTER_MAXN){ if (clusterBindList == NULL || size == 0 || size >= ENDPOINT_MAXN * CLUSTER_MAXN){
iKonkeAfSelfPrint("###clusterBindList is invalid size(%d)\r\n", size); iKonkeAfSelfPrint("###clusterBindList is invalid size(%d)\r\n", size);
return; return;
} }
for (uint8_t i = 0; i < size; i++){ for (uint8_t i = 0; i < size; i++){
g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].endpoint = clusterBindList[i].endpoint; g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].endpoint = clusterBindList[i].endpoint;
g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].cluster = clusterBindList[i].cluster; g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].cluster = clusterBindList[i].cluster;
g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].reportEnable = false; g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].reportEnable = false;
g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].sceneRecallFlg = false; g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].sceneRecallFlg = false;
} }
g_stZclClusterReportPermitTable.size = size; g_stZclClusterReportPermitTable.size = size;
} }
//index get //index get
static uint8_t kZclClusterPermitTableIndexGetByClusterAndEp(uint8_t endpoint, uint16_t cluster) static uint8_t kZclClusterPermitTableIndexGetByClusterAndEp(uint8_t endpoint, uint16_t cluster)
{ {
uint8_t index = 0xFF; uint8_t index = 0xFF;
for (uint8_t i = 0; i < g_stZclClusterReportPermitTable.size; i++){ for (uint8_t i = 0; i < g_stZclClusterReportPermitTable.size; i++){
if (g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].endpoint == endpoint \ if (g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].endpoint == endpoint \
&& g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].cluster == cluster){ && g_stZclClusterReportPermitTable.g_stZclReportPermitList[i].cluster == cluster){
index = i; index = i;
break; break;
} }
} }
return index; return index;
} }
//permit info get //permit info get
bool kZclClusterGetPermitReportInfo(uint8_t endpoint, uint16_t cluster, ZclReportTableSt *zclReportPermit) bool kZclClusterGetPermitReportInfo(uint8_t endpoint, uint16_t cluster, ZclReportTableSt *zclReportPermit)
{ {
if (endpoint > ENDPOINT_MAXN){ if (endpoint > ENDPOINT_MAXN){
iKonkeAfSelfPrint("###11Endpoint %d is too large\r\n", endpoint); iKonkeAfSelfPrint("###11Endpoint %d is too large\r\n", endpoint);
return false; return false;
} }
uint8_t index = kZclClusterPermitTableIndexGetByClusterAndEp(endpoint , cluster); uint8_t index = kZclClusterPermitTableIndexGetByClusterAndEp(endpoint , cluster);
if (index != 0xFF){ if (index != 0xFF){
zclReportPermit->endpoint = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].endpoint; zclReportPermit->endpoint = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].endpoint;
zclReportPermit->cluster = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].cluster; zclReportPermit->cluster = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].cluster;
zclReportPermit->reportEnable = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].reportEnable; zclReportPermit->reportEnable = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].reportEnable;
zclReportPermit->sceneRecallFlg = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].sceneRecallFlg; zclReportPermit->sceneRecallFlg = g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].sceneRecallFlg;
return true; return true;
} }
return false; return false;
} }
//permit info set //permit info set
bool kZclClusterSetPermitReportInfo(uint8_t endpoint, uint16_t cluster, bool reportEnable, bool sceneRecallFlg) bool kZclClusterSetPermitReportInfo(uint8_t endpoint, uint16_t cluster, bool reportEnable, bool sceneRecallFlg)
{ {
bool ret = false; bool ret = false;
if (endpoint > ENDPOINT_MAXN && endpoint != 0xFF){ if (endpoint > ENDPOINT_MAXN && endpoint != 0xFF){
iKonkeAfSelfPrint("###22Endpoint %d is too large\r\n", endpoint); iKonkeAfSelfPrint("###22Endpoint %d is too large\r\n", endpoint);
return false; return false;
} }
uint8_t index = 0; uint8_t index = 0;
if (endpoint != 0xFF){ if (endpoint != 0xFF){
index = kZclClusterPermitTableIndexGetByClusterAndEp(endpoint , cluster); index = kZclClusterPermitTableIndexGetByClusterAndEp(endpoint , cluster);
if (index != 0xFF){ if (index != 0xFF){
g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].reportEnable = reportEnable; g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].reportEnable = reportEnable;
g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].sceneRecallFlg = sceneRecallFlg; g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].sceneRecallFlg = sceneRecallFlg;
ret = true; ret = true;
} }
}else { //㲥 }else { //㲥
for (uint8_t i = 0; i < g_stZclClusterReportPermitTable.size; i++){ for (uint8_t i = 0; i < g_stZclClusterReportPermitTable.size; i++){
for (uint8_t j = 1; j < ENDPOINT_MAXN; j++){ for (uint8_t j = 1; j < ENDPOINT_MAXN; j++){
index = kZclClusterPermitTableIndexGetByClusterAndEp(j , cluster); index = kZclClusterPermitTableIndexGetByClusterAndEp(j , cluster);
if (index != 0xFF){ if (index != 0xFF){
g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].reportEnable = reportEnable; g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].reportEnable = reportEnable;
g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].sceneRecallFlg = sceneRecallFlg; g_stZclClusterReportPermitTable.g_stZclReportPermitList[index].sceneRecallFlg = sceneRecallFlg;
ret = true; ret = true;
} }
} }
} }
} }
iKonkeAfSelfPrint("######kZclClusterSetPermitReportInfo index(%d)ep(%d) cluster(%x)enable(%d)scene(%d)\r\n", iKonkeAfSelfPrint("######kZclClusterSetPermitReportInfo index(%d)ep(%d) cluster(%x)enable(%d)scene(%d)\r\n",
index, endpoint, cluster, reportEnable, sceneRecallFlg ); index, endpoint, cluster, reportEnable, sceneRecallFlg );
return ret; return ret;
} }
kk_err_t kZclOnOffClusterServerInit(pOnOffClusterOnOffStatusCallback pOnOffStatusCallback ) kk_err_t kZclOnOffClusterServerInit(pOnOffClusterOnOffStatusCallback pOnOffStatusCallback )
{ {
g_pfOnOffStatusCallback = pOnOffStatusCallback; g_pfOnOffStatusCallback = pOnOffStatusCallback;
return KET_OK; return KET_OK;
} }
void ON_OFF_Cmd_Handler(uint8_t endpoint,bool onoff) void ON_OFF_Cmd_Handler(uint8_t endpoint,bool onoff)
{ {
OnOffStatusEnum on_off_ctr = (OnOffStatusEnum)onoff; OnOffStatusEnum on_off_ctr = (OnOffStatusEnum)onoff;
kZclClusterSetPermitReportInfo(endpoint,ZCL_CLUSTER_GEN_ON_OFF,true,false); kZclClusterSetPermitReportInfo(endpoint,ZCL_CLUSTER_GEN_ON_OFF,true,false);
kZclOnOffClusterServerOnOffControl(endpoint, on_off_ctr); kZclOnOffClusterServerOnOffControl(endpoint, on_off_ctr);
g_pfOnOffStatusCallback(endpoint,on_off_ctr); }
} /* DESP: Modified attribute reporting interface, reference from SDK callback[emberAfReportingAttributeChangeCallback].
/* DESP: Modified attribute reporting interface, reference from SDK callback[emberAfReportingAttributeChangeCallback]. * Auth: dingmz_frc.20190701.
* Auth: dingmz_frc.20190701. * */
* */ void kOptTunnelReportingPlagiarizeOriginal(uint8_t endpoint, uint16_t clusterId, uint16_t attributeId )
void kOptTunnelReportingPlagiarizeOriginal(uint8_t endpoint, uint16_t clusterId, uint16_t attributeId ) {
{ if(!zb_bindingTblSearched(clusterId,endpoint)){
if(!zb_bindingTblSearched(clusterId,endpoint)){ return;
return; }
} for(u8 i = 0; i < ZCL_REPORTING_TABLE_NUM; i++){
for(u8 i = 0; i < ZCL_REPORTING_TABLE_NUM; i++){ reportCfgInfo_t *pEntry = &reportingTab.reportCfgInfo[i];
reportCfgInfo_t *pEntry = &reportingTab.reportCfgInfo[i]; if( pEntry->endPoint == endpoint
if( pEntry->endPoint == endpoint && pEntry->clusterID == clusterId
&& pEntry->clusterID == clusterId && pEntry->attrID == attributeId) {
&& pEntry->attrID == attributeId) { epInfo_t dstEpInfo;
epInfo_t dstEpInfo; TL_SETSTRUCTCONTENT(dstEpInfo, 0);
TL_SETSTRUCTCONTENT(dstEpInfo, 0);
dstEpInfo.dstAddrMode = APS_DSTADDR_EP_NOTPRESETNT;
dstEpInfo.dstAddrMode = APS_DSTADDR_EP_NOTPRESETNT; dstEpInfo.profileId = pEntry->profileID;
dstEpInfo.profileId = pEntry->profileID; zclAttrInfo_t *pAttrEntry = zcl_findAttribute(pEntry->endPoint, pEntry->clusterID, pEntry->attrID);
zclAttrInfo_t *pAttrEntry = zcl_findAttribute(pEntry->endPoint, pEntry->clusterID, pEntry->attrID); if(!pAttrEntry){
if(!pAttrEntry){ //should not happen.
//should not happen. ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_ZCL_ENTRY);
ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_ZCL_ENTRY); return;
return; }
} u16 len = zcl_getAttrSize(pAttrEntry->type, pAttrEntry->data);
u16 len = zcl_getAttrSize(pAttrEntry->type, pAttrEntry->data);
len = (len>8) ? (8):(len);
len = (len>8) ? (8):(len);
//store for next compare
//store for next compare memcpy(pEntry->prevData, pAttrEntry->data, len);
memcpy(pEntry->prevData, pAttrEntry->data, len);
zcl_sendReportCmd(pEntry->endPoint, &dstEpInfo, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
zcl_sendReportCmd(pEntry->endPoint, &dstEpInfo, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR, pEntry->clusterID, pAttrEntry->id, pAttrEntry->type, pAttrEntry->data);
pEntry->clusterID, pAttrEntry->id, pAttrEntry->type, pAttrEntry->data); }
} }
}
}
}
...@@ -28,11 +28,10 @@ typedef struct tag_zcl_report_table{ ...@@ -28,11 +28,10 @@ typedef struct tag_zcl_report_table{
}ZclReportTableSt; }ZclReportTableSt;
#define MAX_ATTR_CHANGE_SUPPORT_NUMS 8 #define MAX_ATTR_CHANGE_SUPPORT_NUMS 8
typedef void (*pClusterAttributeChangeCallback)(uint8_t endpoint,uint16_t cluster,uint16_t attribute,uint8_t len,uint8_t *data); typedef void (*pClusterAttributeChangeCallback)(uint8_t endpoint,uint16_t cluster,uint16_t attribute,uint8_t *data,uint8_t data_type);
typedef struct { typedef struct {
uint16_t cluster; uint16_t cluster;
uint16_t attribute;
pClusterAttributeChangeCallback change_callback; pClusterAttributeChangeCallback change_callback;
}AttributeChangeConfSt; }AttributeChangeConfSt;
...@@ -41,20 +40,25 @@ typedef void (*pOnOffClusterOnOffStatusCallback)(uint8_t endpoint, OnOffStatusEn ...@@ -41,20 +40,25 @@ typedef void (*pOnOffClusterOnOffStatusCallback)(uint8_t endpoint, OnOffStatusEn
void kZclOnOffClusterServerOnOffSet(uint8_t endpoint,bool onoff); void kZclOnOffClusterServerOnOffSet(uint8_t endpoint,bool onoff);
extern status_t zcl_attrWrite(u8 endpoint, u16 clusterId, zclWriteRec_t *pWriteRec, bool enable); extern status_t zcl_attrWrite(u8 endpoint, u16 clusterId, zclWriteRec_t *pWriteRec, bool enable);
extern zclAttrInfo_t *zcl_attrRead(u8 endpoint, u16 clusterId, u16 attrId, status_t *status);
#define ReadServerAttribute(endpoint,clusterId,attributeID,status) (zcl_attrRead(endpoint,clusterId,attributeID,status))
#define kGetLastRssi() (g_sysDiags.lastMessageRSSI)
#define kGetLastLQI() (g_sysDiags.lastMessageLQI)
void Update_Local_Attribute_Info(void); void Update_Local_Attribute_Info(void);
bool kIsKonkeRemoteGateway(void); bool kIsKonkeRemoteGateway(void);
kk_err_t kZclOnOffClusterServerInit(pOnOffClusterOnOffStatusCallback pOnOffStatusCallback ); kk_err_t kZclOnOffClusterServerInit(pOnOffClusterOnOffStatusCallback pOnOffStatusCallback );
void ikkAttributeChangeCallbackRegister(AttributeChangeConfSt *ConfSt,uint8_t num);
void ON_OFF_Cmd_Handler(uint8_t endpoint,uint8_t cmd); void ON_OFF_Cmd_Handler(uint8_t endpoint,uint8_t cmd);
bool kZclOnOffClusterServerOnOffGet(uint8_t endpoint); bool kZclOnOffClusterServerOnOffGet(uint8_t endpoint);
kk_err_t kZclOnOffClusterServerOnOffControl(uint8_t endpoint, OnOffCtrlEnum ctrlopt ); kk_err_t kZclOnOffClusterServerOnOffControl(uint8_t endpoint, OnOffCtrlEnum ctrlopt );
void ClusterAttributeChangeCallbackRegister(AttributeChangeConfSt *ConfSt,uint8_t num); bool Get_Model_ID(uint8_t *ModeID);
bool kkClusterGetReportingPeriod(uint8_t endpoint, uint16_t cluster_id, uint16_t attribute_id,uint16_t *min_interval, uint16_t *max_interval ); bool kkClusterGetReportingPeriod(uint8_t endpoint, uint16_t cluster_id, uint16_t attribute_id,uint16_t *min_interval, uint16_t *max_interval );
void kOptTunnelReportingPlagiarizeOriginal(uint8_t endpoint, uint16_t clusterId, uint16_t attributeId ); void kOptTunnelReportingPlagiarizeOriginal(uint8_t endpoint, uint16_t clusterId, uint16_t attributeId );
void kZclClusterPermitReportTableInit(BindObjSt clusterBindList[], uint8_t size); void kZclClusterPermitReportTableInit(BindObjSt clusterBindList[], uint8_t size);
......
#include "ikk-debug.h" #include "ikk-debug.h"
#include "ikk-command.h" #include "ikk-command.h"
#include "ikk-common-utils.h"
#include "ikk-token.h"
#include "ikk-network.h"
#include "ikk-cluster.h"
#include "ikk-factory-test.h"
#include "ikk-interpan.h"
//#define OPCODE_REMAP_TABLE_SIZE 20
static uint16_t opcodeReampTable[][2] =
{
//FCC0, AA55
{0xE0, 0x0001}, //write install code,
{0xE1, 0x0003}, //write cmei
{0xE2, 0x0005}, //write isn
{0xE3, 0x0007}, //write mac
{0xE6, 0x0002},
{0xE7, 0x0004},
{0xE8, 0x0006},
{0xE9, 0x0008},
{0xEA, 0x0009},
{0xEB, 0x000A},
//{0xF0, 0xED14},//????
//{0xF1, 0xED04},//????
//{0xF2, 0xED05},//??????
{0xF3, 0x000C}, //??????
{0xF4, 0x000D}, //??????
{0xF5, 0x000E}, //??interPan??
{0xF6, 0x000F}, //??interPan??
{0xF7, 0x0010}, //??????
};
uint16_t kCmdGetMsgCrc16Value( uint8_t* msg, uint8_t len)
{
uint16_t crc = 0xFFFF;
uint16_t i, j = 0;
for (i = 0; i < len; i++)
{
for (j = 0; j < 8; j++)
{
//????a?? ADD BY YWQ
uint8_t c15 = (uint8_t)((crc >> 15 & 1) == 1);
uint8_t bit = (uint8_t)((msg[i] >> (7 - j) & 1) == 1);
crc <<= 1;
if (c15 ^ bit)
{
crc ^= 0x1021;
}
}
}
return crc;
}
/* DESP: remap opcode, arg direction 0: FCC0->AA55 1:AA55->FCC0
* Auth:
* */
uint16_t kCmdOpcodeRemap(uint16_t Opcode, uint8_t direction)
{
for (uint8_t i = 0; i < (sizeof(opcodeReampTable)/(2*sizeof(uint16_t))); i++ ) {
if (opcodeReampTable[i][0] == Opcode) {
return opcodeReampTable[i][1];
}
}
return 0xFFFF;
}
kk_err_t kCmdGeneralMsgPaser(UMsgNodeSt *pMsgNode, ComPortEm port, DataField_st *pDataOut)
{
//UMsgNodeSt uMsgNode = {0};
uint16_t length = 0;
uint8_t control_field = 0;
DataField_st data;
DataField_st send_buf;
uint8_t reply_control_field = 0;
if( NULL == pMsgNode ) {
return KET_ERR_INVALID_PARAM;
}
#if 1 // Just for debug
iKonkeAfSelfPrint("\r\n-- MSG INCOMING[%d]:\r\n", pMsgNode->length);
iKonkeAfSelfPrintBuffer(pMsgNode->buffer, pMsgNode->length);
iKonkeAfSelfPrint("\r\n--------------------\r\n");
#endif
// check for parsable packets
if( pMsgNode->length < 5 /* Minimum Packet Length */ ) {
iKonkeAfSelfPrint("Err: Unparsable Packets!!\r\n");
return KET_ERR_INVALID_PARAM;
}
//length(1) pid(4) ch(1) opcode(1) arg
if (port == ECOM_PORT_FCC0) {
length = (uint16_t)pMsgNode->length;
//control_field = pMsgNode->buffer[4];
data.seq = 0x00;
data.u8Datalen = pMsgNode->buffer[0];
data.u8ArgLen = data.u8Datalen - 6; // fcc0 - id (4) - ch(1) - opcode(1)
data.u8ChannelID = pMsgNode->buffer[5];
data.u16Opcode = kCmdOpcodeRemap((uint16_t)(pMsgNode->buffer[6]), 0);
if(data.u16Opcode == 0xFFFF) {
return KET_ERR_INVALID_PARAM;
}
memcpy(data.u8ARG,&pMsgNode->buffer[7], data.u8ArgLen); //6 = pid(4) + ch(1) + opcode(1)
send_buf.seq = data.seq;
send_buf.u8ChannelID = data.u8ChannelID;
send_buf.u16Opcode = data.u16Opcode;
} else {
length = ((uint16_t)pMsgNode->buffer[2] << 8) | (uint16_t)(pMsgNode->buffer[3]);
control_field = pMsgNode->buffer[4];
data.seq = ((uint16_t)pMsgNode->buffer[5] << 8) | (uint16_t)(pMsgNode->buffer[6]);
data.u8Datalen = pMsgNode->buffer[7];
data.u8ArgLen = data.u8Datalen - 3; // aa55 - ch(1) - opcode(2)
data.u8ChannelID = pMsgNode->buffer[8];
data.u16Opcode = ((uint16_t)pMsgNode->buffer[9] << 8) | (uint16_t)(pMsgNode->buffer[10]);
memcpy(data.u8ARG,&pMsgNode->buffer[11],data.u8Datalen - 3);
send_buf.seq = data.seq;
send_buf.u8ChannelID = data.u8ChannelID;
send_buf.u16Opcode = data.u16Opcode;
}
send_buf.u8Datalen = 0;
iKonkeAfSelfPrint("opcode = %x%x\r\n",send_buf.u16Opcode>>8,(u8)send_buf.u16Opcode);
iKonkeAfSelfPrint("channel = %x\r\n",data.u8ChannelID );
switch(data.u16Opcode) {
case (UART_MSG_QUERY_INFO_OPCODE):
{
reply_control_field = Z_TO_H_NO_ACK;
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ArgLen = 1;
break;
}
case (UART_MSG_WRITE_INSTALL_CODE_OPCODE): // write install code
{
uint8_t buffer[16]= {0};
//check install code length 20200725
uint8_t length = data.u8ARG[0];
if (length != 16) {
send_buf.u8ARG[0] = ERR_FORMAT;
send_buf.u8ARG[1] = data.u8ARG[0];
memcpy(&send_buf.u8ARG[2], &data.u8ARG[1], length);
//send_buf.u8Datalen = data.u8ARG[0] + 5;
send_buf.u8ArgLen = length + 1 + 1;
break;
}
memcpy(buffer, &data.u8ARG[1], 16);
INSTALL_CODE_TOKEN_SET(buffer,16);
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ARG[1] = data.u8ARG[0];
memcpy(&send_buf.u8ARG[2], &data.u8ARG[1], length);
send_buf.u8ArgLen = length + 1 + 1;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_READ_INSTALL_CODE_OPCODE): //read install code
{
uint8_t install_code_len = 0;
send_buf.u8ARG[0] = ERR_OK;
install_code_len = 16;
memcpy(&send_buf.u8ARG[2], INSTALL_CODE_TOKEN_GET(), install_code_len);
send_buf.u8ARG[1] = install_code_len;
send_buf.u8ArgLen = install_code_len + 2; // err(1) + codelen(1)
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_WRITE_CMEI_CODE_OPCODE): // write cmei
{
uint8_t buffer[33];
uint8_t length = data.u8ARG[0];
memset(buffer, 0, 33);
if(length > 32) {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
//send_buf.u8Datalen = 1 + 1 + 3;
}else{
send_buf.u8ARG[0] = ERR_OK;
memcpy(buffer, &data.u8ARG[1], length);
CMEI_TOKEN_SET(buffer,length);
}
memcpy(&send_buf.u8ARG[1], &data.u8ARG[0], data.u8ARG[0] + 1);
send_buf.u8ArgLen = data.u8ARG[0] + 1 + 1;
//send_buf.u8Datalen = data.u8ARG[0] + 4;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_READ_CMEI_CODE_OPCODE): //read cmei
{
uint8_t buffer[33];
uint8_t length = 0;
memset(buffer, 0, 33);
uint8_t *data = CMEI_TOKEN_GET();
iKonkeAfSelfPrint("len %x\r\n",data[0]);
iKonkeAfSelfPrintBuffer(data+1,32);
length = data[0];
memcpy(buffer,data,length +1);
if(length > 32) {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
send_buf.u8ARG[1] = 0x00;
send_buf.u8ArgLen = 2;
} else {
send_buf.u8ARG[0] = ERR_OK;
memcpy(&send_buf.u8ARG[1], buffer, length + 1);
send_buf.u8ArgLen = length + 1 + 1;
}
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_WRITE_ISN_CODE_OPCODE): // write isn
{
uint8_t buffer[33];
uint8_t length = data.u8ARG[0];
memset(buffer, 0, 33);
if(length > 32) {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
//send_buf.u8Datalen = 1 + 1 + 3;
}else{
send_buf.u8ARG[0] = ERR_OK;
memcpy(buffer, &data.u8ARG[1], length);
ISN_TOKEN_SET(buffer,length);
}
memcpy(&send_buf.u8ARG[1], &data.u8ARG[0], data.u8ARG[0] + 1);
send_buf.u8ArgLen = data.u8ARG[0] + 1 + 1;
//send_buf.u8Datalen = data.u8ARG[0] + 4;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_READ_ISN_CODE_OPCODE): //read isn
{
uint8_t buffer[33];
uint8_t length = 0;
memset(buffer, 0, 33);
uint8_t *data = ISN_TOKEN_GET();
iKonkeAfSelfPrint("len %x\r\n",data[0]);
iKonkeAfSelfPrintBuffer(data+1,32);
length = data[0];
memcpy(buffer,data,length +1);
if(length > 32) {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
send_buf.u8ARG[1] = 0x00;
send_buf.u8ArgLen = 2;
} else {
send_buf.u8ARG[0] = ERR_OK;
memcpy(&send_buf.u8ARG[1], buffer, length + 1);
send_buf.u8ArgLen = length + 1 + 1;
}
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_WRITE_MAC_CODE_OPCODE)://ok
{
uint8_t mac_length = 0x00;
addrExt_t addr,local_addr;
flash_read(CFG_MAC_ADDRESS,8,(uint8_t*)local_addr);
mac_length = data.u8ARG[0];
if (mac_length != 8) {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
} else {
send_buf.u8ARG[0] = ERR_OK;
memcpy(addr, &data.u8ARG[1], 8);
SWAP_EUI64((uint8_t *)local_addr);
if(memcmp(local_addr,addr,8) ){
SWAP_EUI64((uint8_t *)addr);
flash_erase(CFG_MAC_ADDRESS);
flash_write(CFG_MAC_ADDRESS,8,addr);
}
}
send_buf.u8ARG[1] = 8;
memcpy(&send_buf.u8ARG[2], &data.u8ARG[1], 8);
send_buf.u8ArgLen = 1 + 1 + 8;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_READ_MAC_CODE_OPCODE)://ok
{
addrExt_t addr;
flash_read(CFG_MAC_ADDRESS,8,(uint8_t*)addr);
// zb_getLocalExtAddr(addr);
send_buf.u8ARG[0] = 0x00;
send_buf.u8ARG[1] = 0x08;
SWAP_EUI64((uint8_t *)addr);
iKonkeAfSelfPrintBuffer(addr,8);
memcpy(&send_buf.u8ARG[2], addr, 8);
send_buf.u8ArgLen = 1 + 1 + 8;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_WRITE_MOUDLE_ID_OPCODE): // write modeid code
{
uint8_t buffer[33];
uint8_t length = data.u8ARG[0];
memset(buffer, 0, 33);
if(length > 32) {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
//send_buf.u8Datalen = 1 + 1 + 3;
}else{
send_buf.u8ARG[0] = ERR_OK;
memcpy(buffer, &data.u8ARG[1], length);
MODEL_ID_TOKEN_SET(buffer,length);
}
memcpy(&send_buf.u8ARG[1], &data.u8ARG[0], data.u8ARG[0] + 1);
send_buf.u8ArgLen = data.u8ARG[0] + 1 + 1;
//send_buf.u8Datalen = data.u8ARG[0] + 4;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_READ_MOUDLE_ID_OPCODE): //read modeid code
{
uint8_t buffer[33];
uint8_t length = 0;
memset(buffer, 0, 33);
uint8_t *data = MODEL_ID_TOKEN_GET();
if(All_Same_Data(&data[1],0xff,32))
{
status_t status;
zclAttrInfo_t *attrInfo = ReadServerAttribute(1,0x0000,0x0005,&status);
length = attrInfo->data[0];
iKonkeAfSelfPrint("len %x\r\n",length);
iKonkeAfSelfPrintBuffer( attrInfo->data+1,32);
memcpy(buffer,attrInfo->data,length +1);
}else{
length = data[0];
iKonkeAfSelfPrint("len %x\r\n",length);
iKonkeAfSelfPrintBuffer(data+1,32);
memcpy(buffer,data,length +1);
}
if(length > 32) {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
send_buf.u8ARG[1] = 0x00;
send_buf.u8ArgLen = 2;
//send_buf.u8Datalen = 1 + 1 + 3;
} else {
send_buf.u8ARG[0] = ERR_OK;
memcpy(&send_buf.u8ARG[1], buffer, length + 1);
send_buf.u8ArgLen = length + 1 + 1;
//send_buf.u8Datalen = length + 1 + 1 + 3;
}
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_READ_DEV_RSSI_OPCODE):
{
reply_control_field = Z_TO_H_NO_ACK;
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ARG[1] = kGetLastRssi();
send_buf.u8ArgLen = 2;
break;
}
case (UART_MSG_WRITE_AGING_TIME_OPCODE)://OK
{
uint16_t agingTime = 0;
agingTime = UINT16_HL(data.u8ARG[0], data.u8ARG[1]);
kSetAgingMaxTime(agingTime);
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ARG[1] = data.u8ARG[0];
send_buf.u8ARG[2] = data.u8ARG[1];
send_buf.u8ArgLen = 3;
//send_buf.u8Datalen = 3 + 3;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_READ_AGING_TIME_OPCODE)://OK
{
uint32_t agingTime = 0;
agingTime = kGetAgingMaxTime();
agingTime = agingTime / 1000 / 60;
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ARG[1] = H1_UINT32(agingTime);
send_buf.u8ARG[2] = H0_UINT32(agingTime);
send_buf.u8ArgLen = 3;
//send_buf.u8Datalen = 3 + 3;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_WRITE_INTERPAN_PARA_OPCODE):
{
uint8_t enable = 0;
uint16_t panId = 0;
uint8_t channel = 0;
int8_t radioTxPower = 0;
enable = data.u8ARG[0];
channel = data.u8ARG[1];
panId = UINT16_HL(data.u8ARG[2], data.u8ARG[3]);
radioTxPower = data.u8ARG[4];
if (enable == 1)
zb_factoryReset();
SetInterpanPara(channel,panId,enable);
send_buf.u8ARG[0] = ERR_OK;
memcpy(&send_buf.u8ARG[1], &data.u8ARG[0], data.u8ArgLen);
send_buf.u8ArgLen = data.u8ArgLen + 1;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
// case (UART_MSG_READ_DEVICE_SNAP_OPCODE):
// {
// uint8_t tmp_value = 0;
// uint8_t send_length = 0;
//
// send_buf.u8ARG[send_length++] = ERR_OK;
// emberAfReadAttribute(1, ZCL_BASIC_CLUSTER_ID, ZCL_STACK_VERSION_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
// &tmp_value, 1, NULL);
// send_buf.u8ARG[send_length++] = tmp_value;
//
// EmberEUI64 localEui64;
// EmberNodeType nodeTypeResult = 0xFF;
// EmberNetworkParameters networkParams;
// emberAfGetEui64(localEui64);
// SWAP_EUI64((uint8_t *)&localEui64);
//
// if(emberAfNetworkState() == EMBER_JOINED_NETWORK) {
// emberAfGetNetworkParameters(&nodeTypeResult, &networkParams);
// send_buf.u8ARG[send_length++] = HI_UINT16(networkParams.panId);
// send_buf.u8ARG[send_length++] = LO_UINT16(networkParams.panId);
// send_buf.u8ARG[send_length++] = HI_UINT16(emberAfGetNodeId());
// send_buf.u8ARG[send_length++] = LO_UINT16(emberAfGetNodeId());
// memcpy(&send_buf.u8ARG[send_length], localEui64, 8);
// send_length = send_length + 8;
// send_buf.u8ARG[send_length++] = networkParams.radioChannel;
// send_buf.u8ARG[send_length++] = networkParams.radioTxPower;
// } else {
// emberAfGetNetworkParameters(&nodeTypeResult, &networkParams);
// send_buf.u8ARG[send_length++] = 0xff;
// send_buf.u8ARG[send_length++] = 0xff;
// send_buf.u8ARG[send_length++] = 0xff;
// send_buf.u8ARG[send_length++] = 0xff;
// memcpy(&send_buf.u8ARG[send_length], localEui64, 8);
// send_length = send_length + 8;
// send_buf.u8ARG[send_length++] = 0xff;
// send_buf.u8ARG[send_length++] = 0xff;
// }
// //SV
// emberAfReadAttribute(1, ZCL_BASIC_CLUSTER_ID, ZCL_APPLICATION_VERSION_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
// &tmp_value, 1, NULL);
// send_buf.u8ARG[send_length++] = tmp_value;
// //HV
// emberAfReadAttribute(1, ZCL_BASIC_CLUSTER_ID, ZCL_HW_VERSION_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
// &tmp_value, 1, NULL);
// send_buf.u8ARG[send_length++] = tmp_value;
// memset(&send_buf.u8ARG[send_length], 0xff, 4);
// send_length = send_length + 4;
// send_buf.u8ARG[send_length++] = emberAfNetworkState();
//
// send_buf.u8ArgLen = send_length;
// //send_buf.u8Datalen = send_length + 3;
// reply_control_field = Z_TO_H_NO_ACK;
//
// break;
// }
//nwk operation request
case (UART_MSG_QUERY_NWK_STATUS_REQUEST_OPCODE)://ok
{
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ARG[1] = kNwkGetCurrentStatus();
send_buf.u8ArgLen = 2;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_JOIN_NWK_REQUEST_OPCODE)://ok
{
uint8_t duration = data.u8ARG[0];//unit:S
if (zb_isDeviceJoinedNwk()){
iKonkeAfSelfPrint("#####NWK Is Joined By Usart Duration(0x%2x)\r\n", duration);
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
}else {
send_buf.u8ARG[0] = ERR_OK;
kNwkFactoryReset(false);
//steering timeout can be set
iKonkeAfSelfPrint("#####Start Steering By Usart Duration(0x%2x)\r\n", duration);
if(duration > 0)
kNwkJoiningStart(duration * 1000, NULL);
}
send_buf.u8ARG[1] = duration;
send_buf.u8ArgLen = 2;
//send_buf.u8Datalen = 5;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_LEAVE_NWK_REQUEST_OPCODE)://ok
{
if( zb_isDeviceJoinedNwk()){
send_buf.u8ARG[0] = ERR_OK;
kNwkFactoryReset(true);
}else {
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
}
send_buf.u8ArgLen = 1;
//send_buf.u8Datalen = 4;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
/*************************************/
case (UART_MSG_ENTER_FACTORY_TEST_OPCODE):
{
uint8_t tmp_value = 0;
if ((tmp_value & 0x01) == 0x01) {
kSetSingleBoardValue(0x00);
}
if ((tmp_value & 0x02) == 0x02) {
kSetFullDeviceValue(0x00);
}
if ((tmp_value & 0x04) == 0x04) {
kSetAgingTestValue(0x00);
}
send_buf.u8ArgLen = 2;
send_buf.u8ARG[0] = ERR_OK;
reply_control_field = Z_TO_H_NO_ACK;
send_buf.u8ARG[1] = kGetFactoryTestValueStatus();
break;
}
default:
{
send_buf.u8ARG[0] = ERR_NOT_EXPECTED;
send_buf.u8ArgLen = 1;
//send_buf.u8Datalen = 4;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
}
memcpy(pDataOut, (uint8_t *)&send_buf, sizeof(DataField_st));
if (send_buf.u8ArgLen == 0) { //if cmd exist, lengtg must > 0
return KET_ERR_CMD_INVALID;
} else {
if (port == ECOM_PORT_FCC0) {
pDataOut->u8Datalen = pDataOut->u8ArgLen;
} else {
pDataOut->u8Datalen = pDataOut->u8ArgLen + 3; //AA 55 (opcode(2), ch(1))
}
return KET_OK;
}
}
uint8_t kCmdMsgDataSentByPort(uint8_t u8Control_Field, DataField_st data, bool isGetResult, ComPortEm port)
{
uint8_t length = 0;
UMsgNodeSt uMsgNode;
memset((uint8_t*)&uMsgNode,0,sizeof(UMsgNodeSt));
uMsgNode.buffer[length++] = 0xAA; //msg header
uMsgNode.buffer[length++] = 0x55; //msg header
uMsgNode.buffer[length++] = 0x00; //msg length
uMsgNode.buffer[length++] = 0x00; //msg length
uMsgNode.buffer[length++] = u8Control_Field;
// seq++;
uMsgNode.buffer[length++] = (uint8_t) (data.seq >> 8);
uMsgNode.buffer[length++] = (uint8_t) data.seq;
uMsgNode.buffer[length++] = data.u8Datalen;
uMsgNode.buffer[length++] = data.u8ChannelID;
uMsgNode.buffer[length++] = (uint8_t) (data.u16Opcode >> 8);
uMsgNode.buffer[length++] = (uint8_t) data.u16Opcode;
memmove(&uMsgNode.buffer[length], data.u8ARG, data.u8Datalen - 3);
length = length + data.u8Datalen - 3;
uMsgNode.buffer[2] = (uint8_t) ((length - 4) >> 8);
uMsgNode.buffer[3] = (uint8_t) (length - 4);
uint16_t crc = kCmdGetMsgCrc16Value(&uMsgNode.buffer[4], length - 4);
uMsgNode.buffer[length++] = (uint8_t) (crc >> 8);
uMsgNode.buffer[length++] = (uint8_t) (crc);
uMsgNode.length = length;
// setting for matcher content.
uMsgNode.matcher[0] = uMsgNode.buffer[2]; //seq
uMsgNode.matcher[1] = uMsgNode.buffer[3];
uMsgNode.matcher_offset = 2;
uMsgNode.matcher_n = 2;
//zigbee send to host ack
if (u8Control_Field == Z_TO_H_NO_ACK) {
uMsgNode.sent_try = 0;
} else if (u8Control_Field == Z_TO_H_WITH_ACK) {
//zigbee send to host notify or control
uMsgNode.sent_try = 1;
}
if (isGetResult) {
uMsgNode.ack = uMsgNode.buffer;
} else {
uMsgNode.ack = NULL;
uMsgNode.ack_length = 0;
}
iKonkeAfSelfPrint("\r\n-- kCmdMsgDataSentByPort[%d]:\r\n", uMsgNode.length);
iKonkeAfSelfPrintBuffer(uMsgNode.buffer, uMsgNode.length);
if (port == ECOM_PORT_UART) {
return kUartMsgSent(&uMsgNode);
}
else if (port == ECOM_PORT_INTERPAN) {
return kInterPanSend(&uMsgNode);
}
return 0;
}
#ifndef __IKONKE_COMMAND_H____________________________ #ifndef __IKONKE_COMMAND_H____________________________
#define __IKONKE_COMMAND_H____________________________ #define __IKONKE_COMMAND_H____________________________
#include "ikk-module-def.h" #include "ikk-module-def.h"
#include "../driver/ikk-uart.h"
#endif
#define CMD_CONTROL_FIELD_HOST_TO_ZIGBEE_NEED_ACK 0x10
#define CMD_CONTROL_FIELD_HOST_TO_ZIGBEE_NO_ACK 0x00
#define CMD_CONTROL_FIELD_ZIGBEE_TO_HOST_NEED_ACK 0x30
#define CMD_CONTROL_FIELD_ZIGBEE_TO_HOST_NO_ACK 0x20
typedef enum {
H_TO_Z_WITH_ACK = CMD_CONTROL_FIELD_HOST_TO_ZIGBEE_NEED_ACK,
H_TO_Z_NO_ACK = CMD_CONTROL_FIELD_HOST_TO_ZIGBEE_NO_ACK,
Z_TO_H_WITH_ACK = CMD_CONTROL_FIELD_ZIGBEE_TO_HOST_NEED_ACK,
Z_TO_H_NO_ACK = CMD_CONTROL_FIELD_ZIGBEE_TO_HOST_NO_ACK,
}CMD_CONTROL_FIELD_E;
typedef struct{
uint16_t seq;
uint8_t u8Datalen;
uint8_t u8ChannelID;
uint16_t u16Opcode;
uint8_t u8ArgLen;
uint8_t u8ARG[128];
}DataField_st;
typedef struct{
uint8_t u8SOFHeaderBuf[2];
uint16_t u16DataLength;
uint8_t u8ControlFied;
//uint16_t u16Seq;
DataField_st stDataField;
}MsgFrameworkFormat_st;
kk_err_t kCmdGeneralMsgPaser(UMsgNodeSt *pMsgNode, ComPortEm port, DataField_st *pDataOut);
uint16_t kCmdOpcodeRemap(uint16_t Opcode, uint8_t direction);
uint16_t kCmdGetMsgCrc16Value( uint8_t* msg, uint8_t len);
uint8_t kCmdMsgDataSentByPort(uint8_t u8Control_Field, DataField_st data, bool isGetResult, ComPortEm port);
#endif
#ifndef __IKONKE_MODULE_DEBUG_H______________________________ #ifndef __IKONKE_MODULE_DEBUG_H______________________________
#define __IKONKE_MODULE_DEBUG_H______________________________ #define __IKONKE_MODULE_DEBUG_H______________________________
#define IKONKE_DEBUG_LOG_ENABLE (1) // ENABLE #define IKONKE_DEBUG_LOG_ENABLE (0) // ENABLE
#define PROMPT_DSR "" #define PROMPT_DSR ""
#if (IKONKE_DEBUG_LOG_ENABLE) #if (IKONKE_DEBUG_LOG_ENABLE)
#define iKonkeAfSelfPrint(...) do { \ #define iKonkeAfSelfPrint(...) do { \
extern int Tl_printf(const char *format, ...);\ extern int Tl_printf(const char *format, ...);\
Tl_printf(PROMPT_DSR); \ Tl_printf(PROMPT_DSR); \
Tl_printf(__VA_ARGS__); \ Tl_printf(__VA_ARGS__); \
}while(0) }while(0)
//#define iKonkeAfSelfDebugExec(x) if ( emberAfPrintEnabled(0xffff) ) { x; } //#define iKonkeAfSelfDebugExec(x) if ( emberAfPrintEnabled(0xffff) ) { x; }
#define iKonkeAfSelfPrintBuffer(buffer, len) DEBUG_ARRAY(1, (buffer), (len)) #define iKonkeAfSelfPrintBuffer(buffer, len) DEBUG_ARRAY(1, (buffer), (len))
//#define iKonkeAfSelfPrintString(buffer) emberAfPrintString(0xffff, (buffer)) //#define iKonkeAfSelfPrintString(buffer) emberAfPrintString(0xffff, (buffer))
#else #else
#define iKonkeAfSelfPrint(...) #define iKonkeAfSelfPrint(...)
//#define iKonkeAfSelfDebugExec(x) //#define iKonkeAfSelfDebugExec(x)
#define iKonkeAfSelfPrintBuffer(buffer, len) #define iKonkeAfSelfPrintBuffer(buffer, len)
//#define iKonkeAfSelfPrintString(buffer) //#define iKonkeAfSelfPrintString(buffer)
#endif #endif
#endif #endif
#include "ikk-factory-test.h" #include "ikk-factory-test.h"
#include "ikk-debug.h" #include "ikk-debug.h"
#include "ikk-token.h" #include "ikk-token.h"
#include "tl_common.h" #include "ikk-common-utils.h"
#include "../driver/ikk-button.h" #include "../driver/ikk-button.h"
#define AGING_TEST_15MIN_VALUE 0xA1 #define AGING_TEST_15MIN_VALUE 0xA1
#define AGING_TEST_8HOU_VALUE 0xA2 #define AGING_TEST_4HOU_VALUE 0xA2
#define AGINE_TEST_DONE_VALUE 0xFA #define AGINE_TEST_DONE_VALUE 0xFA
//已经置老化标志 //已经置老化标志
#define FACTORY_TEST_VALUE 0xF1 #define SINGLE_BOARD_TEST_DONE_VALUE 0xF1 //锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷
//初始值 #define FULL_DEVICE_TEST_DONE_VALUE 0xF2 //锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟?
#define TEST_INIT_VALUE 0xFF #define FORCE_FACTORY_TEST_VALUE 0xF8 //锟斤拷锟斤拷锟斤拷锟斤拷锟角匡拷锟斤拷顺锟?
static ev_timer_event_t *kFactoryTestEvt = NULL;
s32 kFactoryTestEventHandler(void *arg);
static ev_timer_event_t *kFactoryTestEvt = NULL;
s32 kFactoryTestEventHandler(void *arg);
typedef struct{
uint8_t u8BtnId;
uint8_t u8BtnLongPressTimes; //touch keys must be long pressed 2 times, mechanical keys is pressed 1 time typedef struct{
uint32_t u32AgingForceExitTimeMs; //key long pressed time for exit aging test uint8_t u8BtnId;
uint32_t u32AgingForceExitTimeCounter; //key long pressed time for exit aging test uint8_t u8BtnLongPressTimes; //touch keys must be long pressed 2 times, mechanical keys is pressed 1 time
BtnActionEnum elastBtnAction; uint32_t u32AgingForceExitTimeMs; //key long pressed time for exit aging test
BtnActionEnum eCurrentBtnAction; uint32_t u32AgingForceExitTimeCounter; //key long pressed time for exit aging test
bool bIsFirstBtnLongPressed ; BtnActionEnum elastBtnAction;
uint32_t u32FirstBtnLongPressedCountDown; BtnActionEnum eCurrentBtnAction;
}FactoryTestControllerSt; bool bIsFirstBtnLongPressed ;
uint32_t u32FirstBtnLongPressedCountDown;
FactoryTestControllerSt g_stFactoryTestControllerList[AGING_EXIT_MAX_BTN_NUM] \ }FactoryTestControllerSt;
= {{BTN_UNKNOW_ID, 0, 0, 0, EBA_IDLE, EBA_IDLE, 0, 0}, {BTN_UNKNOW_ID, 0, 0, 0, EBA_IDLE, EBA_IDLE, 0, 0}};
typedef enum{FT_SINGLE_BOARD_TEST=0x01, FT_FULL_DEVICE_TEST=0x02, FT_NORMAL_DONE=0x04, FT_FORCE_EXIT=0x08}FT_STATUS;
static FactoryTestStatusEnum g_eFactoryTestStatus = FTS_NORMAL;
static FactoryTestStatusEnum g_eLastFactoryTestStatus = FTS_NORMAL; FactoryTestControllerSt g_stFactoryTestControllerList[AGING_EXIT_MAX_BTN_NUM] \
static uint32_t g_u32AgingTotalTimeMS = 0; = {{BTN_UNKNOW_ID, 0, 0, 0, EBA_IDLE, EBA_IDLE, 0, 0}, {BTN_UNKNOW_ID, 0, 0, 0, EBA_IDLE, EBA_IDLE, 0, 0}};
static pFactoryTestPollCallback g_pFactoryTestPollCallback = NULL;
static uint8_t g_u8LongPressedKeyIndex = 0; static FactoryTestStatusEnum g_eFactoryTestStatus = FTS_NORMAL;
static uint32_t g_u32Count = 0; static FactoryTestStatusEnum g_eLastFactoryTestStatus = FTS_NORMAL;
/* DESP: get the test index by id. static uint32_t g_u32AgingTotalTimeMS = 0;
* Auth: mazj.20200227. static pFactoryTestPollCallback g_pFactoryTestPollCallback = NULL;
* */ static uint8_t g_u8LongPressedKeyIndex = 0;
static uint8_t kGetFactoryTestIndexByID(uint8_t id ) static uint32_t g_u32Count = 0;
{ /* DESP: get the test index by id.
for(int index = 0; index < AGING_EXIT_MAX_BTN_NUM; ++index ) { * Auth: mazj.20200227.
if( g_stFactoryTestControllerList[index].u8BtnId != BTN_UNKNOW_ID ) { * */
if( g_stFactoryTestControllerList[index].u8BtnId == id ) { static uint8_t kGetFactoryTestIndexByID(uint8_t id )
return index; {
} for(int index = 0; index < AGING_EXIT_MAX_BTN_NUM; ++index ) {
}else break; if( g_stFactoryTestControllerList[index].u8BtnId != BTN_UNKNOW_ID ) {
} if( g_stFactoryTestControllerList[index].u8BtnId == id ) {
return index;
return 0XFF; }
} }else break;
}
FactoryTestStatusEnum kGetFactoryTestStatus(void)
{ return 0XFF;
return g_eFactoryTestStatus; }
}
FactoryTestStatusEnum kGetFactoryTestStatus(void)
{
void kFactoryTestBtnActionCallback(unsigned char button_id, BtnActionEnum action) return g_eFactoryTestStatus;
{ }
uint8_t u8FactoryTestIndex = kGetFactoryTestIndexByID(button_id);
iKonkeAfSelfPrint("######kFactoryTestBtnActionCallback,index(%d) id (%d)action(%d)\r\n",u8FactoryTestIndex,button_id, action); void kSetAgingMaxTime(uint16_t value)
if (u8FactoryTestIndex != 0xFF){ {
if(action == EBA_LONGPRESS) nv_sts_t st = NV_SUCC;
g_stFactoryTestControllerList[u8FactoryTestIndex].eCurrentBtnAction = EBA_PRESSED;
else uint16_t temp;
g_stFactoryTestControllerList[u8FactoryTestIndex].eCurrentBtnAction = action; st = nv_flashReadNew(1, NV_MODULE_APP, NV_AGING_TEST_TIME, sizeof(uint16_t), (u8*)&temp);
if(st == NV_SUCC){
//松手复位,触摸按键长时间按着也会自动松手 if(temp != value)
if (g_eFactoryTestStatus == FTS_AGING_WAITING && g_stFactoryTestControllerList[g_u8LongPressedKeyIndex].eCurrentBtnAction == EBA_RELEASED){ {
g_eFactoryTestStatus = FTS_AGING_FORCE_REBOOT; st = nv_flashWriteNew(1, NV_MODULE_APP, NV_AGING_TEST_TIME, sizeof(uint16_t), (u8*)&value);
g_u32Count = FACTORY_TEST_POLL_TIMES; //快点执行自定义函数 iKonkeAfSelfPrint("kSetAgingTestTime:st = %d,data = %d\r\n",st,NV_AGING_TEST_TIME);
iKonkeAfSelfPrint("######33333333333333333 FactoryTest Released\r\n"); }
} }else if(st == NV_ITEM_NOT_FOUND){
} st = nv_flashWriteNew(1, NV_MODULE_APP, NV_AGING_TEST_TIME, sizeof(uint16_t), (u8*)&value);
}
} }
uint32_t kGetAgingMaxTime(void)
void kFactoryTestInit(pFactoryTestPollCallback callback, FactoryTestConfSt conf_list[], uint8_t btn_num) {
{ nv_sts_t st = NV_SUCC;
#if FACTORY_TEST_ENABLE uint32_t maxTime;
if(NULL == callback || NULL == conf_list || btn_num > AGING_EXIT_MAX_BTN_NUM) { uint16_t value = 0;
return; st = nv_flashReadNew(1, NV_MODULE_APP, NV_AGING_TEST_TIME, sizeof(value), (u8*)&value);
} iKonkeAfSelfPrint("kGetAgingTestTime:st = %d,value = %d\r\n",st,value);
for (uint8_t i = 0; i < btn_num; i++){ if(st != NV_SUCC){
g_stFactoryTestControllerList[i].u8BtnId = conf_list[i].u8BtnId; maxTime = FACTORY_TEST_4HOU_MS;
g_stFactoryTestControllerList[i].u8BtnLongPressTimes = conf_list[i].u8BtnLongPressTimes; }
g_stFactoryTestControllerList[i].u32AgingForceExitTimeMs = conf_list[i].u32AgingForceExitTimeMs; else if ((value == 0) || (value == 0xffff)) {
} maxTime = FACTORY_TEST_4HOU_MS;
} else {
maxTime = value * 60 * 1000;
iKonkeAfSelfPrint("######g_stFactoryTestControllerList[0].u8BtnId= %d u8BtnLongPressTimes = %d\r\n", g_stFactoryTestControllerList[0].u8BtnId, g_stFactoryTestControllerList[0].u8BtnLongPressTimes); }
iKonkeAfSelfPrint("######g_stFactoryTestControllerList[1].u8BtnId= %d u8BtnLongPressTimes = %d\r\n", g_stFactoryTestControllerList[1].u8BtnId, g_stFactoryTestControllerList[1].u8BtnLongPressTimes); return maxTime;
}
if (kGetAgingTestValue() != AGINE_TEST_DONE_VALUE){ uint8_t kGetFactoryTestValueStatus(void)
kSetAgingTestValue(AGING_TEST_15MIN_VALUE); {
g_eFactoryTestStatus = FTS_START; uint8_t status = 0;
//启动老化事件
if(kFactoryTestEvt){ #if Z30_DEVICE_SINGLE_BOARD_ENABLE
TL_ZB_TIMER_CANCEL(&kFactoryTestEvt); if (kGetSingleBoardValue() == FORCE_FACTORY_TEST_VALUE) {
} status = status | FT_FORCE_EXIT;
kFactoryTestEvt = TL_ZB_TIMER_SCHEDULE(kFactoryTestEventHandler, NULL, 1000); }else if (kGetSingleBoardValue() != SINGLE_BOARD_TEST_DONE_VALUE) {
g_eFactoryTestStatus = FTS_START; status = status | FT_SINGLE_BOARD_TEST;
}else { }
g_eFactoryTestStatus = FTS_NORMAL; #endif
}
kBtnaIRQCallbackRegister(kFactoryTestBtnActionCallback); #if Z30_DEVICE_FULL_DEVICE_ENBALE
g_pFactoryTestPollCallback = callback; if (kGetFullDeviceValue() == FORCE_FACTORY_TEST_VALUE) {
g_u32AgingTotalTimeMS = 0; status = status | FT_FORCE_EXIT;
// g_u8AgingForceExitBtnId = btn_id; }else if (kGetFullDeviceValue() != FULL_DEVICE_TEST_DONE_VALUE){
#else status = status | FT_FULL_DEVICE_TEST;
uint8_t value = TEST_INIT_VALUE; }else if(kGetSingleBoardValue() == SINGLE_BOARD_TEST_DONE_VALUE){
kSetAgingTestValue(value); status = status | FT_NORMAL_DONE;
g_eFactoryTestStatus = FTS_NORMAL; }
#endif #endif
}
return status;
}
s32 kFactoryTestEventHandler(void *arg) nv_sts_t General_Set_Factory_Test(nv_item_t items,uint8_t value)
{ {
iKonkeAfSelfPrint("######kFactoryTestEventHandler status(%d)\r\n", g_eFactoryTestStatus); nv_sts_t st = NV_SUCC;
uint8_t temp;
g_u32AgingTotalTimeMS += FACTORY_TEST_POLL_TTME_1S; st = nv_flashReadNew(1, NV_MODULE_APP, items, sizeof(uint8_t), (u8*)&temp);
if(st == NV_SUCC){
if (g_eFactoryTestStatus != FTS_AGING_WAITING && g_eFactoryTestStatus != FTS_AGING_WAITING_SECOND_PRESS){ if(temp != value)
switch (g_eFactoryTestStatus) {
{ st = nv_flashWriteNew(1, NV_MODULE_APP, items, sizeof(uint8_t), (u8*)&value);
case (FTS_START): iKonkeAfSelfPrint("kSetSingleBoardValue:st = %d,data = %d\r\n",st,value);
//g_eFactoryTestStatus = FTS_AGING_15MIN; }
g_u32Count = FACTORY_TEST_POLL_TIMES; }else if(st == NV_ITEM_NOT_FOUND){
break; st = nv_flashWriteNew(1, NV_MODULE_APP, items, sizeof(uint8_t), (u8*)&value);
case (FTS_AGING_15MIN): }
//上电后15分钟时间到,15分钟内可以短按按键和长按,但不能组网 return st;
if (g_u32AgingTotalTimeMS >= FACTORY_TEST_15MIN_MS){ }
kSetAgingTestValue(AGING_TEST_8HOU_VALUE); uint8_t General_Get_Factory_Test(nv_item_t items,uint8_t default_value)
g_eFactoryTestStatus = FTS_AGING_8HOU_START; {
//15分钟后重新开始计时 nv_sts_t st = NV_SUCC;
g_u32AgingTotalTimeMS = 0; uint8_t temp;
g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数 st = nv_flashReadNew(1, NV_MODULE_APP, items, sizeof(temp), (u8*)&temp);
} iKonkeAfSelfPrint("kGetSingleBoardValue:st = %d,data = %d\r\n",st,temp);
break; if(st != NV_SUCC){
case (FTS_AGING_8HOU_START): temp = default_value;
//可以设置所有的LED状态一致,在回调函数实现 }
g_eFactoryTestStatus = FTS_AGING_8HOU; return temp;
break; }
case (FTS_AGING_8HOU): void kFactoryTestBtnActionCallback(unsigned char button_id, BtnActionEnum action)
//上电后12小时老化时间到,12小时内不可以短按按键和长按,不能组网 {
if (g_u32AgingTotalTimeMS >= FACTORY_TEST_8HOU_MS){ if (kGetFactoryTestStatus() != FTS_NORMAL)
kSetAgingTestValue(AGINE_TEST_DONE_VALUE); {
g_eFactoryTestStatus = FTS_AGING_DONE; uint8_t u8FactoryTestIndex = kGetFactoryTestIndexByID(button_id);
} if (u8FactoryTestIndex != 0xFF){
break; //add bby maozj 20200828
case (FTS_AGING_DONE): if(action == EBA_LONGPRESS)
//老化完退出当前事件 g_stFactoryTestControllerList[u8FactoryTestIndex].eCurrentBtnAction = EBA_PRESSED;
//return; else
g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数 g_stFactoryTestControllerList[u8FactoryTestIndex].eCurrentBtnAction = action;
break;
case (FTS_AGING_FORCE_EXIT): //松手复位,触摸按键长时间按着也会自动松手
g_eFactoryTestStatus = FTS_AGING_WAITING; if (g_eFactoryTestStatus == FTS_AGING_WAITING && g_stFactoryTestControllerList[g_u8LongPressedKeyIndex].eCurrentBtnAction == EBA_RELEASED){
break; g_eFactoryTestStatus = FTS_AGING_FORCE_REBOOT;
case (FTS_AGING_WAITING): g_u32Count = FACTORY_TEST_POLL_TIMES; //快点执行自定义函数
break; iKonkeAfSelfPrint("######33333333333333333 FactoryTest Released\r\n");
case (FTS_AGING_FIRST_LONG_PRESSED): }
g_eFactoryTestStatus = FTS_AGING_WAITING_SECOND_PRESS; }
break; }
case (FTS_AGING_WAITING_SECOND_PRESS): }
break;
default: kk_err_t kkFactoryMsgInComingPaser(UMsgNodeSt *pMsgNode, ComPortEm port, DataField_st *pDataOut)
break; {
} //UMsgNodeSt uMsgNode = {0};
} uint16_t length = 0;
uint8_t control_field = 0;
for (uint8_t index = 0; index < AGING_EXIT_MAX_BTN_NUM; index++){ DataField_st data;
if (g_stFactoryTestControllerList[index].u8BtnId != BTN_UNKNOW_ID ){ DataField_st send_buf;
if (g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_PRESSED \ uint8_t reply_control_field = 0;
&& g_stFactoryTestControllerList[index].elastBtnAction != EBA_PRESSED){
if( NULL == pMsgNode ) {
g_stFactoryTestControllerList[index].elastBtnAction = EBA_PRESSED; return KET_ERR_INVALID_PARAM;
//g_stFactoryTestControllerList[index].eCurrentBtnAction = EBA_PRESSING; }
//重置长按倒计时计数
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter = \ #if 0 // Just for debug
g_stFactoryTestControllerList[index].u32AgingForceExitTimeMs / FACTORY_TEST_POLL_TTME_1S; iKonkeAfSelfPrint("\r\n-- MSG INCOMING[%d]:\r\n", pMsgNode->length);
}else if (g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_RELEASED \ iKonkeAfSelfPrintBuffer(pMsgNode->buffer, pMsgNode->length, true);
&& g_stFactoryTestControllerList[index].elastBtnAction != EBA_RELEASED){ iKonkeAfSelfPrint("\r\n--------------------\r\n");
iKonkeAfSelfPrint("&&&&&&& EBA_RELEASED u32AgingForceExitTimeCounter == %d\r\n",\ #endif
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter);
g_stFactoryTestControllerList[index].elastBtnAction = EBA_RELEASED; // check for parsable packets
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter = 0; if( pMsgNode->length < 5 /* Minimum Packet Length */ ) {
}else { iKonkeAfSelfPrint("Err: Unparsable Packets!!\r\n");
g_stFactoryTestControllerList[index].elastBtnAction = g_stFactoryTestControllerList[index].eCurrentBtnAction; return KET_ERR_INVALID_PARAM;
} }
//倒计时20S或5S //length(1) pid(4) ch(1) opcode(1) arg
if (g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter > 0 \ if (port == ECOM_PORT_FCC0) {
&& g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_PRESSED){ length = pMsgNode->length;
//control_field = pMsgNode->buffer[4];
iKonkeAfSelfPrint("######u32AgingForceExitTimeCounter-- %d\r\n", \ data.seq = 0x00;
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter); data.u8Datalen = pMsgNode->buffer[0];
data.u8ArgLen = data.u8Datalen - 6; // fcc0 - id (4) - ch(1) - opcode(1)
if (--g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter == 0){ data.u8ChannelID = pMsgNode->buffer[5];
data.u16Opcode = kCmdOpcodeRemap((uint16_t)(pMsgNode->buffer[6]), 0);
iKonkeAfSelfPrint("######u32AgingForceExitTimeCounter == 0\r\n");
if(data.u16Opcode == 0xFFFF) {
if ( g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_1_TIMES \ return KET_ERR_INVALID_PARAM;
|| g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed == true){ }
//successfully exit aging test
g_eFactoryTestStatus = FTS_AGING_FORCE_EXIT; memcpy(data.u8ARG,&pMsgNode->buffer[7], data.u8ArgLen); //6 = pid(4) + ch(1) + opcode(1)
kSetAgingTestValue(AGINE_TEST_DONE_VALUE);
g_u32Count = FACTORY_TEST_POLL_TIMES; //快点执行自定义函数 send_buf.seq = data.seq;
//防止老化状态被重置 send_buf.u8ChannelID = data.u8ChannelID;
g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown = 0; send_buf.u16Opcode = data.u16Opcode;
g_u8LongPressedKeyIndex = index; } else {
//g_u32AgingTotalTimeMS = FACTORY_TEST_12HOU_MS; length = ((uint16_t)pMsgNode->buffer[2] << 8) | (uint16_t)(pMsgNode->buffer[3]);
iKonkeAfSelfPrint("######11111111111 == 0\r\n"); control_field = pMsgNode->buffer[4];
}else if ( g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_2_TIMES){
//触摸按键需要长按两次才能退出老化 data.seq = ((uint16_t)pMsgNode->buffer[5] << 8) | (uint16_t)(pMsgNode->buffer[6]);
g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed = true;
g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown = \ data.u8Datalen = pMsgNode->buffer[7];
(FIRST_BTN_LONG_PRESSED_VALIED_TIME_MS + FACTORY_TEST_POLL_TTME_1S)/ FACTORY_TEST_POLL_TTME_1S; data.u8ArgLen = data.u8Datalen - 3; // aa55 - ch(1) - opcode(2)
g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数 data.u8ChannelID = pMsgNode->buffer[8];
//记录当前的老化状态 data.u16Opcode = ((uint16_t)pMsgNode->buffer[9] << 8) | (uint16_t)(pMsgNode->buffer[10]);
g_eLastFactoryTestStatus = g_eFactoryTestStatus; memcpy(data.u8ARG,&pMsgNode->buffer[11],data.u8Datalen - 3);
g_eFactoryTestStatus = FTS_AGING_FIRST_LONG_PRESSED;
send_buf.seq = data.seq;
iKonkeAfSelfPrint("######2222222222222222222222 == 0\r\n"); send_buf.u8ChannelID = data.u8ChannelID;
} send_buf.u16Opcode = data.u16Opcode;
} }
}else {
//g_stFactoryTestControllerList[index].elastBtnAction = g_stFactoryTestControllerList[index].eCurrentBtnAction; send_buf.u8Datalen = 0;
}
switch (data.u16Opcode) {
//第二次长按有效时间倒计时 case (UART_MSG_QUERY_INFO_OPCODE):
if (g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown > 0 && g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_2_TIMES){ {
if (--g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown == 0){ send_buf.u8ARG[0] = ERR_OK;
g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed = false; send_buf.u8ArgLen = 1;
//恢复之前老化状态 reply_control_field = Z_TO_H_NO_ACK;
g_eFactoryTestStatus = g_eLastFactoryTestStatus; break;
} }
} case (UART_MSG_QUERY_DEVICE_VERSION_OPCODE):
} {
} send_buf.u8ARG[0] = ERR_OK;
//10S执行一次自定义老化,有时会根据不同状态会更新减短时间,让更快执行 //wait to do
if (g_u32Count++ >= FACTORY_TEST_POLL_TIMES){ send_buf.u8ARG[1] = 0x20;
g_u32Count = 0; send_buf.u8ARG[2] = 0x20;
//用户自定义老化测试方案 send_buf.u8ARG[3] = 0XFF;
if (g_pFactoryTestPollCallback){ send_buf.u8ARG[4] = 0XFF;
g_pFactoryTestPollCallback(g_eFactoryTestStatus); send_buf.u8ARG[0] = ERR_OK;;
} send_buf.u8ArgLen = 5;
reply_control_field = Z_TO_H_NO_ACK;
if (g_eFactoryTestStatus == FTS_START){ break;
g_eFactoryTestStatus = FTS_AGING_15MIN; }
}else if (g_eFactoryTestStatus == FTS_AGING_DONE){ case (UART_MSG_QUERY_DEVICE_INFO_OPCODE):
//老化结束退出当前事件 {
return 0; addrExt_t addr;
} flash_read(CFG_MAC_ADDRESS,8,(uint8_t*)addr);
}
return 0; send_buf.u8ARG[0] = ERR_OK;
} SWAP_EUI64((uint8_t *)addr);
memcpy(&send_buf.u8ARG[1],addr,8);
send_buf.u8ArgLen = 9;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_CONFIG_DEVICE_SLEEP_OPCODE):
{
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ArgLen = 1;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_EXIT_FACTORY_TEST_OPCODE):
{
uint8_t token_data = 0;
if(data.u8ARG[0]&0x01)
{
kSetSingleBoardValue(SINGLE_BOARD_TEST_DONE_VALUE);
iKonkeAfSelfPrint("######kGetSingleBoardValue(%x)\r\n", token_data);
send_buf.u8ARG[0] = ERR_OK;
}
if(data.u8ARG[0]&0x02)
{
kSetFullDeviceValue(FULL_DEVICE_TEST_DONE_VALUE);
iKonkeAfSelfPrint("######kGetFullBoardValue(%02x)\r\n", token_data);
send_buf.u8ARG[0] = ERR_OK;
}
if( (data.u8ARG[0]&0x03 == 0x03)||(data.u8ARG[0]&0x04 == 0x04) )
{
kSetAgingTestValue(AGINE_TEST_DONE_VALUE);
iKonkeAfSelfPrint("######kGetAgingTestValue(%02x)\r\n", token_data);
send_buf.u8ARG[0] = ERR_OK;
g_eFactoryTestStatus = FTS_AGING_DONE;
}
send_buf.u8ARG[1] = data.u8ARG[0];
send_buf.u8ArgLen = 2;
reply_control_field = Z_TO_H_NO_ACK;
break;
}
case (UART_MSG_QUERY_FACTORY_INFO_OPCODE):
{
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ARG[1] = kGetFactoryTestValueStatus();
send_buf.u8ArgLen = 2;
reply_control_field = Z_TO_H_NO_ACK;
iKonkeAfSelfPrint("######UART_MSG_QUERY_FACTORY_INFO_OPCODE(%d)\r\n", send_buf.u8ArgLen);
break;
}
case UART_MSG_QUERY_SWITCH_ONOFF_OPCODE:
{
extern uint8_t Key_Press_Test_Flag[5];
for (uint8_t i = 0; i < 6; i++){
if(i < 5){
send_buf.u8ARG[i+1] = Key_Press_Test_Flag[i];
}
else{
send_buf.u8ARG[i+1] = 0xff;
}
}
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ArgLen = 7;
break;
}
case (UART_MSG_ENTER_FACTORY_TEST_OPCODE):
{
uint8_t tmp_value = data.u8ARG[0];
reply_control_field = Z_TO_H_NO_ACK;
if ((tmp_value & 0x01) == 0x01) {
kSetSingleBoardValue(0x00);
}
if ((tmp_value & 0x02) == 0x02) {
kSetFullDeviceValue(0x00);
}
if ((tmp_value & 0x04) == 0x04) {
kSetAgingTestValue(0x00);
}
send_buf.u8ArgLen = 2;
send_buf.u8ARG[0] = ERR_OK;
send_buf.u8ARG[1] = kGetFactoryTestValueStatus();
break;
}
case UART_MSG_ONOFF_SWITCH_OPCODE:
{
uint8_t command = data.u8ARG[0];
if(command == 1){ //控制命令
for (uint8_t i = 0; i < 9; i++){
if(i < 4){
if(data.u8ARG[i+1] == 1)
kZclOnOffClusterServerOnOffControl(i+1, 1);
else if(data.u8ARG[i+1] == 0)
kZclOnOffClusterServerOnOffControl(i+1, 0);
}
else{
data.u8ARG[i+1] = 0xff;
}
}
}
send_buf.u8ARG[0] = ERR_OK;
memcpy(&send_buf.u8ARG[1], &data.u8ARG[1], 8);
send_buf.u8ArgLen = 10;
break;
}
default:
break;
}
memcpy(pDataOut, (uint8_t *)&send_buf, sizeof(DataField_st));
if (send_buf.u8ArgLen == 0) { //if cmd exist, lengtg must > 0
return KET_ERR_CMD_INVALID;
} else {
if (port == ECOM_PORT_FCC0) {
pDataOut->u8Datalen = pDataOut->u8ArgLen;
} else {
pDataOut->u8Datalen = pDataOut->u8ArgLen + 3; //AA 55 (opcode(2), ch(1))
}
return KET_OK;
}
}
void kFactoryTestInit(pFactoryTestPollCallback callback, FactoryTestConfSt conf_list[], uint8_t btn_num)
{
#if FACTORY_TEST_ENABLE
if(NULL == callback || NULL == conf_list || btn_num > AGING_EXIT_MAX_BTN_NUM) {
return;
}
for (uint8_t i = 0; i < btn_num; i++){
g_stFactoryTestControllerList[i].u8BtnId = conf_list[i].u8BtnId;
g_stFactoryTestControllerList[i].u8BtnLongPressTimes = conf_list[i].u8BtnLongPressTimes;
g_stFactoryTestControllerList[i].u32AgingForceExitTimeMs = conf_list[i].u32AgingForceExitTimeMs;
}
iKonkeAfSelfPrint("######g_stFactoryTestControllerList[0].u8BtnId= %d u8BtnLongPressTimes = %d\r\n", g_stFactoryTestControllerList[0].u8BtnId, g_stFactoryTestControllerList[0].u8BtnLongPressTimes);
iKonkeAfSelfPrint("######g_stFactoryTestControllerList[1].u8BtnId= %d u8BtnLongPressTimes = %d\r\n", g_stFactoryTestControllerList[1].u8BtnId, g_stFactoryTestControllerList[1].u8BtnLongPressTimes);
if (kGetAgingTestValue() != AGINE_TEST_DONE_VALUE){
kSetAgingTestValue(AGING_TEST_15MIN_VALUE);
g_eFactoryTestStatus = FTS_START;
//启动老化事件
if(kFactoryTestEvt){
TL_ZB_TIMER_CANCEL(&kFactoryTestEvt);
}
kFactoryTestEvt = TL_ZB_TIMER_SCHEDULE(kFactoryTestEventHandler, NULL, 1000);
g_eFactoryTestStatus = FTS_START;
}else {
g_eFactoryTestStatus = FTS_NORMAL;
}
kBtnaIRQCallbackRegister(kFactoryTestBtnActionCallback);
g_pFactoryTestPollCallback = callback;
g_u32AgingTotalTimeMS = 0;
// g_u8AgingForceExitBtnId = btn_id;
#else
uint8_t value = TEST_INIT_VALUE;
kSetAgingTestValue(value);
g_eFactoryTestStatus = FTS_NORMAL;
#endif
}
s32 kFactoryTestEventHandler(void *arg)
{
// iKonkeAfSelfPrint("######kFactoryTestEventHandler status(%d)\r\n", g_eFactoryTestStatus);
g_u32AgingTotalTimeMS += FACTORY_TEST_POLL_TTME_1S;
if (g_eFactoryTestStatus != FTS_AGING_WAITING && g_eFactoryTestStatus != FTS_AGING_WAITING_SECOND_PRESS){
switch (g_eFactoryTestStatus)
{
case (FTS_START):
//g_eFactoryTestStatus = FTS_AGING_15MIN;
g_u32Count = FACTORY_TEST_POLL_TIMES;
break;
case (FTS_AGING_15MIN):
//上电后15分钟时间到,15分钟内可以短按按键和长按,但不能组网
if (g_u32AgingTotalTimeMS >= FACTORY_TEST_15MIN_MS){
kSetAgingTestValue(AGING_TEST_4HOU_VALUE);
g_eFactoryTestStatus = FTS_AGING_4HOU_START;
//15分钟后重新开始计时
g_u32AgingTotalTimeMS = 0;
g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数
}
break;
case (FTS_AGING_4HOU_START):
//可以设置所有的LED状态一致,在回调函数实现
g_eFactoryTestStatus = FTS_AGING_4HOU;
break;
case (FTS_AGING_4HOU):
//上电后12小时老化时间到,12小时内不可以短按按键和长按,不能组网
if (g_u32AgingTotalTimeMS >= FACTORY_TEST_4HOU_MS){
kSetAgingTestValue(AGINE_TEST_DONE_VALUE);
g_eFactoryTestStatus = FTS_AGING_DONE;
}
break;
case (FTS_AGING_DONE):
//老化完退出当前事件
//return;
g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数
break;
case (FTS_AGING_FORCE_EXIT):
g_eFactoryTestStatus = FTS_AGING_WAITING;
break;
case (FTS_AGING_WAITING):
break;
case (FTS_AGING_FIRST_LONG_PRESSED):
g_eFactoryTestStatus = FTS_AGING_WAITING_SECOND_PRESS;
break;
case (FTS_AGING_WAITING_SECOND_PRESS):
break;
default:
break;
}
}
for (uint8_t index = 0; index < AGING_EXIT_MAX_BTN_NUM; index++){
if (g_stFactoryTestControllerList[index].u8BtnId != BTN_UNKNOW_ID ){
if (g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_PRESSED \
&& g_stFactoryTestControllerList[index].elastBtnAction != EBA_PRESSED){
g_stFactoryTestControllerList[index].elastBtnAction = EBA_PRESSED;
//g_stFactoryTestControllerList[index].eCurrentBtnAction = EBA_PRESSING;
//重置长按倒计时计数
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter = \
g_stFactoryTestControllerList[index].u32AgingForceExitTimeMs / FACTORY_TEST_POLL_TTME_1S;
}else if (g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_RELEASED \
&& g_stFactoryTestControllerList[index].elastBtnAction != EBA_RELEASED){
iKonkeAfSelfPrint("&&&&&&& EBA_RELEASED u32AgingForceExitTimeCounter == %d\r\n",\
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter);
g_stFactoryTestControllerList[index].elastBtnAction = EBA_RELEASED;
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter = 0;
}else {
g_stFactoryTestControllerList[index].elastBtnAction = g_stFactoryTestControllerList[index].eCurrentBtnAction;
}
//倒计时20S或5S
if (g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter > 0 \
&& g_stFactoryTestControllerList[index].eCurrentBtnAction == EBA_PRESSED){
iKonkeAfSelfPrint("######u32AgingForceExitTimeCounter-- %d\r\n", \
g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter);
if (--g_stFactoryTestControllerList[index].u32AgingForceExitTimeCounter == 0){
iKonkeAfSelfPrint("######u32AgingForceExitTimeCounter == 0\r\n");
if ( g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_1_TIMES \
|| g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed == true){
//successfully exit aging test
g_eFactoryTestStatus = FTS_AGING_FORCE_EXIT;
kSetAgingTestValue(AGINE_TEST_DONE_VALUE);
#if Z30_DEVICE_SINGLE_BOARD_ENABLE
if(kGetSingleBoardValue() != SINGLE_BOARD_TEST_DONE_VALUE)
kSetSingleBoardValue(FORCE_FACTORY_TEST_VALUE);
#endif
#if Z30_DEVICE_FULL_DEVICE_ENBALE
if(kGetFullDeviceValue() != FULL_DEVICE_TEST_DONE_VALUE)
kSetFullDeviceValue(FORCE_FACTORY_TEST_VALUE);
#endif
g_u32Count = FACTORY_TEST_POLL_TIMES; //快点执行自定义函数
//防止老化状态被重置
g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown = 0;
g_u8LongPressedKeyIndex = index;
//g_u32AgingTotalTimeMS = FACTORY_TEST_12HOU_MS;
iKonkeAfSelfPrint("######11111111111 == 0\r\n");
}else if ( g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_2_TIMES){
//触摸按键需要长按两次才能退出老化
g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed = true;
g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown = \
(FIRST_BTN_LONG_PRESSED_VALIED_TIME_MS + FACTORY_TEST_POLL_TTME_1S)/ FACTORY_TEST_POLL_TTME_1S;
g_u32Count = FACTORY_TEST_POLL_TIMES;//快点处理自定义函数
//记录当前的老化状态
g_eLastFactoryTestStatus = g_eFactoryTestStatus;
g_eFactoryTestStatus = FTS_AGING_FIRST_LONG_PRESSED;
iKonkeAfSelfPrint("######2222222222222222222222 == 0\r\n");
}
}
}else {
//g_stFactoryTestControllerList[index].elastBtnAction = g_stFactoryTestControllerList[index].eCurrentBtnAction;
}
//第二次长按有效时间倒计时
if (g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown > 0 && g_stFactoryTestControllerList[index].u8BtnLongPressTimes == LONG_PRESS_2_TIMES){
if (--g_stFactoryTestControllerList[index].u32FirstBtnLongPressedCountDown == 0){
g_stFactoryTestControllerList[index].bIsFirstBtnLongPressed = false;
//恢复之前老化状态
g_eFactoryTestStatus = g_eLastFactoryTestStatus;
}
}
}
}
//10S执行一次自定义老化,有时会根据不同状态会更新减短时间,让更快执行
if (g_u32Count++ >= FACTORY_TEST_POLL_TIMES){
g_u32Count = 0;
//用户自定义老化测试方案
if (g_pFactoryTestPollCallback){
g_pFactoryTestPollCallback(g_eFactoryTestStatus);
}
if (g_eFactoryTestStatus == FTS_START){
g_eFactoryTestStatus = FTS_AGING_15MIN;
}else if (g_eFactoryTestStatus == FTS_AGING_DONE){
//老化结束退出当前事件
return 0;
}
}
return 0;
}
#ifndef __IKONKE_MODULE_FACTORY_TEST_H_______________________ #ifndef __IKONKE_MODULE_FACTORY_TEST_H_______________________
#define __IKONKE_MODULE_FACTORY_TEST_H_______________________ #define __IKONKE_MODULE_FACTORY_TEST_H_______________________
#include "ikk-module-def.h" #include "ikk-debug.h"
#include "ikk-debug.h" #include "../driver/ikk-uart.h"
#include "ikk-command.h"
// 定义是否需要产测 // 定义是否需要产测
#define FACTORY_TEST_ENABLE true #define FACTORY_TEST_ENABLE true
//使能debug快速测试老化 //使能debug快速测试老化
#define AGING_DEBUG false #define AGING_DEBUG false
//可以最多两个按钮可以退出老化 //可以最多两个按钮可以退出老化
#define AGING_EXIT_MAX_BTN_NUM 2 #define AGING_EXIT_MAX_BTN_NUM 2
//按键强制退老化时,长按次数,比如铂金10A/16A插座的触摸按键长按5S两次退老化,轻触机械按键只要1次20S //按键强制退老化时,长按次数,比如铂金10A/16A插座的触摸按键长按5S两次退老化,轻触机械按键只要1次20S
#define LONG_PRESS_1_TIMES 1 #define LONG_PRESS_1_TIMES 1
#define LONG_PRESS_2_TIMES 2 #define LONG_PRESS_2_TIMES 2
//强制退老化时间 //强制退老化时间
#define TOUCH_KEY_LONG_PRESS_TIME_MS (5 * 1000) #define TOUCH_KEY_LONG_PRESS_TIME_MS (5 * 1000)
#define MECHANICAL_KEY_LONG_PRESS_TIME_MS (20 * 1000) #define MECHANICAL_KEY_LONG_PRESS_TIME_MS (20 * 1000)
#define FIRST_BTN_LONG_PRESSED_VALIED_TIME_MS (15 * 1000) #define FIRST_BTN_LONG_PRESSED_VALIED_TIME_MS (15 * 1000)
#define FACTORY_TEST_POLL_TTME_1S (1 * 1000) #define FACTORY_TEST_POLL_TTME_1S (1 * 1000)
#define FACTORY_TEST_POLL_TTME_10S (10 * 1000) #define FACTORY_TEST_POLL_TTME_10S (10 * 1000)
#define FACTORY_TEST_POLL_TIMES (FACTORY_TEST_POLL_TTME_10S / FACTORY_TEST_POLL_TTME_1S) #define FACTORY_TEST_POLL_TIMES (FACTORY_TEST_POLL_TTME_10S / FACTORY_TEST_POLL_TTME_1S)
#if AGING_DEBUG #if AGING_DEBUG
#define FACTORY_TEST_15MIN_MS (2 * 60 * 1000) #define FACTORY_TEST_15MIN_MS (2 * 60 * 1000)
#define FACTORY_TEST_8HOU_MS (5 * 1 * 60 * 1000) #define FACTORY_TEST_4HOU_MS (5 * 1 * 60 * 1000)
#else #else
#define FACTORY_TEST_15MIN_MS (15 * 60 * 1000) #define FACTORY_TEST_15MIN_MS (15 * 60 * 1000)
#define FACTORY_TEST_8HOU_MS (8 * 60 * 60 * 1000) #define FACTORY_TEST_4HOU_MS (4 * 60 * 60 * 1000)
#endif #endif
#define FACTORY_TEST_1S (1000) #define FACTORY_TEST_1S (1000)
typedef enum{ //初始值
FTS_NORMAL=0, #define TEST_INIT_VALUE 0xFF
FTS_START, typedef enum{
FTS_AGING_15MIN, FTS_NORMAL=0,
FTS_AGING_8HOU_START, FTS_START,
FTS_AGING_8HOU, FTS_AGING_15MIN,
FTS_AGING_DONE, FTS_AGING_4HOU_START,
FTS_AGING_FORCE_EXIT, FTS_AGING_4HOU,
FTS_AGING_WAITING, FTS_AGING_DONE,
FTS_AGING_FORCE_REBOOT, FTS_AGING_FORCE_EXIT,
FTS_AGING_FIRST_LONG_PRESSED, FTS_AGING_WAITING,
FTS_AGING_WAITING_SECOND_PRESS FTS_AGING_FORCE_REBOOT,
}FactoryTestStatusEnum; FTS_AGING_FIRST_LONG_PRESSED,
FTS_AGING_WAITING_SECOND_PRESS
typedef struct{ }FactoryTestStatusEnum;
uint8_t u8BtnId;
uint8_t u8BtnLongPressTimes; //touch keys must be long pressed 2 times, mechanical keys is pressed 1 time typedef struct{
uint32_t u32AgingForceExitTimeMs; //key long pressed time for exit aging test uint8_t u8BtnId;
}FactoryTestConfSt; uint8_t u8BtnLongPressTimes; //touch keys must be long pressed 2 times, mechanical keys is pressed 1 time
uint32_t u32AgingForceExitTimeMs; //key long pressed time for exit aging test
//10S轮询操作函数,可根据不同长供电产品自定义实现 }FactoryTestConfSt;
typedef void (*pFactoryTestPollCallback)(FactoryTestStatusEnum status);
//10S轮询操作函数,可根据不同长供电产品自定义实现
//获取当前产测状态 typedef void (*pFactoryTestPollCallback)(FactoryTestStatusEnum status);
FactoryTestStatusEnum kGetFactoryTestStatus(void); nv_sts_t General_Set_Factory_Test(nv_item_t items,uint8_t value);
//void kGetFactoryTestBtnAction(uint8_t btn_id, BtnActionEnum action); uint8_t General_Get_Factory_Test(nv_item_t items,uint8_t default_value);
void kFactoryTestInit(pFactoryTestPollCallback callback, FactoryTestConfSt conf_list[], uint8_t btn_num);
#define kSetSingleBoardValue(value) General_Set_Factory_Test(NV_SINGLE_BOARD_TEST_FLG,value)
#endif #define kSetFullDeviceValue(value) General_Set_Factory_Test(NV_FULL_DEVICE_TEST_FLG,value)
#define kSetAgingTestValue(value) General_Set_Factory_Test(NV_AGE_TEST_STEP,value)
#define kGetSingleBoardValue() General_Get_Factory_Test(NV_SINGLE_BOARD_TEST_FLG,TEST_INIT_VALUE)
#define kGetFullDeviceValue() General_Get_Factory_Test(NV_FULL_DEVICE_TEST_FLG,TEST_INIT_VALUE)
#define kGetAgingTestValue() General_Get_Factory_Test(NV_AGE_TEST_STEP,0)
uint8_t kGetFactoryTestValueStatus(void);
uint32_t kGetAgingMaxTime(void);
void kSetAgingMaxTime(uint16_t value);
//获取当前产测状态
FactoryTestStatusEnum kGetFactoryTestStatus(void);
//void kGetFactoryTestBtnAction(uint8_t btn_id, BtnActionEnum action);
void kFactoryTestInit(pFactoryTestPollCallback callback, FactoryTestConfSt conf_list[], uint8_t btn_num);
kk_err_t kkFactoryMsgInComingPaser(UMsgNodeSt *pMsgNode, ComPortEm port, DataField_st *pDataOut);
#endif
#ifndef __IKONKE_MODULE_DEFINE_H_____________________________ #ifndef __IKONKE_MODULE_DEFINE_H_____________________________
#define __IKONKE_MODULE_DEFINE_H_____________________________ #define __IKONKE_MODULE_DEFINE_H_____________________________
#include "tl_common.h" #include "tl_common.h"
// choose the type of equipment, ZC(Coordinator), ZR(Router), ZED(End Device). // choose the type of equipment, ZC(Coordinator), ZR(Router), ZED(End Device).
#define Z30_DEVICE_ZC (0) #define Z30_DEVICE_ZC (0)
#define Z30_DEVICE_ZR (1) #define Z30_DEVICE_ZR (1)
#define Z30_DEVICE_ZED (2) #define Z30_DEVICE_ZED (2)
#define Z30_DEVICE_ZED_SLEEPY (3) #define Z30_DEVICE_ZED_SLEEPY (3)
#define Z30_DEVICE_DTYPE (Z30_DEVICE_ZR) #define Z30_DEVICE_DTYPE (Z30_DEVICE_ZR)
#define Z30_DEVICE_OTA_ENABLE false #define Z30_DEVICE_OTA_ENABLE false
#define Z30_DEVICE_AGING_ENABLE true // 定义是否需要老化,目前一般路由设备需要
// Real time IO operation, no optimization!!! #define Z30_DEVICE_AGING_ENABLE true
#define _IO volatile //单板测试,目前一般是休眠设备需要
#define Z30_DEVICE_SINGLE_BOARD_ENABLE true
#define CLUSTER_BASIC_ID 0X0000 // Basic Cluster用于获取子设备基本信息 //整机测试, 目前一般是休眠设备需要
#define CLUSTER_POWER_ID 0X0001 // 电量 #define Z30_DEVICE_FULL_DEVICE_ENBALE true
#define CLUSTER_IDENTIFY_ID 0X0003 // Identify // Real time IO operation, no optimization!!!
#define CLUSTER_GROUPS_ID 0X0004 // Groups #define _IO volatile
#define CLUSTER_SCENES_ID 0X0005 // Scenes
#define CLUSTER_ONOFF_ID 0X0006 // 开关 #define CLUSTER_BASIC_ID 0X0000 // Basic Cluster用于获取子设备基本信息
#define CLUSTER_LEVEL_CONTROL_ID 0X0008 // Level Control #define CLUSTER_POWER_ID 0X0001 // 电量
#define CLUSTER_IAS_ZONE_ID 0X0500 // IAS Zone(安防探测设备) #define CLUSTER_IDENTIFY_ID 0X0003 // Identify
#define CLUSTER_IAS_WD_ID 0X0502 // IAS WD(安防报警设备) #define CLUSTER_GROUPS_ID 0X0004 // Groups
#define CLUSTER_TEMP_ID 0X0402 // 温度 #define CLUSTER_SCENES_ID 0X0005 // Scenes
#define CLUSTER_HUMI_ID 0X0405 // 湿度 #define CLUSTER_ONOFF_ID 0X0006 // 开关
#define CLUSTER_WINDOW_COVERING_ID 0X0102 // 窗帘 #define CLUSTER_LEVEL_CONTROL_ID 0X0008 // Level Control
#define CLUSTER_ELECTRICAL_MEASUREMENT_ID 0X0B04 // 电气测量 #define CLUSTER_IAS_ZONE_ID 0X0500 // IAS Zone(安防探测设备)
#define CLUSTER_OPTTUNNEL_ID 0XFCC0 // 自定义Cluster-0XFC01,用于实现私有协议 #define CLUSTER_IAS_WD_ID 0X0502 // IAS WD(安防报警设备)
#define CLUSTER_MULTI_CONTROL_ON_OFF_ID 0XFCC6 // 自定义,用于实现ON-OFF多控,只用于绑定表是否多控判断 #define CLUSTER_TEMP_ID 0X0402 // 温度
#define CLUSTER_MULTI_CONTROL_WINDOW_COVERING_OPTTUNNEL_ID 0XFCC7 // 自定义Cluster, 用于实现window-covering多控 #define CLUSTER_HUMI_ID 0X0405 // 湿度
#define CLUSTER_UNKNOW 0XFFFF #define CLUSTER_WINDOW_COVERING_ID 0X0102 // 窗帘
#define CLUSTER_ELECTRICAL_MEASUREMENT_ID 0X0B04 // 电气测量
#define ATTRIBUTE_UNKNOW 0XFFFF #define CLUSTER_OPTTUNNEL_ID 0XFCC0 // 自定义Cluster-0XFC01,用于实现私有协议
#define CLUSTER_MULTI_CONTROL_ON_OFF_ID 0XFCC6 // 自定义,用于实现ON-OFF多控,只用于绑定表是否多控判断
//未知的GPIO引脚定义 #define CLUSTER_MULTI_CONTROL_WINDOW_COVERING_OPTTUNNEL_ID 0XFCC7 // 自定义Cluster, 用于实现window-covering多控
#define PORT_UNKNOW 0xFF #define CLUSTER_UNKNOW 0XFFFF
#define PIN_UNKNOW (uint32_t)0XFF
#define ATTRIBUTE_UNKNOW 0XFFFF
typedef enum kk_error_type {
KET_OK = 0, // 正常(成功) //未知的GPIO引脚定义
#define PORT_UNKNOW 0xFF
KET_FAILED = -1, // 失败 #define PIN_UNKNOW (uint32_t)0XFF
KET_ERR_TIMEOUT = -2, // 操作超时
KET_ERR_MALLOC_FAILED = -3, // malloc失败 //串口通信协议OPCODE
KET_NO_RESPONSE = -4, //不需要ack #define UART_MSG_QUERY_INFO_OPCODE 0x0000
#define UART_MSG_WRITE_INSTALL_CODE_OPCODE 0x0001
KET_ERR_INVALID_FD = -100, // 无效的FD #define UART_MSG_READ_INSTALL_CODE_OPCODE 0x0002
KET_ERR_OPEN_FAIL = -101, // 文件/socket等打开失败 #define UART_MSG_WRITE_CMEI_CODE_OPCODE 0x0003
KET_ERR_CLOSE_FAILED = -102, // 文件/socket等关闭失败 #define UART_MSG_READ_CMEI_CODE_OPCODE 0x0004
KET_ERR_READ_FAILED = -103, // 文件/socket等读取失败 #define UART_MSG_WRITE_ISN_CODE_OPCODE 0x0005
KET_ERR_WRITE_FAILED = -104, // 文件/socket等写入失败 #define UART_MSG_READ_ISN_CODE_OPCODE 0x0006
#define UART_MSG_WRITE_MAC_CODE_OPCODE 0x0007
KET_ERR_INVALID_POINTER = -200, // 无效指针 #define UART_MSG_READ_MAC_CODE_OPCODE 0x0008
KET_ERR_INVALID_PARAM = -201, // 无效参数 #define UART_MSG_WRITE_MOUDLE_ID_OPCODE 0x0009
#define UART_MSG_READ_MOUDLE_ID_OPCODE 0x000A
KET_ERR_CMD_FORMAT = -301, // 指令格式错误 #define UART_MSG_READ_DEV_RSSI_OPCODE 0x000B
KET_ERR_CMD_PARSE_FAILED = -302, // 指令解析错误 #define UART_MSG_WRITE_AGING_TIME_OPCODE 0x000C
KET_ERR_CMD_INVALID = -303, // 指令无效 #define UART_MSG_READ_AGING_TIME_OPCODE 0x000D
KET_ERR_CMD_FAILED = -304, // 指令操作失败 #define UART_MSG_WRITE_INTERPAN_PARA_OPCODE 0x000E
#define UART_MSG_READ_INTERPAN_PARA_OPCODE 0x000F
KET_ERR_NON_EXIST = -900, // 不存在
KET_ERR_NO_PERMISSIONS = -901, // 没有权限 #define UART_MSG_READ_DEVICE_SNAP_OPCODE 0x0010
KET_ERR_PROCESS_ABORT = -902, // 异常中断 #define UART_MSG_JOIN_NWK_REQUEST_OPCODE 0x0100
KET_ERR_NOT_READY = -903, // not ready #define UART_MSG_LEAVE_NWK_REQUEST_OPCODE 0x0101
KET_ERR_OPRATE_ILLEGAL = -904, // 非法操作 #define UART_MSG_QUERY_NWK_STATUS_REQUEST_OPCODE 0x0102
KET_ERR_CRC_WRONG = -905, // 校验错误 #define UART_MSG_NWK_STATUS_NOTIFY_OPCODE 0x0103
KET_ERR_CONTENT_MISMATCH = -906, // 内容不匹配 #define UART_MSG_READ_ATTRIBUTE_REQUEST_OPCODE 0x0104
KET_ERR_INSUFFICIENT_SPACE = -907, // 空间不足 #define UART_MSG_WRITE_ATTRIBUTE_REQUEST_OPCODE 0x0105
KET_ERR_OPRATE_FAILED = -908, // 操作失败 #define UART_MSG_ZCL_COMMAND_REQUEST_OPCODE 0x0106
KET_ERR_OPRATE_IN_PROGRESS = -908, // 操作进行中 #define UART_MSG_BIND_REQUEST_OPCODE 0x0110
KET_ERR_UNKNOW = -999, // 位置错误
}kk_err_t; #define UART_MSG_GATEWAY_NWK_CHANNEL_ONOFF_OPCODE 0x00FC
#define UART_MSG_PRIVATE_PROTOCOL_CONTROL_CHILD_DEVICE_START_OPCODE 0xF000
typedef enum { Z3D_COORDINATOR = 0, Z3D_ROUTER, Z3D_ENDDEVICE }Z3DevTypeEm; #define UART_MSG_PRIVATE_PROTOCOL_CONTROL_CHILD_DEVICE_END_OPCODE 0xF0FF
#define UART_MSG_TTS_OPCODE 0xF100
typedef void (*pFUNC_VOID)(void *);
//factory test message opcode
typedef struct tag_common_opt_callback_st { #define UART_MSG_QUERY_DEVICE_VERSION_OPCODE 0xED00
pFUNC_VOID pfunc; #define UART_MSG_QUERY_DEVICE_INFO_OPCODE 0xED01
void *param; #define UART_MSG_CONFIG_DEVICE_SLEEP_OPCODE 0xED02
}CommonOptCallbackSt; #define UART_MSG_EXIT_FACTORY_TEST_OPCODE 0xED04
#define UART_MSG_QUERY_FACTORY_INFO_OPCODE 0xED05
#endif #define UART_MSG_QUERY_SWITCH_ONOFF_OPCODE 0xED06
#define UART_MSG_ENTER_FACTORY_TEST_OPCODE 0xED14
#define UART_MSG_ONOFF_SWITCH_OPCODE 0xED15
#define UART_MSG_GPIO_TEST_OPCODE 0xED10
#define UART_MSG_READ_RSSI_REQUEST_OPCODE 0xED12
//offline voice panel
#define UART_MSG_HOST_SNAP_REQUEST_OPCODE 0x1000
#define UART_MSG_CTRL_HOST_ONOFF_OPCODE 0x1001 //zigbee module control panel
#define UART_MSG_HOST_ONOFF_NOTIFY_OPCODE 0x1002 //panel onoff status changed notify zigbee
#define UART_MSG_HOST_TRIGGER_SCENE_NOTIFY_OPCODE 0x1003 //pannel recall scene notify zigbees
#define UART_MSG_KEY_LIGHT_SCENE_TRANSFORM_OPCODE 0x1004
#define UART_MSG_TIME_SET_OPCODE 0x1005
#define UART_MSG_TIME_GET_OPCODE 0x1006
#define UART_MSG_DEVICE_OPERATOR_OPCODE 0x1007
#define UART_MSG_FILE_UPDATE_NOTIFY_OPCODE 0x1008
#define UART_MSG_FILE_DATA_REQUEST_OPCODE 0x1009
#define UART_MSG_FILE_UPDATE_STATUS_NOTIFY 0x100A
//bangde human body sensor
#define UART_MSG_BODY_TRIGGER_START_REPORT_OPCODE 0xED03
//bangde sos button
#define UART_MSG_SOS_REPORT_OPCODE 0xED03
//bangde scene button
#define UART_MSG_BUTTON_SCENE_REPORT_OPCODE 0xED03
//bangde environment sensor
#define UART_MSG_QUERY_TEMP_HUMI_INFO_OPCODE 0xED03
//bangde door sensor
#define UART_MSG_BUTTON_ONOFF_REPORT_OPCODE 0xED03
//offline voice panel
//define opcode for private cluster
#define NWK_CHANNEL_ONOFF (uint8_t)(UART_MSG_GATEWAY_NWK_CHANNEL_ONOFF_OPCODE)
#define SNAP_INFO (uint8_t)(UART_MSG_HOST_SNAP_REQUEST_OPCODE)
//#define ONOFF_CONTROL (uint8_t)(UART_MSG_CTRL_HOST_ONOFF_OPCODE)
#define SCENE_TRGGER (uint8_t)(UART_MSG_HOST_TRIGGER_SCENE_NOTIFY_OPCODE)
#define KEY_FUNCTION (uint8_t)(UART_MSG_KEY_LIGHT_SCENE_TRANSFORM_OPCODE)
#define TIME_SET (uint8_t)(UART_MSG_TIME_SET_OPCODE)
#define TIME_GET (uint8_t)(UART_MSG_TIME_GET_OPCODE)
#define DEVICE_OPT (uint8_t)(UART_MSG_DEVICE_OPERATOR_OPCODE)
#define FILE_UPDATE_NOTIFY (uint8_t)(UART_MSG_FILE_UPDATE_NOTIFY_OPCODE)
#define FILE_DATA_REQUEST (uint8_t)(UART_MSG_FILE_DATA_REQUEST_OPCODE )
#define FILE_STATUS_STATUS (uint8_t)(UART_MSG_FILE_UPDATE_STATUS_NOTIFY)
typedef enum kk_error_type {
KET_OK = 0, // 正常(成功)
KET_FAILED = -1, // 失败
KET_ERR_TIMEOUT = -2, // 操作超时
KET_ERR_MALLOC_FAILED = -3, // malloc失败
KET_NO_RESPONSE = -4, //不需要ack
KET_ERR_INVALID_FD = -100, // 无效的FD
KET_ERR_OPEN_FAIL = -101, // 文件/socket等打开失败
KET_ERR_CLOSE_FAILED = -102, // 文件/socket等关闭失败
KET_ERR_READ_FAILED = -103, // 文件/socket等读取失败
KET_ERR_WRITE_FAILED = -104, // 文件/socket等写入失败
KET_ERR_INVALID_POINTER = -200, // 无效指针
KET_ERR_INVALID_PARAM = -201, // 无效参数
KET_ERR_CMD_FORMAT = -301, // 指令格式错误
KET_ERR_CMD_PARSE_FAILED = -302, // 指令解析错误
KET_ERR_CMD_INVALID = -303, // 指令无效
KET_ERR_CMD_FAILED = -304, // 指令操作失败
KET_ERR_NON_EXIST = -900, // 不存在
KET_ERR_NO_PERMISSIONS = -901, // 没有权限
KET_ERR_PROCESS_ABORT = -902, // 异常中断
KET_ERR_NOT_READY = -903, // not ready
KET_ERR_OPRATE_ILLEGAL = -904, // 非法操作
KET_ERR_CRC_WRONG = -905, // 校验错误
KET_ERR_CONTENT_MISMATCH = -906, // 内容不匹配
KET_ERR_INSUFFICIENT_SPACE = -907, // 空间不足
KET_ERR_OPRATE_FAILED = -908, // 操作失败
KET_ERR_OPRATE_IN_PROGRESS = -908, // 操作进行中
KET_ERR_UNKNOW = -999, // 位置错误
}kk_err_t;
typedef enum {
ERR_OK=0x00,
ERR_EXIST=0x01,
ERR_FORMAT=0x02,
ERR_NOT_EXPECTED=0x03,
ERR_WRITE_FAILED=0x04,
ERR_READ_WRITE_TIMEOUT=0x05,
ERR_NOT_EXIST=0x06,
ERR_UNKNOW=0xFF,
}ERR_RET_E;
typedef enum { Z3D_COORDINATOR = 0, Z3D_ROUTER, Z3D_ENDDEVICE }Z3DevTypeEm;
typedef void (*pFUNC_VOID)(void *);
// 操作
typedef enum { ECOM_PORT_UART = 0, ECOM_PORT_RTT, ECOM_PORT_ZIGBEE, ECOM_PORT_INTERPAN, ECOM_PORT_FCC0}ComPortEm;
typedef struct tag_common_opt_callback_st {
pFUNC_VOID pfunc;
void *param;
}CommonOptCallbackSt;
#endif
#include "ikk-network.h" #include "ikk-network.h"
#include "../driver/ikk-led.h" #include "../driver/ikk-led.h"
#include "../driver/ikk-button.h" #include "../driver/ikk-button.h"
#include "ikk-tick-handler.h" #include "ikk-tick-handler.h"
#include "ikk-token.h" #include "ikk-token.h"
#include "tl_common.h" #include "tl_common.h"
#include "ikk-cluster.h" #include "ikk-cluster.h"
#include "../../../../zigbee/aps/aps_api.h" #include "ikk-interpan.h"
#include "../../../../zigbee/common/includes/zb_common.h" #include "ikk-factory-test.h"
/********************************************************************** #include "../../../../zigbee/aps/aps_api.h"
* INCLUDES #include "../../../../zigbee/common/includes/zb_common.h"
*/ /**********************************************************************
* INCLUDES
#define DELAY_RESTORE_NWK_STEERING_TIME_MS (10 * 1000) */
#define DELAY_NWK_DETECT_POWER_ON_TIME_MS (3 * 1000) #define DELAY_RESTORE_NWK_STEERING_TIME_MS (6 * 1000)
//global value #define DELAY_NWK_DETECT_POWER_ON_TIME_MS (3 * 1000)
addrExt_t g_Eui64GatewayAddr = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; #define LED_SLOW_BLINK_CONTINUE_TIME_MS (60 * 1000)
#define LED_FAST_BLINK_CONTINUE_TIME_MS (5 * 1000)
BindObjSt g_lstBindingClusterConf[BINDING_CLUSTER_MAXN] = { {0},{0},{0},{0},{0},{0},{0},{0} };
//global value
addrExt_t g_Eui64GatewayAddr = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
//static value
static bool g_bIsNwkJoiningFlg = false; BindObjSt g_lstBindingClusterConf[BINDING_CLUSTER_MAXN] = { {0},{0},{0},{0},{0},{0},{0},{0} };
static uint32_t g_u32NwkExitCountDownCounter = 0;
//static value
static uint32_t g_u32NwkDetectCountDownCounter = 0; static bool g_bIsNwkJoiningFlg = false;
static uint32_t g_u32NwkJoiningCountdownCounter = 0; static uint32_t g_u32NwkExitCountDownCounter = 0;
// copy current network status. static uint32_t g_u32NwkDetectCountDownCounter = 0;
static NwkStatusEnum g_eCurrentNetworkStatus = ENS_UNKNOW;
//add by maozj 20200225 static uint32_t g_u32NwkJoiningCountdownCounter = 0;
static NwkStatusEnum g_eLastNetworkStatus = ENS_UNKNOW;
static bool g_KeyPressCauasLeave = false;
static NwkSteeringStatusEnum NetworkSteeringState = NWK_STEERING_STATUS_FAILED;
//joining scan channel 1 round failed flag // copy current network status.
static bool g_bNwkSteeringCompleteFlg = false; static NwkStatusEnum g_eCurrentNetworkStatus = ENS_UNKNOW;
//add by maozj 20200225
static int g_u32BindingResultCheckCounter = 0; static NwkStatusEnum g_eLastNetworkStatus = ENS_UNKNOW;
static NwkSteeringStatusEnum NetworkSteeringState = NWK_STEERING_STATUS_FAILED;
// network status notify callback define. //joining scan channel 1 round failed flag
pNetworkStatusNotifyCallback g_pNetworkStatusNotifyCallback = NULL; static bool g_bNwkSteeringCompleteFlg = false;
//add bby maozj 20200511
//network exit complete callback define static int g_u32BindingResultCheckCounter = 0;
pNetworkExitCompleteCallback g_pNetworkExitCompleteCallback = NULL;
pJoinCompleteCallback g_pJoinCompleteCallback = NULL; // network status notify callback define.
pNetworkStatusNotifyCallback g_pNetworkStatusNotifyCallback = NULL;
//add bby maozj 20200511
/*Get Steerint Nwk State*/ //network exit complete callback define
static NwkSteeringStatusEnum Get_Nwk_Steering_Status(void) pNetworkExitCompleteCallback g_pNetworkExitCompleteCallback = NULL;
{
return NetworkSteeringState; pJoinCompleteCallback g_pJoinCompleteCallback = NULL;
}
void Set2NwkJoiningCountdownCounter(u32 time_ms) /*Get Steerint Nwk State*/
{ static NwkSteeringStatusEnum Get_Nwk_Steering_Status(void)
g_u32NwkJoiningCountdownCounter = MS2COUNT(time_ms); {
} return NetworkSteeringState;
bool IsSteeringNwkTimeout(void) }
{
return (g_u32NwkJoiningCountdownCounter == 0); void Set2NwkJoiningCountdownCounter(u32 time_ms)
} {
/*Set Steerint Nwk State*/ g_u32NwkJoiningCountdownCounter = MS2COUNT(time_ms);
void Set_Nwk_Steering_Status(NwkSteeringStatusEnum Status) }
{ bool IsSteeringNwkTimeout(void)
NetworkSteeringState = Status; {
iKonkeAfSelfPrint(" set NetworkSteeringState = %d\r\n", NetworkSteeringState); return (g_u32NwkJoiningCountdownCounter == 0);
} }
/* DESP: 高精度随机值接口,取值[minNum, maxNum]. /*Set Steerint Nwk State*/
Auth: dingmz_frc.20190701. void Set_Nwk_Steering_Status(NwkSteeringStatusEnum Status)
*/ {
uint32_t kGetRandNum(uint32_t minNum, uint32_t maxNum ) NetworkSteeringState = Status;
{ iKonkeAfSelfPrint(" set NetworkSteeringState = %d\r\n", NetworkSteeringState);
if( minNum >= maxNum ) { }
return 0; /* DESP: 高精度随机值接口,取值[minNum, maxNum].
} Auth: dingmz_frc.20190701.
//halCommonGetInt32uMillisecondTick(); */
uint32_t kGetRandNum(uint32_t minNum, uint32_t maxNum )
uint32_t randNum = minNum + drv_u32Rand() % (maxNum - minNum + 1); {
if( minNum >= maxNum ) {
iKonkeAfSelfPrint(" xxx rand num = %d\r\n", randNum); return 0;
}
return randNum; //halCommonGetInt32uMillisecondTick();
}
/* DESP: Check whether the specified cluster is binded. uint32_t randNum = minNum + drv_u32Rand() % (maxNum - minNum + 1);
* RETURN[KET_OK]: is binded!
* RETURN[KET_ERR_NON_EXIST]: is unbinded! iKonkeAfSelfPrint(" xxx rand num = %d\r\n", randNum);
* RETURN[KET_ERR_NO_PERMISSIONS]: this binding item is not configured!
* Auth: dingmz_frc.20191112. return randNum;
* */ }
kk_err_t kNwkClusterBindingObjIsOK(uint8_t endpoint, uint16_t cluster ) /* DESP: Check whether the specified cluster is binded.
{ * RETURN[KET_OK]: is binded!
aps_binding_table_t aps_binding_tbl; * RETURN[KET_ERR_NON_EXIST]: is unbinded!
memcpy(&aps_binding_tbl,aps_bindingTblGet(),sizeof(aps_binding_tbl)); * RETURN[KET_ERR_NO_PERMISSIONS]: this binding item is not configured!
for(int index = 0; index < APS_BINDING_TABLE_NUM ;index++ ) { * Auth: dingmz_frc.20191112.
uint16_t cluster_temp = aps_binding_tbl.table[index].src_table.cluster_id; * */
uint8_t src_ep = aps_binding_tbl.table[index].src_table.src_ep; kk_err_t kNwkClusterBindingObjIsOK(uint8_t endpoint, uint16_t cluster )
//iKonkeAfSelfPrint("###kNwkClusterBindingObjIsOK : endpoint(%d), cluster(%d)\r\n", src_ep, cluster_temp); {
if(src_ep == endpoint && cluster_temp == cluster ) { aps_binding_table_t aps_binding_tbl;
return KET_OK; memcpy(&aps_binding_tbl,aps_bindingTblGet(),sizeof(aps_binding_tbl));
} for(int index = 0; index < APS_BINDING_TABLE_NUM ;index++ ) {
} uint16_t cluster_temp = aps_binding_tbl.table[index].src_table.cluster_id;
// If binding table is not set, query whether it has been configured. uint8_t src_ep = aps_binding_tbl.table[index].src_table.src_ep;
for(int index = 0; index < BINDING_CLUSTER_MAXN; ++index ) { //iKonkeAfSelfPrint("###kNwkClusterBindingObjIsOK : endpoint(%d), cluster(%d)\r\n", src_ep, cluster_temp);
if( g_lstBindingClusterConf[index].endpoint == endpoint && if(src_ep == endpoint && cluster_temp == cluster ) {
g_lstBindingClusterConf[index].cluster == cluster ) { return KET_OK;
return KET_ERR_NON_EXIST; }
} }
} // If binding table is not set, query whether it has been configured.
for(int index = 0; index < BINDING_CLUSTER_MAXN; ++index ) {
return KET_ERR_NO_PERMISSIONS; if( g_lstBindingClusterConf[index].endpoint == endpoint &&
} g_lstBindingClusterConf[index].cluster == cluster ) {
// on binding-table set <index> <cluster> <local ep> <remote ep> <EUI> return KET_ERR_NON_EXIST;
static u8 kNwkClusterBindingObjSet(uint8_t endpoint, uint16_t cluster_id, addrExt_t eui64 ) }
{ }
zdo_bind_req_t req;
memset(&req, 0, sizeof(zdo_bind_req_t)); return KET_ERR_NO_PERMISSIONS;
u8 bindStatus = ZDO_SUCCESS; }
// on binding-table set <index> <cluster> <local ep> <remote ep> <EUI>
ZB_IEEE_ADDR_COPY(req.src_addr, NIB_IEEE_ADDRESS()); static u8 kNwkClusterBindingObjSet(uint8_t endpoint, uint16_t cluster_id, addrExt_t eui64 )
req.src_endpoint = endpoint; {
iKonkeAfSelfPrint("### src addr : endpoint(%d), cluster(%2x)\r\n", endpoint, cluster_id); zdo_bind_req_t req;
Print_Ieee_Addr(NIB_IEEE_ADDRESS()); memset(&req, 0, sizeof(zdo_bind_req_t));
u8 bindStatus = ZDO_SUCCESS;
req.dst_addr_mode = LONG_EXADDR_DSTENDPOINT;
ZB_IEEE_ADDR_COPY(req.src_addr, NIB_IEEE_ADDRESS());
ZB_IEEE_ADDR_COPY(req.dst_ext_addr, eui64); req.src_endpoint = endpoint;
req.dst_endpoint = 1; iKonkeAfSelfPrint("### src addr : endpoint(%d), cluster(%2x)\r\n", endpoint, cluster_id);
iKonkeAfSelfPrint("### des addr : endpoint(%d), cluster(%2x)\r\n", req.dst_endpoint); Print_Ieee_Addr(NIB_IEEE_ADDRESS());
Print_Ieee_Addr(eui64);
req.dst_addr_mode = LONG_EXADDR_DSTENDPOINT;
req.cid16_l = cluster_id&0xff;
req.cid16_h = cluster_id>>8; ZB_IEEE_ADDR_COPY(req.dst_ext_addr, eui64);
req.dst_endpoint = 1;
u8 sn = 0; iKonkeAfSelfPrint("### des addr : endpoint(%d), cluster(%2x)\r\n", req.dst_endpoint);
bindStatus = zb_zdoBindUnbindReq(TRUE, &req, &sn, NULL); Print_Ieee_Addr(eui64);
iKonkeAfSelfPrint("----set bind result[%d]: endpoint(%d), cluster(%2x)\r\n", bindStatus, endpoint, cluster_id); req.cid16_l = cluster_id&0xff;
return bindStatus; req.cid16_h = cluster_id>>8;
}
u8 sn = 0;
kk_err_t kNwkClusterBindingInspect(void ) bindStatus = zb_zdoBindUnbindReq(TRUE, &req, &sn, NULL);
{
uint8_t ALL_FF[8] = {0}; iKonkeAfSelfPrint("----set bind result[%d]: endpoint(%d), cluster(%2x)\r\n", bindStatus, endpoint, cluster_id);
memset(ALL_FF,0xff,sizeof(ALL_FF)); return bindStatus;
kNwkGetGateWayEui64(g_Eui64GatewayAddr); }
if(!memcmp(g_Eui64GatewayAddr,ALL_FF,sizeof(g_Eui64GatewayAddr)) ){ kk_err_t kNwkClusterBindingInspect(void )
return KET_ERR_NO_PERMISSIONS; {
} uint8_t ALL_FF[8] = {0};
memset(ALL_FF,0xff,sizeof(ALL_FF));
for(int ix = 0; ix < BINDING_CLUSTER_MAXN; ++ix ) { kNwkGetGateWayEui64(g_Eui64GatewayAddr);
if( g_lstBindingClusterConf[ix].cluster != CLUSTER_UNKNOW ) {
kk_err_t err = kNwkClusterBindingObjIsOK(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster); if(!memcmp(g_Eui64GatewayAddr,ALL_FF,sizeof(g_Eui64GatewayAddr)) ){
if( err == KET_ERR_NON_EXIST ) { return KET_ERR_NO_PERMISSIONS;
kNwkClusterBindingObjSet(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster, g_Eui64GatewayAddr); }
}
}else { for(int ix = 0; ix < BINDING_CLUSTER_MAXN; ++ix ) {
break; if( g_lstBindingClusterConf[ix].cluster != CLUSTER_UNKNOW ) {
} kk_err_t err = kNwkClusterBindingObjIsOK(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster);
} if( err == KET_ERR_NON_EXIST ) {
kNwkClusterBindingObjSet(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster, g_Eui64GatewayAddr);
return KET_OK; }
} }else {
/* DESP: device cluster binding trigger interface. break;
* Auth: dingmz_frc.20191112. }
* */ }
kk_err_t kNwkClusterBindingTrigger(void )
{ return KET_OK;
uint8_t ALL_FF[8] = {0}; }
kk_err_t err = KET_ERR_UNKNOW; /* DESP: device cluster binding trigger interface.
if( g_u32BindingResultCheckCounter > 0 ) { * Auth: dingmz_frc.20191112.
return KET_ERR_OPRATE_IN_PROGRESS; * */
} kk_err_t kNwkClusterBindingTrigger(void )
{
#ifdef ZCL_USING_IAS_ZONE_CLUSTER_SERVER uint8_t ALL_FF[8] = {0};
g_u32EnrollResultCheckCounter = MS2COUNT(ENROLL_SCHD_DURATION); kk_err_t err = KET_ERR_UNKNOW;
#endif if( g_u32BindingResultCheckCounter > 0 ) {
return KET_ERR_OPRATE_IN_PROGRESS;
memset(ALL_FF,0xff,sizeof(ALL_FF)); }
kNwkGetGateWayEui64(g_Eui64GatewayAddr);
#ifdef ZCL_USING_IAS_ZONE_CLUSTER_SERVER
iKonkeAfSelfPrint("##########GetEui64FromFlash %x%x%x%x%x%x%x%x --\r\n",g_Eui64GatewayAddr[7], g_Eui64GatewayAddr[6], \ g_u32EnrollResultCheckCounter = MS2COUNT(ENROLL_SCHD_DURATION);
g_Eui64GatewayAddr[5], g_Eui64GatewayAddr[4], g_Eui64GatewayAddr[3], g_Eui64GatewayAddr[2], g_Eui64GatewayAddr[1],g_Eui64GatewayAddr[0]); #endif
iKonkeAfSelfPrint("Gateway IEEE have existed\r\n"); memset(ALL_FF,0xff,sizeof(ALL_FF));
kNwkGetGateWayEui64(g_Eui64GatewayAddr);
if(!memcmp(g_Eui64GatewayAddr,ALL_FF,sizeof(g_Eui64GatewayAddr)) ){
return KET_ERR_NO_PERMISSIONS; iKonkeAfSelfPrint("##########GetEui64FromFlash %x%x%x%x%x%x%x%x --\r\n",g_Eui64GatewayAddr[7], g_Eui64GatewayAddr[6], \
} g_Eui64GatewayAddr[5], g_Eui64GatewayAddr[4], g_Eui64GatewayAddr[3], g_Eui64GatewayAddr[2], g_Eui64GatewayAddr[1],g_Eui64GatewayAddr[0]);
for(int ix = 0; ix < BINDING_CLUSTER_MAXN; ++ix ) { iKonkeAfSelfPrint("Gateway IEEE have existed\r\n");
if( g_lstBindingClusterConf[ix].cluster != CLUSTER_UNKNOW ) {
kk_err_t err1 = kNwkClusterBindingObjIsOK(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster); if(!memcmp(g_Eui64GatewayAddr,ALL_FF,sizeof(g_Eui64GatewayAddr)) ){
if( err1 == KET_ERR_NON_EXIST ) { return KET_ERR_NO_PERMISSIONS;
if(kNwkClusterBindingObjSet(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster, g_Eui64GatewayAddr) == ZDO_SUCCESS) }
err = KET_OK;
} for(int ix = 0; ix < BINDING_CLUSTER_MAXN; ++ix ) {
}else { if( g_lstBindingClusterConf[ix].cluster != CLUSTER_UNKNOW ) {
break; kk_err_t err1 = kNwkClusterBindingObjIsOK(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster);
} if( err1 == KET_ERR_NON_EXIST ) {
} if(kNwkClusterBindingObjSet(g_lstBindingClusterConf[ix].endpoint, g_lstBindingClusterConf[ix].cluster, g_Eui64GatewayAddr) == ZDO_SUCCESS)
return err; err = KET_OK;
} }
}else {
void kNwkGetGateWayEui64(addrExt_t eui64) break;
{ }
uint16_t index; }
tl_zbExtAddrByShortAddr(0x0000,eui64,&index); return err;
} }
/* DESP: If the network status notification callback has been associated, the network status needs to be synchronized. void kNwkGetGateWayEui64(addrExt_t eui64)
* Auth: dingmz_frc.20191109. {
* */ uint16_t index;
void kNwkNetworkStatusNotifyCall(NwkStatusEnum nwkst ) tl_zbExtAddrByShortAddr(0x0000,eui64,&index);
{ }
g_eCurrentNetworkStatus = nwkst;
/* DESP: If the network status notification callback has been associated, the network status needs to be synchronized.
if( g_eCurrentNetworkStatus != g_eLastNetworkStatus ) { * Auth: dingmz_frc.20191109.
g_eLastNetworkStatus = g_eCurrentNetworkStatus; * */
void kNwkNetworkStatusNotifyCall(NwkStatusEnum nwkst )
if( g_pNetworkStatusNotifyCallback ) { {
g_pNetworkStatusNotifyCallback(g_eCurrentNetworkStatus); g_eCurrentNetworkStatus = nwkst;
}
} if( g_eCurrentNetworkStatus != g_eLastNetworkStatus ) {
if( g_eCurrentNetworkStatus == ENS_ONLINE ) { g_eLastNetworkStatus = g_eCurrentNetworkStatus;
g_u32NwkJoiningCountdownCounter= MS2COUNT(0);
addrExt_t addr; if( g_pNetworkStatusNotifyCallback ) {
kNwkGetGateWayEui64(addr); g_pNetworkStatusNotifyCallback(g_eCurrentNetworkStatus);
Gateway_IEEE_Addr_Save(addr); }
iKonkeAfSelfPrint("#####kNwkNetworkStatusNotifyCall,Join Network addr=%x%x%x%x-%x%x%x%x!\r\n", }
addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],addr[6],addr[7]); if( g_eCurrentNetworkStatus == ENS_ONLINE ) {
} g_u32NwkJoiningCountdownCounter= MS2COUNT(0);
} addrExt_t addr;
/* DESP: Network module tick loop handler interface. kNwkGetGateWayEui64(addr);
* Auth: dingmz_frc.20191106. Gateway_IEEE_Addr_Save(addr);
* */ iKonkeAfSelfPrint("#####kNwkNetworkStatusNotifyCall,Join Network addr=%x%x%x%x-%x%x%x%x!\r\n",
void kNwkModuleActionDetectCallback(void ) addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],addr[6],addr[7]);
{ }
//static EmberNetworkStatus s_old_network_st = EMBER_NO_NETWORK; }
static uint16_t ucRestoreSteeringCount = 0; /* DESP: Network module tick loop handler interface.
* Auth: dingmz_frc.20191106.
// joining procedure * */
if( g_u32NwkJoiningCountdownCounter > 0 ) { void kNwkModuleActionDetectCallback(void )
--g_u32NwkJoiningCountdownCounter; {
//iKonkeAfSelfPrint("#%d##%d###\r\n",g_u32NwkJoiningCountdownCounter,zb_isDeviceJoinedNwk()); //static EmberNetworkStatus s_old_network_st = EMBER_NO_NETWORK;
if((g_u32NwkJoiningCountdownCounter > 0) && (!zb_isDeviceJoinedNwk())) { static uint16_t ucRestoreSteeringCount = 0;
if( (g_bNwkSteeringCompleteFlg == true)&&(Get_Nwk_Steering_Status() == NWK_STEERING_STATUS_FAILED))
{ // joining procedure
/*begin modify by maozj 20191127 repair issue that Difficult to network when gateway network permission joining is enabled with delay*/ if( g_u32NwkJoiningCountdownCounter > 0 ) {
ucRestoreSteeringCount = 0; --g_u32NwkJoiningCountdownCounter;
g_bNwkSteeringCompleteFlg = false; //iKonkeAfSelfPrint("#%d##%d###\r\n",g_u32NwkJoiningCountdownCounter,zb_isDeviceJoinedNwk());
u8 status = bdb_networkSteerStart(); if((g_u32NwkJoiningCountdownCounter > 0) && (!zb_isDeviceJoinedNwk())) {
if( (g_bNwkSteeringCompleteFlg == true)&&(Get_Nwk_Steering_Status() == NWK_STEERING_STATUS_FAILED))
// network status notify. {
kNwkNetworkStatusNotifyCall(ENS_JOINING); /*begin modify by maozj 20191127 repair issue that Difficult to network when gateway network permission joining is enabled with delay*/
//add by maozj 20200321 for get joining network status ucRestoreSteeringCount = 0;
g_bIsNwkJoiningFlg = true; g_bNwkSteeringCompleteFlg = false;
iKonkeAfSelfPrint("$$$$$$$$$$ Network Steering Start!status = %d\r\n",status); u8 status = bdb_networkSteerStart();
}else {
//other situation,must restart steering // network status notify.
if ( ucRestoreSteeringCount++ > MS2COUNT(DELAY_RESTORE_NWK_STEERING_TIME_MS)){ kNwkNetworkStatusNotifyCall(ENS_JOINING);
ucRestoreSteeringCount = 0; //add by maozj 20200321 for get joining network status
g_bNwkSteeringCompleteFlg = true; g_bIsNwkJoiningFlg = true;
Set_Nwk_Steering_Status(NWK_STEERING_STATUS_FAILED); iKonkeAfSelfPrint("$$$$$$$$$$ Network Steering Start!status = %d\r\n",status);
//iKonkeAfSelfPrint("#########Steering Again...\r\n"); }else {
} //other situation,must restart steering
} if ( ucRestoreSteeringCount++ > MS2COUNT(DELAY_RESTORE_NWK_STEERING_TIME_MS)){
} ucRestoreSteeringCount = 0;
else if( g_u32NwkJoiningCountdownCounter == 0 ) g_bNwkSteeringCompleteFlg = true;
{ Set_Nwk_Steering_Status(NWK_STEERING_STATUS_FAILED);
iKonkeAfSelfPrint("$$$$$$$$$$ Network Steering Stop!\r\n"); //iKonkeAfSelfPrint("#########Steering Again...\r\n");
g_bNwkSteeringCompleteFlg = false; }
}
g_bIsNwkJoiningFlg = false;//add by maozj 20200327 }
else if( g_u32NwkJoiningCountdownCounter == 0 )
//start get mac and self bind cluster {
kNwkClusterBindingTrigger(); iKonkeAfSelfPrint("$$$$$$$$$$ Network Steering Stop!\r\n");
g_bNwkSteeringCompleteFlg = false;
if( zb_isDeviceJoinedNwk())
{ g_bIsNwkJoiningFlg = false;//add by maozj 20200327
if( g_pJoinCompleteCallback )
{ //start get mac and self bind cluster
iKonkeAfSelfPrint("777777g_pJoinCompleteCallback succeed\r\n"); kNwkClusterBindingTrigger();
g_pJoinCompleteCallback(EJC_JOIN_SUCCEED);
} if( zb_isDeviceJoinedNwk())
kNwkNetworkStatusNotifyCall(ENS_ONLINE ); {
} if( g_pJoinCompleteCallback )
else{ {
if( g_pJoinCompleteCallback ) iKonkeAfSelfPrint("777777g_pJoinCompleteCallback succeed\r\n");
{ g_pJoinCompleteCallback(EJC_JOIN_SUCCEED);
iKonkeAfSelfPrint("888888g_pJoinCompleteCallback succeed\r\n"); }
g_pJoinCompleteCallback(EJC_JOIN_FAILED); kNwkNetworkStatusNotifyCall(ENS_ONLINE );
} }
} else{
} if( g_pJoinCompleteCallback )
} {
iKonkeAfSelfPrint("888888g_pJoinCompleteCallback succeed\r\n");
if (g_u32NwkExitCountDownCounter > 0){ g_pJoinCompleteCallback(EJC_JOIN_FAILED);
if (--g_u32NwkExitCountDownCounter == 0){ }
if (g_pNetworkExitCompleteCallback){ }
g_pNetworkExitCompleteCallback(); }
} }
}
} if (g_u32NwkExitCountDownCounter > 0){
if (g_u32NwkDetectCountDownCounter > 0){ if (--g_u32NwkExitCountDownCounter == 0){
if (--g_u32NwkDetectCountDownCounter == 0){ if (g_pNetworkExitCompleteCallback){
//上电3s 后推送网络状态 g_pNetworkExitCompleteCallback();
if( zb_isDeviceJoinedNwk()) }
kNwkNetworkStatusNotifyCall(ENS_ONLINE); }
else }
g_eCurrentNetworkStatus = ENS_LEAVED; if (g_u32NwkDetectCountDownCounter > 0){
} if (--g_u32NwkDetectCountDownCounter == 0){
} //上电3s 后推送网络状态
if( zb_isDeviceJoinedNwk())
kNwkNetworkStatusNotifyCall(ENS_ONLINE);
} else
///* DESP: network module initialize interface. g_eCurrentNetworkStatus = ENS_LEAVED;
// * PARAM[item_list] the cluster objects requiring auto binding. }
// * PARAM[nwk_led_id] Associate a light to indicate network status: }
// * S1[offline] led off;
// * S2[joining] led blink;
// * S3[online] led on for route device ,and led off for sleepy device. }
// * Note: If this parameter is LED_UNKNOW_ID, it means that the network indicator is not associated!! ///* DESP: network module initialize interface.
// * PARAM[nwk_button_id] Associate a button for network operation. // * PARAM[item_list] the cluster objects requiring auto binding.
// * Auth: menmeng_li.20210523. // * PARAM[nwk_led_id] Associate a light to indicate network status:
// * */ // * S1[offline] led off;
void kNwkModuleInit(BindObjSt cluster_obj_list[], uint8_t cluster_obj_num, pNetworkStatusNotifyCallback pNSCallback // * S2[joining] led blink;
, pNetworkExitCompleteCallback pNECallback) // * S3[online] led on for route device ,and led off for sleepy device.
{ // * Note: If this parameter is LED_UNKNOW_ID, it means that the network indicator is not associated!!
for(int index = 0; index < cluster_obj_num; ++index ) { // * PARAM[nwk_button_id] Associate a button for network operation.
iKonkeAfSelfPrint("Cluster[%02d]: endpoint(%d), cluster_id(%2x)\r\n", index // * Auth: menmeng_li.20210523.
, cluster_obj_list[index].endpoint, cluster_obj_list[index].cluster); // * */
} void kNwkModuleInit(BindObjSt cluster_obj_list[], uint8_t cluster_obj_num, pNetworkStatusNotifyCallback pNSCallback
iKonkeAfSelfPrint("-----------------\r\n"); , pNetworkExitCompleteCallback pNECallback)
{
memset(g_lstBindingClusterConf, 0XFF, sizeof(g_lstBindingClusterConf)); for(int index = 0; index < cluster_obj_num; ++index ) {
iKonkeAfSelfPrint("Cluster[%02d]: endpoint(%d), cluster_id(%2x)\r\n", index
if( cluster_obj_list ) { , cluster_obj_list[index].endpoint, cluster_obj_list[index].cluster);
uint8_t objs_num = (cluster_obj_num < BINDING_CLUSTER_MAXN)?cluster_obj_num:BINDING_CLUSTER_MAXN; }
memcpy(g_lstBindingClusterConf, cluster_obj_list, sizeof(BindObjSt) * objs_num); iKonkeAfSelfPrint("-----------------\r\n");
memset(g_lstBindingClusterConf, 0XFF, sizeof(g_lstBindingClusterConf));
}
//add by maozj 20200511 if( cluster_obj_list ) {
g_pNetworkExitCompleteCallback = pNECallback; uint8_t objs_num = (cluster_obj_num < BINDING_CLUSTER_MAXN)?cluster_obj_num:BINDING_CLUSTER_MAXN;
memcpy(g_lstBindingClusterConf, cluster_obj_list, sizeof(BindObjSt) * objs_num);
g_pNetworkStatusNotifyCallback = pNSCallback;
//add by maozj20200325
//g_u32JoinNwkTimeMs = (join_nwk_time < NWK_STEERING_DEFAULT_TIMEOUT_MS)?NWK_STEERING_DEFAULT_TIMEOUT_MS : join_nwk_time; }
//add by maozj 20200511
//kBtnaIRQCallbackRegister(kNwkNetworkButtonAcitonCallback); g_pNetworkExitCompleteCallback = pNECallback;
g_u32NwkDetectCountDownCounter = MS2COUNT(DELAY_NWK_DETECT_POWER_ON_TIME_MS);
//Cannot Detect Network g_pNetworkStatusNotifyCallback = pNSCallback;
if( (kNwkGetCurrentStatus() == ENS_ONLINE )&&(g_pNetworkStatusNotifyCallback)) { //add by maozj20200325
g_pNetworkStatusNotifyCallback(ENS_ONLINE); //g_u32JoinNwkTimeMs = (join_nwk_time < NWK_STEERING_DEFAULT_TIMEOUT_MS)?NWK_STEERING_DEFAULT_TIMEOUT_MS : join_nwk_time;
}
//kBtnaIRQCallbackRegister(kNwkNetworkButtonAcitonCallback);
} g_u32NwkDetectCountDownCounter = MS2COUNT(DELAY_NWK_DETECT_POWER_ON_TIME_MS);
bool kNwkIsExiting(void) //Cannot Detect Network
{ if( (kNwkGetCurrentStatus() == ENS_ONLINE )&&(g_pNetworkStatusNotifyCallback)) {
if (g_u32NwkExitCountDownCounter > 0){ g_pNetworkStatusNotifyCallback(ENS_ONLINE);
return true; }
}
return false; }
} bool kNwkIsExiting(void)
/* DESP: The interface of resource release and reset after the device is restored to the factory, which is executed when the network is removed. {
* Auth: dingmz_frc.20191106. if (g_u32NwkExitCountDownCounter > 0){
* */ return true;
void kNwkFactoryReset(bool is_nwk_indicator) }
{ return false;
kNwkJoiningStart(0, NULL); }
/* DESP: The interface of resource release and reset after the device is restored to the factory, which is executed when the network is removed.
memset(g_Eui64GatewayAddr, 0xFF, sizeof(g_Eui64GatewayAddr)); * Auth: dingmz_frc.20191106.
Gateway_IEEE_Addr_Save(g_Eui64GatewayAddr); * */
Update_Local_Attribute_Info(); void kNwkFactoryReset(bool is_nwk_indicator)
// //add by maozj 20200320 {
//#if Z30_DEVICE_OTA_ENABLE kNwkJoiningStart(0, NULL);
// kSetOTAStatus(OTA_NORMAL);
//#endif memset(g_Eui64GatewayAddr, 0xFF, sizeof(g_Eui64GatewayAddr));
// EmberNodeId node = 0xFFFF; Gateway_IEEE_Addr_Save(g_Eui64GatewayAddr);
// kNwksaveNodeIdToFlash(node);
// //add by maozj 20200320
g_u32NwkJoiningCountdownCounter = 0; //#if Z30_DEVICE_OTA_ENABLE
// g_u32EnrollResultCheckCounter = 0; // kSetOTAStatus(OTA_NORMAL);
// g_u32RejoinResultCheckCounter = 0; //#endif
// g_u32BindingResultCheckCounter = 0; // EmberNodeId node = 0xFFFF;
// kNwksaveNodeIdToFlash(node);
//led can blink when network leaved g_u32NwkJoiningCountdownCounter = 0;
if (is_nwk_indicator == true){ // g_u32EnrollResultCheckCounter = 0;
zb_factoryReset(); // g_u32RejoinResultCheckCounter = 0;
// g_u32BindingResultCheckCounter = 0;
kNwkNetworkStatusNotifyCall(ENS_LEAVED);
//add by maozj 20200407 for reset count down after network leaved
g_u32NwkExitCountDownCounter = MS2COUNT(5*1000); //led can blink when network leaved
} if (is_nwk_indicator == true){
// kNwkScheduleTaskStop(SCHEDULE_ALLOPT_ID); zb_factoryReset();
// g_KeyPressCauasLeave = true;
// //add by maozj 20191213 need identify whether gateway is made by konke //add by maozj 20200407 for reset count down after network leaved
// uint8_t isKonkeGateway = 0; g_u32NwkExitCountDownCounter = MS2COUNT(LED_FAST_BLINK_CONTINUE_TIME_MS);
// halCommonSetToken(TOKEN_IS_KONKE_GATEWAY, &isKonkeGateway); kNwkNetworkStatusNotifyCall(ENS_LEAVED);
iKonkeAfSelfPrint("kNwkFactoryReset\r\n"); Update_Local_Attribute_Info();
} }
Set_Nwk_Steering_Status(NWK_STEERING_STATUS_FAILED);
void NetworkLeaveHandler(nlme_leave_cnf_t *pLeaveCnf) // kNwkScheduleTaskStop(SCHEDULE_ALLOPT_ID);
{ }
iKonkeAfSelfPrint("Leave Handler,Nwk State = %d\r\n",kNwkGetCurrentStatus());
void NetworkLeaveHandler(nlme_leave_cnf_t *pLeaveCnf)
if((pLeaveCnf->status == 0)&&(kNwkGetCurrentStatus() != ENS_JOINING)) {
{ if(g_KeyPressCauasLeave)
//如果正处于离网中状态,则不执行以下函数 {
if(g_u32NwkExitCountDownCounter == 0) g_KeyPressCauasLeave = false;
{ return;
kNwkJoiningStart(0, NULL); }
iKonkeAfSelfPrint("Leave Handler,Nwk State = %d\r\n",kNwkGetCurrentStatus());
g_u32NwkJoiningCountdownCounter = 0; if((pLeaveCnf->status == 0)&&(kNwkGetCurrentStatus() != ENS_JOINING))
memset(g_Eui64GatewayAddr, 0xFF, sizeof(g_Eui64GatewayAddr)); {
Gateway_IEEE_Addr_Save(g_Eui64GatewayAddr); //如果正处于离网中状态,则不执行以下函数
if(g_u32NwkExitCountDownCounter == 0)
kNwkNetworkStatusNotifyCall(ENS_LEAVED); {
//add by maozj 20200407 for reset count down after network leaved kNwkJoiningStart(0, NULL);
g_u32NwkExitCountDownCounter = MS2COUNT(5*1000);
} g_u32NwkJoiningCountdownCounter = 0;
} memset(g_Eui64GatewayAddr, 0xFF, sizeof(g_Eui64GatewayAddr));
} Gateway_IEEE_Addr_Save(g_Eui64GatewayAddr);
kNwkNetworkStatusNotifyCall(ENS_LEAVED);
///* DESP: get the current network status. // //add by maozj 20200407 for reset count down after network leaved
// * Auth: dingmz_frc.20191109. //g_u32NwkExitCountDownCounter = MS2COUNT(5*1000);
// * */ }
NwkStatusEnum kNwkGetCurrentStatus(void ) }
{ }
NwkStatusEnum status;
if(zb_isDeviceJoinedNwk()){
status = ENS_ONLINE; ///* DESP: get the current network status.
g_bIsNwkJoiningFlg = false; // * Auth: dingmz_frc.20191109.
} // * */
else if(g_bIsNwkJoiningFlg){ NwkStatusEnum kNwkGetCurrentStatus(void )
status = ENS_JOINING; {
} NwkStatusEnum status;
else{ if(zb_isDeviceJoinedNwk()){
g_bIsNwkJoiningFlg = false; status = ENS_ONLINE;
status = ENS_LEAVED; g_bIsNwkJoiningFlg = false;
} }
return status; else if(g_bIsNwkJoiningFlg){
} status = ENS_JOINING;
}
else{
bool JoinNetworkHandler(zdo_tc_join_ind_t *join_info) g_bIsNwkJoiningFlg = false;
{ status = ENS_LEAVED;
iKonkeAfSelfPrint("Join Network,short id = %2x!!!!!!!\r\n",join_info->devShortAddr); }
iKonkeAfSelfPrint("Join Network,COO Nwk IEEE Addr id = %x-%x-%x-%x-%x-%x-%x-%x!!!!!!!\r\n",join_info->parentIeeeAddr[0],join_info->parentIeeeAddr[1],join_info->parentIeeeAddr[2],join_info->parentIeeeAddr[3], return status;
join_info->parentIeeeAddr[4],join_info->parentIeeeAddr[5],join_info->parentIeeeAddr[6],join_info->parentIeeeAddr[7]); }
iKonkeAfSelfPrint("Join Network,Device Nwk IEEE Addr id = %x-%x-%x-%x-%x-%x-%x-%x!!!!!!!\r\n",join_info->devIeeeAddr[0],join_info->devIeeeAddr[1],join_info->devIeeeAddr[2],join_info->devIeeeAddr[3],
join_info->devIeeeAddr[4],join_info->devIeeeAddr[5],join_info->devIeeeAddr[6],join_info->devIeeeAddr[7]);
return 0; bool JoinNetworkHandler(zdo_tc_join_ind_t *join_info)
} {
iKonkeAfSelfPrint("Join Network,short id = %2x!!!!!!!\r\n",join_info->devShortAddr);
static ev_timer_event_t *kUserScheduleTaskEvt = NULL; iKonkeAfSelfPrint("Join Network,COO Nwk IEEE Addr id = %x-%x-%x-%x-%x-%x-%x-%x!!!!!!!\r\n",join_info->parentIeeeAddr[0],join_info->parentIeeeAddr[1],join_info->parentIeeeAddr[2],join_info->parentIeeeAddr[3],
extern s32 kUserScheduleTaskHandler(void *arg); join_info->parentIeeeAddr[4],join_info->parentIeeeAddr[5],join_info->parentIeeeAddr[6],join_info->parentIeeeAddr[7]);
kk_err_t kNwkScheduleTaskRegister(uint32_t TimeOut) iKonkeAfSelfPrint("Join Network,Device Nwk IEEE Addr id = %x-%x-%x-%x-%x-%x-%x-%x!!!!!!!\r\n",join_info->devIeeeAddr[0],join_info->devIeeeAddr[1],join_info->devIeeeAddr[2],join_info->devIeeeAddr[3],
{ join_info->devIeeeAddr[4],join_info->devIeeeAddr[5],join_info->devIeeeAddr[6],join_info->devIeeeAddr[7]);
kk_err_t err = KET_FAILED; return 0;
if(!ev_timer_exist(kUserScheduleTaskEvt)) { }
kUserScheduleTaskEvt = TL_ZB_TIMER_SCHEDULE(kUserScheduleTaskHandler, NULL, TimeOut);
err = KET_OK; static ev_timer_event_t *kUserScheduleTaskEvt = NULL;
} extern s32 kUserScheduleTaskHandler(void *arg);
return err; kk_err_t kNwkScheduleTaskRegister(uint32_t TimeOut)
} {
if(kUserScheduleTaskEvt){
TL_ZB_TIMER_CANCEL(&kUserScheduleTaskEvt);
void kNwkJoiningStart(uint32_t u32JoiningDuration, pJoinCompleteCallback callback) }
{ kUserScheduleTaskEvt = TL_ZB_TIMER_SCHEDULE(kUserScheduleTaskHandler, NULL, TimeOut);
if( u32JoiningDuration > 0 ) return KET_OK;
{ }
if(!zb_isDeviceJoinedNwk())
{
iKonkeAfSelfPrint("#####Set Steering Counter\r\n"); void kNwkJoiningStart(uint32_t u32JoiningDuration, pJoinCompleteCallback callback)
g_u32NwkJoiningCountdownCounter= MS2COUNT(u32JoiningDuration); {
g_pJoinCompleteCallback = callback; if( u32JoiningDuration > 0 )
kTickRunnningTrigger(); {
#if Z30_DEVICE_AGING_ENABLE
//add by maozj 20191206 if (kGetFactoryTestStatus() != FTS_NORMAL /*&& kGetFactoryTestStatus() != FTS_AGING_15MIN*/){
g_bNwkSteeringCompleteFlg = true; return;
} }
} #endif
else if(!zb_isDeviceJoinedNwk())
{ {
g_u32NwkJoiningCountdownCounter= MS2COUNT(0); //disable interpan
g_pJoinCompleteCallback = NULL; kInterpanDisable();
}
} iKonkeAfSelfPrint("#####Set Steering Counter\r\n");
g_u32NwkJoiningCountdownCounter= MS2COUNT(u32JoiningDuration);
g_pJoinCompleteCallback = callback;
status_t General_Report(uint8_t src_ep,uint8_t des_ep,uint16_t cluster,uint16_t Attribute,uint8_t Data_Type,uint8_t *value) kTickRunnningTrigger();
{
epInfo_t dstEpInfo; //add by maozj 20191206
static ReportAttrData_ST reportInfo; g_bNwkSteeringCompleteFlg = true;
uint8_t paload_len = 0; }
TL_SETSTRUCTCONTENT(dstEpInfo, 0); }
else
dstEpInfo.dstAddrMode = APS_SHORT_DSTADDR_WITHEP; {
dstEpInfo.dstEp = des_ep; g_u32NwkJoiningCountdownCounter= MS2COUNT(0);
dstEpInfo.dstAddr.shortAddr = 0x0000; g_pJoinCompleteCallback = NULL;
dstEpInfo.profileId = HA_PROFILE_ID; }
dstEpInfo.txOptions = 0; }
dstEpInfo.radius = 0;
reportInfo.attribute = Attribute; status_t General_Report(uint8_t src_ep,uint8_t des_ep,uint16_t cluster,uint16_t Attribute,uint8_t Data_Type,uint8_t *value)
reportInfo.attri_type = Data_Type; {
if(!zcl_analogDataType(Data_Type)){ epInfo_t dstEpInfo;
if(Data_Type == ZCL_DATA_TYPE_CHAR_STR) static ReportAttrData_ST reportInfo;
paload_len = value[0]+1; uint8_t paload_len = 0;
else TL_SETSTRUCTCONTENT(dstEpInfo, 0);
paload_len = zcl_getDataTypeLen(Data_Type);
if(paload_len < MAX_PALOAD_LEN) dstEpInfo.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
memcpy(reportInfo.value, value,paload_len); dstEpInfo.dstEp = des_ep;
} dstEpInfo.dstAddr.shortAddr = 0x0000;
paload_len += 3; dstEpInfo.profileId = HA_PROFILE_ID;
dstEpInfo.txOptions = 0;
return zcl_sendCmd(src_ep, &dstEpInfo, cluster, ZCL_CMD_REPORT, false, dstEpInfo.radius = 0;
ZCL_FRAME_SERVER_CLIENT_DIR, true, 0, ZCL_SEQ_NUM, (uint16_t )paload_len, (uint8_t *)&reportInfo);
} reportInfo.attribute = Attribute;
reportInfo.attri_type = Data_Type;
if(!zcl_analogDataType(Data_Type)){
if(Data_Type == ZCL_DATA_TYPE_CHAR_STR)
paload_len = value[0]+1;
else
paload_len = zcl_getDataTypeLen(Data_Type);
if(paload_len < MAX_PALOAD_LEN)
memcpy(reportInfo.value, value,paload_len);
}
paload_len += 3;
return zcl_sendCmd(src_ep, &dstEpInfo, cluster, ZCL_CMD_REPORT, false,
ZCL_FRAME_SERVER_CLIENT_DIR, true, 0, ZCL_SEQ_NUM, (uint16_t )paload_len, (uint8_t *)&reportInfo);
}
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "ikk-opt-tunnel.h" #include "ikk-opt-tunnel.h"
#include "ikk-debug.h" #include "ikk-debug.h"
#include "ikk-config.h" #include "ikk-config.h"
#include "../../../../zigbee/zcl/zcl_include.h" #include "ikk-token.h"
#include "../../../../zigbee/zcl/zcl_include.h"
// FCC0-0000 // FCC0-0000
#pragma pack(1) #pragma pack(1)
typedef struct tag_private_clsFCC0_attr0000_frame_st { typedef struct tag_private_clsFCC0_attr0000_frame_st {
unsigned char length; // frame length - not include itself!!! unsigned char length; // frame length - not include itself!!!
unsigned int device_id;// device id unsigned int device_id;// device id
unsigned char channel; // channel unsigned char channel; // channel
unsigned char opcode; // pocode unsigned char opcode; // pocode
unsigned char arg[OPTTUNNEL_OPTDATA_MAXLEN - 7]; // opcode arg unsigned char arg[OPTTUNNEL_OPTDATA_MAXLEN - 7]; // opcode arg
} }
__attribute__((packed)) OptTunnelOptDataFrameSt; __attribute__((packed)) OptTunnelOptDataFrameSt;
uint8_t g_tmp_buffer[OPTTUNNEL_CHUNK_MAXLEN+1] = { 0 }, g_tmp_length = 0; uint8_t g_tmp_buffer[OPTTUNNEL_CHUNK_MAXLEN+1] = { 0 }, g_tmp_length = 0;
// private protocol optdata message incoming process callback // private protocol optdata message incoming process callback
pFUNC_OPTDATA_MESSAGE_CALLBACK g_pOptDataIncomingMessageCallback = NULL; pFUNC_OPTDATA_MESSAGE_CALLBACK g_pOptDataIncomingMessageCallback = NULL;
extern bool Get_Model_ID(uint8_t *ModeID);
extern _CODE_ZCL_ zclReadCmd_t *zcl_parseInReadCmd(zclIncoming_t *pCmd); extern _CODE_ZCL_ zclReadCmd_t *zcl_parseInReadCmd(zclIncoming_t *pCmd);
extern _CODE_ZCL_ status_t zcl_readRsp(u8 srcEp, epInfo_t *pDstEpInfo, u16 clusterId, u16 manuCode, u8 disableDefaultRsp, u8 direction, u8 seqNo, zclReadRspCmd_t *readRspCmd); extern _CODE_ZCL_ status_t zcl_readRsp(u8 srcEp, epInfo_t *pDstEpInfo, u16 clusterId, u16 manuCode, u8 disableDefaultRsp, u8 direction, u8 seqNo, zclReadRspCmd_t *readRspCmd);
//_CODE_ZCL_ static status_t zcl_Private_cmdHandler(zclIncoming_t *pInMsg); //_CODE_ZCL_ static status_t zcl_Private_cmdHandler(zclIncoming_t *pInMsg);
// //
// //
// //
// //
//_CODE_ZCL_ status_t zcl_private_fcc0_register(u8 endpoint, u16 manuCode, u8 attrNum, const zclAttrInfo_t attrTbl[], cluster_forAppCb_t cb) //_CODE_ZCL_ status_t zcl_private_fcc0_register(u8 endpoint, u16 manuCode, u8 attrNum, const zclAttrInfo_t attrTbl[], cluster_forAppCb_t cb)
//{ //{
// return zcl_registerCluster(endpoint, ZCL_CLUSTER_PRIVATE_FCC0, manuCode, attrNum, attrTbl, zcl_Private_cmdHandler, cb); // return zcl_registerCluster(endpoint, ZCL_CLUSTER_PRIVATE_FCC0, manuCode, attrNum, attrTbl, zcl_Private_cmdHandler, cb);
//} //}
// //
//_CODE_ZCL_ static status_t zcl_private_clientCmdHandler(zclIncoming_t *pInMsg) //_CODE_ZCL_ static status_t zcl_private_clientCmdHandler(zclIncoming_t *pInMsg)
//{ //{
// u8 status = ZCL_STA_SUCCESS; // u8 status = ZCL_STA_SUCCESS;
// apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t*)pInMsg->msg; // apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t*)pInMsg->msg;
// iKonkeAfSelfPrint("#############zcl_private_clientCmdHandler ,command id =%x!!!!!!!\r\n",pInMsg->hdr.cmd); // iKonkeAfSelfPrint("#############zcl_private_clientCmdHandler ,command id =%x!!!!!!!\r\n",pInMsg->hdr.cmd);
//// switch(pInMsg->hdr.cmd) //// switch(pInMsg->hdr.cmd)
//// { //// {
//// case ZCL_CMD_BASIC_RESET_FAC_DEFAULT: //// case ZCL_CMD_BASIC_RESET_FAC_DEFAULT:
//// if(pInMsg->clusterAppCb){ //// if(pInMsg->clusterAppCb){
//// zclIncomingAddrInfo_t addrInfo; //// zclIncomingAddrInfo_t addrInfo;
//// addrInfo.dirCluster = pInMsg->hdr.frmCtrl.bf.dir; //// addrInfo.dirCluster = pInMsg->hdr.frmCtrl.bf.dir;
//// addrInfo.profileId = pApsdeInd->indInfo.profile_id; //// addrInfo.profileId = pApsdeInd->indInfo.profile_id;
//// addrInfo.srcAddr = pApsdeInd->indInfo.src_short_addr; //// addrInfo.srcAddr = pApsdeInd->indInfo.src_short_addr;
//// addrInfo.dstAddr = pApsdeInd->indInfo.dst_addr; //// addrInfo.dstAddr = pApsdeInd->indInfo.dst_addr;
//// addrInfo.srcEp = pApsdeInd->indInfo.src_ep; //// addrInfo.srcEp = pApsdeInd->indInfo.src_ep;
//// addrInfo.dstEp = pApsdeInd->indInfo.dst_ep; //// addrInfo.dstEp = pApsdeInd->indInfo.dst_ep;
//// ////
//// status = pInMsg->clusterAppCb(&addrInfo, ZCL_CMD_BASIC_RESET_FAC_DEFAULT, NULL); //// status = pInMsg->clusterAppCb(&addrInfo, ZCL_CMD_BASIC_RESET_FAC_DEFAULT, NULL);
//// }else{ //// }else{
//// status = ZCL_STA_FAILURE; //// status = ZCL_STA_FAILURE;
//// } //// }
//// break; //// break;
//// default: //// default:
//// status = ZCL_STA_UNSUP_CLUSTER_COMMAND; //// status = ZCL_STA_UNSUP_CLUSTER_COMMAND;
//// break; //// break;
//// } //// }
// //
// return status; // return status;
//} //}
// //
//_CODE_ZCL_ static status_t zcl_Private_cmdHandler(zclIncoming_t *pInMsg) //_CODE_ZCL_ static status_t zcl_Private_cmdHandler(zclIncoming_t *pInMsg)
//{ //{
// if(pInMsg->hdr.frmCtrl.bf.dir == ZCL_FRAME_CLIENT_SERVER_DIR){ // if(pInMsg->hdr.frmCtrl.bf.dir == ZCL_FRAME_CLIENT_SERVER_DIR){
// return zcl_private_clientCmdHandler(pInMsg); // return zcl_private_clientCmdHandler(pInMsg);
// }else{ // }else{
// return ZCL_STA_UNSUP_CLUSTER_COMMAND; // return ZCL_STA_UNSUP_CLUSTER_COMMAND;
// } // }
//} //}
// //
///********************************************************************* uint8_t kOptTunnelChunkRead(uint8_t endpoint,
// * @fn private_fcc0Cb uint16_t clusterId,
// * uint16_t attributeId,
// * @brief Handler for ZCL FCC0 command. This function will set attribute first. uint16_t manufacturerCode,
// * uint8_t *buffer,
// * @param pAddrInfo uint8_t *length_out)
// * @param cmdId - onoff cluster command id {
// * @param cmdPayload iKonkeAfSelfPrint("&&&&&&&&&&&&&Token Read cluster(%2X), attr(%2X)\r\n", clusterId, attributeId);
// * uint8_t length = 0;
// * @return status_t if (buffer == NULL){
// */ iKonkeAfSelfPrint("Err: Buffer is null(%d)!!\r\n");
//status_t private_fcc0Cb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload) return 0xff;
//{ }
// zcl_privateAttr_t *pFcc0_data = zcl_privateAttrGet();
// iKonkeAfSelfPrint("#############private_fcc0Cb ,command id =%x!!!!!!!\r\n",cmdId); if( clusterId == PRIV_CLUSTER_FCC0 ) {
// if(pAddrInfo->dstEp == SAMPLE_LIGHT_ENDPOINT){ switch(attributeId) {
// switch(cmdId){ case (ZCL_CMEI_ATTRIBUTE_ID):
// case ZCL_CMD_ONOFF_ON: {
// case ZCL_CMD_ONOFF_OFF: uint8_t *data = CMEI_TOKEN_GET();
// case ZCL_CMD_ONOFF_TOGGLE: length = data[0];
// //sampleLight_onoff(cmdId); memcpy(buffer, data, length+1);
// break; break;
// default: }
// break; case (ZCL_ISN_ATTRIBUTE_ID):
// } {
// } uint8_t *data = ISN_TOKEN_GET();
// length = data[0];
// return ZCL_STA_SUCCESS; memcpy(buffer, data, length+1);
//} break;
}
status_t kOptTunnelMessageReadResponse(zclIncoming_t *pInHdlrMsg,uint8_t *pData) case (ZCL_InstallCode_ATTRIBUTE_ID):
{ {
u8 status = ZCL_STA_SUCCESS; length = 16;
u16 clusterId = pInHdlrMsg->msg->indInfo.cluster_id; buffer[0] = length;
u8 endpoint = pInHdlrMsg->msg->indInfo.dst_ep; memcpy(&buffer[1], INSTALL_CODE_TOKEN_GET(), length);
break;
}
/* Parse In Read Command */ default:
zclReadCmd_t *pReadCmd = zcl_parseInReadCmd(pInHdlrMsg); return 0xfe;
if(pReadCmd == NULL){ }
return ZCL_STA_INSUFFICIENT_SPACE; }
}else{ if (buffer[0] <= OPTTUNNEL_CHUNK_MAXLEN){
pInHdlrMsg->attrCmd = (void *)pReadCmd; *length_out = buffer[0];
} }else {
*length_out = 0;
if(!pInHdlrMsg->msg->indInfo.security_status){ }
return ZCL_STA_FAILURE; return 0;
} }
/* DESP: Private clsuter attribute read interface, for chunk data.
/* Build Read Response Command */ * Auth: dingmz_frc.20190703.
u16 len = sizeof(zclReadRspCmd_t) + (pReadCmd->numAttr * sizeof(zclReadRspStatus_t)); * */
zclReadRspCmd_t *pReadRspCmd = (zclReadRspCmd_t *)ev_buf_allocate(len); kk_err_t kOptTunnelAttrChunkLocalRead(uint16_t attribute_id, unsigned char *chunk_buffer, unsigned char *length_in_out )
if(!pReadRspCmd){ {
return ZCL_STA_INSUFFICIENT_SPACE; if( NULL == chunk_buffer || NULL == length_in_out ) {
} return KET_ERR_INVALID_POINTER;
pReadRspCmd->numAttr = pReadCmd->numAttr; }
uint8_t status = 0;
pReadRspCmd->attrList[0].dataType = ZCL_DATA_TYPE_CHAR_STR; kk_err_t err = KET_OK;
pReadRspCmd->attrList[0].data = pData;
pReadRspCmd->attrList[0].attrID = pReadCmd->attrID[0]; status = kOptTunnelChunkRead(1, PRIV_CLUSTER_FCC0, attribute_id, 0x1268, chunk_buffer, length_in_out);
pReadRspCmd->attrList[0].status = ZCL_STA_SUCCESS; if( status == 0 ) {
*length_in_out = chunk_buffer[0] + 1;
epInfo_t dstEp; }else {
TL_SETSTRUCTCONTENT(dstEp, 0); iKonkeAfSelfPrint("Err: Chunk read err(%d)!!\r\n", status);
*length_in_out = 0;
dstEp.dstEp = pInHdlrMsg->msg->indInfo.src_ep; err = KET_ERR_UNKNOW;
dstEp.profileId = pInHdlrMsg->msg->indInfo.profile_id; }
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
dstEp.dstAddr.shortAddr = pInHdlrMsg->msg->indInfo.src_short_addr; return err;
dstEp.txOptions |= APS_TX_OPT_ACK_TX; }
if(pInHdlrMsg->msg->indInfo.security_status & SECURITY_IN_APSLAYER){ status_t kOptTunnelMessageReadResponse(zclIncoming_t *pInHdlrMsg,uint8_t *pData)
dstEp.txOptions |= APS_TX_OPT_SECURITY_ENABLED; {
} u8 status = ZCL_STA_SUCCESS;
u16 clusterId = pInHdlrMsg->msg->indInfo.cluster_id;
status = zcl_readRsp(endpoint, &dstEp, clusterId, pInHdlrMsg->hdr.manufCode, false, !pInHdlrMsg->hdr.frmCtrl.bf.dir, pInHdlrMsg->hdr.seqNum, pReadRspCmd); u8 endpoint = pInHdlrMsg->msg->indInfo.dst_ep;
return status;
}
status_t kOptTunnelMessageWriteResponse(zclIncoming_t *pCmd,uint8_t *pData) /* Parse In Read Command */
{ zclReadCmd_t *pReadCmd = zcl_parseInReadCmd(pInHdlrMsg);
u8 status = ZCL_STA_SUCCESS; if(pReadCmd == NULL){
u16 clusterId = pCmd->msg->indInfo.cluster_id; return ZCL_STA_INSUFFICIENT_SPACE;
u8 endpoint = pCmd->msg->indInfo.dst_ep; }else{
uint8_t tmp_buffer[64] ={0}; pInHdlrMsg->attrCmd = (void *)pReadCmd;
uint8_t i =0; }
uint8_t payload_len = pData[0];
if(!pInHdlrMsg->msg->indInfo.security_status){
return ZCL_STA_FAILURE;
// 8 0 51 86 10 0 0 0 0 }
if(pCmd->hdr.cmd == ZCL_CMD_WRITE){
tmp_buffer[i++] = 0x00; /* Build Read Response Command */
tmp_buffer[i++] = ZCL_STA_SUCCESS; //0 u16 len = sizeof(zclReadRspCmd_t) + (pReadCmd->numAttr * sizeof(zclReadRspStatus_t));
tmp_buffer[i++] = 00; //1 zclReadRspCmd_t *pReadRspCmd = (zclReadRspCmd_t *)ev_buf_allocate(len);
tmp_buffer[i++] = 00; //2 if(!pReadRspCmd){
tmp_buffer[i++] = ZCL_DATA_TYPE_CHAR_STR; //3 type return ZCL_STA_INSUFFICIENT_SPACE;
tmp_buffer[i++] = payload_len+1; //4 len }
tmp_buffer[i++] = payload_len; //5 len pReadRspCmd->numAttr = pReadCmd->numAttr;
if(payload_len +7 < 64)
{
memcpy(&tmp_buffer[i],&pData[1],payload_len); pReadRspCmd->attrList[0].dataType = ZCL_DATA_TYPE_CHAR_STR;
} pReadRspCmd->attrList[0].data = pData;
tmp_buffer[0] = payload_len + 6; pReadRspCmd->attrList[0].attrID = pReadCmd->attrID[0];
epInfo_t dstEp; pReadRspCmd->attrList[0].status = ZCL_STA_SUCCESS;
TL_SETSTRUCTCONTENT(dstEp, 0);
epInfo_t dstEp;
dstEp.dstEp = pCmd->msg->indInfo.src_ep; TL_SETSTRUCTCONTENT(dstEp, 0);
dstEp.profileId = pCmd->msg->indInfo.profile_id;
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP; dstEp.dstEp = pInHdlrMsg->msg->indInfo.src_ep;
dstEp.dstAddr.shortAddr = pCmd->msg->indInfo.src_short_addr; dstEp.profileId = pInHdlrMsg->msg->indInfo.profile_id;
dstEp.txOptions |= APS_TX_OPT_ACK_TX; dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
if(pCmd->msg->indInfo.security_status & SECURITY_IN_APSLAYER){ dstEp.dstAddr.shortAddr = pInHdlrMsg->msg->indInfo.src_short_addr;
dstEp.txOptions |= APS_TX_OPT_SECURITY_ENABLED; dstEp.txOptions |= APS_TX_OPT_ACK_TX;
} if(pInHdlrMsg->msg->indInfo.security_status & SECURITY_IN_APSLAYER){
status = zcl_sendCmd(endpoint, &dstEp, clusterId, ZCL_CMD_WRITE_RSP, FALSE, !pCmd->hdr.frmCtrl.bf.dir, false, pCmd->hdr.manufCode, pCmd->hdr.seqNum, tmp_buffer[0], &tmp_buffer[1]); dstEp.txOptions |= APS_TX_OPT_SECURITY_ENABLED;
} }
return status;
} status = zcl_readRsp(endpoint, &dstEp, clusterId, pInHdlrMsg->hdr.manufCode, false, !pInHdlrMsg->hdr.frmCtrl.bf.dir, pInHdlrMsg->hdr.seqNum, pReadRspCmd);
/* DESP: private protocol command process. return status;
* Auth: dingmz_frc.20190704. }
* */ status_t kOptTunnelMessageWriteResponse(zclIncoming_t *pCmd,uint8_t *pData)
kk_err_t kOptTunnelMessageIncoming(OptMethodEm method,zclIncoming_t *pCmd) {
{ u8 status = ZCL_STA_SUCCESS;
kk_err_t status = KET_OK; u16 clusterId = pCmd->msg->indInfo.cluster_id;
// 0 0 42 7 6 0 51 86 10 0 0 oring data zcl global write 0xfcc0 0x0000 0x42 {06 00 51 86 10 00 00} u8 endpoint = pCmd->msg->indInfo.dst_ep;
//out 6 0 51 86 10 0 0 0 uint8_t tmp_buffer[64] ={0};
iKonkeAfSelfPrint("\r\n-------------------------\r\n"); uint8_t i =0;
uint8_t payload_len = pData[0];
// device id
uint32_t modeid = (uint32_t)MODEL_ID;
uint8_t tmp_buffer[6]; // 8 0 51 86 10 0 0 0 0
tmp_buffer[0] = 5; if(pCmd->hdr.cmd == ZCL_CMD_WRITE){
tmp_buffer[1] = modeid>>24; tmp_buffer[i++] = 0x00;
tmp_buffer[2] = modeid>>16; tmp_buffer[i++] = ZCL_STA_SUCCESS; //0
tmp_buffer[3] = modeid>>8; tmp_buffer[i++] = 00; //1
tmp_buffer[4] = modeid; tmp_buffer[i++] = 00; //2
switch(method) { tmp_buffer[i++] = ZCL_DATA_TYPE_CHAR_STR; //3 type
case (EOM_WRITE): tmp_buffer[i++] = payload_len+1; //4 len
{ tmp_buffer[i++] = payload_len; //5 len
uint8_t length = (uint8_t)pCmd->dataLen - 4; if(payload_len +7 < 64)
if( pCmd->pData ) { {
memcpy(g_tmp_buffer, pCmd->pData+4, length); memcpy(&tmp_buffer[i],&pData[1],payload_len);
g_tmp_length = length; }
} tmp_buffer[0] = payload_len + 6;
iKonkeAfSelfPrint("#######kOptTunnelMessageIncoming length(0x%d)\r\n", length); epInfo_t dstEp;
iKonkeAfSelfPrintBuffer(g_tmp_buffer,length); TL_SETSTRUCTCONTENT(dstEp, 0);
//copy device id dstEp.dstEp = pCmd->msg->indInfo.src_ep;
memcpy(&g_tmp_buffer[1],&tmp_buffer[1],4); dstEp.profileId = pCmd->msg->indInfo.profile_id;
// switch(attribute_id) dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
// { dstEp.dstAddr.shortAddr = pCmd->msg->indInfo.src_short_addr;
// case (ECA_OPTDATA): dstEp.txOptions |= APS_TX_OPT_ACK_TX;
// { if(pCmd->msg->indInfo.security_status & SECURITY_IN_APSLAYER){
if( length >= 7 ) { dstEp.txOptions |= APS_TX_OPT_SECURITY_ENABLED;
iKonkeAfSelfPrint("\r\n########################OPTDATA WRITE,g_tmp_length = %d\r\n",g_tmp_length); }
if( g_pOptDataIncomingMessageCallback ) { status = zcl_sendCmd(endpoint, &dstEp, clusterId, ZCL_CMD_WRITE_RSP, FALSE, !pCmd->hdr.frmCtrl.bf.dir, false, pCmd->hdr.manufCode, pCmd->hdr.seqNum, tmp_buffer[0], &tmp_buffer[1]);
g_tmp_length = g_tmp_length - 6; }
if(KET_NO_RESPONSE == g_pOptDataIncomingMessageCallback(g_tmp_buffer[5], g_tmp_buffer[6], g_tmp_buffer + 7, &g_tmp_length)){ return status;
return KET_NO_RESPONSE; }
} /* DESP: private protocol command process.
g_tmp_length += 7; * Auth: dingmz_frc.20190704.
g_tmp_buffer[0] = g_tmp_length - 1; * */
iKonkeAfSelfPrint("#######kOptTunnelMessageIncoming11111 length(0x%2x)\r\n", g_tmp_buffer[0]); kk_err_t kOptTunnelMessageIncoming(OptMethodEm method,zclIncoming_t *pCmd)
iKonkeAfSelfPrintBuffer(g_tmp_buffer,g_tmp_buffer[0]+1); {
kOptTunnelMessageWriteResponse(pCmd, g_tmp_buffer); kk_err_t status = KET_OK;
} // 0 0 42 7 6 0 51 86 10 0 0 oring data zcl global write 0xfcc0 0x0000 0x42 {06 00 51 86 10 00 00}
}else { //out 6 0 51 86 10 0 0 0
return KET_ERR_INVALID_PARAM; iKonkeAfSelfPrint("\r\n-------------------------\r\n");
}
// // device id
// break; uint32_t modeid = (uint32_t)MODEL_ID;
// } uint8_t tmp_buffer[6];
// } tmp_buffer[0] = 5;
break; tmp_buffer[1] = modeid>>24;
} tmp_buffer[2] = modeid>>16;
case (EOM_READ ): tmp_buffer[3] = modeid>>8;
{ tmp_buffer[4] = modeid;
// switch(attribute_id){ switch(method) {
// // OptData read command is same to write opcode 0x00, read the device snap. case (EOM_WRITE):
// case (ECA_OPTDATA): {
// { uint8_t length = (uint8_t)pCmd->dataLen - 4;
iKonkeAfSelfPrint("\r\n########################OPTDATA READ\r\n"); if( pCmd->pData ) {
if( g_pOptDataIncomingMessageCallback ) { memcpy(g_tmp_buffer, pCmd->pData+4, length);
memcpy(&g_tmp_buffer[2],&tmp_buffer[1],4); g_tmp_length = length;
g_tmp_buffer[6] = 0x00; }
g_tmp_buffer[7] = 0x00; iKonkeAfSelfPrint("#######kOptTunnelMessageIncoming length(0x%d)\r\n", length);
g_tmp_buffer[8] = 0x00; iKonkeAfSelfPrintBuffer(g_tmp_buffer,length);
g_tmp_buffer[9] = 0x00;
g_tmp_length = 0; //copy device id
g_pOptDataIncomingMessageCallback(0, 0, g_tmp_buffer + 8, &g_tmp_length); memcpy(&g_tmp_buffer[1],&tmp_buffer[1],4);
g_tmp_length += 7; // switch(attribute_id)
g_tmp_buffer[0] = g_tmp_length; //length // {
g_tmp_buffer[1] = g_tmp_length - 1; //string length // case (ECA_OPTDATA):
kOptTunnelMessageReadResponse(pCmd, g_tmp_buffer); // {
} if( length >= 7 ) {
// break; iKonkeAfSelfPrint("\r\n########################OPTDATA WRITE,g_tmp_length = %d\r\n",g_tmp_length);
// } if( g_pOptDataIncomingMessageCallback ) {
// } g_tmp_length = g_tmp_length - 6;
break; if(KET_NO_RESPONSE == g_pOptDataIncomingMessageCallback(g_tmp_buffer[5], g_tmp_buffer[6], g_tmp_buffer + 7, &g_tmp_length)){
} return KET_NO_RESPONSE;
default: break; }
} g_tmp_length += 7;
g_tmp_buffer[0] = g_tmp_length - 1;
return status; iKonkeAfSelfPrint("#######kOptTunnelMessageIncoming11111 length(0x%2x)\r\n", g_tmp_buffer[0]);
} iKonkeAfSelfPrintBuffer(g_tmp_buffer,g_tmp_buffer[0]+1);
kOptTunnelMessageWriteResponse(pCmd, g_tmp_buffer);
/* DESP: Private protocol message(command) reporting interface }
* Auth: dingmz_frc.20191113. }else {
* */ return KET_ERR_INVALID_PARAM;
extern status_t General_Report(uint8_t src_ep,uint8_t des_ep,uint16_t cluster,uint16_t Attribute,uint8_t Data_Type,uint8_t *value); }
static status_t kOptTunnelOODReport(uint16_t attribute_id,uint8_t channel, uint8_t opcode, uint8_t *arg, uint8_t length ) //
{ // break;
uint8_t temp_buffer[64] = {0}; // }
if(length < 64) // }
memmove(temp_buffer+1, arg, length); break;
temp_buffer[0] = length; }
memmove(g_tmp_buffer,temp_buffer,length+1); case (EOM_READ ):
{
return General_Report(channel,1,PRIV_CLUSTER_FCC0,attribute_id,ZCL_DATA_TYPE_CHAR_STR,g_tmp_buffer); // switch(attribute_id){
} // // OptData read command is same to write opcode 0x00, read the device snap.
/* DESP: Private protocol common report interface. // case (ECA_OPTDATA):
* Auth: dingmz_frc.20191113. // {
* */ iKonkeAfSelfPrint("\r\n########################OPTDATA READ\r\n");
kk_err_t kOptTunnelCommonReport(uint16_t attribute_id ) if( g_pOptDataIncomingMessageCallback ) {
{ memcpy(&g_tmp_buffer[2],&tmp_buffer[1],4);
if( attribute_id == OPTTUNNEL_UNKNOW ) { g_tmp_buffer[6] = 0x00;
return KET_ERR_NON_EXIST; g_tmp_buffer[7] = 0x00;
} g_tmp_buffer[8] = 0x00;
g_tmp_buffer[9] = 0x00;
kk_err_t err = KET_OK; g_tmp_length = 0;
g_pOptDataIncomingMessageCallback(0, 0, g_tmp_buffer + 8, &g_tmp_length);
switch(attribute_id) { g_tmp_length += 7;
case (ECA_OPTDATA): g_tmp_buffer[0] = g_tmp_length; //length
{ g_tmp_buffer[1] = g_tmp_length - 1; //string length
uint32_t modeid = (uint32_t)MODEL_ID; kOptTunnelMessageReadResponse(pCmd, g_tmp_buffer);
iKonkeAfSelfPrint("#######kOptTunnelCommonReport OPTDATA\r\n"); }
g_tmp_buffer[1] = modeid>>24; // break;
g_tmp_buffer[2] = modeid>>16; // }
g_tmp_buffer[3] = modeid>>8; // }
g_tmp_buffer[4] = modeid; break;
g_tmp_buffer[5] = 0x00;//channel }
g_tmp_buffer[6] = 0x00;//opcode default: break;
if( g_pOptDataIncomingMessageCallback ) { }
g_tmp_length = 0;
g_tmp_buffer[7] = 0x00;//add by maozj 20200511 return status;
g_pOptDataIncomingMessageCallback(0, 0, g_tmp_buffer + 7, &g_tmp_length); }
g_tmp_length += 7;
g_tmp_buffer[0] = g_tmp_length - 1; /* DESP: Private protocol message(command) reporting interface
}else { * Auth: dingmz_frc.20191113.
err = KET_ERR_INVALID_POINTER; * */
} extern status_t General_Report(uint8_t src_ep,uint8_t des_ep,uint16_t cluster,uint16_t Attribute,uint8_t Data_Type,uint8_t *value);
break; static status_t kOptTunnelCommonReportSend(uint16_t attribute_id, uint8_t *arg, uint8_t length )
} {
default: uint8_t temp_buffer[64] = {0};
{ if( arg && length > 0 )
err = KET_ERR_OPRATE_ILLEGAL; memmove(temp_buffer+1, arg, length);
break; temp_buffer[0] = length;
} memmove(g_tmp_buffer,temp_buffer,length+1);
}
if( err == KET_OK && g_tmp_length > 1) { return General_Report(1,1,PRIV_CLUSTER_FCC0,attribute_id,ZCL_DATA_TYPE_CHAR_STR,g_tmp_buffer);
if(kOptTunnelOODReport(attribute_id,g_tmp_buffer[5],g_tmp_buffer[6],g_tmp_buffer,g_tmp_buffer[0]+1)== ZCL_STA_SUCCESS) }
err = KET_OK; /* DESP: Private protocol common report interface.
else * Auth: dingmz_frc.20191113.
err = KET_FAILED; * */
} kk_err_t kOptTunnelCommonReport(uint16_t attribute_id )
{
return err; if( attribute_id == OPTTUNNEL_UNKNOW ) {
} return KET_ERR_NON_EXIST;
}
kk_err_t kOptTunnelModuleInit(pFUNC_OPTDATA_MESSAGE_CALLBACK pOptdataIncomingCallback ) kk_err_t err = KET_OK;
{ uint8_t bufCount = 0;
g_pOptDataIncomingMessageCallback = pOptdataIncomingCallback;
switch(attribute_id) {
return KET_OK; case (ECA_OPTDATA):
} {
uint8_t modeid[8] = {0};
if(Get_Model_ID(modeid))
{
g_tmp_buffer[bufCount++] = 0;
g_tmp_buffer[bufCount++] = modeid[4];
g_tmp_buffer[bufCount++] = modeid[5];
g_tmp_buffer[bufCount++] = modeid[6];
g_tmp_buffer[bufCount++] = modeid[7];
g_tmp_buffer[5] = 0x00;//channel
g_tmp_buffer[6] = 0x00;//opcode
}
if( g_pOptDataIncomingMessageCallback ) {
g_tmp_length = 0;
g_tmp_buffer[7] = 0x00;//add by maozj 20200511
g_pOptDataIncomingMessageCallback(0, 0, g_tmp_buffer + 7, &g_tmp_length);
g_tmp_length += 7;
g_tmp_buffer[0] = g_tmp_length - 1;
}else {
err = KET_ERR_INVALID_POINTER;
}
break;
}
case (ECA_ASSOCIATED_AOUNCE):
{
addrExt_t u64LocalEui64 = { 0 };
uint16_t NodeID = zb_getLocalShortAddr();
uint16_t index;
tl_zbExtAddrByShortAddr(NodeID,u64LocalEui64,&index);
g_tmp_buffer[0] = (NodeID >> 8) & 0xff;
g_tmp_buffer[1] = (NodeID >> 0) & 0xff;
SWAP_EUI64(u64LocalEui64);
memcpy(g_tmp_buffer + 2, u64LocalEui64, 8);
g_tmp_length = 10;
break;
}
case (ECA_CMEI):
case (ECA_ISN ):
{
g_tmp_length = OPTTUNNEL_CHUNK_MAXLEN;
kOptTunnelAttrChunkLocalRead(attribute_id, g_tmp_buffer, &g_tmp_length);
iKonkeAfSelfPrint("####Report CHUNK Read length(0x%x) \r\n", g_tmp_length);
break;
}
case (ECA_INSTALL_CODE):
g_tmp_length = OPTTUNNEL_CHUNK_MAXLEN;
kOptTunnelAttrChunkLocalRead(ZCL_InstallCode_ATTRIBUTE_ID, g_tmp_buffer, &g_tmp_length);
break;
default:
{
err = KET_ERR_OPRATE_ILLEGAL;
break;
}
}
if( err == KET_OK && g_tmp_length > 1) {
if(kOptTunnelCommonReportSend(attribute_id,g_tmp_buffer,g_tmp_buffer[0]+1)== ZCL_STA_SUCCESS)
err = KET_OK;
else
err = KET_FAILED;
}
return err;
}
/* DESP: Private protocol message(command) reporting interface
* Auth: dingmz_frc.20191113.
* */
kk_err_t kOptTunnelOODReport(uint8_t channel, uint8_t opcode, uint8_t *arg, uint8_t length )
{
uint8_t bufCount = 0;
uint8_t modeid[8] = {0};
if(Get_Model_ID(modeid))
{
g_tmp_buffer[bufCount++] = 0; // totle length
g_tmp_buffer[bufCount++] = modeid[4];
g_tmp_buffer[bufCount++] = modeid[5];
g_tmp_buffer[bufCount++] = modeid[6];
g_tmp_buffer[bufCount++] = modeid[7];
g_tmp_buffer[bufCount++] = channel;//channel
g_tmp_buffer[bufCount++] = opcode;//opcode
}
if( arg && length > 0 ) {
memcpy(g_tmp_buffer + bufCount, arg, length);
bufCount += length;
}
g_tmp_buffer[0] = bufCount - 1;
return kOptTunnelCommonReportSend(ECA_OPTDATA, g_tmp_buffer, bufCount);
}
kk_err_t kOptTunnelModuleInit(pFUNC_OPTDATA_MESSAGE_CALLBACK pOptdataIncomingCallback )
{
g_pOptDataIncomingMessageCallback = pOptdataIncomingCallback;
return KET_OK;
}
...@@ -10,6 +10,18 @@ ...@@ -10,6 +10,18 @@
#define PRIV_CLUSTER_FCC0 0XFCC0 #define PRIV_CLUSTER_FCC0 0XFCC0
// Server attributes
#define ZCL_OPT_DATA_ATTRIBUTE_ID 0x0000 // Ver.: always
#define ZCL_TTS_ATTRIBUTE_ID 0x0001 // Ver.: always
#define ZCL_MTO_RR_RspRandom_ATTRIBUTE_ID 0x0002 // Ver.: always
#define ZCL_AssociatedAnnounce_ATTRIBUTE_ID 0x0003 // Ver.: always
#define ZCL_CMEI_ATTRIBUTE_ID 0x0010 // Ver.: always
#define ZCL_ISN_ATTRIBUTE_ID 0x0011 // Ver.: always
#define ZCL_InstallCode_ATTRIBUTE_ID 0x0012 // Ver.: always
#define ZCL_CHUNK_N1_ATTRIBUTE_ID 0x0013 // Ver.: always
#define OPTTUNNEL_OPTDATA_ID 0x0000 // FCC0 Cluster Attribute 0x0000 #define OPTTUNNEL_OPTDATA_ID 0x0000 // FCC0 Cluster Attribute 0x0000
#define OPTTUNNEL_OPTDATA_MAXLEN 128 #define OPTTUNNEL_OPTDATA_MAXLEN 128
...@@ -51,10 +63,6 @@ typedef kk_err_t (*pFUNC_OPTDATA_MESSAGE_CALLBACK)(uint8_t channel, uint8_t opco ...@@ -51,10 +63,6 @@ typedef kk_err_t (*pFUNC_OPTDATA_MESSAGE_CALLBACK)(uint8_t channel, uint8_t opco
void Set2NwkJoiningCountdownCounter(u32 time_ms); void Set2NwkJoiningCountdownCounter(u32 time_ms);
/* DESP: Private protocol common report interface.
* Auth: mengmengli_frc.20210527.
* */
kk_err_t kOptTunnelCommonReport(uint16_t attribute_id );
/* DESP: private clsuter protocol module init interface. /* DESP: private clsuter protocol module init interface.
...@@ -66,14 +74,7 @@ kk_err_t kOptTunnelModuleInit(pFUNC_OPTDATA_MESSAGE_CALLBACK pOptdataIncomingCal ...@@ -66,14 +74,7 @@ kk_err_t kOptTunnelModuleInit(pFUNC_OPTDATA_MESSAGE_CALLBACK pOptdataIncomingCal
kk_err_t kOptTunnelOODReport(uint8_t channel, uint8_t opcode, uint8_t *arg, uint8_t length );
......
#if (__PROJECT_TL_DIMMABLE_LIGHT__) /**********************************************************************
* INCLUDES
/********************************************************************** */
* INCLUDES #include "ikk-debug.h"
*/ #include "ikk-tick-handler.h"
#include "ikk-debug.h" #include "tl_common.h"
#include "ikk-tick-handler.h"
#include "tl_common.h"
static ev_timer_event_t *Tick_timerEvt = NULL;
static ev_timer_event_t *Tick_timerEvt = NULL; extern void kBtnModuleActionDetectCallback(void );
//extern bool kBtnModuleActionIsGoing(void );
extern void kBtnModuleActionDetectCallback(void ); extern void kLedModuleActionDetectCallback(void );
//extern bool kBtnModuleActionIsGoing(void ); //extern bool kLedModuleActionIsGoing(void );
extern void kLedModuleActionDetectCallback(void ); extern void kNwkModuleActionDetectCallback(void );
//extern bool kLedModuleActionIsGoing(void ); //attribute change check callback
extern void kNwkModuleActionDetectCallback(void ); extern void kRelayModuleActionDetectCallback(uint8_t poll_time);
//attribute change check callback
extern void kRelayModuleActionDetectCallback(uint8_t poll_time); extern void AttributeValueCheckCallback(void);
static s32 kTickEventHandler(void *arg) static s32 kTickEventHandler(void *arg)
{ {
kLedModuleActionDetectCallback(); kLedModuleActionDetectCallback();
kBtnModuleActionDetectCallback(); kBtnModuleActionDetectCallback();
kNwkModuleActionDetectCallback(); kNwkModuleActionDetectCallback();
kRelayModuleActionDetectCallback(TICK_LOOP_NMS); kRelayModuleActionDetectCallback(TICK_LOOP_NMS);
return 0; AttributeValueCheckCallback();
} return 0;
}
void Tick_Time_Init(void)
{ void Tick_Time_Init(void)
if(Tick_timerEvt){ {
TL_ZB_TIMER_CANCEL(&Tick_timerEvt); if(Tick_timerEvt){
} TL_ZB_TIMER_CANCEL(&Tick_timerEvt);
Tick_timerEvt = TL_ZB_TIMER_SCHEDULE(kTickEventHandler, NULL, TICK_LOOP_NMS); }
} Tick_timerEvt = TL_ZB_TIMER_SCHEDULE(kTickEventHandler, NULL, TICK_LOOP_NMS);
}
/* DESP: tick handler continue running trigger interface.
* Auth: dingmz_frc.20191107. /* DESP: tick handler continue running trigger interface.
* */ * Auth: dingmz_frc.20191107.
void kTickRunnningTrigger(void ) * */
{ void kTickRunnningTrigger(void )
if(!ev_timer_exist(Tick_timerEvt)) { {
Tick_timerEvt = TL_ZB_TIMER_SCHEDULE(kTickEventHandler, NULL, TICK_LOOP_NMS); if(!ev_timer_exist(Tick_timerEvt)) {
} Tick_timerEvt = TL_ZB_TIMER_SCHEDULE(kTickEventHandler, NULL, TICK_LOOP_NMS);
} }
}
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */
...@@ -15,5 +15,4 @@ void Tick_Time_Init(void); ...@@ -15,5 +15,4 @@ void Tick_Time_Init(void);
* */ * */
void kTickRunnningTrigger(void ); void kTickRunnningTrigger(void );
#endif #endif
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "ikk-token.h" #include "ikk-token.h"
#include "../../../../zigbee/zcl/zcl_include.h"
#include "ikk-common-utils.h"
extern addrExt_t g_Eui64GatewayAddr; extern addrExt_t g_Eui64GatewayAddr;
uint8_t Flash_Buffer_Data[USER_SIZE];
/*********************************************************************
* @fn Get Gateway Addr OPTTUNEL_TOKEN_ST sOptunnel_Token = {{1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6},{16,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26},{16,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46},{16,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66}};
* /*********************************************************************
* @brief * @fn Get Gateway Addr
* *
* @param None * @brief
* *
* @return * @param None
*/ *
uint8_t* Gateway_IEEE_Addr_Get(void) * @return
{ */
nv_sts_t st = NV_SUCC; uint8_t* Gateway_IEEE_Addr_Get(void)
{
st = nv_flashReadNew(1, NV_MODULE_KEYPAIR, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)g_Eui64GatewayAddr); nv_sts_t st = NV_SUCC;
iKonkeAfSelfPrint("flashRead:::\r\n");
DEBUG_ARRAY(1,g_Eui64GatewayAddr,sizeof(addrExt_t));
if(st != NV_SUCC){
memset(g_Eui64GatewayAddr,0xff,sizeof(addrExt_t));
}
return g_Eui64GatewayAddr;
}
/*********************************************************************
* @fn Save Gateway Addr
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t Gateway_IEEE_Addr_Save(addrExt_t addr)
{
nv_sts_t st = NV_SUCC;
addrExt_t temp_addr;
st = nv_flashReadNew(1, NV_MODULE_KEYPAIR, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)temp_addr);
iKonkeAfSelfPrint("flashRead:::temp_addr\r\n");
DEBUG_ARRAY(1,temp_addr,sizeof(addrExt_t));
if(st == NV_SUCC){
if(memcmp(temp_addr,addr,sizeof(addrExt_t)))
st = nv_flashWriteNew(1, NV_MODULE_KEYPAIR, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_KEYPAIR, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}
iKonkeAfSelfPrint("Gateway_IEEE_Addr_Save result = %d\r\n",st);
return st;
}
/*********************************************************************
* @fn Get MFG CODE
*
* @brief
*
* @param None
*
* @return
*/
uint16_t MFG_Code_Get(void)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_KEYPAIR, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st != NV_SUCC){
mfg_code_temp = 0;
}
return mfg_code_temp;
}
/*********************************************************************
* @fn Save mfg_code
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t MFG_Code_Save(uint16_t mfgcode)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_KEYPAIR, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st == NV_SUCC){
if(mfg_code_temp != mfgcode)
st = nv_flashWriteNew(1, NV_MODULE_KEYPAIR, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_KEYPAIR, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
}
iKonkeAfSelfPrint("MFG_CODE_Save result = %d\r\n",st);
return st;
}
/*********************************************************************
* @fn Get age test step
*
* @brief
*
* @param None
*
* @return
*/
uint8_t kGetAgingTestValue(void)
{
nv_sts_t st = NV_SUCC;
uint8_t temp;
st = nv_flashReadNew(1, NV_MODULE_KEYPAIR, NV_AGE_TEST_STEP, sizeof(temp), (u8*)&temp);
iKonkeAfSelfPrint("kGetAgingTestValue:st = %d,data = %d\r\n",st,temp);
if(st != NV_SUCC){
temp = 0;
}
return temp;
}
/*********************************************************************
* @fn Save age test step
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t kSetAgingTestValue(uint8_t value)
{
nv_sts_t st = NV_SUCC;
uint8_t temp;
st = nv_flashReadNew(1, NV_MODULE_KEYPAIR, NV_AGE_TEST_STEP, sizeof(uint8_t), (u8*)&temp);
if(st == NV_SUCC){
if(temp != value)
{
st = nv_flashWriteNew(1, NV_MODULE_KEYPAIR, NV_AGE_TEST_STEP, sizeof(uint8_t), (u8*)&value);
iKonkeAfSelfPrint("kSetAgingTestValue:st = %d,data = %d\r\n",st,value);
}
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_KEYPAIR, NV_AGE_TEST_STEP, sizeof(uint8_t), (u8*)&value);
}
return st;
}
bool kGetIndicatorNotDisturbModeFlg(void)
{
nv_sts_t st = NV_SUCC;
uint8_t temp;
st = nv_flashReadNew(1, NV_MODULE_KEYPAIR, NV_NO_DISTURB_MODE, sizeof(temp), (u8*)&temp);
if(st != NV_SUCC){
temp = 0;
iKonkeAfSelfPrint("kGetIndicatorNotDisturbModeFlg failed!!\r\n");
}
return (temp == 1) ;
}
nv_sts_t kSetIndicatorNotDisturbModeFlg(uint8_t value)
{
nv_sts_t st = NV_SUCC;
st = nv_flashWriteNew(1, NV_MODULE_KEYPAIR, NV_NO_DISTURB_MODE, sizeof(uint8_t), (u8*)&value);
if(st != NV_SUCC)
{
iKonkeAfSelfPrint("kSetIndicatorNotDisturbModeFlg failed!!\r\n");
}
return st;
}
void falsh_test(void)
{
addrExt_t addr;
memcpy(addr,Gateway_IEEE_Addr_Get(),sizeof(addrExt_t));
iKonkeAfSelfPrint("flashRead11111:::\r\n");
DEBUG_ARRAY(1,addr,sizeof(addrExt_t));
addr[0] = 11;
addr[1] = 22;
Gateway_IEEE_Addr_Save(addr);
iKonkeAfSelfPrint("flashRead22222:::\r\n");
DEBUG_ARRAY(1,addr,sizeof(addrExt_t));
}
st = nv_flashReadNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)g_Eui64GatewayAddr);
iKonkeAfSelfPrint("flashRead:::\r\n");
DEBUG_ARRAY(1,g_Eui64GatewayAddr,sizeof(addrExt_t));
if(st != NV_SUCC){
memset(g_Eui64GatewayAddr,0xff,sizeof(addrExt_t));
}
return g_Eui64GatewayAddr;
}
/*********************************************************************
* @fn Save Gateway Addr
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t Gateway_IEEE_Addr_Save(addrExt_t addr)
{
nv_sts_t st = NV_SUCC;
addrExt_t temp_addr;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)temp_addr);
iKonkeAfSelfPrint("flashRead:::temp_addr\r\n");
DEBUG_ARRAY(1,temp_addr,sizeof(addrExt_t));
if(st == NV_SUCC){
if(memcmp(temp_addr,addr,sizeof(addrExt_t)))
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}
iKonkeAfSelfPrint("Gateway_IEEE_Addr_Save result = %d\r\n",st);
return st;
}
/*********************************************************************
* @fn Get MFG CODE
*
* @brief
*
* @param None
*
* @return
*/
uint16_t MFG_Code_Get(void)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st != NV_SUCC){
mfg_code_temp = 0;
}
return mfg_code_temp;
}
/*********************************************************************
* @fn Save mfg_code
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t MFG_Code_Save(uint16_t mfgcode)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st == NV_SUCC){
if(mfg_code_temp != mfgcode){
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
iKonkeAfSelfPrint("MFG_CODE_Save result = %d\r\n",st);
}
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
}
return st;
}
bool kGetIndicatorNotDisturbModeFlg(void)
{
nv_sts_t st = NV_SUCC;
uint8_t temp;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_NO_DISTURB_MODE, sizeof(temp), (u8*)&temp);
if(st != NV_SUCC){
temp = 0;
iKonkeAfSelfPrint("kGetIndicatorNotDisturbModeFlg failed!!\r\n");
}
iKonkeAfSelfPrint("Read st =%d,data=%d\r\n",st,temp);
return (temp == 1) ;
}
nv_sts_t kSetIndicatorNotDisturbModeFlg(uint8_t value)
{
nv_sts_t st = NV_SUCC;
uint8_t temp;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_NO_DISTURB_MODE, sizeof(temp), (u8*)&temp);
if(st == NV_SUCC){
if(temp != value)
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_NO_DISTURB_MODE, sizeof(uint8_t), (u8*)&value);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_NO_DISTURB_MODE, sizeof(uint8_t), (u8*)&value);
}
if(st != NV_SUCC)
{
iKonkeAfSelfPrint("kSetIndicatorNotDisturbModeFlg failed!!\r\n");
}
return st;
}
bool kGetInterpanEnableFlg(void)
{
nv_sts_t st = NV_SUCC;
uint8_t temp;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_INTERPAN_ENABLE_FLG, sizeof(temp), (u8*)&temp);
if(st != NV_SUCC){
temp = 1;
iKonkeAfSelfPrint("kGetInterpanEnableFlg failed!!\r\n");
}
return (temp == 1) ;
}
nv_sts_t kSetInterpanEnableFlg(uint8_t value)
{
nv_sts_t st = NV_SUCC;
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_INTERPAN_ENABLE_FLG, sizeof(uint8_t), (u8*)&value);
if(st != NV_SUCC)
{
iKonkeAfSelfPrint("kSetIndicatorNotDisturbModeFlg failed!!\r\n");
}
return st;
}
void Flash_Test_Save(uint8_t value)
{
uint8_t data = Flash_Test_Get();
if(value != data)
{
flash_read(TOKEN_USER_LOCATION,USER_SIZE,Flash_Buffer_Data);
iKonkeAfSelfPrintBuffer(Flash_Buffer_Data,USER_SIZE);
iKonkeAfSelfPrint("Erase Sector!!\r\n");
Flash_Buffer_Data[0] = value;
flash_erase(TOKEN_USER_LOCATION);
flash_write(TOKEN_USER_LOCATION,1,&value);
}
}
uint8_t Flash_Test_Get(void)
{
uint8_t value;
flash_read(TOKEN_USER_LOCATION,1,&value);
return value;
}
void Print_Flash_Data(void)
{
flash_read(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token);
iKonkeAfSelfPrint("install code :\r\n");
iKonkeAfSelfPrintBuffer(sOptunnel_Token.install_code.install_code_data,16);
iKonkeAfSelfPrint("modeid :len = %d\r\n",sOptunnel_Token.modeid.modeid_len);
iKonkeAfSelfPrintBuffer(sOptunnel_Token.modeid.modeid_data,32);
iKonkeAfSelfPrint("cmei :len = %d\r\n",32);
iKonkeAfSelfPrintBuffer(sOptunnel_Token.cmei.cmei_data,sOptunnel_Token.cmei.cmei_len);
iKonkeAfSelfPrint("isn :len = %d\r\n",sOptunnel_Token.isn.isn_len);
iKonkeAfSelfPrintBuffer(sOptunnel_Token.isn.isn_data,32);
uint8_t addr[254] = {0};
flash_read(CFG_MAC_ADDRESS,254,(uint8_t*)addr);
iKonkeAfSelfPrint("mac data::::\r\n");
iKonkeAfSelfPrintBuffer(addr,254);
}
uint8_t g_buffer[33] = {0};
uint8_t* General_Custom_Token_Get(uint8_t item)
{
flash_read(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token);
switch(item)
{
case CUSTOM_ITEMS_INSTALL_CODE:
{
memcpy(g_buffer,sOptunnel_Token.install_code.install_code_data,16);
break;
}
case CUSTOM_ITEMS_MODEL_ID:
{
if(sOptunnel_Token.modeid.modeid_len != 0xff)
memcpy(g_buffer,(uint8_t*)&sOptunnel_Token.modeid,sOptunnel_Token.modeid.modeid_len+1);
else{
g_buffer[0] = 32;
memset(g_buffer+1,0xff,32);
}
break;
}
case CUSTOM_ITEMS_CMEI_CODE:
{
if(sOptunnel_Token.cmei.cmei_len != 0xff)
memcpy(g_buffer,(uint8_t*)&sOptunnel_Token.cmei,sOptunnel_Token.cmei.cmei_len+1);
else{
g_buffer[0] = 32;
memset(g_buffer+1,0xff,32);
}
break;
}
case CUSTOM_ITEMS_ISN_CODE:
{
if(sOptunnel_Token.isn.isn_len != 0xff)
memcpy(g_buffer,(uint8_t*)&sOptunnel_Token.isn,sOptunnel_Token.isn.isn_len+1);
else{
g_buffer[0] = 32;
memset(g_buffer+1,0xff,32);
}
break;
}
default:
break;
}
return g_buffer;
}
uint8_t General_Custom_Token_Save(uint8_t item,uint8_t *buff,uint8_t len)
{
if((buff == NULL)||((len == 0)))
return 0xff;
if(len > 32)
return 0xfe;
OPTTUNEL_TOKEN_ST sOptunnel_Token_temp;
uint8_t rewrite_flash = 0;
uint8_t valid_len = 0;
iKonkeAfSelfPrint("will write data len =%d:\r\n",len);
iKonkeAfSelfPrintBuffer(buff,len);
flash_read(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token_temp);
switch(item)
{
case CUSTOM_ITEMS_INSTALL_CODE:
{
iKonkeAfSelfPrint("read install code:\r\n");
iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.install_code.install_code_data,16);
if(len >16)
return 0xfe;
if((!memcmp(sOptunnel_Token_temp.install_code.install_code_data,buff,len))
&&(All_Same_Data(&sOptunnel_Token_temp.install_code.install_code_data[len],0xff,16-len)))
{
//same data ,not need rewrite!
return 0;
}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.install_code.install_code_data,0xff,16)){
flash_write(TOKEN_USER_LOCATION+INSTALL_CODE_LOC_OFFSET,len,buff);
return 0;
}else{
memset(sOptunnel_Token_temp.install_code.install_code_data,0xff,16);
memcpy(sOptunnel_Token_temp.install_code.install_code_data,buff,len);
rewrite_flash = 1;
}
break;
}
case CUSTOM_ITEMS_MODEL_ID:
{
iKonkeAfSelfPrint("read modeid data len =%d:\r\n",sOptunnel_Token_temp.modeid.modeid_len);
iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.modeid.modeid_data,32);
valid_len = (sOptunnel_Token_temp.modeid.modeid_len > len)?sOptunnel_Token_temp.modeid.modeid_len :len;
if((!memcmp(sOptunnel_Token_temp.modeid.modeid_data,buff,len))
&&(All_Same_Data(&sOptunnel_Token_temp.modeid.modeid_data[len],0xff,32-len)))
{
//same data ,not need rewrite!
return 0;
}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.modeid,0xff,32)){
flash_write(TOKEN_USER_LOCATION+MODEL_ID_LOC_OFFSET,len,buff);
return 0;
}else{
sOptunnel_Token_temp.modeid.modeid_len = len;
memset(sOptunnel_Token_temp.modeid.modeid_data,0xff,valid_len);
memcpy(sOptunnel_Token_temp.modeid.modeid_data,buff,len);
rewrite_flash = 1;
}
break;
}
case CUSTOM_ITEMS_CMEI_CODE:
{
iKonkeAfSelfPrint("read cmei data len =%d:\r\n",sOptunnel_Token_temp.cmei.cmei_len);
iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.cmei.cmei_data,32);
valid_len = (sOptunnel_Token_temp.cmei.cmei_len > len)?sOptunnel_Token_temp.cmei.cmei_len :len;
if((!memcmp(sOptunnel_Token_temp.cmei.cmei_data,buff,len))
&&(All_Same_Data(&sOptunnel_Token_temp.cmei.cmei_data[len],0xff,32-len)))
{
//same data ,not need rewrite!
return 0;
}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.cmei,0xff,32)){
flash_write(TOKEN_USER_LOCATION+CMEI_LOC_OFFSET,len,buff);
return 0;
}else{
sOptunnel_Token_temp.cmei.cmei_len = len;
memset(sOptunnel_Token_temp.cmei.cmei_data,0xff,valid_len);
memcpy(sOptunnel_Token_temp.cmei.cmei_data,buff,len);
rewrite_flash = 1;
}
break;
}
case CUSTOM_ITEMS_ISN_CODE:
{
iKonkeAfSelfPrint("read isn data len =%d:\r\n",sOptunnel_Token_temp.isn.isn_len);
iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.isn.isn_data,32);
valid_len = (sOptunnel_Token_temp.isn.isn_len > len)?sOptunnel_Token_temp.isn.isn_len :len;
if((!memcmp(sOptunnel_Token_temp.isn.isn_data,buff,len))
&&(All_Same_Data(&sOptunnel_Token_temp.isn.isn_data[len],0xff,32-len)))
{
//same data ,not need rewrite!
return 0;
}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.isn,0xff,32)){
flash_write(TOKEN_USER_LOCATION+ISN_LOC_OFFSET,len,buff);
return 0;
}else{
sOptunnel_Token_temp.isn.isn_len = len;
memset(sOptunnel_Token_temp.isn.isn_data,0xff,valid_len);
memcpy(sOptunnel_Token_temp.isn.isn_data,buff,len);
rewrite_flash = 1;
}
break;
}
default:
break;
}
if(rewrite_flash){
flash_erase(TOKEN_USER_LOCATION);
flash_write(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token_temp);
Print_Flash_Data();
return 0;
}
return 0xfd;
}
void falsh_test(uint8_t count)
{
// uint8_t install_code1[] = {1,2,3,4,5,6,7,8,9,0x0a};
// uint8_t install_code2[] = {1,2,3,4,5,6,7,8,9,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
// if(count%2)
// General_Custom_Token_Save(CUSTOM_ITEMS_INSTALL_CODE,install_code1,sizeof(install_code1));
// else
// General_Custom_Token_Save(CUSTOM_ITEMS_INSTALL_CODE,install_code2,sizeof(install_code2));
// uint8_t *p = MODEL_ID_TOKEN_GET();
Print_Flash_Data();
// iKonkeAfSelfPrint("len =%d:\r\n",p[0]);
// iKonkeAfSelfPrintBuffer(p+1,32);
}
...@@ -4,6 +4,70 @@ ...@@ -4,6 +4,70 @@
#include "tl_common.h" #include "tl_common.h"
#define TOKEN_USER_LOCATION 0x78000
#define USER_SIZE 256
#define INSTALL_CODE_LOC_OFFSET 0 //16Byte //0
#define MODEL_ID_LOC_OFFSET 64 //33Byte //16+33
#define CMEI_LOC_OFFSET 64+64 //33Byte //16+33+33
#define ISN_LOC_OFFSET 64+64+64 //33Byte //16+33+33+33
enum{
CUSTOM_ITEMS_INSTALL_CODE = 1,
CUSTOM_ITEMS_MODEL_ID ,
CUSTOM_ITEMS_CMEI_CODE ,
CUSTOM_ITEMS_ISN_CODE ,
CUSTOM_ITEMS_RESERVED ,
}CUSTOM_ITEMS;
#define INSTALL_CODE_INDEX 0
#define MODEL_ID_INDEX 1
#define INSTALL_CODE_INDEX 0
#define INSTALL_CODE_INDEX 0
#define INSTALL_CODE_INDEX 0
typedef struct
{
struct{
uint8_t install_code_data[16];
uint8_t res[48];
}install_code;
struct{
uint8_t modeid_len;
uint8_t modeid_data[32];
uint8_t res[31];
}modeid;
struct{
uint8_t cmei_len;
uint8_t cmei_data[32];
uint8_t res[31];
}cmei;
struct{
uint8_t isn_len;
uint8_t isn_data[32];
uint8_t res[31];
}isn;
uint8_t reserved[32];
}OPTTUNEL_TOKEN_ST;
extern OPTTUNEL_TOKEN_ST sOptunnel_Token;
void Flash_Test_Save(uint8_t value);
uint8_t Flash_Test_Get(void);
uint8_t General_Custom_Token_Save(uint8_t item,uint8_t *buff,uint8_t len);
uint8_t *General_Custom_Token_Get(uint8_t item);
#define INSTALL_CODE_TOKEN_GET() (General_Custom_Token_Get(CUSTOM_ITEMS_INSTALL_CODE))
#define MODEL_ID_TOKEN_GET() (General_Custom_Token_Get(CUSTOM_ITEMS_MODEL_ID))
#define CMEI_TOKEN_GET() (General_Custom_Token_Get(CUSTOM_ITEMS_CMEI_CODE))
#define ISN_TOKEN_GET() (General_Custom_Token_Get(CUSTOM_ITEMS_ISN_CODE))
#define INSTALL_CODE_TOKEN_SET(buffer,len) (General_Custom_Token_Save(CUSTOM_ITEMS_INSTALL_CODE,buffer,len))
#define MODEL_ID_TOKEN_SET(buffer,len) (General_Custom_Token_Save(CUSTOM_ITEMS_MODEL_ID,buffer,len))
#define CMEI_TOKEN_SET(buffer,len) (General_Custom_Token_Save(CUSTOM_ITEMS_CMEI_CODE,buffer,len))
#define ISN_TOKEN_SET(buffer,len) (General_Custom_Token_Save(CUSTOM_ITEMS_ISN_CODE,buffer,len))
nv_sts_t Gateway_IEEE_Addr_Save(addrExt_t addr); nv_sts_t Gateway_IEEE_Addr_Save(addrExt_t addr);
...@@ -13,14 +77,12 @@ uint16_t MFG_Code_Get(void); ...@@ -13,14 +77,12 @@ uint16_t MFG_Code_Get(void);
nv_sts_t MFG_Code_Save(uint16_t mfgcode); nv_sts_t MFG_Code_Save(uint16_t mfgcode);
uint8_t kGetAgingTestValue(void);
nv_sts_t kSetAgingTestValue(uint8_t value);
bool kGetIndicatorNotDisturbModeFlg(void); bool kGetIndicatorNotDisturbModeFlg(void);
nv_sts_t kSetIndicatorNotDisturbModeFlg(uint8_t value); nv_sts_t kSetIndicatorNotDisturbModeFlg(uint8_t value);
#if 0 nv_sts_t kSetInterpanEnableFlg(uint8_t value);
void falsh_test(void); bool kGetInterpanEnableFlg(void);
#if 1
void falsh_test(uint8_t count);
#endif #endif
#endif /* _SAMPLE_LIGHT_H_ */ #endif /* _SAMPLE_LIGHT_H_ */
/******************************************************************************************************** /********************************************************************************************************
* @file firmwareEncryptChk.c * @file firmwareEncryptChk.c
* *
* @brief This is the source file for firmwareEncryptChk * @brief This is the source file for firmwareEncryptChk
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#include "tl_common.h" #include "tl_common.h"
#if UID_ENABLE #if UID_ENABLE
#include "firmware_encrypt.h" #include "firmware_encrypt.h"
#endif #endif
#include "firmwareEncryptChk.h" #include "firmwareEncryptChk.h"
/** /**
* @brief Only support for 8258/8278/b91, if you want to this function, please contact to us. * @brief Only support for 8258/8278/b91, if you want to this function, please contact to us.
*/ */
u8 firmwareCheckWithUID(void) u8 firmwareCheckWithUID(void)
{ {
#if UID_ENABLE #if UID_ENABLE
u32 flash_mid = 0; u32 flash_mid = 0;
u8 flash_uid[16] = {0}; u8 flash_uid[16] = {0};
int flag = flash_read_mid_uid_with_check(&flash_mid, flash_uid); int flag = flash_read_mid_uid_with_check(&flash_mid, flash_uid);
if(flag == 0){ if(flag == 0){
return 1; return 1;
} }
u8 ciphertext[16] = {0}; u8 ciphertext[16] = {0};
firmware_encrypt_based_on_uid(flash_uid, ciphertext); firmware_encrypt_based_on_uid(flash_uid, ciphertext);
u8 code[16] = {0}; u8 code[16] = {0};
flash_read(CFG_FIRMWARE_ENCRYPTION, 16, code); flash_read(CFG_FIRMWARE_ENCRYPTION, 16, code);
if(memcmp(ciphertext, code, 16)){ if(memcmp(ciphertext, code, 16)){
return 1; return 1;
} }
#endif #endif
return 0; return 0;
} }
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "ikk-token.h" #include "ikk-token.h"
extern addrExt_t g_Eui64GatewayAddr; extern addrExt_t g_Eui64GatewayAddr;
/********************************************************************* /*********************************************************************
* @fn Get Gateway Addr * @fn Get Gateway Addr
* *
* @brief * @brief
* *
* @param None * @param None
* *
* @return * @return
*/ */
uint8_t* Gateway_IEEE_Addr_Get(void) uint8_t* Gateway_IEEE_Addr_Get(void)
{ {
nv_sts_t st = NV_SUCC; nv_sts_t st = NV_SUCC;
st = nv_flashReadNew(1, NV_MODULE_USER, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)g_Eui64GatewayAddr);
iKonkeAfSelfPrint("flashRead:::\r\n");
DEBUG_ARRAY(1,g_Eui64GatewayAddr,sizeof(addrExt_t));
if(st != NV_SUCC){
memset(g_Eui64GatewayAddr,0xff,sizeof(addrExt_t));
}
return g_Eui64GatewayAddr;
}
/*********************************************************************
* @fn Save Gateway Addr
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t Gateway_IEEE_Addr_Save(addrExt_t addr)
{
nv_sts_t st = NV_SUCC;
addrExt_t temp_addr;
st = nv_flashReadNew(1, NV_MODULE_USER, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)temp_addr);
iKonkeAfSelfPrint("flashRead:::temp_addr\r\n");
DEBUG_ARRAY(1,temp_addr,sizeof(addrExt_t));
if(st == NV_SUCC){
if(memcmp(temp_addr,addr,sizeof(addrExt_t)))
st = nv_flashWriteNew(1, NV_MODULE_USER, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_USER, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}
iKonkeAfSelfPrint("Gateway_IEEE_Addr_Save result = %d\r\n",st);
return st;
}
/*********************************************************************
* @fn Get MFG CODE
*
* @brief
*
* @param None
*
* @return
*/
uint16_t MFG_Code_Get(void)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_USER, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st != NV_SUCC){
mfg_code_temp = 0;
}
return mfg_code_temp;
}
/*********************************************************************
* @fn Save mfg_code
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t MFG_Code_Save(uint16_t mfgcode)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_USER, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st == NV_SUCC){
if(mfg_code_temp != mfgcode)
st = nv_flashWriteNew(1, NV_MODULE_USER, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_USER, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
}
iKonkeAfSelfPrint("MFG_CODE_Save result = %d\r\n",st);
return st;
}
void falsh_test(void)
{
addrExt_t addr;
memcpy(addr,Gateway_IEEE_Addr_Get(),sizeof(addrExt_t));
iKonkeAfSelfPrint("flashRead11111:::\r\n");
DEBUG_ARRAY(1,addr,sizeof(addrExt_t));
addr[0] = 11;
addr[1] = 22;
Gateway_IEEE_Addr_Save(addr);
iKonkeAfSelfPrint("flashRead22222:::\r\n");
DEBUG_ARRAY(1,addr,sizeof(addrExt_t));
}
st = nv_flashReadNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)g_Eui64GatewayAddr);
iKonkeAfSelfPrint("flashRead:::\r\n");
DEBUG_ARRAY(1,g_Eui64GatewayAddr,sizeof(addrExt_t));
if(st != NV_SUCC){
memset(g_Eui64GatewayAddr,0xff,sizeof(addrExt_t));
}
return g_Eui64GatewayAddr;
}
/*********************************************************************
* @fn Save Gateway Addr
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t Gateway_IEEE_Addr_Save(addrExt_t addr)
{
nv_sts_t st = NV_SUCC;
addrExt_t temp_addr;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)temp_addr);
iKonkeAfSelfPrint("flashRead:::temp_addr\r\n");
DEBUG_ARRAY(1,temp_addr,sizeof(addrExt_t));
if(st == NV_SUCC){
if(memcmp(temp_addr,addr,sizeof(addrExt_t)))
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
}
iKonkeAfSelfPrint("Gateway_IEEE_Addr_Save result = %d\r\n",st);
return st;
}
/*********************************************************************
* @fn Get MFG CODE
*
* @brief
*
* @param None
*
* @return
*/
uint16_t MFG_Code_Get(void)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st != NV_SUCC){
mfg_code_temp = 0;
}
return mfg_code_temp;
}
/*********************************************************************
* @fn Save mfg_code
*
* @brief
*
* @param None
*
* @return
*/
nv_sts_t MFG_Code_Save(uint16_t mfgcode)
{
nv_sts_t st = NV_SUCC;
uint16_t mfg_code_temp;
st = nv_flashReadNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
if(st == NV_SUCC){
if(mfg_code_temp != mfgcode)
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
}else if(st == NV_ITEM_NOT_FOUND){
st = nv_flashWriteNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
}
iKonkeAfSelfPrint("MFG_CODE_Save result = %d\r\n",st);
return st;
}
void falsh_test(void)
{
addrExt_t addr;
memcpy(addr,Gateway_IEEE_Addr_Get(),sizeof(addrExt_t));
iKonkeAfSelfPrint("flashRead11111:::\r\n");
DEBUG_ARRAY(1,addr,sizeof(addrExt_t));
addr[0] = 11;
addr[1] = 22;
Gateway_IEEE_Addr_Save(addr);
iKonkeAfSelfPrint("flashRead22222:::\r\n");
DEBUG_ARRAY(1,addr,sizeof(addrExt_t));
}
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>tl_zigbee_sdk</name> <name>tl_zigbee_sdk</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>
<buildSpec> <buildSpec>
<buildCommand> <buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers> <triggers>clean,full,incremental,</triggers>
<arguments> <arguments>
<dictionary> <dictionary>
<key>?name?</key> <key>?name?</key>
<value></value> <value></value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key> <key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value> <value>true</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key> <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value> <value>all</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key> <key>org.eclipse.cdt.make.core.buildArguments</key>
<value>-j4</value> <value>-j4</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key> <key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value> <value>make</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key> <key>org.eclipse.cdt.make.core.buildLocation</key>
<value>${workspace_loc:/tl_zigbee_sdk/Debug}</value> <value>${workspace_loc:/tl_zigbee_sdk/Debug}</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key> <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value> <value>clean</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.contents</key> <key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value> <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key> <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value> <value>false</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key> <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value> <value>true</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key> <key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value> <value>true</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key> <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value> <value>all</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key> <key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value> <value>true</value>
</dictionary> </dictionary>
<dictionary> <dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key> <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>false</value> <value>false</value>
</dictionary> </dictionary>
</arguments> </arguments>
</buildCommand> </buildCommand>
<buildCommand> <buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers> <triggers>full,incremental,</triggers>
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
</buildSpec> </buildSpec>
<natures> <natures>
<nature>org.eclipse.cdt.core.cnature</nature> <nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>com.telink.tc32eclipse.core.TC32nature</nature> <nature>com.telink.tc32eclipse.core.TC32nature</nature>
</natures> </natures>
<linkedResources> <linkedResources>
<link> <link>
<name>apps</name> <name>apps</name>
<type>2</type> <type>2</type>
<locationURI>virtual:/virtual</locationURI> <locationURI>virtual:/virtual</locationURI>
</link> </link>
<link> <link>
<name>div_mod.S</name> <name>div_mod.S</name>
<type>1</type> <type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/tc32/div_mod.S</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/tc32/div_mod.S</locationURI>
</link> </link>
<link> <link>
<name>platform</name> <name>platform</name>
<type>2</type> <type>2</type>
<locationURI>virtual:/virtual</locationURI> <locationURI>virtual:/virtual</locationURI>
</link> </link>
<link> <link>
<name>proj</name> <name>proj</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/proj</locationURI> <locationURI>PARENT-2-PROJECT_LOC/proj</locationURI>
</link> </link>
<link> <link>
<name>zbhci</name> <name>zbhci</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/zbhci</locationURI> <locationURI>PARENT-2-PROJECT_LOC/zbhci</locationURI>
</link> </link>
<link> <link>
<name>zigbee</name> <name>zigbee</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/zigbee</locationURI> <locationURI>PARENT-2-PROJECT_LOC/zigbee</locationURI>
</link> </link>
<link> <link>
<name>apps/3LightPanelDemo</name> <name>apps/3LightPanelDemo</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/apps/3LightPanelDemo</locationURI> <locationURI>PARENT-2-PROJECT_LOC/apps/3LightPanelDemo</locationURI>
</link> </link>
<link> <link>
<name>apps/bootLoader</name> <name>apps/bootLoader</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/apps/bootLoader</locationURI> <locationURI>PARENT-2-PROJECT_LOC/apps/bootLoader</locationURI>
</link> </link>
<link> <link>
<name>apps/common</name> <name>apps/common</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/apps/common</locationURI> <locationURI>PARENT-2-PROJECT_LOC/apps/common</locationURI>
</link> </link>
<link> <link>
<name>apps/sampleContactSensor</name> <name>apps/sampleContactSensor</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/apps/sampleContactSensor</locationURI> <locationURI>PARENT-2-PROJECT_LOC/apps/sampleContactSensor</locationURI>
</link> </link>
<link> <link>
<name>apps/sampleGW</name> <name>apps/sampleGW</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/apps/sampleGW</locationURI> <locationURI>PARENT-2-PROJECT_LOC/apps/sampleGW</locationURI>
</link> </link>
<link> <link>
<name>apps/sampleLight</name> <name>apps/sampleLight</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/apps/sampleLight</locationURI> <locationURI>PARENT-2-PROJECT_LOC/apps/sampleLight</locationURI>
</link> </link>
<link> <link>
<name>apps/sampleSwitch</name> <name>apps/sampleSwitch</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/apps/sampleSwitch</locationURI> <locationURI>PARENT-2-PROJECT_LOC/apps/sampleSwitch</locationURI>
</link> </link>
<link> <link>
<name>platform/boot</name> <name>platform/boot</name>
<type>2</type> <type>2</type>
<locationURI>virtual:/virtual</locationURI> <locationURI>virtual:/virtual</locationURI>
</link> </link>
<link> <link>
<name>platform/chip_8258</name> <name>platform/chip_8258</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/chip_8258</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/chip_8258</locationURI>
</link> </link>
<link> <link>
<name>platform/chip_826x</name> <name>platform/chip_826x</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/chip_826x</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/chip_826x</locationURI>
</link> </link>
<link> <link>
<name>platform/chip_8278</name> <name>platform/chip_8278</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/chip_8278</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/chip_8278</locationURI>
</link> </link>
<link> <link>
<name>platform/firmware_encrypt.h</name> <name>platform/firmware_encrypt.h</name>
<type>1</type> <type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/tc32/firmware_encrypt.h</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/tc32/firmware_encrypt.h</locationURI>
</link> </link>
<link> <link>
<name>platform/libfirmware_encrypt.a</name> <name>platform/libfirmware_encrypt.a</name>
<type>1</type> <type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/tc32/libfirmware_encrypt.a</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/tc32/libfirmware_encrypt.a</locationURI>
</link> </link>
<link> <link>
<name>platform/platform.h</name> <name>platform/platform.h</name>
<type>1</type> <type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/platform.h</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/platform.h</locationURI>
</link> </link>
<link> <link>
<name>platform/services</name> <name>platform/services</name>
<type>2</type> <type>2</type>
<locationURI>virtual:/virtual</locationURI> <locationURI>virtual:/virtual</locationURI>
</link> </link>
<link> <link>
<name>apps/common/00ikonke_app</name> <name>apps/common/00ikonke_app</name>
<type>2</type> <type>2</type>
<location>E:/TeLin_Zigbee_SDK/tl_zigbee_sdk/apps/common/00ikonke_app</location> <location>E:/telin_zigbee_sdk/tl_zigbee_sdk/apps/common/00ikonke_app</location>
</link> </link>
<link> <link>
<name>platform/boot/8258</name> <name>platform/boot/8258</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/boot/8258</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/boot/8258</locationURI>
</link> </link>
<link> <link>
<name>platform/boot/826x</name> <name>platform/boot/826x</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/boot/826x</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/boot/826x</locationURI>
</link> </link>
<link> <link>
<name>platform/boot/8278</name> <name>platform/boot/8278</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/boot/8278</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/boot/8278</locationURI>
</link> </link>
<link> <link>
<name>platform/boot/link_cfg.S</name> <name>platform/boot/link_cfg.S</name>
<type>1</type> <type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/boot/link_cfg.S</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/boot/link_cfg.S</locationURI>
</link> </link>
<link> <link>
<name>platform/services/irq_handler.c</name> <name>platform/services/irq_handler.c</name>
<type>1</type> <type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/platform/services/b85m/irq_handler.c</locationURI> <locationURI>PARENT-2-PROJECT_LOC/platform/services/b85m/irq_handler.c</locationURI>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>
/******************************************************************************************************** /********************************************************************************************************
* @file boot_8258.link * @file boot_8258.link
* *
* @brief This is the link file for B85 * @brief This is the link file for B85
* *
* @author Driver & Zigbee Group * @author Driver & Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
/* to tell the linker the program begin from __start label in cstartup.s, thus do not treat it as a unused symbol */ /* to tell the linker the program begin from __start label in cstartup.s, thus do not treat it as a unused symbol */
ENTRY(__start) ENTRY(__start)
SECTIONS SECTIONS
{ {
. = 0x0; . = 0x0;
.vectors : .vectors :
{ {
*(.vectors) *(.vectors)
*(.vectors.*) /* MUST as follows, when compile with -ffunction-sections -fdata-sections, session name may changed */ *(.vectors.*) /* MUST as follows, when compile with -ffunction-sections -fdata-sections, session name may changed */
} }
. = (. * (1 - __BOOT_LOADER_IMAGE)) + (__FW_RAMCODE_SIZE_MAX * __BOOT_LOADER_IMAGE); . = (. * (1 - __BOOT_LOADER_IMAGE)) + (__FW_RAMCODE_SIZE_MAX * __BOOT_LOADER_IMAGE);
.ram_code : .ram_code :
{ {
*(.ram_code) *(.ram_code)
*(.ram_code.*) *(.ram_code.*)
} }
. = (((. + 15) / 16)*16); /* must 16 byte align if use "AT" for ".text" */ . = (((. + 15) / 16)*16); /* must 16 byte align if use "AT" for ".text" */
PROVIDE(_rstored_ = . ); PROVIDE(_rstored_ = . );
PROVIDE(_ramcode_size_ = . ); PROVIDE(_ramcode_size_ = . );
PROVIDE(_ramcode_size_div_16_ = (. + 15 ) / 16); PROVIDE(_ramcode_size_div_16_ = (. + 15 ) / 16);
PROVIDE(_ramcode_size_div_256_ = (. + 255) / 256); PROVIDE(_ramcode_size_div_256_ = (. + 255) / 256);
PROVIDE(_ramcode_size_div_16_align_256_ = ( (. + 255) / 256) * 16); PROVIDE(_ramcode_size_div_16_align_256_ = ( (. + 255) / 256) * 16);
PROVIDE(_ramcode_size_align_256_ = ( (. + 255) / 256) * 256); PROVIDE(_ramcode_size_align_256_ = ( (. + 255) / 256) * 256);
. = (_rstored_ + __FW_OFFSET); . = (_rstored_ + __FW_OFFSET);
.text : .text :
AT(_rstored_) AT(_rstored_)
{ {
*(.text) *(.text)
*(.text.*) *(.text.*)
} }
.rodata : .rodata :
{ {
*(.rodata) *(.rodata)
*(.rodata.*) *(.rodata.*)
} }
. = (((. + 3) / 4)*4); . = (((. + 3) / 4)*4);
PROVIDE(_dstored_ = .); /*location in flash*/ PROVIDE(_dstored_ = .); /*location in flash*/
PROVIDE(_dstored_bin_ = . - __FW_OFFSET); /*location in bin*/ PROVIDE(_dstored_bin_ = . - __FW_OFFSET); /*location in bin*/
PROVIDE(_code_size_ = . - __FW_OFFSET); PROVIDE(_code_size_ = . - __FW_OFFSET);
. = 0x840900 + _ramcode_size_align_256_; . = 0x840900 + _ramcode_size_align_256_;
.data : .data :
AT ( _dstored_bin_ ) AT ( _dstored_bin_ )
{ {
. = (((. + 3) / 4)*4); . = (((. + 3) / 4)*4);
PROVIDE(_start_data_ = . ); PROVIDE(_start_data_ = . );
*(.data); *(.data);
*(.data.*); *(.data.*);
. = (((. + 3) / 4)*4); . = (((. + 3) / 4)*4);
PROVIDE(_end_data_ = . ); PROVIDE(_end_data_ = . );
} }
.bss : .bss :
{ {
. = (((. + 3) / 4)*4); . = (((. + 3) / 4)*4);
PROVIDE(_start_bss_ = .); PROVIDE(_start_bss_ = .);
*(.sbss) *(.sbss)
*(.sbss.*) *(.sbss.*)
*(.bss) *(.bss)
*(.bss.*) *(.bss.*)
} }
PROVIDE(_end_bss_ = .); PROVIDE(_end_bss_ = .);
/* ASSERT((_end_bss_ < 0x848000), "RETENTION OVERFOLWN!!!!!") */ /* ASSERT((_end_bss_ < 0x848000), "RETENTION OVERFOLWN!!!!!") */
. = (((. + 3) / 4)*4); . = (((. + 3) / 4)*4);
PROVIDE(_custom_stored_ = _dstored_ + _end_data_ - _start_data_); PROVIDE(_custom_stored_ = _dstored_ + _end_data_ - _start_data_);
PROVIDE(_custom_stored_bin_ = _dstored_bin_ + _end_data_ - _start_data_); PROVIDE(_custom_stored_bin_ = _dstored_bin_ + _end_data_ - _start_data_);
.custom_data : .custom_data :
AT ( _custom_stored_bin_ ) AT ( _custom_stored_bin_ )
{ {
PROVIDE(_start_custom_data_ = .); PROVIDE(_start_custom_data_ = .);
*(.custom_data); *(.custom_data);
*(.custom_data.*); *(.custom_data.*);
PROVIDE(_end_custom_data_ = .); PROVIDE(_end_custom_data_ = .);
} }
.custom_bss(NOLOAD) : .custom_bss(NOLOAD) :
{ {
PROVIDE(_start_custom_bss_ = .); PROVIDE(_start_custom_bss_ = .);
*(.custom_bss); *(.custom_bss);
*(.custom_bss.*); *(.custom_bss.*);
PROVIDE(_end_custom_bss_ = .); PROVIDE(_end_custom_bss_ = .);
} }
PROVIDE(_bin_size_ = _code_size_ + _end_data_ - _start_data_ + _end_custom_data_ - _start_custom_data_); PROVIDE(_bin_size_ = _code_size_ + _end_data_ - _start_data_ + _end_custom_data_ - _start_custom_data_);
PROVIDE(_bin_size_div_16 = ( _bin_size_ + 15 ) / 16 ); PROVIDE(_bin_size_div_16 = ( _bin_size_ + 15 ) / 16 );
PROVIDE(_ictag_start_ = 0x840000 + _ramcode_size_align_256_); PROVIDE(_ictag_start_ = 0x840000 + _ramcode_size_align_256_);
PROVIDE(_ictag_end_ = 0x840000 + _ramcode_size_align_256_ + 0x100); PROVIDE(_ictag_end_ = 0x840000 + _ramcode_size_align_256_ + 0x100);
PROVIDE(_stack_end_ = (((_end_custom_bss_ + 0x800) + 255) / 256 ) * 256); PROVIDE(_stack_end_ = (((_end_custom_bss_ + 0x800) + 255) / 256 ) * 256);
ASSERT((_stack_end_ < 0x850000), "STACK OVERFOLWN!!!!!") ASSERT((_stack_end_ < 0x850000), "STACK OVERFOLWN!!!!!")
} }
\ No newline at end of file
/******************************************************************************************************** /********************************************************************************************************
* @file tlPrintf.h * @file tlPrintf.h
* *
* @brief This is the header file for tlPrintf * @brief This is the header file for tlPrintf
* *
* @author Driver & Zigbee Group * @author Driver & Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#pragma once #pragma once
#if defined(MCU_CORE_B91) #if defined(MCU_CORE_B91)
#include <stdio.h> #include <stdio.h>
#endif #endif
#if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278) #if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278)
int Tl_printf(const char *format, ...); int Tl_printf(const char *format, ...);
#endif #endif
#define SKD_LOG_ENABLE FALSE
#if (UART_PRINTF_MODE || USB_PRINTF_MODE)
#if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278) #if (UART_PRINTF_MODE || USB_PRINTF_MODE)
#define printf Tl_printf #if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278)
#endif #define printf Tl_printf
#endif
#define TRACE printf
#define DEBUG(compileFlag, ...) do{ \ #define TRACE printf
if(compileFlag) TRACE(__VA_ARGS__); \
}while(0) #define DEBUG(compileFlag, ...) do{ \
if(compileFlag) TRACE(__VA_ARGS__); \
#define DEBUG_ARRAY(compileFlag, arrayAddr, len) do{ \ }while(0)
if(compileFlag){ \
TRACE("*********************************\n"); \ #define DEBUG_ARRAY(compileFlag, arrayAddr, len) do{ \
unsigned char i = 0; \ if(compileFlag){ \
do{ \ TRACE("*********************************\n"); \
TRACE(" %x", ((unsigned char *)arrayAddr)[i++]); \ unsigned char i = 0; \
}while(i < len); \ do{ \
TRACE("\n*********************************\n"); \ TRACE(" %x", ((unsigned char *)arrayAddr)[i++]); \
} \ }while(i < len); \
}while(0) TRACE("\n*********************************\n"); \
#else } \
#if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278) }while(0)
#define printf #if SKD_LOG_ENABLE
#endif #define sdk_printf printf
#else
#define TRACE #define sdk_printf
#define DEBUG(compileFlag, ...) #endif
#define DEBUG_ARRAY(compileFlag, arrayAddr, len) #else
#endif #if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278)
#define printf
#endif
#define TRACE
#define DEBUG(compileFlag, ...)
#define DEBUG_ARRAY(compileFlag, arrayAddr, len)
#endif
/******************************************************************************************************** /********************************************************************************************************
* @file drv_nv.c * @file drv_nv.c
* *
* @brief This is the source file for drv_nv * @brief This is the source file for drv_nv
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#include "../tl_common.h" #include "../tl_common.h"
#if FLASH_CAP_SIZE_1M #if FLASH_CAP_SIZE_1M
u32 g_u32MacFlashAddr = FLASH_ADDR_0F_MAC_ADDR_1M; u32 g_u32MacFlashAddr = FLASH_ADDR_0F_MAC_ADDR_1M;
u32 g_u32CfgFlashAddr = FLASH_ADDR_OF_F_CFG_INFO_1M; u32 g_u32CfgFlashAddr = FLASH_ADDR_OF_F_CFG_INFO_1M;
#else #else
u32 g_u32MacFlashAddr = FLASH_ADDR_OF_MAC_ADDR_512K; u32 g_u32MacFlashAddr = FLASH_ADDR_OF_MAC_ADDR_512K;
u32 g_u32CfgFlashAddr = FLASH_ADDR_OF_F_CFG_INFO_512K; u32 g_u32CfgFlashAddr = FLASH_ADDR_OF_F_CFG_INFO_512K;
#endif #endif
nv_sts_t nv_index_update(u16 id, u8 opSect, u16 opItemIdx, nv_info_idx_t *idx){ nv_sts_t nv_index_update(u16 id, u8 opSect, u16 opItemIdx, nv_info_idx_t *idx){
u32 idxStartAddr = MODULE_IDX_START(id, opSect); u32 idxStartAddr = MODULE_IDX_START(id, opSect);
flash_write(idxStartAddr+opItemIdx*sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)idx); flash_write(idxStartAddr+opItemIdx*sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)idx);
return NV_SUCC; return NV_SUCC;
} }
nv_sts_t nv_index_read(u16 id, u8 itemId, u16 len, u8 opSect, u32 totalItemNum, u16 *idxNo){ nv_sts_t nv_index_read(u16 id, u8 itemId, u16 len, u8 opSect, u32 totalItemNum, u16 *idxNo){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
u32 idxTotalNum = totalItemNum; u32 idxTotalNum = totalItemNum;
u32 idxStartAddr = MODULE_IDX_START(id, opSect) + (idxTotalNum) * sizeof(nv_info_idx_t); u32 idxStartAddr = MODULE_IDX_START(id, opSect) + (idxTotalNum) * sizeof(nv_info_idx_t);
u16 opItemIdx = idxTotalNum; u16 opItemIdx = idxTotalNum;
u16 readIdxNum = 4; u16 readIdxNum = 4;
nv_info_idx_t idxInfo[4]; nv_info_idx_t idxInfo[4];
u8 jump = 0; u8 jump = 0;
u8 itemFlag = ITEM_FIELD_VALID; u8 itemFlag = ITEM_FIELD_VALID;
u16 itemTotalSize = ITEM_TOTAL_LEN(len); u16 itemTotalSize = ITEM_TOTAL_LEN(len);
if(itemId == ITEM_FIELD_IDLE){ if(itemId == ITEM_FIELD_IDLE){
itemFlag = ITEM_FIELD_IDLE; itemFlag = ITEM_FIELD_IDLE;
itemTotalSize = 0xffff; itemTotalSize = 0xffff;
} }
ret = NV_ITEM_NOT_FOUND; ret = NV_ITEM_NOT_FOUND;
s32 i = 0; s32 i = 0;
while(idxTotalNum > 0){ while(idxTotalNum > 0){
readIdxNum = (idxTotalNum > 4) ? 4 : idxTotalNum; readIdxNum = (idxTotalNum > 4) ? 4 : idxTotalNum;
idxStartAddr -= readIdxNum * sizeof(nv_info_idx_t); idxStartAddr -= readIdxNum * sizeof(nv_info_idx_t);
opItemIdx -= readIdxNum; opItemIdx -= readIdxNum;
idxTotalNum -= readIdxNum; idxTotalNum -= readIdxNum;
flash_read(idxStartAddr, readIdxNum * sizeof(nv_info_idx_t), (u8*)idxInfo); flash_read(idxStartAddr, readIdxNum * sizeof(nv_info_idx_t), (u8*)idxInfo);
for(i = readIdxNum - 1; i >= 0; i--){ for(i = readIdxNum - 1; i >= 0; i--){
if(itemId != ITEM_FIELD_IDLE){ if(itemId != ITEM_FIELD_IDLE){
if(idxInfo[i].usedState == itemFlag && idxInfo[i].size == itemTotalSize && idxInfo[i].itemId == itemId){ if(idxInfo[i].usedState == itemFlag && idxInfo[i].size == itemTotalSize && idxInfo[i].itemId == itemId){
jump = 1; jump = 1;
break; break;
} }
}else{ }else{
if(idxInfo[i].usedState != itemFlag || idxInfo[i].size != itemTotalSize || idxInfo[i].itemId != itemId){ if(idxInfo[i].usedState != itemFlag || idxInfo[i].size != itemTotalSize || idxInfo[i].itemId != itemId){
jump = 1; jump = 1;
break; break;
} }
} }
} }
if(jump){ if(jump){
opItemIdx += i; opItemIdx += i;
*idxNo = opItemIdx; *idxNo = opItemIdx;
ret = NV_SUCC; ret = NV_SUCC;
break; break;
} }
} }
return ret; return ret;
} }
nv_sts_t nv_sector_read(u16 id, u8 sectTotalNum, nv_sect_info_t *sectInfo){ nv_sts_t nv_sector_read(u16 id, u8 sectTotalNum, nv_sect_info_t *sectInfo){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
nv_sect_info_t s; nv_sect_info_t s;
u32 moduleStartAddr = MODULES_START_ADDR(id); u32 moduleStartAddr = MODULES_START_ADDR(id);
s32 i = 0; s32 i = 0;
for(i = 0; i < sectTotalNum; i++){ for(i = 0; i < sectTotalNum; i++){
flash_read(moduleStartAddr, sizeof(nv_sect_info_t), (u8 *)&s); flash_read(moduleStartAddr, sizeof(nv_sect_info_t), (u8 *)&s);
if(s.usedFlag == NV_SECTOR_VALID && s.idName == id){ if(s.usedFlag == NV_SECTOR_VALID && s.idName == id){
memcpy(sectInfo, &s, sizeof(nv_sect_info_t)); memcpy(sectInfo, &s, sizeof(nv_sect_info_t));
break; break;
} }
moduleStartAddr += NV_SECTOR_SIZE(id); moduleStartAddr += NV_SECTOR_SIZE(id);
} }
if( i == sectTotalNum){ if( i == sectTotalNum){
ret = NV_ITEM_NOT_FOUND; ret = NV_ITEM_NOT_FOUND;
} }
return ret; return ret;
} }
nv_sts_t nv_write_item(u16 id, u8 itemId, u8 opSect, u16 opItemIdx, u16 len, u8 *buf, bool isFlashCopy){ nv_sts_t nv_write_item(u16 id, u8 itemId, u8 opSect, u16 opItemIdx, u16 len, u8 *buf, bool isFlashCopy){
/* write index to flash */ /* write index to flash */
nv_info_idx_t idxInfo; nv_info_idx_t idxInfo;
memset((u8 *)&idxInfo, 0, sizeof(nv_info_idx_t)); memset((u8 *)&idxInfo, 0, sizeof(nv_info_idx_t));
u32 idxStartAddr = MODULE_IDX_START(id, opSect); u32 idxStartAddr = MODULE_IDX_START(id, opSect);
u32 offset = 0; u32 offset = 0;
if(opItemIdx == 0){ if(opItemIdx == 0){
offset = MODULE_CONTEXT_START(id, opSect, len); offset = MODULE_CONTEXT_START(id, opSect, len);
}else{ }else{
flash_read(idxStartAddr + (opItemIdx - 1)*sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8*)&idxInfo); flash_read(idxStartAddr + (opItemIdx - 1)*sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8*)&idxInfo);
offset = ((idxInfo.offset + idxInfo.size + 3) & (~0x03)); offset = ((idxInfo.offset + idxInfo.size + 3) & (~0x03));
} }
idxInfo.usedState = ITEM_FIELD_OPERATION; idxInfo.usedState = ITEM_FIELD_OPERATION;
idxInfo.size = len + sizeof(itemHdr_t); idxInfo.size = len + sizeof(itemHdr_t);
idxInfo.offset = offset; idxInfo.offset = offset;
idxInfo.itemId = itemId; idxInfo.itemId = itemId;
flash_write(idxStartAddr+opItemIdx*sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)&idxInfo); flash_write(idxStartAddr+opItemIdx*sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)&idxInfo);
/* write context to flash */ /* write context to flash */
if(isFlashCopy){ if(isFlashCopy){
/* if need copy th data from flash, read it into ram, and then write it to flash */ /* if need copy th data from flash, read it into ram, and then write it to flash */
u8 copyLen = 48; u8 copyLen = 48;
u8 *pTemp = (u8 *)ev_buf_allocate(copyLen); u8 *pTemp = (u8 *)ev_buf_allocate(copyLen);
if(pTemp){ if(pTemp){
u8 wLen = 0; u8 wLen = 0;
u16 toalLen = idxInfo.size; //len; u16 toalLen = idxInfo.size; //len;
u32 sAddr = (u32)buf; u32 sAddr = (u32)buf;
u32 dAddr = idxInfo.offset; u32 dAddr = idxInfo.offset;
while(toalLen > 0){ while(toalLen > 0){
wLen = (toalLen > copyLen) ? copyLen : toalLen; wLen = (toalLen > copyLen) ? copyLen : toalLen;
flash_read(sAddr, wLen, pTemp); flash_read(sAddr, wLen, pTemp);
flash_write(dAddr, wLen, pTemp); flash_write(dAddr, wLen, pTemp);
toalLen -= wLen; toalLen -= wLen;
sAddr += wLen; sAddr += wLen;
dAddr += wLen; dAddr += wLen;
} }
ev_buf_free(pTemp); ev_buf_free(pTemp);
}else{ }else{
return NV_NOT_ENOUGH_SAPCE; return NV_NOT_ENOUGH_SAPCE;
} }
}else{ }else{
u32 checkSum = 0; u32 checkSum = 0;
itemHdr_t hdr; itemHdr_t hdr;
u32 payloadAddr = idxInfo.offset+sizeof(itemHdr_t); u32 payloadAddr = idxInfo.offset+sizeof(itemHdr_t);
for(s32 i = 0; i < len; i++){ for(s32 i = 0; i < len; i++){
checkSum += buf[i]; checkSum += buf[i];
} }
flash_write(payloadAddr, len, buf); flash_write(payloadAddr, len, buf);
/* check the checksum */ /* check the checksum */
u8 vCheck[16]; u8 vCheck[16];
u16 tLen = len; u16 tLen = len;
u16 unitLen; u16 unitLen;
u32 checkSumRead = 0; u32 checkSumRead = 0;
while(tLen > 0){ while(tLen > 0){
unitLen = (tLen > 16) ? 16 : tLen; unitLen = (tLen > 16) ? 16 : tLen;
flash_read(payloadAddr, unitLen, vCheck); flash_read(payloadAddr, unitLen, vCheck);
for(s32 i = 0; i < unitLen; i++){ for(s32 i = 0; i < unitLen; i++){
checkSumRead += vCheck[i]; checkSumRead += vCheck[i];
} }
tLen -= unitLen; tLen -= unitLen;
payloadAddr += unitLen; payloadAddr += unitLen;
} }
if(checkSum == checkSumRead){ if(checkSum == checkSumRead){
hdr.itemId = itemId; hdr.itemId = itemId;
hdr.size = len; hdr.size = len;
hdr.used = ITEM_FIELD_VALID; hdr.used = ITEM_FIELD_VALID;
hdr.checkSum = checkSum; hdr.checkSum = checkSum;
flash_write(idxInfo.offset, sizeof(itemHdr_t), (u8*)&hdr); flash_write(idxInfo.offset, sizeof(itemHdr_t), (u8*)&hdr);
}else{ }else{
return NV_CHECK_SUM_ERROR; return NV_CHECK_SUM_ERROR;
} }
} }
/* check the correct, if correct, change the state in the index */ /* check the correct, if correct, change the state in the index */
u8 staOffset = OFFSETOF(nv_info_idx_t, usedState); u8 staOffset = OFFSETOF(nv_info_idx_t, usedState);
idxInfo.usedState = ITEM_FIELD_VALID; idxInfo.usedState = ITEM_FIELD_VALID;
flash_write(idxStartAddr+opItemIdx*sizeof(nv_info_idx_t)+staOffset, 1, (u8 *)&idxInfo.usedState); flash_write(idxStartAddr+opItemIdx*sizeof(nv_info_idx_t)+staOffset, 1, (u8 *)&idxInfo.usedState);
return NV_SUCC; return NV_SUCC;
} }
nv_sts_t nv_flashReadByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx, u16 len, u8 *buf){ nv_sts_t nv_flashReadByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx, u16 len, u8 *buf){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
u32 idxStartAddr = MODULE_IDX_START(id, opSect); u32 idxStartAddr = MODULE_IDX_START(id, opSect);
nv_info_idx_t idx; nv_info_idx_t idx;
flash_read(idxStartAddr + opIdx * sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)&idx); flash_read(idxStartAddr + opIdx * sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)&idx);
if(idx.usedState != ITEM_FIELD_VALID){ if(idx.usedState != ITEM_FIELD_VALID){
return NV_ITEM_NOT_FOUND; return NV_ITEM_NOT_FOUND;
} }
itemHdr_t hdr; itemHdr_t hdr;
flash_read(idx.offset, sizeof(itemHdr_t), (u8*)&hdr); flash_read(idx.offset, sizeof(itemHdr_t), (u8*)&hdr);
if(hdr.size == len && hdr.used == ITEM_FIELD_VALID && hdr.itemId == itemId){ if(hdr.size == len && hdr.used == ITEM_FIELD_VALID && hdr.itemId == itemId){
flash_read(idx.offset + sizeof(itemHdr_t), len, buf); flash_read(idx.offset + sizeof(itemHdr_t), len, buf);
}else{ }else{
ret = NV_ITEM_NOT_FOUND; ret = NV_ITEM_NOT_FOUND;
} }
return ret; return ret;
} }
nv_sts_t nv_itemDeleteByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx){ nv_sts_t nv_itemDeleteByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
u32 idxStartAddr = MODULE_IDX_START(id, opSect); u32 idxStartAddr = MODULE_IDX_START(id, opSect);
nv_info_idx_t idx; nv_info_idx_t idx;
u8 staOffset = OFFSETOF(nv_info_idx_t, usedState); u8 staOffset = OFFSETOF(nv_info_idx_t, usedState);
idx.usedState = ITEM_FIELD_INVALID; idx.usedState = ITEM_FIELD_INVALID;
flash_write(idxStartAddr+opIdx*sizeof(nv_info_idx_t)+staOffset, 1, &(idx.usedState)); flash_write(idxStartAddr+opIdx*sizeof(nv_info_idx_t)+staOffset, 1, &(idx.usedState));
return ret; return ret;
} }
nv_sts_t nv_flashWriteNew(u8 single, u16 id, u8 itemId, u16 len, u8 *buf){ nv_sts_t nv_flashWriteNew(u8 single, u16 id, u8 itemId, u16 len, u8 *buf){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
nv_sect_info_t sectInfo; nv_sect_info_t sectInfo;
u8 opSect = 0; u8 opSect = 0;
u32 moduleStartAddr = MODULES_START_ADDR(id); u32 moduleStartAddr = MODULES_START_ADDR(id);
s32 i = 0; s32 i = 0;
/* check item length, if */ /* check item length, if */
if(NV_SECTOR_SIZE(id) < ITEM_TOTAL_LEN(len) + MODULE_INFO_SIZE(id)){ if(NV_SECTOR_SIZE(id) < ITEM_TOTAL_LEN(len) + MODULE_INFO_SIZE(id)){
return NV_NOT_ENOUGH_SAPCE; return NV_NOT_ENOUGH_SAPCE;
} }
/* search valid operation sub-sector */ /* search valid operation sub-sector */
ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo); ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo);
if(ret != NV_SUCC){ if(ret != NV_SUCC){
#if 0 #if 0
for(s32 j = 0; j < MODULE_SECTOR_NUM; j++){ for(s32 j = 0; j < MODULE_SECTOR_NUM; j++){
flash_erase(moduleStartAddr + j * FLASH_SECTOR_SIZE); flash_erase(moduleStartAddr + j * FLASH_SECTOR_SIZE);
} }
#endif #endif
opSect = 0; opSect = 0;
}else{ }else{
opSect = sectInfo.opSect; opSect = sectInfo.opSect;
} }
/* /*
* search the index, find a valid space to write * search the index, find a valid space to write
* read 4 indexes once */ * read 4 indexes once */
u32 idxStartAddr = MODULE_IDX_START(id, opSect); u32 idxStartAddr = MODULE_IDX_START(id, opSect);
u16 wItemIdx = 0; u16 wItemIdx = 0;
nv_info_idx_t idxInfo[4]; nv_info_idx_t idxInfo[4];
u8 sectorUpdate = 0; u8 sectorUpdate = 0;
s32 idxTotalNum = MODULE_IDX_NUM(id); s32 idxTotalNum = MODULE_IDX_NUM(id);
ret = nv_index_read(id, ITEM_FIELD_IDLE, len, opSect, idxTotalNum, &wItemIdx); ret = nv_index_read(id, ITEM_FIELD_IDLE, len, opSect, idxTotalNum, &wItemIdx);
if(ret == NV_SUCC){ if(ret == NV_SUCC){
flash_read(idxStartAddr + wItemIdx * sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)idxInfo ); flash_read(idxStartAddr + wItemIdx * sizeof(nv_info_idx_t), sizeof(nv_info_idx_t), (u8 *)idxInfo );
if((wItemIdx == idxTotalNum - 1) || if((wItemIdx == idxTotalNum - 1) ||
(idxInfo[0].offset + idxInfo[0].size + ITEM_TOTAL_LEN(len)) > MODULE_SECT_END(id, opSect)){ (idxInfo[0].offset + idxInfo[0].size + ITEM_TOTAL_LEN(len)) > MODULE_SECT_END(id, opSect)){
sectorUpdate = 1; sectorUpdate = 1;
}else{ }else{
wItemIdx += 1; wItemIdx += 1;
} }
} }
u8 oldSect = opSect; u8 oldSect = opSect;
if(sectorUpdate){ if(sectorUpdate){
wItemIdx = 0; wItemIdx = 0;
opSect = (opSect + 1) & (MODULE_SECTOR_NUM - 1); opSect = (opSect + 1) & (MODULE_SECTOR_NUM - 1);
u8 nv_realSectNum = NV_SECTOR_SIZE(id)/FLASH_SECTOR_SIZE; u8 nv_realSectNum = NV_SECTOR_SIZE(id)/FLASH_SECTOR_SIZE;
u32 eraseAddr = moduleStartAddr + opSect * NV_SECTOR_SIZE(id); u32 eraseAddr = moduleStartAddr + opSect * NV_SECTOR_SIZE(id);
for(s32 k = 0; k < nv_realSectNum; k++){ for(s32 k = 0; k < nv_realSectNum; k++){
//flash_erase(moduleStartAddr + opSect * FLASH_SECTOR_SIZE); //flash_erase(moduleStartAddr + opSect * FLASH_SECTOR_SIZE);
flash_erase(eraseAddr); flash_erase(eraseAddr);
eraseAddr += FLASH_SECTOR_SIZE; eraseAddr += FLASH_SECTOR_SIZE;
} }
u32 sizeusedAddr = 0; u32 sizeusedAddr = 0;
u8 readIdxNum = 0; u8 readIdxNum = 0;
sizeusedAddr = MODULE_CONTEXT_START(id, opSect, len); sizeusedAddr = MODULE_CONTEXT_START(id, opSect, len);
idxStartAddr = MODULE_IDX_START(id, oldSect); idxStartAddr = MODULE_IDX_START(id, oldSect);
idxTotalNum = MODULE_IDX_NUM(id); idxTotalNum = MODULE_IDX_NUM(id);
/* copy valid items to new sector */ /* copy valid items to new sector */
while(idxTotalNum > 0){ while(idxTotalNum > 0){
readIdxNum = (idxTotalNum > 4) ? 4 : idxTotalNum; readIdxNum = (idxTotalNum > 4) ? 4 : idxTotalNum;
flash_read(idxStartAddr, readIdxNum * sizeof(nv_info_idx_t), (u8*)idxInfo); flash_read(idxStartAddr, readIdxNum * sizeof(nv_info_idx_t), (u8*)idxInfo);
for( i = 0; i < readIdxNum; i++){ for( i = 0; i < readIdxNum; i++){
if(idxInfo[i].usedState == ITEM_FIELD_VALID && if(idxInfo[i].usedState == ITEM_FIELD_VALID &&
(idxInfo[i].itemId != itemId || ((idxInfo[i].itemId == itemId) && !single))){ (idxInfo[i].itemId != itemId || ((idxInfo[i].itemId == itemId) && !single))){
ret = nv_write_item(id, idxInfo[i].itemId, opSect, wItemIdx, idxInfo[i].size-sizeof(itemHdr_t), (u8*)idxInfo[i].offset, TRUE); ret = nv_write_item(id, idxInfo[i].itemId, opSect, wItemIdx, idxInfo[i].size-sizeof(itemHdr_t), (u8*)idxInfo[i].offset, TRUE);
if(ret != NV_SUCC){ if(ret != NV_SUCC){
return ret; return ret;
} }
sizeusedAddr += idxInfo[i].size; sizeusedAddr += idxInfo[i].size;
sizeusedAddr = ((sizeusedAddr + 0x03) & (~0x03)); sizeusedAddr = ((sizeusedAddr + 0x03) & (~0x03));
wItemIdx += 1; wItemIdx += 1;
} }
} }
idxTotalNum -= readIdxNum; idxTotalNum -= readIdxNum;
idxStartAddr += readIdxNum * sizeof(nv_info_idx_t); idxStartAddr += readIdxNum * sizeof(nv_info_idx_t);
} }
idxTotalNum = MODULE_IDX_NUM(id); idxTotalNum = MODULE_IDX_NUM(id);
if(wItemIdx == idxTotalNum || (sizeusedAddr + ITEM_TOTAL_LEN(len)) > MODULE_SECT_END(id, opSect)){ if(wItemIdx == idxTotalNum || (sizeusedAddr + ITEM_TOTAL_LEN(len)) > MODULE_SECT_END(id, opSect)){
return NV_NOT_ENOUGH_SAPCE; return NV_NOT_ENOUGH_SAPCE;
} }
} }
/* search the same item id, need to delete after update */ /* search the same item id, need to delete after update */
u8 deleteItemEn = 0; u8 deleteItemEn = 0;
u16 deleteIdx = 0; u16 deleteIdx = 0;
idxTotalNum = MODULE_IDX_NUM(id); idxTotalNum = MODULE_IDX_NUM(id);
if(single){ if(single){
if(NV_SUCC == nv_index_read(id, itemId, len, opSect, idxTotalNum, &deleteIdx)){ if(NV_SUCC == nv_index_read(id, itemId, len, opSect, idxTotalNum, &deleteIdx)){
deleteItemEn = 1; deleteItemEn = 1;
} }
} }
/* sector is full, and then need write in the another sector */ /* sector is full, and then need write in the another sector */
ret = nv_write_item(id, itemId, opSect, wItemIdx, len, buf, FALSE); ret = nv_write_item(id, itemId, opSect, wItemIdx, len, buf, FALSE);
/* the last item set as invalid */ /* the last item set as invalid */
idxStartAddr = MODULE_IDX_START(id, opSect); idxStartAddr = MODULE_IDX_START(id, opSect);
if(deleteItemEn){ if(deleteItemEn){
u8 staOffset = OFFSETOF(nv_info_idx_t, usedState); u8 staOffset = OFFSETOF(nv_info_idx_t, usedState);
idxInfo[0].usedState = ITEM_FIELD_INVALID; idxInfo[0].usedState = ITEM_FIELD_INVALID;
flash_write(idxStartAddr+deleteIdx*sizeof(nv_info_idx_t)+staOffset, 1, &(idxInfo[0].usedState)); flash_write(idxStartAddr+deleteIdx*sizeof(nv_info_idx_t)+staOffset, 1, &(idxInfo[0].usedState));
} }
if(ret == NV_SUCC){ if(ret == NV_SUCC){
if(sectorUpdate){ if(sectorUpdate){
sectInfo.idName = id; sectInfo.idName = id;
sectInfo.opSect = opSect; sectInfo.opSect = opSect;
sectInfo.usedFlag = NV_SECTOR_INVALID; sectInfo.usedFlag = NV_SECTOR_INVALID;
flash_write(MODULE_SECT_START(id, oldSect), sizeof(nv_sect_info_t), (u8*)&sectInfo); flash_write(MODULE_SECT_START(id, oldSect), sizeof(nv_sect_info_t), (u8*)&sectInfo);
sectInfo.usedFlag = NV_SECTOR_VALID; sectInfo.usedFlag = NV_SECTOR_VALID;
sectInfo.opSect = opSect; sectInfo.opSect = opSect;
flash_write(MODULE_SECT_START(id, opSect), sizeof(nv_sect_info_t), (u8*)&sectInfo); flash_write(MODULE_SECT_START(id, opSect), sizeof(nv_sect_info_t), (u8*)&sectInfo);
}else{ }else{
if(wItemIdx == 0){ if(wItemIdx == 0){
sectInfo.idName = id; sectInfo.idName = id;
sectInfo.usedFlag = NV_SECTOR_VALID; sectInfo.usedFlag = NV_SECTOR_VALID;
sectInfo.opSect = opSect; sectInfo.opSect = opSect;
flash_write(MODULE_SECT_START(id, opSect), sizeof(nv_sect_info_t), (u8*)&sectInfo); flash_write(MODULE_SECT_START(id, opSect), sizeof(nv_sect_info_t), (u8*)&sectInfo);
} }
} }
} }
return ret; return ret;
} }
nv_sts_t nv_flashReadNew(u8 single, u8 id, u8 itemId, u16 len, u8 *buf){ nv_sts_t nv_flashReadNew(u8 single, u8 id, u8 itemId, u16 len, u8 *buf){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
nv_sect_info_t sectInfo; nv_sect_info_t sectInfo;
u8 opSect = 0; u8 opSect = 0;
s32 idxTotalNum = 0; s32 idxTotalNum = 0;
u16 opIdx = 0; u16 opIdx = 0;
ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo); ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo);
if(ret != NV_SUCC){ if(ret != NV_SUCC){
return ret; return ret;
} }
opSect = sectInfo.opSect; opSect = sectInfo.opSect;
idxTotalNum = MODULE_IDX_NUM(id); idxTotalNum = MODULE_IDX_NUM(id);
ret = NV_ITEM_NOT_FOUND; ret = NV_ITEM_NOT_FOUND;
ret = nv_index_read(id, itemId, len, opSect, idxTotalNum, &opIdx); ret = nv_index_read(id, itemId, len, opSect, idxTotalNum, &opIdx);
if(single){ if(single){
if(ret == NV_SUCC){ if(ret == NV_SUCC){
ret = nv_flashReadByIndex(id, itemId, opSect, opIdx, len, buf); ret = nv_flashReadByIndex(id, itemId, opSect, opIdx, len, buf);
} }
}else{ }else{
itemIfno_t *pInfo = (itemIfno_t*)buf; itemIfno_t *pInfo = (itemIfno_t*)buf;
pInfo->opIndex = opIdx; pInfo->opIndex = opIdx;
pInfo->opSect = opSect; pInfo->opSect = opSect;
} }
return ret; return ret;
} }
nv_sts_t nv_nwkFrameCountSearch(u8 id, u8 opSect, u32 *frameCount, u32 *validAddr){ nv_sts_t nv_nwkFrameCountSearch(u8 id, u8 opSect, u32 *frameCount, u32 *validAddr){
nv_sts_t ret = NV_ITEM_NOT_FOUND; nv_sts_t ret = NV_ITEM_NOT_FOUND;
u16 frmCntTotalNum = FRAMECOUNT_NUM_PER_SECT(); u16 frmCntTotalNum = FRAMECOUNT_NUM_PER_SECT();
u32 sizeUsed = frmCntTotalNum * 4; u32 sizeUsed = frmCntTotalNum * 4;
u32 pageUsed = (sizeUsed & 0xff) ? sizeUsed/FLASH_PAGE_SIZE+1 : sizeUsed/FLASH_PAGE_SIZE; u32 pageUsed = (sizeUsed & 0xff) ? sizeUsed/FLASH_PAGE_SIZE+1 : sizeUsed/FLASH_PAGE_SIZE;
u16 checkSize = 0; u16 checkSize = 0;
*validAddr = FRAMECOUNT_PAYLOAD_START(opSect); *validAddr = FRAMECOUNT_PAYLOAD_START(opSect);
u32 *opPageAddr = (u32 *)(MODULE_SECT_END(id, opSect) - FLASH_PAGE_SIZE); u32 *opPageAddr = (u32 *)(MODULE_SECT_END(id, opSect) - FLASH_PAGE_SIZE);
s32 i = 0; s32 i = 0;
u32 checkValid[4]; u32 checkValid[4];
for(i = 0; i < pageUsed-1; i++){ for(i = 0; i < pageUsed-1; i++){
flash_read((u32)opPageAddr, 4, (u8 *)checkValid); flash_read((u32)opPageAddr, 4, (u8 *)checkValid);
if(checkValid[0] != 0xffffffff){ if(checkValid[0] != 0xffffffff){
checkSize = FLASH_PAGE_SIZE; checkSize = FLASH_PAGE_SIZE;
break; break;
}else{ }else{
*validAddr = (u32)opPageAddr; //???validAddr = opPageAddr; *validAddr = (u32)opPageAddr; //???validAddr = opPageAddr;
} }
opPageAddr -= FLASH_PAGE_SIZE/4; opPageAddr -= FLASH_PAGE_SIZE/4;
} }
if( i == pageUsed-1){ if( i == pageUsed-1){
opPageAddr = (u32 *)(FRAMECOUNT_PAYLOAD_START(opSect)); opPageAddr = (u32 *)(FRAMECOUNT_PAYLOAD_START(opSect));
checkSize = (FLASH_PAGE_SIZE - sizeof(nv_sect_info_t)) & (~0x03); checkSize = (FLASH_PAGE_SIZE - sizeof(nv_sect_info_t)) & (~0x03);
} }
opPageAddr = (u32 *)(((u32)opPageAddr + FLASH_PAGE_SIZE) & (~(FLASH_PAGE_SIZE - 1))); opPageAddr = (u32 *)(((u32)opPageAddr + FLASH_PAGE_SIZE) & (~(FLASH_PAGE_SIZE - 1)));
u8 unitSize = 16; u8 unitSize = 16;
while(checkSize){ while(checkSize){
u8 readSize = (checkSize > unitSize) ? unitSize : checkSize; u8 readSize = (checkSize > unitSize) ? unitSize : checkSize;
opPageAddr -= readSize/4; opPageAddr -= readSize/4;
checkSize -= readSize; checkSize -= readSize;
flash_read((u32)opPageAddr, readSize, (u8 *)checkValid); flash_read((u32)opPageAddr, readSize, (u8 *)checkValid);
if(checkValid[0] != 0xffffffff){ if(checkValid[0] != 0xffffffff){
*frameCount = checkValid[0]; *frameCount = checkValid[0];
for(s32 i = 1; i < readSize/4; i++){ for(s32 i = 1; i < readSize/4; i++){
if(checkValid[i] != 0xffffffff){ if(checkValid[i] != 0xffffffff){
*frameCount = checkValid[i]; *frameCount = checkValid[i];
if(i == (readSize/4 - 1)){ if(i == (readSize/4 - 1)){
*validAddr = (u32)(opPageAddr + i + 1); *validAddr = (u32)(opPageAddr + i + 1);
return NV_SUCC; return NV_SUCC;
} }
}else{ }else{
*validAddr = (u32)(opPageAddr + i); *validAddr = (u32)(opPageAddr + i);
return NV_SUCC; return NV_SUCC;
} }
} }
}else{ }else{
*validAddr = (u32)opPageAddr; *validAddr = (u32)opPageAddr;
} }
} }
return ret; return ret;
} }
nv_sts_t nv_nwkFrameCountSaveToFlash(u32 frameCount){ nv_sts_t nv_nwkFrameCountSaveToFlash(u32 frameCount){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
nv_sect_info_t sectInfo; nv_sect_info_t sectInfo;
u8 opSect = 0; u8 opSect = 0;
u8 id = NV_MODULE_NWK_FRAME_COUNT; u8 id = NV_MODULE_NWK_FRAME_COUNT;
u32 moduleStartAddr = MODULES_START_ADDR(id); u32 moduleStartAddr = MODULES_START_ADDR(id);
/* search valid operation sub-sector */ /* search valid operation sub-sector */
ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo); ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo);
if(ret != NV_SUCC){ if(ret != NV_SUCC){
for(s32 j = 0; j < MODULE_SECTOR_NUM; j++){ for(s32 j = 0; j < MODULE_SECTOR_NUM; j++){
flash_erase(moduleStartAddr + j * FLASH_SECTOR_SIZE); flash_erase(moduleStartAddr + j * FLASH_SECTOR_SIZE);
} }
opSect = 0; opSect = 0;
}else{ }else{
opSect = sectInfo.opSect; opSect = sectInfo.opSect;
} }
u32 lastFrmCnt; u32 lastFrmCnt;
u32 wAddr; u32 wAddr;
u8 oldSect = opSect; u8 oldSect = opSect;
u8 sectorUpdate = 0; u8 sectorUpdate = 0;
if(NV_SUCC == nv_nwkFrameCountSearch(id, opSect, &lastFrmCnt, &wAddr)){ if(NV_SUCC == nv_nwkFrameCountSearch(id, opSect, &lastFrmCnt, &wAddr)){
if(wAddr == (MODULE_SECT_END(id, opSect))){ if(wAddr == (MODULE_SECT_END(id, opSect))){
opSect = (opSect + 1) & (MODULE_SECTOR_NUM - 1); opSect = (opSect + 1) & (MODULE_SECTOR_NUM - 1);
flash_erase(moduleStartAddr + opSect * FLASH_SECTOR_SIZE); flash_erase(moduleStartAddr + opSect * FLASH_SECTOR_SIZE);
flash_write(FRAMECOUNT_PAYLOAD_START(opSect), 4, (u8*)&lastFrmCnt); flash_write(FRAMECOUNT_PAYLOAD_START(opSect), 4, (u8*)&lastFrmCnt);
wAddr = FRAMECOUNT_PAYLOAD_START(opSect) + 4; wAddr = FRAMECOUNT_PAYLOAD_START(opSect) + 4;
sectorUpdate = 1; sectorUpdate = 1;
} }
} }
flash_write(wAddr, 4, (u8*)&frameCount); flash_write(wAddr, 4, (u8*)&frameCount);
if(sectorUpdate || (wAddr == FRAMECOUNT_PAYLOAD_START(opSect))){ if(sectorUpdate || (wAddr == FRAMECOUNT_PAYLOAD_START(opSect))){
sectInfo.usedFlag = NV_SECTOR_VALID; sectInfo.usedFlag = NV_SECTOR_VALID;
sectInfo.opSect = opSect; sectInfo.opSect = opSect;
sectInfo.idName = id; sectInfo.idName = id;
flash_write((u32)MODULE_SECT_START(id, opSect), sizeof(nv_sect_info_t), (u8 *)&sectInfo); flash_write((u32)MODULE_SECT_START(id, opSect), sizeof(nv_sect_info_t), (u8 *)&sectInfo);
if(sectorUpdate){ if(sectorUpdate){
sectInfo.usedFlag = NV_SECTOR_INVALID; sectInfo.usedFlag = NV_SECTOR_INVALID;
flash_write((u32)MODULE_SECT_START(id, oldSect), sizeof(nv_sect_info_t), (u8 *)&sectInfo); flash_write((u32)MODULE_SECT_START(id, oldSect), sizeof(nv_sect_info_t), (u8 *)&sectInfo);
} }
} }
return ret; return ret;
} }
nv_sts_t nv_nwkFrameCountFromFlash(u32 *frameCount){ nv_sts_t nv_nwkFrameCountFromFlash(u32 *frameCount){
nv_sts_t ret = NV_SUCC; nv_sts_t ret = NV_SUCC;
u8 id = NV_MODULE_NWK_FRAME_COUNT; u8 id = NV_MODULE_NWK_FRAME_COUNT;
nv_sect_info_t sectInfo; nv_sect_info_t sectInfo;
u32 lastFrmCnt; u32 lastFrmCnt;
u32 wAddr; u32 wAddr;
u8 opSect = 0; u8 opSect = 0;
/* search valid operation sub-sector */ /* search valid operation sub-sector */
ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo); ret = nv_sector_read(id, MODULE_SECTOR_NUM, &sectInfo);
if(ret != NV_SUCC){ if(ret != NV_SUCC){
return ret; return ret;
} }
opSect = sectInfo.opSect; opSect = sectInfo.opSect;
ret = nv_nwkFrameCountSearch(id, opSect, &lastFrmCnt, &wAddr); ret = nv_nwkFrameCountSearch(id, opSect, &lastFrmCnt, &wAddr);
if(ret == NV_SUCC){ if(ret == NV_SUCC){
*frameCount = lastFrmCnt; *frameCount = lastFrmCnt;
} }
return ret; return ret;
} }
nv_sts_t nv_resetModule(u8 modules){ nv_sts_t nv_resetModule(u8 modules){
u32 eraseAddr = MODULES_START_ADDR(modules); u32 eraseAddr = MODULES_START_ADDR(modules);
u8 sectNumber = NV_SECTOR_SIZE(modules)/FLASH_SECTOR_SIZE; u8 sectNumber = NV_SECTOR_SIZE(modules)/FLASH_SECTOR_SIZE;
for(s32 i = 0; i < MODULE_SECTOR_NUM; i++){ for(s32 i = 0; i < MODULE_SECTOR_NUM; i++){
for(s32 j = 0; j < sectNumber; j++){ for(s32 j = 0; j < sectNumber; j++){
flash_erase(eraseAddr); flash_erase(eraseAddr);
eraseAddr += FLASH_SECTOR_SIZE; eraseAddr += FLASH_SECTOR_SIZE;
} }
} }
return SUCCESS; return SUCCESS;
} }
nv_sts_t nv_resetAll(void){ nv_sts_t nv_resetAll(void){
#if NV_ENABLE #if NV_ENABLE
foreach(i, NV_MAX_MODULS){ foreach(i, NV_MAX_MODULS){
nv_resetModule(i); nv_resetModule(i);
} }
#endif #endif
return SUCCESS; return SUCCESS;
} }
nv_sts_t nv_init(u8 rst){ nv_sts_t nv_init(u8 rst){
if(rst){ if(rst){
/* if reset is true, erase all flash for NV */ /* if reset is true, erase all flash for NV */
nv_resetAll(); nv_resetAll();
} }
return NV_SUCC; return NV_SUCC;
} }
//nv_sts_t nv_resetToFactoryNew(void){ //nv_sts_t nv_resetToFactoryNew(void){
//#if NV_ENABLE //#if NV_ENABLE
// if(!nv_facrotyNewRstFlagCheck()){ // if(!nv_facrotyNewRstFlagCheck()){
// nv_facrotyNewRstFlagSet(); // nv_facrotyNewRstFlagSet();
// } // }
// //
// foreach(i, NV_MAX_MODULS){ // foreach(i, NV_MAX_MODULS){
// if(i != NV_MODULE_NWK_FRAME_COUNT){ // if(i != NV_MODULE_NWK_FRAME_COUNT){
// nv_resetModule(i); // nv_resetModule(i);
// } // }
// } // }
// //
// nv_facrotyNewRstFlagClear(); // nv_facrotyNewRstFlagClear();
//#endif //#endif
// return SUCCESS; // return SUCCESS;
//} //}
nv_sts_t nv_resetToFactoryNew(void){ nv_sts_t nv_resetToFactoryNew(void){
#if NV_ENABLE #if NV_ENABLE
if(!nv_facrotyNewRstFlagCheck()){ if(!nv_facrotyNewRstFlagCheck()){
nv_facrotyNewRstFlagSet(); nv_facrotyNewRstFlagSet();
} }
foreach(i, NV_MAX_MODULS){ foreach(i, NV_MAX_MODULS){
if((i != NV_MODULE_NWK_FRAME_COUNT)&&(i != NV_MODULE_KEYPAIR)){ if((i != NV_MODULE_NWK_FRAME_COUNT)&&(i != NV_MODULE_APP)){
nv_resetModule(i); nv_resetModule(i);
} }
} }
nv_facrotyNewRstFlagClear(); //lmm add for not clear user flash nv_facrotyNewRstFlagClear(); //lmm add for not clear user flash
#endif #endif
return SUCCESS; return SUCCESS;
} }
bool nv_facrotyNewRstFlagCheck(void){ bool nv_facrotyNewRstFlagCheck(void){
u8 flag = ITEM_FIELD_IDLE; u8 flag = ITEM_FIELD_IDLE;
flash_read(CFG_FACTORY_RST_CNT, 1, &flag); flash_read(CFG_FACTORY_RST_CNT, 1, &flag);
return ((flag == 0xff) ? FALSE : TRUE); return ((flag == 0xff) ? FALSE : TRUE);
} }
void nv_facrotyNewRstFlagSet(void){ void nv_facrotyNewRstFlagSet(void){
u8 flag = ITEM_FIELD_VALID; u8 flag = ITEM_FIELD_VALID;
flash_write(CFG_FACTORY_RST_CNT, 1, &flag); flash_write(CFG_FACTORY_RST_CNT, 1, &flag);
} }
void nv_facrotyNewRstFlagClear(void){ void nv_facrotyNewRstFlagClear(void){
flash_erase(CFG_FACTORY_RST_CNT); flash_erase(CFG_FACTORY_RST_CNT);
} }
/******************************************************************************************************** /********************************************************************************************************
* @file drv_nv.h * @file drv_nv.h
* *
* @brief This is the header file for drv_nv * @brief This is the header file for drv_nv
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#pragma once #pragma once
/******************************************************************** /********************************************************************
* @brief Flash map usage. * @brief Flash map usage.
* *
* #if !defined(BOOT_LOADER_MODE) || (BOOT_LOADER_MODE == 0) * #if !defined(BOOT_LOADER_MODE) || (BOOT_LOADER_MODE == 0)
* 512k 1M * 512k 1M
* 0x80000 ------------ 0x100000 ------------ * 0x80000 ------------ 0x100000 ------------
* | | | MAC_Addr | * | | | MAC_Addr |
* | NV_2 | 0xFF000 |------------| * | NV_2 | 0xFF000 |------------|
* | | | F_CFG_Info | * | | | F_CFG_Info |
* 0x7A000 |------------| 0xFE000 |------------| * 0x7A000 |------------| 0xFE000 |------------|
* | U_Cfg_Info | | U_Cfg_Info | * | U_Cfg_Info | | U_Cfg_Info |
* 0x78000 |------------| 0xFC000 |------------| * 0x78000 |------------| 0xFC000 |------------|
* | F_CFG_Info | | Reserved | * | F_CFG_Info | | Reserved |
* 0x77000 |------------| 0x96000 |------------| * 0x77000 |------------| 0x96000 |------------|
* | MAC_Addr | | NV | * | MAC_Addr | | NV |
* 0x76000 |------------| 0x80000 |------------| * 0x76000 |------------| 0x80000 |------------|
* | | | | * | | | |
* | OTA_Image | | | * | OTA_Image | | |
* | | | OTA_Image | * | | | OTA_Image |
* 0x40000 |------------| | | * 0x40000 |------------| | |
* | | | | * | | | |
* | NV_1 | 0x40000 |------------| * | NV_1 | 0x40000 |------------|
* | | | | * | | | |
* 0x34000 |------------| | | * 0x34000 |------------| | |
* | | | Firmware | * | | | Firmware |
* | Firmware | 208k | | 256k * | Firmware | 208k | | 256k
* | | | | * | | | |
* 0x00000 ------------ 0x00000 ------------ * 0x00000 ------------ 0x00000 ------------
* *
* #else * #else
* 512k 1M * 512k 1M
* 0x80000 ------------ 0x100000 ------------ * 0x80000 ------------ 0x100000 ------------
* | | | MAC_Addr | * | | | MAC_Addr |
* | NV_2 | 0xFF000 |------------| * | NV_2 | 0xFF000 |------------|
* | | | F_CFG_Info | * | | | F_CFG_Info |
* 0x7A000 |------------| 0xFE000 |------------| * 0x7A000 |------------| 0xFE000 |------------|
* | U_Cfg_Info | | U_Cfg_Info | * | U_Cfg_Info | | U_Cfg_Info |
* 0x78000 |------------| 0xFC000 |------------| * 0x78000 |------------| 0xFC000 |------------|
* | F_CFG_Info | | | * | F_CFG_Info | | |
* 0x77000 |------------| | NV | * 0x77000 |------------| | NV |
* | MAC_Addr | | | * | MAC_Addr | | |
* 0x76000 |------------| 0xE6000 |------------| * 0x76000 |------------| 0xE6000 |------------|
* | | | | * | | | |
* | NV_1 | | | * | NV_1 | | |
* | | | OTA_Image | * | | | OTA_Image |
* 0x6A000 |------------| | | * 0x6A000 |------------| | |
* | | | | * | | | |
* | OTA_Image | 0x77000 |------------| * | OTA_Image | 0x77000 |------------|
* | | | | * | | | |
* 0x39000 |------------| | | * 0x39000 |------------| | |
* | | | Firmware | * | | | Firmware |
* | Firmware | 196k | | 444k * | Firmware | 196k | | 444k
* | | | | * | | | |
* 0x08000 |------------| 0x08000 |------------| * 0x08000 |------------| 0x08000 |------------|
* | BootLoader | | BootLoader | * | BootLoader | | BootLoader |
* 0x00000 ------------ 0x00000 ------------ * 0x00000 ------------ 0x00000 ------------
* *
* #endif * #endif
*/ */
/* Flash Base Address define */ /* Flash Base Address define */
#if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278) #if defined(MCU_CORE_826x) || defined(MCU_CORE_8258) || defined(MCU_CORE_8278)
#define FLASH_TLNK_FLAG_OFFSET 8 #define FLASH_TLNK_FLAG_OFFSET 8
#elif defined(MCU_CORE_B91) #elif defined(MCU_CORE_B91)
#define FLASH_TLNK_FLAG_OFFSET 32 #define FLASH_TLNK_FLAG_OFFSET 32
#endif #endif
/************************************************************************ /************************************************************************
* Flash address of factory setting parameters, * Flash address of factory setting parameters,
* where are stored the MAC ADDRESS and CALIBRATION information. * where are stored the MAC ADDRESS and CALIBRATION information.
*/ */
//512k flash //512k flash
#define FLASH_ADDR_OF_MAC_ADDR_512K 0x76000 #define FLASH_ADDR_OF_MAC_ADDR_512K 0x76000
#define FLASH_ADDR_OF_F_CFG_INFO_512K 0x77000 #define FLASH_ADDR_OF_F_CFG_INFO_512K 0x77000
//1M flash //1M flash
#define FLASH_ADDR_0F_MAC_ADDR_1M 0xFF000 #define FLASH_ADDR_0F_MAC_ADDR_1M 0xFF000
#define FLASH_ADDR_OF_F_CFG_INFO_1M 0xFE000 #define FLASH_ADDR_OF_F_CFG_INFO_1M 0xFE000
/************************************************************************/ /************************************************************************/
extern u32 g_u32MacFlashAddr; extern u32 g_u32MacFlashAddr;
extern u32 g_u32CfgFlashAddr; extern u32 g_u32CfgFlashAddr;
#define MAC_BASE_ADD (g_u32MacFlashAddr) #define MAC_BASE_ADD (g_u32MacFlashAddr)
#define FACTORY_CFG_BASE_ADD (g_u32CfgFlashAddr) #define FACTORY_CFG_BASE_ADD (g_u32CfgFlashAddr)
/************************************************************************/ /************************************************************************/
/************************************************************************************** /**************************************************************************************
* The following is the detailed factory configure information (F_CFG_Info). * The following is the detailed factory configure information (F_CFG_Info).
*/ */
/* 8 bytes for MAC address. */ /* 8 bytes for MAC address. */
#define CFG_MAC_ADDRESS (MAC_BASE_ADD) #define CFG_MAC_ADDRESS (MAC_BASE_ADD)
/* 2 bytes for USB ID. */ /* 2 bytes for USB ID. */
#define CFG_TELINK_USB_ID (MAC_BASE_ADD + 0x40) #define CFG_TELINK_USB_ID (MAC_BASE_ADD + 0x40)
/* 1 byte for frequency offset calibration. */ /* 1 byte for frequency offset calibration. */
#define CFG_FREQUENCY_OFFSET (FACTORY_CFG_BASE_ADD) #define CFG_FREQUENCY_OFFSET (FACTORY_CFG_BASE_ADD)
/* 2 bytes for TP GAIN. /* 2 bytes for TP GAIN.
* 0x77040(or 0xFE040) for BLE TP_GAIN_0, 0x77041(or 0xFE041) for BLE TP_GAIN_1, * 0x77040(or 0xFE040) for BLE TP_GAIN_0, 0x77041(or 0xFE041) for BLE TP_GAIN_1,
* 0x77042(or 0xFE042) for zigbee TP_GAIN_0, 0x77043(or 0xFE043) for zigbee TP_GAIN_1. */ * 0x77042(or 0xFE042) for zigbee TP_GAIN_0, 0x77043(or 0xFE043) for zigbee TP_GAIN_1. */
#define CFG_TP_GAIN (FACTORY_CFG_BASE_ADD + 0x42) #define CFG_TP_GAIN (FACTORY_CFG_BASE_ADD + 0x42)
/* Not supported for current SDK. */ /* Not supported for current SDK. */
#define CFG_32K_COUNTER_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x80) #define CFG_32K_COUNTER_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x80)
/* Not supported for current SDK. */ /* Not supported for current SDK. */
#define CFG_ADC_CALIBRATION (FACTORY_CFG_BASE_ADD + 0xC0) #define CFG_ADC_CALIBRATION (FACTORY_CFG_BASE_ADD + 0xC0)
/* Not supported for current SDK. */ /* Not supported for current SDK. */
#define CFG_24M_CRYSTAL_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x100) #define CFG_24M_CRYSTAL_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x100)
/* Not supported for current SDK. */ /* Not supported for current SDK. */
#define CFG_T_SENSOR_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x140) #define CFG_T_SENSOR_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x140)
/* UID-based Firmware Encryption data(16 bytes), 0x77180(or 0xFE180) ~ 0x7718F(or 0xFE18F). */ /* UID-based Firmware Encryption data(16 bytes), 0x77180(or 0xFE180) ~ 0x7718F(or 0xFE18F). */
#define CFG_FIRMWARE_ENCRYPTION (FACTORY_CFG_BASE_ADD + 0x180) #define CFG_FIRMWARE_ENCRYPTION (FACTORY_CFG_BASE_ADD + 0x180)
/* 2 bytes for VDD_F calibration. /* 2 bytes for VDD_F calibration.
* 0x771C0(or 0xFF1C0) for DCDC trim, * 0x771C0(or 0xFF1C0) for DCDC trim,
* 0x771C1(or 0xFF1C1) for LDO trim. * 0x771C1(or 0xFF1C1) for LDO trim.
*/ */
#define CFG_VDD_F_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x1C0) #define CFG_VDD_F_CALIBRATION (FACTORY_CFG_BASE_ADD + 0x1C0)
/************************************************************************************** /**************************************************************************************
* The following is the detailed user configure information (U_CFG_Info). * The following is the detailed user configure information (U_CFG_Info).
*/ */
/* 16 bytes for pre-install code. */ /* 16 bytes for pre-install code. */
#if FLASH_CAP_SIZE_1M #if FLASH_CAP_SIZE_1M
#define CFG_PRE_INSTALL_CODE (0xFD000) #define CFG_PRE_INSTALL_CODE (0xFD000)
#else #else
#define CFG_PRE_INSTALL_CODE (0x78000) #define CFG_PRE_INSTALL_CODE (0x78000)
#endif #endif
/* 1 byte for factory reset. /* 1 byte for factory reset.
* If not 0xFF, means the device is doing factory reset(erase NV). * If not 0xFF, means the device is doing factory reset(erase NV).
* The device will check this byte when powered on, if it is not 0xFF, * The device will check this byte when powered on, if it is not 0xFF,
* it will erase NV first. * it will erase NV first.
*/ */
#if FLASH_CAP_SIZE_1M #if FLASH_CAP_SIZE_1M
#define CFG_FACTORY_RST_CNT (0xFC000) #define CFG_FACTORY_RST_CNT (0xFC000)
#else #else
#define CFG_FACTORY_RST_CNT (0x79000) #define CFG_FACTORY_RST_CNT (0x79000)
#endif #endif
/************************************************************************************** /**************************************************************************************
* Flash address of NV module. * Flash address of NV module.
*/ */
#if !defined(BOOT_LOADER_MODE) || (BOOT_LOADER_MODE == 0) #if !defined(BOOT_LOADER_MODE) || (BOOT_LOADER_MODE == 0)
#if FLASH_CAP_SIZE_1M #if FLASH_CAP_SIZE_1M
#define NV_BASE_ADDRESS (0x80000) #define NV_BASE_ADDRESS (0x80000)
#else #else
#define NV_BASE_ADDRESS (0x34000) #define NV_BASE_ADDRESS (0x34000)
#define NV_BASE_ADDRESS2 (0x7A000) #define NV_BASE_ADDRESS2 (0x7A000)
#endif #endif
#else #else
#if FLASH_CAP_SIZE_1M #if FLASH_CAP_SIZE_1M
#define NV_BASE_ADDRESS (0xE6000) #define NV_BASE_ADDRESS (0xE6000)
#else #else
#define NV_BASE_ADDRESS (0x6A000) #define NV_BASE_ADDRESS (0x6A000)
#define NV_BASE_ADDRESS2 (0x7A000) #define NV_BASE_ADDRESS2 (0x7A000)
#endif #endif
#endif #endif
/************************************************************************ /************************************************************************
* Flash address of APP firmware. * Flash address of APP firmware.
*/ */
#define FLASH_ADDR_OF_APP_FW APP_IMAGE_ADDR #define FLASH_ADDR_OF_APP_FW APP_IMAGE_ADDR
/************************************************************************ /************************************************************************
* Flash address of OTA image. * Flash address of OTA image.
*/ */
#if !defined(BOOT_LOADER_MODE) || (BOOT_LOADER_MODE == 0) #if !defined(BOOT_LOADER_MODE) || (BOOT_LOADER_MODE == 0)
#if FLASH_CAP_SIZE_1M #if FLASH_CAP_SIZE_1M
//max size = (0x80000 - 0) / 2 = 256k //max size = (0x80000 - 0) / 2 = 256k
#define FLASH_OTA_IMAGE_MAX_SIZE ((NV_BASE_ADDRESS - FLASH_ADDR_OF_APP_FW) / 2) #define FLASH_OTA_IMAGE_MAX_SIZE ((NV_BASE_ADDRESS - FLASH_ADDR_OF_APP_FW) / 2)
#else #else
//max size = (0x34000 - 0) = 208k //max size = (0x34000 - 0) = 208k
#define FLASH_OTA_IMAGE_MAX_SIZE (NV_BASE_ADDRESS - FLASH_ADDR_OF_APP_FW) #define FLASH_OTA_IMAGE_MAX_SIZE (NV_BASE_ADDRESS - FLASH_ADDR_OF_APP_FW)
#endif #endif
//unchangeable address //unchangeable address
#define FLASH_ADDR_OF_OTA_IMAGE (0x40000) #define FLASH_ADDR_OF_OTA_IMAGE (0x40000)
#else #else
//1M Flash: max size = (0xE6000 - 0x8000) / 2 = 444k //1M Flash: max size = (0xE6000 - 0x8000) / 2 = 444k
//512k Flash: max size = (0x6A000 - 0x8000) / 2 = 196k //512k Flash: max size = (0x6A000 - 0x8000) / 2 = 196k
#define FLASH_OTA_IMAGE_MAX_SIZE ((NV_BASE_ADDRESS - FLASH_ADDR_OF_APP_FW) / 2) #define FLASH_OTA_IMAGE_MAX_SIZE ((NV_BASE_ADDRESS - FLASH_ADDR_OF_APP_FW) / 2)
//1M Flash: ota addr = 0x8000 + 444k = 0x77000 //1M Flash: ota addr = 0x8000 + 444k = 0x77000
//512k Flash: ota addr = 0x8000 + 196k = 0x39000 //512k Flash: ota addr = 0x8000 + 196k = 0x39000
#define FLASH_ADDR_OF_OTA_IMAGE (FLASH_ADDR_OF_APP_FW + FLASH_OTA_IMAGE_MAX_SIZE) #define FLASH_ADDR_OF_OTA_IMAGE (FLASH_ADDR_OF_APP_FW + FLASH_OTA_IMAGE_MAX_SIZE)
#endif #endif
/******************************************* DUAL_MODE ********************************************************/ /******************************************* DUAL_MODE ********************************************************/
/* Don't care, will be delete. */ /* Don't care, will be delete. */
#if DUAL_MODE #if DUAL_MODE
//NOTE: firmware must less then 192K if UDAL_MODE used //NOTE: firmware must less then 192K if UDAL_MODE used
typedef enum{ typedef enum{
TYPE_TLK_MESH = 0x000000A3,// don't change, must same with telink mesh SDK TYPE_TLK_MESH = 0x000000A3,// don't change, must same with telink mesh SDK
TYPE_SIG_MESH = 0x0000003A,// don't change, must same with telink mesh SDK TYPE_SIG_MESH = 0x0000003A,// don't change, must same with telink mesh SDK
TYPE_TLK_BLE_SDK = 0x000000C3,// don't change, must same with telink mesh SDK TYPE_TLK_BLE_SDK = 0x000000C3,// don't change, must same with telink mesh SDK
TYPE_TLK_ZIGBEE = 0x0000003C,// don't change, must same with telink mesh SDK TYPE_TLK_ZIGBEE = 0x0000003C,// don't change, must same with telink mesh SDK
TYPE_DUAL_MODE_STANDBY = 0x00000065,// dual mode state was standby to be selected TYPE_DUAL_MODE_STANDBY = 0x00000065,// dual mode state was standby to be selected
TYPE_DUAL_MODE_RECOVER = 0x00000056,// don't change, must same with telink mesh SDK, recover for mesh TYPE_DUAL_MODE_RECOVER = 0x00000056,// don't change, must same with telink mesh SDK, recover for mesh
}telink_sdk_type_t; }telink_sdk_type_t;
#define CFG_TELINK_SDK_TYPE (0x73000) #define CFG_TELINK_SDK_TYPE (0x73000)
#define CFG_TELINK_SIG_MESH_CRC (0x73040) #define CFG_TELINK_SIG_MESH_CRC (0x73040)
#define CFG_TELINK_SIG_MESH_CODE_4K (0x75000) #define CFG_TELINK_SIG_MESH_CODE_4K (0x75000)
#define CFG_TELINK_DUAL_MODE_ENABLE (0x76080) #define CFG_TELINK_DUAL_MODE_ENABLE (0x76080)
#endif /* DUAL_MODE */ #endif /* DUAL_MODE */
/******************************************** END ***********************************************************/ /******************************************** END ***********************************************************/
/* sector info(4Bytes) + index info(8Bytes) + index info(8Bytes) + ... */ /* sector info(4Bytes) + index info(8Bytes) + index info(8Bytes) + ... */
typedef struct{ typedef struct{
u16 usedFlag; u16 usedFlag;
u8 idName; u8 idName;
u8 opSect; u8 opSect;
}nv_sect_info_t; }nv_sect_info_t;
typedef struct{ typedef struct{
u32 offset; u32 offset;
u16 size; u16 size;
u8 itemId; u8 itemId;
u8 usedState; u8 usedState;
}nv_info_idx_t; }nv_info_idx_t;
/* item: item_hdr(8Bytes) + payload*/ /* item: item_hdr(8Bytes) + payload*/
typedef struct{ typedef struct{
u32 checkSum; u32 checkSum;
u16 size; u16 size;
u8 itemId; u8 itemId;
u8 used; u8 used;
}itemHdr_t; }itemHdr_t;
typedef struct{ typedef struct{
u16 opIndex; u16 opIndex;
u8 opSect; u8 opSect;
}itemIfno_t; }itemIfno_t;
//If OTA enabled, the maximum space used for nv module t is 56K, thus the item num cannot over 14 //If OTA enabled, the maximum space used for nv module t is 56K, thus the item num cannot over 14
/***************************************************************************************************************************** /*****************************************************************************************************************************
* Store zigbee information in flash. * Store zigbee information in flash.
* Module ID | 512K Flash | 1M Flash | * Module ID | 512K Flash | 1M Flash |
* -----------------------------|-----------------------------------|-----------------------------------| * -----------------------------|-----------------------------------|-----------------------------------|
* NV_MODULE_ZB_INFO | 0x34000 - 0x36000 | 0x80000 - 0x82000 | * NV_MODULE_ZB_INFO | 0x34000 - 0x36000 | 0x80000 - 0x82000 |
* NV_MODULE_ADDRESS_TABLE | 0x36000 - 0x38000 | 0x82000 - 0x84000 | * NV_MODULE_ADDRESS_TABLE | 0x36000 - 0x38000 | 0x82000 - 0x84000 |
* NV_MODULE_APS | 0x38000 - 0x3a000 | 0x84000 - 0x86000 | * NV_MODULE_APS | 0x38000 - 0x3a000 | 0x84000 - 0x86000 |
* NV_MODULE_ZCL | 0x3a000 - 0x3c000 | 0x86000 - 0x88000 | * NV_MODULE_ZCL | 0x3a000 - 0x3c000 | 0x86000 - 0x88000 |
* NV_MODULE_NWK_FRAME_COUNT | 0x3c000 - 0x3e000 | 0x88000 - 0x8a000 | * NV_MODULE_NWK_FRAME_COUNT | 0x3c000 - 0x3e000 | 0x88000 - 0x8a000 |
* NV_MODULE_OTA | 0x3e000 - 0x40000 | 0x8a000 - 0x8c000 | * NV_MODULE_OTA | 0x3e000 - 0x40000 | 0x8a000 - 0x8c000 |
* NV_MODULE_APP | 0x7a000 - 0x7c000 | 0x8c000 - 0x8e000 | * NV_MODULE_APP | 0x7a000 - 0x7c000 | 0x8c000 - 0x8e000 |
* NV_MODULE_KEYPAIR | 0x7c000 - 0x80000 | 0x8e000 - 0x96000 | * NV_MODULE_KEYPAIR | 0x7c000 - 0x80000 | 0x8e000 - 0x96000 |
* | *16K - can store 127 nodes | *32K - can store 302 nodes | * | *16K - can store 127 nodes | *32K - can store 302 nodes |
* NV_MAX_MODULS * NV_MAX_MODULS
*/ */
typedef enum{ typedef enum{
NV_MODULE_ZB_INFO = 0, NV_MODULE_ZB_INFO = 0,
NV_MODULE_ADDRESS_TABLE = 1, NV_MODULE_ADDRESS_TABLE = 1,
NV_MODULE_APS = 2, NV_MODULE_APS = 2,
NV_MODULE_ZCL = 3, NV_MODULE_ZCL = 3,
NV_MODULE_NWK_FRAME_COUNT = 4, NV_MODULE_NWK_FRAME_COUNT = 4,
NV_MODULE_OTA = 5, NV_MODULE_OTA = 5,
NV_MODULE_APP = 6, NV_MODULE_APP = 6,
NV_MODULE_KEYPAIR = 7, NV_MODULE_KEYPAIR = 7,
NV_MAX_MODULS NV_MAX_MODULS
}nv_module_t; }nv_module_t;
typedef enum{ typedef enum{
NV_ITEM_ID_INVALID = 0,/* Item id 0 should not be used. */ NV_ITEM_ID_INVALID = 0,/* Item id 0 should not be used. */
NV_ITEM_ZB_INFO = 1, NV_ITEM_ZB_INFO = 1,
NV_ITEM_ADDRESS_FOR_NEIGHBOR, NV_ITEM_ADDRESS_FOR_NEIGHBOR,
NV_ITEM_ADDRESS_FOR_BIND, NV_ITEM_ADDRESS_FOR_BIND,
NV_ITEM_APS_SSIB, NV_ITEM_APS_SSIB,
NV_ITEM_APS_GROUP_TABLE, NV_ITEM_APS_GROUP_TABLE,
NV_ITEM_APS_BINDING_TABLE, NV_ITEM_APS_BINDING_TABLE,
NV_ITEM_NWK_FRAME_COUNT, NV_ITEM_NWK_FRAME_COUNT,
NV_ITEM_SS_KEY_PAIR, NV_ITEM_SS_KEY_PAIR,
NV_ITEM_OTA_HDR_SERVERINFO, NV_ITEM_OTA_HDR_SERVERINFO,
NV_ITEM_OTA_CODE, NV_ITEM_OTA_CODE,
NV_ITEM_ZCL_REPORT = 0x20, NV_ITEM_ZCL_REPORT = 0x20,
NV_ITEM_ZCL_ON_OFF, NV_ITEM_ZCL_ON_OFF,
NV_ITEM_ZCL_LEVEL, NV_ITEM_ZCL_LEVEL,
NV_ITEM_ZCL_COLOR_CTRL, NV_ITEM_ZCL_COLOR_CTRL,
NV_ITEM_ZCL_SCENE_TABLE, NV_ITEM_ZCL_SCENE_TABLE,
NV_ITEM_ZCL_GP_PROXY_TABLE, NV_ITEM_ZCL_GP_PROXY_TABLE,
NV_ITEM_ZCL_GP_SINK_TABLE, NV_ITEM_ZCL_GP_SINK_TABLE,
NV_ITEM_APP_SIMPLE_DESC, NV_ITEM_APP_SIMPLE_DESC,
NV_ITEM_APP_POWER_CNT, NV_ITEM_APP_POWER_CNT,
NV_GATEWAY_ADDR, //lmm add NV_GATEWAY_ADDR, //lmm add
NV_MFG_CODE, //lmm add NV_MFG_CODE, //lmm add
NV_AGE_TEST_STEP, //lmm add NV_AGE_TEST_STEP, //lmm add
NV_MFC_CODE, //lmm add NV_SINGLE_BOARD_TEST_FLG, //lmm add
NV_NO_DISTURB_MODE, //lmm add NV_FULL_DEVICE_TEST_FLG, //lmm add
NV_MFC_CODE, //lmm add
NV_ITEM_ID_MAX = 0xFF,/* Item id 0xFF should not be used. */ NV_NO_DISTURB_MODE, //lmm add
}nv_item_t; NV_AGING_TEST_TIME, //lmm add
NV_INTERPAN_ENABLE_FLG, //lmm add
typedef enum{
NV_SUCC, NV_ITEM_ID_MAX = 0xFF,/* Item id 0xFF should not be used. */
NV_INVALID_MODULS = 1, }nv_item_t;
NV_INVALID_ID ,
NV_ITEM_NOT_FOUND, typedef enum{
NV_NOT_ENOUGH_SAPCE, NV_SUCC,
NV_ITEM_LEN_NOT_MATCH, NV_INVALID_MODULS = 1,
NV_CHECK_SUM_ERROR, NV_INVALID_ID ,
NV_ENABLE_PROTECT_ERROR, NV_ITEM_NOT_FOUND,
NV_NO_MEDIA NV_NOT_ENOUGH_SAPCE,
} nv_sts_t; NV_ITEM_LEN_NOT_MATCH,
NV_CHECK_SUM_ERROR,
NV_ENABLE_PROTECT_ERROR,
#define FLASH_PAGE_SIZE 256 NV_NO_MEDIA
#define FLASH_SECTOR_SIZE 4096//4K } nv_sts_t;
#define NV_SECTOR_VALID 0x5A5A
#define NV_SECTOR_INVALID 0x5050 #define FLASH_PAGE_SIZE 256
#define NV_SECTOR_IDLE 0xFFFF #define FLASH_SECTOR_SIZE 4096//4K
#define ITEM_FIELD_VALID 0x5A #define NV_SECTOR_VALID 0x5A5A
#define ITEM_FIELD_INVALID 0x50 #define NV_SECTOR_INVALID 0x5050
#define ITEM_FIELD_OPERATION 0xFA #define NV_SECTOR_IDLE 0xFFFF
#define ITEM_FIELD_IDLE 0xFF
#define ITEM_FIELD_VALID 0x5A
#define ITEM_FIELD_INVALID 0x50
#if FLASH_CAP_SIZE_1M #define ITEM_FIELD_OPERATION 0xFA
#define MODULES_START_ADDR(id) (NV_BASE_ADDRESS + FLASH_SECTOR_SIZE * (2 * id)) #define ITEM_FIELD_IDLE 0xFF
#define NV_SECTOR_SIZE(id) ((id == NV_MODULE_KEYPAIR) ? (4 * FLASH_SECTOR_SIZE) : FLASH_SECTOR_SIZE)
#define MODULE_INFO_SIZE(id) ((id == NV_MODULE_OTA || id == NV_MODULE_KEYPAIR || id == NV_MODULE_ADDRESS_TABLE) ? ((id == NV_MODULE_KEYPAIR) ? (12*FLASH_PAGE_SIZE) : (4*FLASH_PAGE_SIZE)) : (2*FLASH_PAGE_SIZE))
#else #if FLASH_CAP_SIZE_1M
#define MODULES_START_ADDR(id) ((id < 6) ? (NV_BASE_ADDRESS + FLASH_SECTOR_SIZE * (2 * id)) : (NV_BASE_ADDRESS2 + FLASH_SECTOR_SIZE * (2 * (id-6)))) #define MODULES_START_ADDR(id) (NV_BASE_ADDRESS + FLASH_SECTOR_SIZE * (2 * id))
#define NV_SECTOR_SIZE(id) ((id == NV_MODULE_KEYPAIR) ? (2 * FLASH_SECTOR_SIZE) : FLASH_SECTOR_SIZE) #define NV_SECTOR_SIZE(id) ((id == NV_MODULE_KEYPAIR) ? (4 * FLASH_SECTOR_SIZE) : FLASH_SECTOR_SIZE)
#define MODULE_INFO_SIZE(id) ((id == NV_MODULE_OTA || id == NV_MODULE_KEYPAIR || id == NV_MODULE_ADDRESS_TABLE) ? (4*FLASH_PAGE_SIZE) : (2*FLASH_PAGE_SIZE)) #define MODULE_INFO_SIZE(id) ((id == NV_MODULE_OTA || id == NV_MODULE_KEYPAIR || id == NV_MODULE_ADDRESS_TABLE) ? ((id == NV_MODULE_KEYPAIR) ? (12*FLASH_PAGE_SIZE) : (4*FLASH_PAGE_SIZE)) : (2*FLASH_PAGE_SIZE))
#endif #else
#define MODULES_START_ADDR(id) ((id < 6) ? (NV_BASE_ADDRESS + FLASH_SECTOR_SIZE * (2 * id)) : (NV_BASE_ADDRESS2 + FLASH_SECTOR_SIZE * (2 * (id-6))))
#define MODULE_SECTOR_NUM (2) #define NV_SECTOR_SIZE(id) ((id == NV_MODULE_KEYPAIR) ? (2 * FLASH_SECTOR_SIZE) : FLASH_SECTOR_SIZE)
#define MODULE_INFO_SIZE(id) ((id == NV_MODULE_OTA || id == NV_MODULE_KEYPAIR || id == NV_MODULE_ADDRESS_TABLE) ? (4*FLASH_PAGE_SIZE) : (2*FLASH_PAGE_SIZE))
#define MODULE_IDX_SIZE(id) (MODULE_INFO_SIZE(id) - sizeof(nv_sect_info_t)) #endif
#define MODULE_SECT_START(id, sectNo) (MODULES_START_ADDR(id) + sectNo * (NV_SECTOR_SIZE(id)))
#define MODULE_SECT_END(id, sectNo) (MODULES_START_ADDR(id) + (sectNo + 1) * (NV_SECTOR_SIZE(id))) #define MODULE_SECTOR_NUM (2)
#define MODULE_IDX_START(id, sectNo) (MODULE_SECT_START(id, sectNo) + sizeof(nv_sect_info_t))
#define MODULE_IDX_NUM(id) (MODULE_IDX_SIZE(id) / (sizeof(nv_info_idx_t))) #define MODULE_IDX_SIZE(id) (MODULE_INFO_SIZE(id) - sizeof(nv_sect_info_t))
#define MODULE_CONTEXT_START(id, sectNo, len) (MODULE_SECT_START(id, sectNo) + MODULE_INFO_SIZE(id)) #define MODULE_SECT_START(id, sectNo) (MODULES_START_ADDR(id) + sectNo * (NV_SECTOR_SIZE(id)))
#define ITEM_TOTAL_LEN(len) (len + sizeof(itemHdr_t)) #define MODULE_SECT_END(id, sectNo) (MODULES_START_ADDR(id) + (sectNo + 1) * (NV_SECTOR_SIZE(id)))
#define FRAMECOUNT_PAYLOAD_START(opSect) (((MODULE_SECT_START(NV_MODULE_NWK_FRAME_COUNT, opSect) + sizeof(nv_sect_info_t)) + 0x03) & (~0x03)) #define MODULE_IDX_START(id, sectNo) (MODULE_SECT_START(id, sectNo) + sizeof(nv_sect_info_t))
#define FRAMECOUNT_NUM_PER_SECT() ((((FLASH_SECTOR_SIZE - sizeof(nv_sect_info_t)) & (~0x03))) / 4) #define MODULE_IDX_NUM(id) (MODULE_IDX_SIZE(id) / (sizeof(nv_info_idx_t)))
#define MODULE_CONTEXT_START(id, sectNo, len) (MODULE_SECT_START(id, sectNo) + MODULE_INFO_SIZE(id))
#define ITEM_TOTAL_LEN(len) (len + sizeof(itemHdr_t))
#define FRAMECOUNT_PAYLOAD_START(opSect) (((MODULE_SECT_START(NV_MODULE_NWK_FRAME_COUNT, opSect) + sizeof(nv_sect_info_t)) + 0x03) & (~0x03))
#define FRAMECOUNT_NUM_PER_SECT() ((((FLASH_SECTOR_SIZE - sizeof(nv_sect_info_t)) & (~0x03))) / 4)
nv_sts_t nv_resetAll(void);
nv_sts_t nv_resetModule(u8 modules);
nv_sts_t nv_flashWriteNew(u8 single, u16 id, u8 itemId, u16 len, u8 *buf);
nv_sts_t nv_flashReadNew(u8 single, u8 id, u8 itemId, u16 len, u8 *buf);
nv_sts_t nv_itemDeleteByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx); nv_sts_t nv_resetAll(void);
nv_sts_t nv_flashReadByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx, u16 len, u8 *buf); nv_sts_t nv_resetModule(u8 modules);
nv_sts_t nv_resetToFactoryNew(void); nv_sts_t nv_flashWriteNew(u8 single, u16 id, u8 itemId, u16 len, u8 *buf);
bool nv_facrotyNewRstFlagCheck(void); nv_sts_t nv_flashReadNew(u8 single, u8 id, u8 itemId, u16 len, u8 *buf);
void nv_facrotyNewRstFlagSet(void); nv_sts_t nv_itemDeleteByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx);
void nv_facrotyNewRstFlagClear(void); nv_sts_t nv_flashReadByIndex(u8 id, u8 itemId, u8 opSect, u16 opIdx, u16 len, u8 *buf);
nv_sts_t nv_nwkFrameCountSaveToFlash(u32 frameCount); nv_sts_t nv_resetToFactoryNew(void);
nv_sts_t nv_nwkFrameCountFromFlash(u32 *frameCount); bool nv_facrotyNewRstFlagCheck(void);
void nv_facrotyNewRstFlagSet(void);
void nv_facrotyNewRstFlagClear(void);
nv_sts_t nv_nwkFrameCountSaveToFlash(u32 frameCount);
nv_sts_t nv_nwkFrameCountFromFlash(u32 *frameCount);
/******************************************************************************************************** /********************************************************************************************************
* @file ev_timer.h * @file ev_timer.h
* *
* @brief This is the header file for ev_timer * @brief This is the header file for ev_timer
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#pragma once #pragma once
/** /**
* @brief Definition for timer event * @brief Definition for timer event
*/ */
#define TIMER_EVENT_NUM (40) #define TIMER_EVENT_NUM (24)
#define TIMER_EVENT_ENOUGH_NUM (TIMER_EVENT_NUM - 4) #define TIMER_EVENT_ENOUGH_NUM (TIMER_EVENT_NUM - 4)
/** /**
* @brief Type definition for timer callback function * @brief Type definition for timer callback function
*/ */
typedef int (*ev_timer_callback_t)(void *data); typedef int (*ev_timer_callback_t)(void *data);
/** /**
* @brief Type definition for timer event * @brief Type definition for timer event
*/ */
typedef struct ev_timer_event_t { typedef struct ev_timer_event_t {
struct ev_timer_event_t *next; //!< Used internal struct ev_timer_event_t *next; //!< Used internal
ev_timer_callback_t cb; //!< Callback function when expire, this must be specified ev_timer_callback_t cb; //!< Callback function when expire, this must be specified
void *data; //!< Callback function arguments. void *data; //!< Callback function arguments.
u32 timeout; //!< In millisecond u32 timeout; //!< In millisecond
u32 period; //!< Used internal u32 period; //!< Used internal
u32 curSysTick; //!< Used internal, system tick when registering u32 curSysTick; //!< Used internal, system tick when registering
u8 resv[2]; u8 resv[2];
u8 isRunning; //!< Used internal u8 isRunning; //!< Used internal
u8 used; //!< Used internal u8 used; //!< Used internal
} ev_timer_event_t; } ev_timer_event_t;
typedef struct ev_timer_event_pool_s { typedef struct ev_timer_event_pool_s {
ev_timer_event_t evt[TIMER_EVENT_NUM]; ev_timer_event_t evt[TIMER_EVENT_NUM];
u32 used_num; u32 used_num;
} ev_timer_event_pool_t; } ev_timer_event_pool_t;
bool ev_timer_enough(void); bool ev_timer_enough(void);
void ev_timer_update(u32 updateTime); void ev_timer_update(u32 updateTime);
void ev_timer_setPrevSysTick(u32 tick); void ev_timer_setPrevSysTick(u32 tick);
u32 ev_timer_used_num(void); u32 ev_timer_used_num(void);
/** /**
* @brief EV timer pool initialization * @brief EV timer pool initialization
* *
* @param[in] None * @param[in] None
* *
* @return None * @return None
*/ */
void ev_timer_init(void); void ev_timer_init(void);
/** /**
* @brief Process EV timer events * @brief Process EV timer events
* *
* @param[in] None * @param[in] None
* *
* @return None * @return None
*/ */
void ev_timer_process(void); void ev_timer_process(void);
/** /**
* @brief Get the nearest EV timer events * @brief Get the nearest EV timer events
* *
* @param[in] None * @param[in] None
* *
* @return None * @return None
*/ */
ev_timer_event_t *ev_timer_nearestGet(void); ev_timer_event_t *ev_timer_nearestGet(void);
/** /**
* @brief Check whether a specified timer exist or not * @brief Check whether a specified timer exist or not
* *
* @param[in] evt - The specified timer event * @param[in] evt - The specified timer event
* *
* @return True indicating the timer is already exist. <BR> * @return True indicating the timer is already exist. <BR>
* False indicating the timer is not exist. <BR> * False indicating the timer is not exist. <BR>
*/ */
bool ev_timer_exist(ev_timer_event_t *evt); bool ev_timer_exist(ev_timer_event_t *evt);
/** /**
* @brief Set a new timer * @brief Set a new timer
* *
* @param[in] evt - The timer event including the callback function * @param[in] evt - The timer event including the callback function
* @param[in] timeout - Timeout in millisecond * @param[in] timeout - Timeout in millisecond
* *
* @return None * @return None
*/ */
void ev_on_timer(ev_timer_event_t *evt, u32 timeout); void ev_on_timer(ev_timer_event_t *evt, u32 timeout);
/** /**
* @brief Cancel an existed timer * @brief Cancel an existed timer
* *
* @param[in] e - The existed timer event * @param[in] e - The existed timer event
* *
* @return None * @return None
*/ */
void ev_unon_timer(ev_timer_event_t *evt); void ev_unon_timer(ev_timer_event_t *evt);
/** /**
* @brief push timer task to task list * @brief push timer task to task list
* *
* @param[in] func - the callback of the timer event * @param[in] func - the callback of the timer event
* *
* @param[in] arg - the parameter to the callback * @param[in] arg - the parameter to the callback
* *
* @param cycle - the timer interval * @param cycle - the timer interval
* *
* @return the status * @return the status
*/ */
ev_timer_event_t *ev_timer_taskPost(ev_timer_callback_t func, void *arg, u32 t_ms); ev_timer_event_t *ev_timer_taskPost(ev_timer_callback_t func, void *arg, u32 t_ms);
#define TL_ZB_TIMER_SCHEDULE(cb, arg, timeout) (ev_timer_taskPost((cb), (arg), (timeout))) #define TL_ZB_TIMER_SCHEDULE(cb, arg, timeout) (ev_timer_taskPost((cb), (arg), (timeout)))
/** /**
* @brief cancel timer task from task list * @brief cancel timer task from task list
* *
* @param[in] te - the pointer to the the timer event pointer * @param[in] te - the pointer to the the timer event pointer
* *
* @return the status * @return the status
*/ */
u8 ev_timer_taskCancel(ev_timer_event_t **evt); u8 ev_timer_taskCancel(ev_timer_event_t **evt);
#define TL_ZB_TIMER_CANCEL(evt) (ev_timer_taskCancel(evt)) #define TL_ZB_TIMER_CANCEL(evt) (ev_timer_taskCancel(evt))
/******************************************************************************************************** /********************************************************************************************************
* @file tl_common.h * @file tl_common.h
* *
* @brief This is the header file for tl_common * @brief This is the header file for tl_common
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#pragma once #pragma once
#include "app_cfg.h" #include "app_cfg.h"
#include "platform.h" #include "platform.h"
#include "common/types.h" #include "common/types.h"
#include "common/compiler.h" #include "common/compiler.h"
#include "common/static_assert.h" #include "common/static_assert.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/bit.h" #include "common/bit.h"
#include "common/utility.h" #include "common/utility.h"
#include "common/utlist.h" #include "common/utlist.h"
#include "common/list.h" #include "common/list.h"
#include "common/string.h" #include "common/string.h"
#include "common/tlPrintf.h" #include "common/tlPrintf.h"
#include "common/mempool.h" #include "common/mempool.h"
#include "os/ev_poll.h" #include "os/ev_poll.h"
#include "os/ev_buffer.h" #include "os/ev_buffer.h"
#include "os/ev_queue.h" #include "os/ev_queue.h"
#include "os/ev_timer.h" #include "os/ev_timer.h"
#include "os/ev.h" #include "os/ev.h"
#include "drivers/drv_hw.h" #include "drivers/drv_hw.h"
#include "drivers/drv_radio.h" #include "drivers/drv_radio.h"
#include "drivers/drv_gpio.h" #include "drivers/drv_gpio.h"
#include "drivers/drv_adc.h" #include "drivers/drv_adc.h"
#include "drivers/drv_flash.h" #include "drivers/drv_flash.h"
#include "drivers/drv_i2c.h" #include "drivers/drv_i2c.h"
#include "drivers/drv_spi.h" #include "drivers/drv_spi.h"
#include "drivers/drv_pwm.h" #include "drivers/drv_pwm.h"
#include "drivers/drv_uart.h" #include "drivers/drv_uart.h"
#include "drivers/drv_pm.h" #include "drivers/drv_pm.h"
#include "drivers/drv_timer.h" #include "drivers/drv_timer.h"
#include "drivers/drv_keyboard.h" #include "drivers/drv_keyboard.h"
#include "drivers/drv_nv.h" #include "drivers/drv_nv.h"
#include "drivers/drv_putchar.h" #include "drivers/drv_putchar.h"
#include "drivers/drv_usb.h" #include "drivers/drv_usb.h"
This source diff could not be displayed because it is too large. You can view the blob instead.
/******************************************************************************************************** /********************************************************************************************************
* @file bdb.h * @file bdb.h
* *
* @brief This is the header file for bdb * @brief This is the header file for bdb
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
#ifndef BDB_H #ifndef BDB_H
#define BDB_H #define BDB_H
/** @addtogroup TELINK_ZIGBEE_STACK TELINK ZigBee Stack /** @addtogroup TELINK_ZIGBEE_STACK TELINK ZigBee Stack
* @{ * @{
*/ */
/** @addtogroup TELINK_ZIGBEE_BDB telink bdb /** @addtogroup TELINK_ZIGBEE_BDB telink bdb
* @{ * @{
*/ */
/** @addtogroup zb_bdb_constant BDB Constants /** @addtogroup zb_bdb_constant BDB Constants
* Definition for Constants used by all nodes * Definition for Constants used by all nodes
* @{ * @{
*/ */
#define BDBC_MAX_SAME_NETWROK_RETRY_ATTEMPTS 10 //<! the maximum number of join or key exchange attempts made to the same network #define BDBC_MAX_SAME_NETWROK_RETRY_ATTEMPTS 10 //<! the maximum number of join or key exchange attempts made to the same network
#define BDBC_MIN_COMMISSIONING_TIME (180) /**1000)*/ //!< the minimum duration in seconds for which a network is opened to allow new nodes to join or for a device to identify itself #define BDBC_MIN_COMMISSIONING_TIME (180) /**1000)*/ //!< the minimum duration in seconds for which a network is opened to allow new nodes to join or for a device to identify itself
#define BDBC_REC_SAME_NETWROK_RETRY_ATTEMPTS 3 //!< the RECOMMENDED maximum number of join or key exchange attempts made to the same network #define BDBC_REC_SAME_NETWROK_RETRY_ATTEMPTS 3 //!< the RECOMMENDED maximum number of join or key exchange attempts made to the same network
#define BDBC_TC_LINK_KEY_EXCHANGE_TIMEOUT (5) //!< the maximum time in seconds a joining node will wait for a response when sending an APS request key to the Trust Center #define BDBC_TC_LINK_KEY_EXCHANGE_TIMEOUT (5) //!< the maximum time in seconds a joining node will wait for a response when sending an APS request key to the Trust Center
/** @} end of group zb_bdb_constant */ /** @} end of group zb_bdb_constant */
/** @addtogroup zb_bdb_constant_tl BDB Constants for zb_bdb_constant_touchlink /** @addtogroup zb_bdb_constant_tl BDB Constants for zb_bdb_constant_touchlink
* Definition for Constants used by all nodes supporting touchlink * Definition for Constants used by all nodes supporting touchlink
* @{ * @{
*/ */
#define BDBC_TL_INTRP_TRANSId_LIFETIME (8*1000) //<! the maximum length of time an inter-PAN transaction ID remains valid #define BDBC_TL_INTRP_TRANSId_LIFETIME (8*1000) //<! the maximum length of time an inter-PAN transaction ID remains valid
#define BDBC_TL_MIN_STARTUP_DELAY_TIME (2*1000) //<! the length of time an initiator waits to ensure the target has completed its network startup procedure #define BDBC_TL_MIN_STARTUP_DELAY_TIME (2*1000) //<! the length of time an initiator waits to ensure the target has completed its network startup procedure
#define BDBC_TL_PRIMARY_CHANNEL_SET 0x02108800 //!< the bitmask for the channel set comprised of channels 11, 15, 20 and 25, that will be used for a non-extended touchlink scan. #define BDBC_TL_PRIMARY_CHANNEL_SET 0x02108800 //!< the bitmask for the channel set comprised of channels 11, 15, 20 and 25, that will be used for a non-extended touchlink scan.
#define BDBC_TL_RX_WINDOW_DURATION (5*1000) //!< the maximum duration that a node leaves its receiver enabled during touchlink for subsequent responses #define BDBC_TL_RX_WINDOW_DURATION (5*1000) //!< the maximum duration that a node leaves its receiver enabled during touchlink for subsequent responses
#define BDBC_TL_SCAN_TIME_BASE_DURATION 250 //!< the base duration for a touchlink scan operation during which the receiver is enabled for scan responses after having transmitted a scan request #define BDBC_TL_SCAN_TIME_BASE_DURATION 250 //!< the base duration for a touchlink scan operation during which the receiver is enabled for scan responses after having transmitted a scan request
#define BDBC_TL_SECONDARY_CHANNEL_SET (0x07fff800^BDBC_TL_PRIMARY_CHANNEL_SET) //!< the bitmask for the channel set comprised of the remaining IEEE 802.15.4-2003 channels except BDBC_TL_PRIMARY_CHANNEL_SET #define BDBC_TL_SECONDARY_CHANNEL_SET (0x07fff800^BDBC_TL_PRIMARY_CHANNEL_SET) //!< the bitmask for the channel set comprised of the remaining IEEE 802.15.4-2003 channels except BDBC_TL_PRIMARY_CHANNEL_SET
/** @} end of group zb_bdb_constant_tl */ /** @} end of group zb_bdb_constant_tl */
enum ll_device_id { enum ll_device_id {
LL_DEV_ONOFF_LIGHT = 0x0000, LL_DEV_ONOFF_LIGHT = 0x0000,
LL_DEV_ONOFF_PLUGIN_UNIT = 0x0010, LL_DEV_ONOFF_PLUGIN_UNIT = 0x0010,
LL_DEV_DIMMABLE_LIGHT = 0x0100, LL_DEV_DIMMABLE_LIGHT = 0x0100,
LL_DEV_DIMMABLE_PLUGIN_UNIT = 0x0110, LL_DEV_DIMMABLE_PLUGIN_UNIT = 0x0110,
LL_DEV_COLOR_LIGHT = 0x0200, LL_DEV_COLOR_LIGHT = 0x0200,
LL_DEV_EXTENDED_COLOR_LIGHT = 0x0210, LL_DEV_EXTENDED_COLOR_LIGHT = 0x0210,
LL_DEV_COLOR_TEMPERATURE_LIGHT = 0x0220, LL_DEV_COLOR_TEMPERATURE_LIGHT = 0x0220,
LL_DEV_COLOR_CONTROLLER = 0x0800, LL_DEV_COLOR_CONTROLLER = 0x0800,
LL_DEV_COLOR_SCENE_CONTROLLER = 0x0810, LL_DEV_COLOR_SCENE_CONTROLLER = 0x0810,
LL_DEV_NON_COLOR_CONTROLLER = 0x0820, LL_DEV_NON_COLOR_CONTROLLER = 0x0820,
LL_DEV_NON_COLOR_SCENE_CONTROLLER = 0x0830, LL_DEV_NON_COLOR_SCENE_CONTROLLER = 0x0830,
LL_DEV_CONTROL_BRIDGE = 0x0840, LL_DEV_CONTROL_BRIDGE = 0x0840,
LL_DEV_ONOFF_SENSOR = 0x0850, LL_DEV_ONOFF_SENSOR = 0x0850,
}; };
enum ha_device_id { enum ha_device_id {
HA_DEV_ONOFF_SWITCH = 0x0000, HA_DEV_ONOFF_SWITCH = 0x0000,
HA_DEV_LEVEL_CTRL_SWITCH = 0x0001, HA_DEV_LEVEL_CTRL_SWITCH = 0x0001,
HA_DEV_ONOFF_OUTPUT = 0x0002, HA_DEV_ONOFF_OUTPUT = 0x0002,
HA_DEV_LEVEL_CTRLABLE_OUTPUT = 0x0003, HA_DEV_LEVEL_CTRLABLE_OUTPUT = 0x0003,
HA_DEV_SCENE_SELECTOR = 0x0004, HA_DEV_SCENE_SELECTOR = 0x0004,
HA_DEV_CONFIG_TOOL = 0x0005, HA_DEV_CONFIG_TOOL = 0x0005,
HA_DEV_REMOTE_CTRL = 0x0006, HA_DEV_REMOTE_CTRL = 0x0006,
HA_DEV_COMBINED_INTERFACE = 0x0007, HA_DEV_COMBINED_INTERFACE = 0x0007,
HA_DEV_RANGE_EXTENDER = 0x0008, HA_DEV_RANGE_EXTENDER = 0x0008,
HA_DEV_MAINS_PWR_OUTLET = 0x0009, HA_DEV_MAINS_PWR_OUTLET = 0x0009,
HA_DEV_DOOR_LOCK = 0x000A, HA_DEV_DOOR_LOCK = 0x000A,
HA_DEV_DOOR_LOCK_CTRLER = 0x000B, HA_DEV_DOOR_LOCK_CTRLER = 0x000B,
HA_DEV_SIMPLE_SENSOR = 0x000C, HA_DEV_SIMPLE_SENSOR = 0x000C,
HA_DEV_CONSUMPTION_AWARENESS = 0x000D, HA_DEV_CONSUMPTION_AWARENESS = 0x000D,
HA_DEV_HOME_GATEWAY = 0x0050, HA_DEV_HOME_GATEWAY = 0x0050,
HA_DEV_SMART_PLUG = 0x0051, HA_DEV_SMART_PLUG = 0x0051,
HA_DEV_WHITE_GOOD = 0x0052, HA_DEV_WHITE_GOOD = 0x0052,
HA_DEV_METER_INTERFACE = 0x0053, HA_DEV_METER_INTERFACE = 0x0053,
HA_DEV_ONOFF_LIGHT = 0x0100, HA_DEV_ONOFF_LIGHT = 0x0100,
HA_DEV_DIMMABLE_LIGHT = 0x0101, HA_DEV_DIMMABLE_LIGHT = 0x0101,
HA_DEV_COLOR_DIMMABLE_LIGHT = 0x0102, HA_DEV_COLOR_DIMMABLE_LIGHT = 0x0102,
HA_DEV_ONOFF_LIGHT_SWITCH = 0x0103, HA_DEV_ONOFF_LIGHT_SWITCH = 0x0103,
HA_DEV_DIMMER_SWITCH = 0x0104, HA_DEV_DIMMER_SWITCH = 0x0104,
HA_DEV_COLOR_DIMMER_SWITCH = 0x0105, HA_DEV_COLOR_DIMMER_SWITCH = 0x0105,
HA_DEV_LIGHT_SENSOR = 0x0106, HA_DEV_LIGHT_SENSOR = 0x0106,
HA_DEV_OCCUPANCY_SENSOR = 0x0107, HA_DEV_OCCUPANCY_SENSOR = 0x0107,
HA_DEV_ONOFF_BALLAST = 0x0108, HA_DEV_ONOFF_BALLAST = 0x0108,
HA_DEV_DIMMABLE_BALLAST = 0x0109, HA_DEV_DIMMABLE_BALLAST = 0x0109,
HA_DEV_ONOFF_PLUG_IN_UNIT = 0x010A, HA_DEV_ONOFF_PLUG_IN_UNIT = 0x010A,
HA_DEV_DIMMANLE_PLUG_IN_UNIT = 0x010B, HA_DEV_DIMMANLE_PLUG_IN_UNIT = 0x010B,
HA_DEV_COLOR_TEMPERATURE_LIGHT = 0x010C, HA_DEV_COLOR_TEMPERATURE_LIGHT = 0x010C,
HA_DEV_EXTENDED_COLOR_LIGHT = 0x010D, HA_DEV_EXTENDED_COLOR_LIGHT = 0x010D,
HA_DEV_LIGHT_LEVEL_SENSOR = 0x010E, HA_DEV_LIGHT_LEVEL_SENSOR = 0x010E,
HA_DEV_COLOR_CONTROLLER = 0x0800, HA_DEV_COLOR_CONTROLLER = 0x0800,
HA_DEV_COLOR_SCENE_CONTROLLER = 0x0810, HA_DEV_COLOR_SCENE_CONTROLLER = 0x0810,
HA_DEV_NON_COLOR_CONTROLLER = 0x0820, HA_DEV_NON_COLOR_CONTROLLER = 0x0820,
HA_DEV_NON_COLOR_SCENE_CONTROLLER = 0x0830, HA_DEV_NON_COLOR_SCENE_CONTROLLER = 0x0830,
HA_DEV_CONTROL_BRIDGE = 0x0840, HA_DEV_CONTROL_BRIDGE = 0x0840,
HA_DEV_ONOFF_SENSOR = 0x0850, HA_DEV_ONOFF_SENSOR = 0x0850,
HA_DEV_SHADE = 0x0200, HA_DEV_SHADE = 0x0200,
HA_DEV_SHADE_CTRLER = 0x0201, HA_DEV_SHADE_CTRLER = 0x0201,
HA_DEV_WINDOW_COVERING_DEVICE = 0x0202, HA_DEV_WINDOW_COVERING_DEVICE = 0x0202,
HA_DEV_WINDOW_COVERING_CTRLER = 0x0203, HA_DEV_WINDOW_COVERING_CTRLER = 0x0203,
HA_DEV_HEATING_COOLING_UNIT = 0x0300, HA_DEV_HEATING_COOLING_UNIT = 0x0300,
HA_DEV_THERMOSTAT = 0x0301, HA_DEV_THERMOSTAT = 0x0301,
HA_DEV_TEMPERATURE_SENSOR = 0x0302, HA_DEV_TEMPERATURE_SENSOR = 0x0302,
HA_DEV_PUMP = 0x0303, HA_DEV_PUMP = 0x0303,
HA_DEV_PUMP_CTRLER = 0x0304, HA_DEV_PUMP_CTRLER = 0x0304,
HA_DEV_PRESSURE_SENSOR = 0x0305, HA_DEV_PRESSURE_SENSOR = 0x0305,
HA_DEV_FLOW_SENSOR = 0x0306, HA_DEV_FLOW_SENSOR = 0x0306,
HA_DEV_IAS_CIE = 0x0400, HA_DEV_IAS_CIE = 0x0400,
HA_DEV_IAS_ACE = 0x0401, HA_DEV_IAS_ACE = 0x0401,
HA_DEV_IAS_ZONE = 0x0402, HA_DEV_IAS_ZONE = 0x0402,
HA_DEV_IAS_WD = 0x0403, HA_DEV_IAS_WD = 0x0403,
}; };
/** @addtogroup zb_bdb_tc_key_exchange_method TCLinkKeyExchangeMethod /** @addtogroup zb_bdb_tc_key_exchange_method TCLinkKeyExchangeMethod
* Definition for trust center key exchange method * Definition for trust center key exchange method
* @{ * @{
*/ */
enum{ enum{
TCKEY_EXCHANGE_METHOD_APSRK = 0, //<! APS Request Key TCKEY_EXCHANGE_METHOD_APSRK = 0, //<! APS Request Key
TCKEY_EXCHANGE_METHOD_CBKE = 1, //<! Certificate Based Key Exchange TCKEY_EXCHANGE_METHOD_CBKE = 1, //<! Certificate Based Key Exchange
TCKEY_EXCHANGE_METHOD_RESV //<! Reserved TCKEY_EXCHANGE_METHOD_RESV //<! Reserved
}; };
/** @} end of group zb_bdb_tc_key_exchange_method */ /** @} end of group zb_bdb_tc_key_exchange_method */
/** @addtogroup NodeJoinLinkKeyType /** @addtogroup NodeJoinLinkKeyType
* Definition for link key type with which the node was able to decrypt the network key when the node joins a new network. * Definition for link key type with which the node was able to decrypt the network key when the node joins a new network.
* @{ * @{
*/ */
enum{ enum{
LINKKEY_TYPE_TC = 0, //<! Default global Trust Center link key LINKKEY_TYPE_TC = 0, //<! Default global Trust Center link key
LINKKEY_TYPE_GB = 1, //<! Distributed security global link key LINKKEY_TYPE_GB = 1, //<! Distributed security global link key
LINKKEY_TYPE_PRECONFIG = 2, //<! Install code derived preconfigured link key LINKKEY_TYPE_PRECONFIG = 2, //<! Install code derived preconfigured link key
LINKKEY_TYPE_TL_PRECONFIG =3 //<! Touchlink preconfigured link key LINKKEY_TYPE_TL_PRECONFIG =3 //<! Touchlink preconfigured link key
}; };
/** @} end of group NodeJoinLinkKeyType */ /** @} end of group NodeJoinLinkKeyType */
/** @addtogroup CommissioningStatus /** @addtogroup CommissioningStatus
* Definition for Commissioning status. * Definition for Commissioning status.
* @{ * @{
*/ */
enum{ enum{
BDB_COMMISSION_STA_SUCCESS = 0, //<! The commissioning sub-procedure was successful. BDB_COMMISSION_STA_SUCCESS = 0, //<! The commissioning sub-procedure was successful.
BDB_COMMISSION_STA_IN_PROGRESS, //<! One of the commissioning sub-procedures has started but is not yet complete BDB_COMMISSION_STA_IN_PROGRESS, //<! One of the commissioning sub-procedures has started but is not yet complete
BDB_COMMISSION_STA_NOT_AA_CAPABLE, //<! The initiator is not address assignment capable during touchlink. BDB_COMMISSION_STA_NOT_AA_CAPABLE, //<! The initiator is not address assignment capable during touchlink.
BDB_COMMISSION_STA_NO_NETWORK, //<! A network has not been found during network steering or touchlink BDB_COMMISSION_STA_NO_NETWORK, //<! A network has not been found during network steering or touchlink
BDB_COMMISSION_STA_TARGET_FAILURE, //<! A node has not joined a network when requested during touchlink BDB_COMMISSION_STA_TARGET_FAILURE, //<! A node has not joined a network when requested during touchlink
BDB_COMMISSION_STA_FORMATION_FAILURE, //<! A network could not be formed during network formation. BDB_COMMISSION_STA_FORMATION_FAILURE, //<! A network could not be formed during network formation.
BDB_COMMISSION_STA_NO_IDENTIFY_QUERY_RESPONSE,//<! No response to an identify query command has been received during finding & binding BDB_COMMISSION_STA_NO_IDENTIFY_QUERY_RESPONSE,//<! No response to an identify query command has been received during finding & binding
BDB_COMMISSION_STA_BINDING_TABLE_FULL, //<! A binding table entry could not be created due to insufficient space in the binding table during finding & binding BDB_COMMISSION_STA_BINDING_TABLE_FULL, //<! A binding table entry could not be created due to insufficient space in the binding table during finding & binding
BDB_COMMISSION_STA_NO_SCAN_RESPONSE, //<! No response to a scan request inter-PAN command has been received during touchlink BDB_COMMISSION_STA_NO_SCAN_RESPONSE, //<! No response to a scan request inter-PAN command has been received during touchlink
BDB_COMMISSION_STA_NOT_PERMITTED, //<! A touchlink (steal) attempt was made when a node is already connected to a centralized security network BDB_COMMISSION_STA_NOT_PERMITTED, //<! A touchlink (steal) attempt was made when a node is already connected to a centralized security network
BDB_COMMISSION_STA_TCLK_EX_FAILURE, //<! The Trust Center link key exchange procedure has failed attempting to join a centralized security network. BDB_COMMISSION_STA_TCLK_EX_FAILURE, //<! The Trust Center link key exchange procedure has failed attempting to join a centralized security network.
BDB_COMMISSION_STA_PARENT_LOST, BDB_COMMISSION_STA_PARENT_LOST,
BDB_COMMISSION_STA_REJOIN_FAILURE, BDB_COMMISSION_STA_REJOIN_FAILURE,
BDB_COMMISSION_STA_FORMATION_DONE, BDB_COMMISSION_STA_FORMATION_DONE,
}; };
/** @} end of group CommissioningStatus */ /** @} end of group CommissioningStatus */
enum{ enum{
BDB_INIT_STATUS_SUCCESS = 0, BDB_INIT_STATUS_SUCCESS = 0,
BDB_INIT_STATUS_FAILURE, BDB_INIT_STATUS_FAILURE,
}; };
/** @addtogroup bdbAttrId /** @addtogroup bdbAttrId
* Definition for bdb attribute identifier * Definition for bdb attribute identifier
* @{ * @{
*/ */
enum{ enum{
BDB_ATTR_PRIMARY_CHANNEL_SET = 0x60, //!< attribute Identifier: primaryChannelSet BDB_ATTR_PRIMARY_CHANNEL_SET = 0x60, //!< attribute Identifier: primaryChannelSet
BDB_ATTR_SECONDARY_CHANNEL_SET, //!< attribute Identifier: secondaryChannelSet BDB_ATTR_SECONDARY_CHANNEL_SET, //!< attribute Identifier: secondaryChannelSet
BDB_ATTR_COMMISSIONING_GROUP_ID, //<! attribute Identifier: commissioningGroupId BDB_ATTR_COMMISSIONING_GROUP_ID, //<! attribute Identifier: commissioningGroupId
BDB_ATTR_COMMISSIONING_MODE, //<! attribute Identifier: commissioningMode BDB_ATTR_COMMISSIONING_MODE, //<! attribute Identifier: commissioningMode
BDB_ATTR_COMMISSIONING_STATUS, //<! attribute Identifier: commissioningStatus BDB_ATTR_COMMISSIONING_STATUS, //<! attribute Identifier: commissioningStatus
BDB_ATTR_JOINING_NODE_EUI64, //<! attribute Identifier: joiningNodeEui64 BDB_ATTR_JOINING_NODE_EUI64, //<! attribute Identifier: joiningNodeEui64
BDB_ATTR_JOINING_NODE_TC_LNKKEY, //!< attribute Identifier: joiningNodeNewTCLinkKey BDB_ATTR_JOINING_NODE_TC_LNKKEY, //!< attribute Identifier: joiningNodeNewTCLinkKey
BDB_ATTR_COMMISSIONING_CAP, //!< attribute Identifier: nodeCommissioningCapability BDB_ATTR_COMMISSIONING_CAP, //!< attribute Identifier: nodeCommissioningCapability
BDB_ATTR_JOIN_USE_INSTALL_CODE_KEY, //!< attribute Identifier: joinUsesInstallCodeKey BDB_ATTR_JOIN_USE_INSTALL_CODE_KEY, //!< attribute Identifier: joinUsesInstallCodeKey
BDB_ATTR_NODE_IS_ON_NETWORK, //!< attribute Identifier: nodeIsOnANetwork BDB_ATTR_NODE_IS_ON_NETWORK, //!< attribute Identifier: nodeIsOnANetwork
BDB_ATTR_NODE_JOIN_LNKKEY_TYPE, //!< attribute Identifier: nodeJoinLinkKeyType BDB_ATTR_NODE_JOIN_LNKKEY_TYPE, //!< attribute Identifier: nodeJoinLinkKeyType
BDB_ATTR_TC_REQUIRE_KEY_EXCHANGE, //!< attribute Identifier: tcRequireKeyExchange BDB_ATTR_TC_REQUIRE_KEY_EXCHANGE, //!< attribute Identifier: tcRequireKeyExchange
BDB_ATTR_SCAN_DURATION, //!< attribute Identifier: scanDuration BDB_ATTR_SCAN_DURATION, //!< attribute Identifier: scanDuration
BDB_ATTR_TC_LNKKEY_EXCHANGE_ATTEMPT, //!< attribute Identifier: tcLinkKeyExchangeAttempts BDB_ATTR_TC_LNKKEY_EXCHANGE_ATTEMPT, //!< attribute Identifier: tcLinkKeyExchangeAttempts
BDB_ATTR_TC_LNKKEY_EXCHANGE_ATTEMPT_MAX,//!< attribute Identifier: tcLinkKeyExchangeAttemptsMax BDB_ATTR_TC_LNKKEY_EXCHANGE_ATTEMPT_MAX,//!< attribute Identifier: tcLinkKeyExchangeAttemptsMax
BDB_ATTR_TC_LNKKEY_EXCHANGE_METHOD, //!< attribute Identifier: tcLinkKeyExchangeMethod BDB_ATTR_TC_LNKKEY_EXCHANGE_METHOD, //!< attribute Identifier: tcLinkKeyExchangeMethod
BDB_ATTR_TC_NODE_JOIN_TIMEOUT //!< attribute Identifier: tcNodeJoinTimeout BDB_ATTR_TC_NODE_JOIN_TIMEOUT //!< attribute Identifier: tcNodeJoinTimeout
}; };
/** @} end of group bdbAttrId */ /** @} end of group bdbAttrId */
enum{ enum{
BDB_STATE_IDLE = 0, BDB_STATE_IDLE = 0,
BDB_STATE_INIT, BDB_STATE_INIT,
BDB_STATE_COMMISSIONING_TOUCHLINK, BDB_STATE_COMMISSIONING_TOUCHLINK,
BDB_STATE_COMMISSIONING_NETWORK_STEER, BDB_STATE_COMMISSIONING_NETWORK_STEER,
BDB_STATE_COMMISSIONING_NETWORK_FORMATION, BDB_STATE_COMMISSIONING_NETWORK_FORMATION,
BDB_STATE_COMMISSIONING_FINDORBIND, BDB_STATE_COMMISSIONING_FINDORBIND,
BDB_STATE_COMMISSIONING_BUSY, BDB_STATE_COMMISSIONING_BUSY,
BDB_STATE_REJOIN_DONE, BDB_STATE_REJOIN_DONE,
}; };
enum{ enum{
BDB_EVT_IDLE, BDB_EVT_IDLE,
BDB_EVT_INIT_DONE, BDB_EVT_INIT_DONE,
BDB_EVT_COMMISSIONING_START, BDB_EVT_COMMISSIONING_START,
BDB_EVT_COMMISSIONING_TOUCHLINK_NO_RESP, BDB_EVT_COMMISSIONING_TOUCHLINK_NO_RESP,
BDB_EVT_COMMISSIONING_TOUCHLINK_FINISH, BDB_EVT_COMMISSIONING_TOUCHLINK_FINISH,
BDB_EVT_COMMISSIONING_NETWORK_STEER_PERMITJOIN, BDB_EVT_COMMISSIONING_NETWORK_STEER_PERMITJOIN,
BDB_EVT_COMMISSIONING_NETWORK_STEER_RETRIEVE_TCLINK_KEY, BDB_EVT_COMMISSIONING_NETWORK_STEER_RETRIEVE_TCLINK_KEY,
BDB_EVT_COMMISSIONING_NETWORK_STEER_FINISH, BDB_EVT_COMMISSIONING_NETWORK_STEER_FINISH,
BDB_EVT_COMMISSIONING_NETWORK_FORMATION_PERMITJOIN, BDB_EVT_COMMISSIONING_NETWORK_FORMATION_PERMITJOIN,
BDB_EVT_COMMISSIONING_NETWORK_FORMATION_FINISH, BDB_EVT_COMMISSIONING_NETWORK_FORMATION_FINISH,
BDB_EVT_COMMISSIONING_FINDORBIND_FINISH, BDB_EVT_COMMISSIONING_FINDORBIND_FINISH,
BDB_EVT_COMMISSIONING_FINDORBIND_SIMPLE_DESC_REQ, BDB_EVT_COMMISSIONING_FINDORBIND_SIMPLE_DESC_REQ,
}; };
/** /**
* Definition for network type * Definition for network type
* *
*/ */
enum{ enum{
NETWORK_TYPE_DISTRIBUTED, NETWORK_TYPE_DISTRIBUTED,
NETWORK_TYPE_CENTRALIZED, NETWORK_TYPE_CENTRALIZED,
}; };
/** /**
* Definition for the role during commissioning * Definition for the role during commissioning
* *
*/ */
enum{ enum{
BDB_COMMISSIONING_ROLE_NONE = 0, BDB_COMMISSIONING_ROLE_NONE = 0,
BDB_COMMISSIONING_ROLE_INITIATOR, BDB_COMMISSIONING_ROLE_INITIATOR,
BDB_COMMISSIONING_ROLE_TARGET BDB_COMMISSIONING_ROLE_TARGET
}; };
/** @addtogroup bdbAttributeIdentifierStruct /** @addtogroup bdbAttributeIdentifierStruct
* Definition struct for bdb Attribute Identifier table * Definition struct for bdb Attribute Identifier table
* @{ * @{
*/ */
typedef struct{ typedef struct{
u8 offset; //!< the offset of the attribute in the bdbAttribute struct u8 offset; //!< the offset of the attribute in the bdbAttribute struct
u8 len; //!< the length of the attribute in the bdbAttribute struct u8 len; //!< the length of the attribute in the bdbAttribute struct
}bdb_attrTbl_t; }bdb_attrTbl_t;
/** @} end of bdbAttributeIdentifierStruct */ /** @} end of bdbAttributeIdentifierStruct */
/** @addtogroup bdbCommissioningMode /** @addtogroup bdbCommissioningMode
* Definition for Commissioning Mode. * Definition for Commissioning Mode.
* @{ * @{
*/ */
typedef struct{ typedef struct{
u8 touchlink:1; //<! whether attempt Touchlink commissioning u8 touchlink:1; //<! whether attempt Touchlink commissioning
u8 networkSteer:1; //<! whether attempt network steering u8 networkSteer:1; //<! whether attempt network steering
u8 networkFormation:1; //<! whether attempt to form a network u8 networkFormation:1; //<! whether attempt to form a network
u8 findOrBind:1; //<! whether attempt finding & binding u8 findOrBind:1; //<! whether attempt finding & binding
u8 resv:4; //<! reserved u8 resv:4; //<! reserved
}bdb_commissioningMode_t; }bdb_commissioningMode_t;
/** @} end of group bdbCommissioningMode */ /** @} end of group bdbCommissioningMode */
/** @addtogroup NodeCommissioningCapability /** @addtogroup NodeCommissioningCapability
* Definition for commissioning capabilities struct. * Definition for commissioning capabilities struct.
* @{ * @{
*/ */
typedef enum{ typedef enum{
BDB_NODE_COMMISSION_CAP_STEER = (1 << 0), BDB_NODE_COMMISSION_CAP_STEER = (1 << 0),
BDB_NODE_COMMISSION_CAP_FORMATION = (1 << 1), BDB_NODE_COMMISSION_CAP_FORMATION = (1 << 1),
BDB_NODE_COMMISSION_CAP_FINDORBIND = (1 << 2), BDB_NODE_COMMISSION_CAP_FINDORBIND = (1 << 2),
BDB_NODE_COMMISSION_CAP_TOUCHLINK = (1 << 3), BDB_NODE_COMMISSION_CAP_TOUCHLINK = (1 << 3),
}bdb_nodeCommissioningCap_e; }bdb_nodeCommissioningCap_e;
/** @} end of group NodeCommissioningCapability */ /** @} end of group NodeCommissioningCapability */
/** @addtogroup zb_bdb_attr BDB Attributes /** @addtogroup zb_bdb_attr BDB Attributes
* Definition for Attributes for bdb * Definition for Attributes for bdb
* @{ * @{
*/ */
typedef struct{ typedef struct{
u32 primaryChannelSet; //!< the channel set, defined by the application u32 primaryChannelSet; //!< the channel set, defined by the application
u32 secondaryChannelSet; //!< the channel set, defined by the application u32 secondaryChannelSet; //!< the channel set, defined by the application
u16 commissioningGroupId; //<! the identifier of the group on which the initiator applies finding & binding. u16 commissioningGroupId; //<! the identifier of the group on which the initiator applies finding & binding.
bdb_commissioningMode_t commissioningMode; //<! the commissioning methods and options taken when commissioning is invoked bdb_commissioningMode_t commissioningMode; //<! the commissioning methods and options taken when commissioning is invoked
u8 commissioningStatus; //<! the status of its commissioning attempt u8 commissioningStatus; //<! the status of its commissioning attempt
addrExt_t joiningNodeEui64; //<! the EUI-64 of the node joining the centralized security network addrExt_t joiningNodeEui64; //<! the EUI-64 of the node joining the centralized security network
u8 joiningNodeNewTCLinkKey[16]; //!< the new link key established with the joining node but which has not yet been confirmed u8 joiningNodeNewTCLinkKey[16]; //!< the new link key established with the joining node but which has not yet been confirmed
bdb_nodeCommissioningCap_e nodeCommissioningCapability; //!< the commissioning capabilities of the node bdb_nodeCommissioningCap_e nodeCommissioningCapability; //!< the commissioning capabilities of the node
u8 joinUsesInstallCodeKey; //!< indicates whether it requires an install code derived preconfigured link key to be preinstalled, only for ZC u8 joinUsesInstallCodeKey; //!< indicates whether it requires an install code derived preconfigured link key to be preinstalled, only for ZC
u8 nodeIsOnANetwork; //!< indicates whether a node is joined to a network u8 nodeIsOnANetwork; //!< indicates whether a node is joined to a network
u8 nodeJoinLinkKeyType; //!< indicates the type of link key,only for ZR/ZED u8 nodeJoinLinkKeyType; //!< indicates the type of link key,only for ZR/ZED
u8 tcRequireKeyExchange; //!< whether the Trust Center requires a joining device to exchange its initial link key with a new link key generated by the Trust Center u8 tcRequireKeyExchange; //!< whether the Trust Center requires a joining device to exchange its initial link key with a new link key generated by the Trust Center
u8 scanDuration; //!< the duration of an IEEE 802.15.4 scan operation per channel u8 scanDuration; //!< the duration of an IEEE 802.15.4 scan operation per channel
u8 tcLinkKeyExchangeAttempts; //!< the number of key establishment attempts that have been made to establish a new link key after joining u8 tcLinkKeyExchangeAttempts; //!< the number of key establishment attempts that have been made to establish a new link key after joining
u8 tcLinkKeyExchangeAttemptsMax; //!< the maximum number of key establishment attempts that will be made before giving up on the key establishment u8 tcLinkKeyExchangeAttemptsMax; //!< the maximum number of key establishment attempts that will be made before giving up on the key establishment
u8 tcLinkKeyExchangeMethod; //!< the method used to establish a new link key u8 tcLinkKeyExchangeMethod; //!< the method used to establish a new link key
u8 tcNodeJoinTimeout; //<! a timeout in seconds for the Trust Center to remove the Trust Center link key f the newly joined node that did not successfully establish a new link key u8 tcNodeJoinTimeout; //<! a timeout in seconds for the Trust Center to remove the Trust Center link key f the newly joined node that did not successfully establish a new link key
u8 resv[2]; u8 resv[2];
}bdb_attr_t; }bdb_attr_t;
/** @} end of group zb_bdb_attr */ /** @} end of group zb_bdb_attr */
#define FIND_BIND_QUEUE_SIZE 5 #define FIND_BIND_QUEUE_SIZE 5
typedef struct{ typedef struct{
u16 addr; u16 addr;
u8 endpoint; u8 endpoint;
u8 resv; u8 resv;
}findBindDst_t; }findBindDst_t;
typedef struct{ typedef struct{
findBindDst_t findBindDstInfo[FIND_BIND_QUEUE_SIZE]; findBindDst_t findBindDstInfo[FIND_BIND_QUEUE_SIZE];
u8 front; u8 front;
u8 rear; u8 rear;
}findBindQ_t; }findBindQ_t;
typedef void (*bdb_initAppCb_t)(u8 status, u8 joinedNetwork); typedef void (*bdb_initAppCb_t)(u8 status, u8 joinedNetwork);
typedef void (*bdb_commissioningAppCb_t)(u8 status, void *arg); typedef void (*bdb_commissioningAppCb_t)(u8 status, void *arg);
typedef void (*bdb_zclIdentifyCb_t)(u8 endpoint, u16 srcAddr, u16 identifyTime); typedef void (*bdb_zclIdentifyCb_t)(u8 endpoint, u16 srcAddr, u16 identifyTime);
typedef void (*bdb_findBindSuccessCb_t)(findBindDst_t *pDstInfo); typedef void (*bdb_findBindSuccessCb_t)(findBindDst_t *pDstInfo);
/* /*
* @brief Definition for zll commissioning type * @brief Definition for zll commissioning type
* *
* */ * */
typedef struct{ typedef struct{
bdb_initAppCb_t bdbInitCb; bdb_initAppCb_t bdbInitCb;
bdb_commissioningAppCb_t bdbcommissioningCb; bdb_commissioningAppCb_t bdbcommissioningCb;
bdb_zclIdentifyCb_t bdbIdentifyCb; bdb_zclIdentifyCb_t bdbIdentifyCb;
bdb_findBindSuccessCb_t bdbFindBindSuccessCb; bdb_findBindSuccessCb_t bdbFindBindSuccessCb;
}bdb_appCb_t; }bdb_appCb_t;
typedef struct{ typedef struct{
u8 *key; /* the key used */ u8 *key; /* the key used */
u8 keyType; /* ERTIFICATION_KEY or MASTER_KEY key for touch-link or distribute network u8 keyType; /* ERTIFICATION_KEY or MASTER_KEY key for touch-link or distribute network
SS_UNIQUE_LINK_KEY or SS_GLOBAL_LINK_KEY for central network */ SS_UNIQUE_LINK_KEY or SS_GLOBAL_LINK_KEY for central network */
}bdb_linkKey_t; }bdb_linkKey_t;
typedef struct{ typedef struct{
bdb_linkKey_t tcLinkKey; /* pre-configure tc link key for central network: bdb_linkKey_t tcLinkKey; /* pre-configure tc link key for central network:
global tc link key: ZC/ZR/ZED; global tc link key: ZC/ZR/ZED;
unique tc link key: only for ZR/ZED, unique tc link key: only for ZR/ZED,
if ZC is using unique link key, need to access paieKeySet to set/get link key */ if ZC is using unique link key, need to access paieKeySet to set/get link key */
bdb_linkKey_t distributeLinkKey; /* link key for distribute network, for distribute network */ bdb_linkKey_t distributeLinkKey; /* link key for distribute network, for distribute network */
bdb_linkKey_t touchLinkKey; /* touch link key, for distribute network */ bdb_linkKey_t touchLinkKey; /* touch link key, for distribute network */
}bdb_linkKey_info_t; }bdb_linkKey_info_t;
/** @addtogroup bdb_joinNetworkkSetting_t BDB commissioning settings /** @addtogroup bdb_joinNetworkkSetting_t BDB commissioning settings
* Definition for commissioning settings for bdb * Definition for commissioning settings for bdb
* @{ * @{
*/ */
typedef struct{ typedef struct{
bdb_linkKey_info_t linkKey; bdb_linkKey_info_t linkKey;
u8 touchlinkEnable; /* enable/disable touch-link */ u8 touchlinkEnable; /* enable/disable touch-link */
u8 touchlinkChannel; /* operation channel for touch-link target */ u8 touchlinkChannel; /* operation channel for touch-link target */
u8 touchlinkLqiThreshold; /* threshold for touch-link scan req/resp command */ u8 touchlinkLqiThreshold; /* threshold for touch-link scan req/resp command */
}bdb_commissionSetting_t; }bdb_commissionSetting_t;
/** @} end of group bdb_joinNetworkkSetting_t */ /** @} end of group bdb_joinNetworkkSetting_t */
/** @addtogroup zb_bdb_ctx BDB context /** @addtogroup zb_bdb_ctx BDB context
* Definition for context for bdb * Definition for context for bdb
* @{ * @{
*/ */
typedef struct{ typedef struct{
af_simple_descriptor_t *simpleDesc; af_simple_descriptor_t *simpleDesc;
bdb_commissionSetting_t *commissionSettings; bdb_commissionSetting_t *commissionSettings;
union{ union{
ev_timer_event_t *identifyTimer; ev_timer_event_t *identifyTimer;
ev_timer_event_t *retrieveTcLkKeyTimer; ev_timer_event_t *retrieveTcLkKeyTimer;
}; };
bdb_appCb_t *bdbAppCb; bdb_appCb_t *bdbAppCb;
findBindQ_t *pFindBindQ; findBindQ_t *pFindBindQ;
u16 *clusterList; u16 *clusterList;
u16 *matchClusterList; u16 *matchClusterList;
findBindDst_t findDstInfo; findBindDst_t findDstInfo;
findBindDst_t bindDstInfo; findBindDst_t bindDstInfo;
u8 clusterNum; u8 clusterNum;
u8 matchClusterNum; u8 matchClusterNum;
u8 networkType; u8 networkType;
u8 state; u8 state;
u8 status; u8 status;
u8 role; u8 role;
u8 channel; u8 channel;
u8 inited:1; u8 inited:1;
u8 factoryNew:1; u8 factoryNew:1;
u8 leaveDoing:1; u8 leaveDoing:1;
u8 resv:5; u8 resv:5;
u8 initResult; u8 initResult;
}bdb_ctx_t; }bdb_ctx_t;
/** @} end of group zb_bdb_ctx */ /** @} end of group zb_bdb_ctx */
extern bdb_attr_t g_bdbAttrs; extern bdb_attr_t g_bdbAttrs;
extern bdb_ctx_t g_bdbCtx; extern bdb_ctx_t g_bdbCtx;
#define BDB_ATTR() g_bdbAttrs #define BDB_ATTR() g_bdbAttrs
#define PRE_INSTALL_KEY_ENABLE(type) do{ \ #define PRE_INSTALL_KEY_ENABLE(type) do{ \
g_bdbAttrs.joinUsesInstallCodeKey = 1; \ g_bdbAttrs.joinUsesInstallCodeKey = 1; \
g_bdbAttrs.nodeJoinLinkKeyType = type; \ g_bdbAttrs.nodeJoinLinkKeyType = type; \
}while(0) }while(0)
#define NODE_COMMISSIONING_CAPABILITY_SET(v) g_bdbAttrs.nodeCommissioningCapability = v; #define NODE_COMMISSIONING_CAPABILITY_SET(v) g_bdbAttrs.nodeCommissioningCapability = v;
#define BDB_STATE_SET(v) g_bdbCtx.state = v #define BDB_STATE_SET(v) g_bdbCtx.state = v
#define BDB_STATE_GET() g_bdbCtx.state #define BDB_STATE_GET() g_bdbCtx.state
#define BDB_STATUS_SET(v) g_bdbCtx.status = v #define BDB_STATUS_SET(v) g_bdbCtx.status = v
#define BDB_STATUS_GET() g_bdbCtx.status #define BDB_STATUS_GET() g_bdbCtx.status
#define BDB_ATTR_GROUP_ID_SET(v) g_bdbAttrs.commissioningGroupId = v #define BDB_ATTR_GROUP_ID_SET(v) g_bdbAttrs.commissioningGroupId = v
/** /**
* @brief bdb initialization * @brief bdb initialization
* *
* @param[in] simple_desc - the pointer to device's simple description * @param[in] simple_desc - the pointer to device's simple description
* @param[in] setting - bdb commissioning settings * @param[in] setting - bdb commissioning settings
* @param[in] cb - call back for bdb * @param[in] cb - call back for bdb
* @param[in] repower - 1: real power-on, 0: from deep sleep * @param[in] repower - 1: real power-on, 0: from deep sleep
* *
* @return None * @return None
*/ */
u8 bdb_init(af_simple_descriptor_t *simple_desc, bdb_commissionSetting_t *setting, bdb_appCb_t *cb, u8 repower); u8 bdb_init(af_simple_descriptor_t *simple_desc, bdb_commissionSetting_t *setting, bdb_appCb_t *cb, u8 repower);
/** /**
* @brief commissioning: form a network * @brief commissioning: form a network
* *
* @param[in] none * @param[in] none
* @param[in] repower - 1: real power-on, 0: from deep sleep * @param[in] repower - 1: real power-on, 0: from deep sleep
* *
* @return None * @return None
*/ */
u8 bdb_networkFormationStart(void); u8 bdb_networkFormationStart(void);
/** /**
* @brief commissioning: steer a network * @brief commissioning: steer a network
* *
* @param[in] none * @param[in] none
* *
* @return None * @return None
*/ */
u8 bdb_networkSteerStart(void); u8 bdb_networkSteerStart(void);
/** /**
* @brief commissioning: touch-link, only used for touch-link initiator, * @brief commissioning: touch-link, only used for touch-link initiator,
* for touch-link target, only need to call bdb_touchlinkEnable() before bdb_init() * for touch-link target, only need to call bdb_touchlinkEnable() before bdb_init()
* *
* @param[in] role: BDB_COMMISSIONING_ROLE_INITIATOR or BDB_COMMISSIONING_ROLE_TARGET * @param[in] role: BDB_COMMISSIONING_ROLE_INITIATOR or BDB_COMMISSIONING_ROLE_TARGET
* *
* @return None * @return None
*/ */
u8 bdb_networkTouchLinkStart(u8 role); u8 bdb_networkTouchLinkStart(u8 role);
/** /**
* @brief commissioning: finding & binding * @brief commissioning: finding & binding
* initiator: it will be timeout if it can't receive identify response within 5s * initiator: it will be timeout if it can't receive identify response within 5s
* target: it will close identify timer after 3mins * target: it will close identify timer after 3mins
* *
* @param[in] role: BDB_COMMISSIONING_ROLE_INITIATOR or BDB_COMMISSIONING_ROLE_TARGET * @param[in] role: BDB_COMMISSIONING_ROLE_INITIATOR or BDB_COMMISSIONING_ROLE_TARGET
* *
* @return None * @return None
*/ */
u8 bdb_findAndBindStart(u8 role); u8 bdb_findAndBindStart(u8 role);
/** /**
* @brief bdb finding and binding match cluster list set, only for initiator * @brief bdb finding and binding match cluster list set, only for initiator
* *
* @param[in] clusterNum: * @param[in] clusterNum:
* @param[in] clusterId: * @param[in] clusterId:
* *
* @return None * @return None
*/ */
void bdb_findBindMatchClusterSet(u8 clusterNum, u16 clusterId[]); void bdb_findBindMatchClusterSet(u8 clusterNum, u16 clusterId[]);
/** /**
* @brief bdb finding and binding active endpoint add, only for initiator * @brief bdb finding and binding active endpoint add, only for initiator
* *
* @param[in] dstInfo * @param[in] dstInfo
* *
* @return None * @return None
*/ */
bool bdb_addIdentifyActiveEpForFB(findBindDst_t dstInfo); bool bdb_addIdentifyActiveEpForFB(findBindDst_t dstInfo);
/** /**
* @brief bdb default reporting config * @brief bdb default reporting config
* *
* @param[in] endpoint: * @param[in] endpoint:
* @param[in] profileID: * @param[in] profileID:
* @param[in] clusterID: * @param[in] clusterID:
* @param[in] attrID: * @param[in] attrID:
* @param[in] minReportInt: * @param[in] minReportInt:
* @param[in] maxReportInt: * @param[in] maxReportInt:
* @param[in] reportableChange: * @param[in] reportableChange:
* *
* @return status_t * @return status_t
*/ */
status_t bdb_defaultReportingCfg(u8 endpoint, u16 profileID, u16 clusterID, u16 attrID, u16 minReportInt, u16 maxReportInt, u8 *reportableChange); status_t bdb_defaultReportingCfg(u8 endpoint, u16 profileID, u16 clusterID, u16 attrID, u16 minReportInt, u16 maxReportInt, u8 *reportableChange);
/* /*
* @fn bdb_zdoStartDevCnf * @fn bdb_zdoStartDevCnf
* *
* @brief node start confirm handle * @brief node start confirm handle
* *
* @param startDevCnf * @param startDevCnf
* *
*/ */
void bdb_zdoStartDevCnf(zdo_start_device_confirm_t *startDevCnf); void bdb_zdoStartDevCnf(zdo_start_device_confirm_t *startDevCnf);
/** /**
* @brief bdb attribute initialization * @brief bdb attribute initialization
* *
* @param[in] none * @param[in] none
* *
* @return None * @return None
*/ */
void tl_bdbAttrInit(void); void tl_bdbAttrInit(void);
/** /**
* @brief Load install code from NV * @brief Load install code from NV
* *
* @param[out] keyType * @param[out] keyType
* @param[out] derivedKey * @param[out] derivedKey
* *
* @return RET_OK or RET_NOT_FOUND * @return RET_OK or RET_NOT_FOUND
*/ */
u8 bdb_preInstallCodeLoad(u8 *keyType, u8 derivedKey[]); u8 bdb_preInstallCodeLoad(u8 *keyType, u8 derivedKey[]);
/** /**
* @brief Add pre-install code to NV * @brief Add pre-install code to NV
* *
* @param[in] ieeeAddr: the ieee address of the device using unique link key join * @param[in] ieeeAddr: the ieee address of the device using unique link key join
* *
* @param[in] pInstallCode: the pointer of install code * @param[in] pInstallCode: the pointer of install code
* *
* @return None * @return None
*/ */
void bdb_preInstallCodeAdd(addrExt_t ieeeAddr, u8 *pInstallCode); void bdb_preInstallCodeAdd(addrExt_t ieeeAddr, u8 *pInstallCode);
/** /**
* @brief bdb re-start * @brief bdb re-start
* *
* @param[in] none * @param[in] none
* *
* @return None * @return None
*/ */
void tl_bdbReset(void); void tl_bdbReset(void);
/** /**
* @brief reset to factory-new device * @brief reset to factory-new device
* *
* @param[in] none * @param[in] none
* *
* @return None * @return None
*/ */
void tl_bdbReset2FN(void); void tl_bdbReset2FN(void);
/** /**
* @brief bdb_retrieveTcLinkKeyDone * @brief bdb_retrieveTcLinkKeyDone
* *
* @param[in] status * @param[in] status
* *
* @return None * @return None
*/ */
void bdb_retrieveTcLinkKeyDone(u8 status); void bdb_retrieveTcLinkKeyDone(u8 status);
/** /**
* @brief check the bdb state * @brief check the bdb state
* *
* @param 1: idle, 0: busy * @param 1: idle, 0: busy
* *
* @return * @return
*/ */
bool bdb_isIdle(void); bool bdb_isIdle(void);
/** /**
* @brief bdb_linkKeyCfg * @brief bdb_linkKeyCfg
* *
* @param[in] setting * @param[in] setting
* @param[in] isFactoryNew * @param[in] isFactoryNew
* *
* @return None * @return None
*/ */
void bdb_linkKeyCfg(bdb_commissionSetting_t *setting, u8 isFactoryNew); void bdb_linkKeyCfg(bdb_commissionSetting_t *setting, u8 isFactoryNew);
/** @} end of group zb_bdb_attr */ /** @} end of group zb_bdb_attr */
/** @} end of group TELINK_ZIGBEE_INTERPAN */ /** @} end of group TELINK_ZIGBEE_INTERPAN */
/** @} end of group TELINK_ZIGBEE_STACK */ /** @} end of group TELINK_ZIGBEE_STACK */
#endif /* BDB_H */ #endif /* BDB_H */
/******************************************************************************************************** /********************************************************************************************************
* @file mac_phy.c * @file mac_phy.c
* *
* @brief This is the source file for mac_phy * @brief This is the source file for mac_phy
* *
* @author Zigbee Group * @author Zigbee Group
* @date 2019 * @date 2019
* *
* @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") * @par Copyright (c) 2019, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Unless for usage inside a TELINK integrated circuit, redistributions * 2. Unless for usage inside a TELINK integrated circuit, redistributions
* in binary form must reproduce the above copyright notice, this list of * in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other * conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. * materials provided with the distribution.
* *
* 3. Neither the name of TELINK, nor the names of its contributors may be * 3. Neither the name of TELINK, nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. This software, with or without modification, must only be used with a * 4. This software, with or without modification, must only be used with a
* TELINK integrated circuit. All other usages are subject to written permission * TELINK integrated circuit. All other usages are subject to written permission
* from TELINK and different commercial license may apply. * from TELINK and different commercial license may apply.
* *
* 5. Licensee shall be solely responsible for any claim to the extent arising out of or * 5. Licensee shall be solely responsible for any claim to the extent arising out of or
* relating to such deletion(s), modification(s) or alteration(s). * relating to such deletion(s), modification(s) or alteration(s).
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************************************/ *******************************************************************************************************/
/********************************************************************** /**********************************************************************
* INCLUDES * INCLUDES
*/ */
#include "../common/includes/zb_common.h" #include "../common/includes/zb_common.h"
#include "compiler.h" #include "compiler.h"
/********************************************************************** /**********************************************************************
* LOCAL CONSTANTS * LOCAL CONSTANTS
*/ */
#define LOGICCHANNEL_TO_PHYSICAL(p) (((p)-10)*5) #define LOGICCHANNEL_TO_PHYSICAL(p) (((p)-10)*5)
#define RF_DROP_REASON_INVALID_CRC 0x01 #define RF_DROP_REASON_INVALID_CRC 0x01
#define RF_DROP_REASON_RF_BUSY 0x02 #define RF_DROP_REASON_RF_BUSY 0x02
#define RF_DROP_REASON_EXPECT_ACK 0x03 #define RF_DROP_REASON_EXPECT_ACK 0x03
#define RF_DROP_REASON_INVALIC_BEACON 0x04 #define RF_DROP_REASON_INVALIC_BEACON 0x04
#define RF_DROP_REASON_FILTER_PANID 0x05 #define RF_DROP_REASON_FILTER_PANID 0x05
#define RF_DROP_REASON_FILTER_DSTADDR 0x06 #define RF_DROP_REASON_FILTER_DSTADDR 0x06
#define RF_DROP_REASON_FILTER_LEN 0x07 #define RF_DROP_REASON_FILTER_LEN 0x07
#define RF_DROP_REASON_INVALIC_FRAME_TYPE 0x08 #define RF_DROP_REASON_INVALIC_FRAME_TYPE 0x08
/********************************************************************** /**********************************************************************
* LOCAL TYPEDEFS * LOCAL TYPEDEFS
*/ */
typedef enum{ typedef enum{
RF_GAIN_MODE_AUTO, RF_GAIN_MODE_AUTO,
RF_GAIN_MODE_MANU_MAX, RF_GAIN_MODE_MANU_MAX,
}rf_rxGainMode_t; }rf_rxGainMode_t;
/********************************************************************** /**********************************************************************
* GLOBAL VARIABLES * GLOBAL VARIABLES
*/ */
u8 g_zb_txPowerSet = ZB_DEFAULT_TX_POWER_IDX; u8 g_zb_txPowerSet = ZB_DEFAULT_TX_POWER_IDX;
/********************************************************************** /**********************************************************************
* LOCAL VARIABLES * LOCAL VARIABLES
*/ */
_attribute_aligned_(4) u8 rf_tx_buf[ZB_RADIO_TX_HDR_LEN + 127]; _attribute_aligned_(4) u8 rf_tx_buf[ZB_RADIO_TX_HDR_LEN + 127];
_attribute_aligned_(4) u8 rf_ack_buf[ZB_RADIO_TX_HDR_LEN + 7]; _attribute_aligned_(4) u8 rf_ack_buf[ZB_RADIO_TX_HDR_LEN + 7];
u8 *rf_rxBuf = NULL; u8 *rf_rxBuf = NULL;
u8 rfMode = RF_STATE_TX; u8 rfMode = RF_STATE_TX;
volatile u8 rf_busyFlag = 0; volatile u8 rf_busyFlag = 0;
volatile s8 soft_rssi; volatile s8 soft_rssi;
volatile s32 sum_rssi, cnt_rssi = 1; volatile s32 sum_rssi, cnt_rssi = 1;
u8 fPaEn; u8 fPaEn;
u32 rf_pa_txen_pin; u32 rf_pa_txen_pin;
u32 rf_pa_rxen_pin; u32 rf_pa_rxen_pin;
/********************************************************************** /**********************************************************************
* LOCAL FUNCTIONS * LOCAL FUNCTIONS
*/ */
#define ZB_SWTICH_TO_TXMODE() do{ \ #define ZB_SWTICH_TO_TXMODE() do{ \
if(fPaEn) { \ if(fPaEn) { \
drv_gpio_write(rf_pa_txen_pin, 1); \ drv_gpio_write(rf_pa_txen_pin, 1); \
drv_gpio_write(rf_pa_rxen_pin, 0); \ drv_gpio_write(rf_pa_rxen_pin, 0); \
} \ } \
ZB_RADIO_TRX_SWITCH(RF_MODE_TX, LOGICCHANNEL_TO_PHYSICAL(rf_getChannel())); \ ZB_RADIO_TRX_SWITCH(RF_MODE_TX, LOGICCHANNEL_TO_PHYSICAL(rf_getChannel())); \
}while(0) }while(0)
#define ZB_SWTICH_TO_RXMODE() do{ \ #define ZB_SWTICH_TO_RXMODE() do{ \
if(fPaEn) { \ if(fPaEn) { \
drv_gpio_write(rf_pa_txen_pin, 0); \ drv_gpio_write(rf_pa_txen_pin, 0); \
drv_gpio_write(rf_pa_rxen_pin, 1); \ drv_gpio_write(rf_pa_rxen_pin, 1); \
} \ } \
ZB_RADIO_TRX_SWITCH(RF_MODE_RX, LOGICCHANNEL_TO_PHYSICAL(rf_getChannel())); \ ZB_RADIO_TRX_SWITCH(RF_MODE_RX, LOGICCHANNEL_TO_PHYSICAL(rf_getChannel())); \
}while(0) }while(0)
/********************************************************************* /*********************************************************************
* @fn rf_reset * @fn rf_reset
* *
* @brief Reset RF module and do the RF power up. * @brief Reset RF module and do the RF power up.
* *
* @param none * @param none
* *
* @return none * @return none
*/ */
void rf_reset(void) void rf_reset(void)
{ {
rf_setTrxState(RF_STATE_TX); rf_setTrxState(RF_STATE_TX);
rf_setTxPower(g_zb_txPowerSet); rf_setTxPower(g_zb_txPowerSet);
rf_setChannel(g_zbMacPib.phyChannelCur); rf_setChannel(g_zbMacPib.phyChannelCur);
if(rf_rxBuf){ if(rf_rxBuf){
rf_setRxBuf(rf_rxBuf); rf_setRxBuf(rf_rxBuf);
}else{ }else{
rf_setRxBuf(tl_getRxBuf()); rf_setRxBuf(tl_getRxBuf());
} }
ZB_RADIO_TRX_CFG(RF_PKT_BUFF_LEN); ZB_RADIO_TRX_CFG(RF_PKT_BUFF_LEN);
ZB_RADIO_RX_ENABLE; ZB_RADIO_RX_ENABLE;
ZB_RADIO_TX_ENABLE; ZB_RADIO_TX_ENABLE;
ZB_TIMESTAMP_ENABLE; ZB_TIMESTAMP_ENABLE;
} }
static void rf_edDetect(void) static void rf_edDetect(void)
{ {
s8 rssi; s8 rssi;
rssi = ZB_RADIO_RSSI_GET(); rssi = ZB_RADIO_RSSI_GET();
//soft_rssi = rssi;//(rssi + soft_rssi)/2; //soft_rssi = rssi;//(rssi + soft_rssi)/2;
sum_rssi += rssi; sum_rssi += rssi;
if(++cnt_rssi >= 0xfffffe){ if(++cnt_rssi >= 0xfffffe){
sum_rssi = sum_rssi / cnt_rssi; sum_rssi = sum_rssi / cnt_rssi;
cnt_rssi = 1; cnt_rssi = 1;
} }
} }
static void rf_mac_ack_build(void) static void rf_mac_ack_build(void)
{ {
/* ack buf */ /* ack buf */
memset(rf_ack_buf, 0, 12); memset(rf_ack_buf, 0, 12);
ZB_RADIO_DMA_HDR_BUILD(rf_ack_buf, 3); ZB_RADIO_DMA_HDR_BUILD(rf_ack_buf, 3);
rf_ack_buf[4] = 5; rf_ack_buf[4] = 5;
rf_ack_buf[5] = 0x02; rf_ack_buf[5] = 0x02;
rf_ack_buf[6] = 0x00; rf_ack_buf[6] = 0x00;
} }
/********************************************************************* /*********************************************************************
* @fn rf_init * @fn rf_init
* *
* @brief Initialize RF module and do the RF power up. * @brief Initialize RF module and do the RF power up.
* *
* @param none * @param none
* *
* @return none * @return none
*/ */
void rf_init(void) void rf_init(void)
{ {
rf_reset(); rf_reset();
rf_mac_ack_build(); rf_mac_ack_build();
/* Register ED-Scan polling function, but disable it at beginning. */ /* Register ED-Scan polling function, but disable it at beginning. */
ev_on_poll(EV_POLL_ED_DETECT, rf_edDetect); ev_on_poll(EV_POLL_ED_DETECT, rf_edDetect);
ev_disable_poll(EV_POLL_ED_DETECT); ev_disable_poll(EV_POLL_ED_DETECT);
} }
/********************************************************************* /*********************************************************************
* @fn rf_setRxBuf * @fn rf_setRxBuf
* *
* @brief Set RX buffer to dma and enable DMA. * @brief Set RX buffer to dma and enable DMA.
* *
* @param pBuf - the allocated rx buffer * @param pBuf - the allocated rx buffer
* *
* @return none * @return none
*/ */
void rf_setRxBuf(u8 *pBuf) void rf_setRxBuf(u8 *pBuf)
{ {
rf_rxBuf = pBuf; rf_rxBuf = pBuf;
ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf); ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf);
ZB_RADIO_RX_BUF_SET(rf_rxBuf);//todo: 826x/8258 need fix rf driver ZB_RADIO_RX_BUF_SET(rf_rxBuf);//todo: 826x/8258 need fix rf driver
} }
/********************************************************************* /*********************************************************************
* @fn rf_TrxStateGet * @fn rf_TrxStateGet
* *
* @brief Get current TRX state. * @brief Get current TRX state.
* *
* @param none * @param none
* *
* @return state * @return state
*/ */
u8 rf_TrxStateGet(void) u8 rf_TrxStateGet(void)
{ {
return rfMode; return rfMode;
} }
/********************************************************************* /*********************************************************************
* @fn rf_setTrxState * @fn rf_setTrxState
* *
* @brief Go to specified state and set related register. * @brief Go to specified state and set related register.
* *
* @param state - Specified state * @param state - Specified state
* *
* @return none * @return none
*/ */
_attribute_ram_code_ void rf_setTrxState(u8 state) _attribute_ram_code_ void rf_setTrxState(u8 state)
{ {
#ifndef WIN32 #ifndef WIN32
if(RF_STATE_RX == state || RF_STATE_ED == state){ if(RF_STATE_RX == state || RF_STATE_ED == state){
if(TL_ZB_MAC_STATUS_GET() == ZB_MAC_STATE_ACTIVE_SCAN || RF_STATE_ED == state){ if(TL_ZB_MAC_STATUS_GET() == ZB_MAC_STATE_ACTIVE_SCAN || RF_STATE_ED == state){
ZB_RADIO_MODE_AUTO_GAIN(); ZB_RADIO_MODE_AUTO_GAIN();
}else{ }else{
ZB_RADIO_MODE_MAX_GAIN(); ZB_RADIO_MODE_MAX_GAIN();
} }
ZB_SWTICH_TO_RXMODE(); ZB_SWTICH_TO_RXMODE();
rfMode = RF_STATE_RX; rfMode = RF_STATE_RX;
}else if(RF_STATE_TX == state){ }else if(RF_STATE_TX == state){
ZB_SWTICH_TO_TXMODE(); ZB_SWTICH_TO_TXMODE();
WaitUs(ZB_TX_WAIT_US); WaitUs(ZB_TX_WAIT_US);
rfMode = RF_STATE_TX; rfMode = RF_STATE_TX;
}else{ }else{
/* Close RF */ /* Close RF */
rf_paShutDown(); rf_paShutDown();
ZB_RADIO_TRX_SWITCH(RF_MODE_OFF, LOGICCHANNEL_TO_PHYSICAL(rf_getChannel())); ZB_RADIO_TRX_SWITCH(RF_MODE_OFF, LOGICCHANNEL_TO_PHYSICAL(rf_getChannel()));
rfMode = RF_STATE_OFF; rfMode = RF_STATE_OFF;
} }
#endif /* WIN32 */ #endif /* WIN32 */
} }
/********************************************************************* /*********************************************************************
* @fn rf_setChannel * @fn rf_setChannel
* *
* @brief Set specified channel to RF module. * @brief Set specified channel to RF module.
* *
* @param chn - 11~26 * @param chn - 11~26
* *
* @return none * @return none
*/ */
void rf_setChannel(u8 chn) void rf_setChannel(u8 chn)
{ {
if((chn < TL_ZB_MAC_CHANNEL_START) || (chn > TL_ZB_MAC_CHANNEL_STOP)){ if((chn < TL_ZB_MAC_CHANNEL_START) || (chn > TL_ZB_MAC_CHANNEL_STOP)){
return; return;
} }
g_zbMacPib.phyChannelCur = chn; g_zbMacPib.phyChannelCur = chn;
ZB_RADIO_TRX_SWITCH(ZB_RADIO_TRX_STA_GET(), LOGICCHANNEL_TO_PHYSICAL(chn)); ZB_RADIO_TRX_SWITCH(ZB_RADIO_TRX_STA_GET(), LOGICCHANNEL_TO_PHYSICAL(chn));
} }
/********************************************************************* /*********************************************************************
* @fn rf_getChannel * @fn rf_getChannel
* *
* @brief Get specified channel. * @brief Get specified channel.
* *
* @param none * @param none
* *
* @return chn * @return chn
*/ */
inline u8 rf_getChannel(void) inline u8 rf_getChannel(void)
{ {
return g_zbMacPib.phyChannelCur; return g_zbMacPib.phyChannelCur;
} }
/********************************************************************* /*********************************************************************
* @fn rf_setTxPower * @fn rf_setTxPower
* *
* @brief Set specified transmitted power. * @brief Set specified transmitted power.
* *
* @param txPower - Specified power * @param txPower - Specified power
* *
* @return none * @return none
*/ */
void rf_setTxPower(u8 power) void rf_setTxPower(u8 power)
{ {
if(fPaEn){ if(fPaEn){
ZB_RADIO_TX_POWER_SET(ZB_RADIO_TX_0DBM); ZB_RADIO_TX_POWER_SET(ZB_RADIO_TX_0DBM);
}else{ }else{
ZB_RADIO_TX_POWER_SET(power); ZB_RADIO_TX_POWER_SET(power);
} }
} }
/********************************************************************* /*********************************************************************
* @fn rf_getLqi * @fn rf_getLqi
* *
* @brief Get calculated Link Quality value * @brief Get calculated Link Quality value
* *
* @param rssi * @param rssi
* *
* @return lqi result * @return lqi result
*/ */
u8 rf_getLqi(s8 rssi) u8 rf_getLqi(s8 rssi)
{ {
rf_rxGainMode_t mode = RF_GAIN_MODE_MANU_MAX; rf_rxGainMode_t mode = RF_GAIN_MODE_MANU_MAX;
if(TL_ZB_MAC_STATUS_GET() == ZB_MAC_STATE_ACTIVE_SCAN){ if(TL_ZB_MAC_STATUS_GET() == ZB_MAC_STATE_ACTIVE_SCAN){
mode = RF_GAIN_MODE_AUTO; mode = RF_GAIN_MODE_AUTO;
} }
u8 lqi = 0; u8 lqi = 0;
ZB_RADIO_RSSI_TO_LQI(mode, rssi, lqi); ZB_RADIO_RSSI_TO_LQI(mode, rssi, lqi);
return lqi; return lqi;
} }
/********************************************************************* /*********************************************************************
* @fn rf_startED * @fn rf_startED
* *
* @brief Start ED detect * @brief Start ED detect
* *
* @param none * @param none
* *
* @return none * @return none
*/ */
void rf_startED(void) void rf_startED(void)
{ {
#ifndef WIN32 #ifndef WIN32
soft_rssi = -110; soft_rssi = -110;
sum_rssi = 0; sum_rssi = 0;
cnt_rssi = 0; cnt_rssi = 0;
ev_enable_poll(EV_POLL_ED_DETECT); ev_enable_poll(EV_POLL_ED_DETECT);
/* Change to ED mode */ /* Change to ED mode */
rf_setTrxState(RF_STATE_ED); rf_setTrxState(RF_STATE_ED);
#endif #endif
} }
/********************************************************************* /*********************************************************************
* @fn rf_stopED * @fn rf_stopED
* *
* @brief Stop Energy Detect * @brief Stop Energy Detect
* *
* @param none * @param none
* *
* @return ED result * @return ED result
*/ */
u8 rf_stopED(void) u8 rf_stopED(void)
{ {
#ifndef WIN32 #ifndef WIN32
u8 ed; u8 ed;
u32 temp; u32 temp;
if(cnt_rssi == 0) cnt_rssi = 1; if(cnt_rssi == 0) cnt_rssi = 1;
soft_rssi = sum_rssi/cnt_rssi; soft_rssi = sum_rssi/cnt_rssi;
ev_disable_poll(EV_POLL_ED_DETECT);/*WISE_FIX_ME*/ ev_disable_poll(EV_POLL_ED_DETECT);/*WISE_FIX_ME*/
/* Transfer the RSSI value to ED value */ /* Transfer the RSSI value to ED value */
if(soft_rssi <= -106){ if(soft_rssi <= -106){
ed = 0; ed = 0;
}else if(soft_rssi >= -6){ }else if(soft_rssi >= -6){
ed = 0xff; ed = 0xff;
}else{ }else{
temp = (soft_rssi + 106) * 255; temp = (soft_rssi + 106) * 255;
ed = temp/100; ed = temp/100;
} }
return ed; return ed;
#else #else
return 0; return 0;
#endif #endif
} }
_attribute_ram_code_ u8 rf_performCCA(void) _attribute_ram_code_ u8 rf_performCCA(void)
{ {
u32 t1 = clock_time(); u32 t1 = clock_time();
s8 rssi_peak = -110; s8 rssi_peak = -110;
s8 rssi_cur = -110; s8 rssi_cur = -110;
s32 rssiSum = 0; s32 rssiSum = 0;
s32 cnt = 1; s32 cnt = 1;
rssi_cur = ZB_RADIO_RSSI_GET(); rssi_cur = ZB_RADIO_RSSI_GET();
rssiSum += rssi_cur; rssiSum += rssi_cur;
while(!clock_time_exceed(t1,128)){ while(!clock_time_exceed(t1,128)){
rssi_cur = ZB_RADIO_RSSI_GET(); rssi_cur = ZB_RADIO_RSSI_GET();
rssiSum += rssi_cur; rssiSum += rssi_cur;
cnt++; cnt++;
} }
rssi_peak = rssiSum/cnt; rssi_peak = rssiSum/cnt;
if(rssi_peak > CCA_THRESHOLD || (rf_busyFlag & TX_BUSY)){//Return if currently in TX state if(rssi_peak > CCA_THRESHOLD || (rf_busyFlag & TX_BUSY)){//Return if currently in TX state
return PHY_CCA_BUSY; return PHY_CCA_BUSY;
}else{ }else{
return PHY_CCA_IDLE; return PHY_CCA_IDLE;
} }
} }
void rf802154_tx_ready(u8 *buf, u8 len) void rf802154_tx_ready(u8 *buf, u8 len)
{ {
/* Fill the telink RF header */ /* Fill the telink RF header */
ZB_RADIO_DMA_HDR_BUILD(rf_tx_buf, len); ZB_RADIO_DMA_HDR_BUILD(rf_tx_buf, len);
rf_tx_buf[4] = len + 2; rf_tx_buf[4] = len + 2;
memcpy(rf_tx_buf + 5, buf, len); memcpy(rf_tx_buf + 5, buf, len);
} }
_attribute_ram_code_ void rf802154_tx(void) _attribute_ram_code_ void rf802154_tx(void)
{ {
rf_setTrxState(RF_STATE_TX); rf_setTrxState(RF_STATE_TX);
ZB_RADIO_TX_DONE_CLR; ZB_RADIO_TX_DONE_CLR;
ZB_RADIO_RX_DONE_CLR; ZB_RADIO_RX_DONE_CLR;
ZB_RADIO_TX_START(rf_tx_buf);//Manual mode ZB_RADIO_TX_START(rf_tx_buf);//Manual mode
} }
/********************************************************************* /*********************************************************************
* @fn rf_paInit * @fn rf_paInit
* *
* @brief Initialize PA. * @brief Initialize PA.
* *
* @param none * @param none
* *
* @param none * @param none
* *
* @return none * @return none
*/ */
void rf_paInit(u32 TXEN_pin, u32 RXEN_pin) void rf_paInit(u32 TXEN_pin, u32 RXEN_pin)
{ {
rf_pa_txen_pin = TXEN_pin; rf_pa_txen_pin = TXEN_pin;
rf_pa_rxen_pin = RXEN_pin; rf_pa_rxen_pin = RXEN_pin;
drv_gpio_func_set(rf_pa_txen_pin); drv_gpio_func_set(rf_pa_txen_pin);
drv_gpio_output_en(rf_pa_txen_pin, 1); drv_gpio_output_en(rf_pa_txen_pin, 1);
drv_gpio_write(rf_pa_txen_pin, 0); drv_gpio_write(rf_pa_txen_pin, 0);
drv_gpio_func_set(rf_pa_rxen_pin); drv_gpio_func_set(rf_pa_rxen_pin);
drv_gpio_output_en(rf_pa_rxen_pin, 1); drv_gpio_output_en(rf_pa_rxen_pin, 1);
drv_gpio_write(rf_pa_rxen_pin, 1); drv_gpio_write(rf_pa_rxen_pin, 1);
fPaEn = 1; fPaEn = 1;
} }
_attribute_ram_code_ void rf_paShutDown(void) _attribute_ram_code_ void rf_paShutDown(void)
{ {
if(fPaEn){ if(fPaEn){
drv_gpio_write(rf_pa_txen_pin, 0); // PA TX_DIS drv_gpio_write(rf_pa_txen_pin, 0); // PA TX_DIS
drv_gpio_write(rf_pa_rxen_pin, 0); // PA RX_DIS drv_gpio_write(rf_pa_rxen_pin, 0); // PA RX_DIS
} }
} }
/********************************************************************* /*********************************************************************
* @fn rf_rx_irq_handler * @fn rf_rx_irq_handler
* *
* @brief RX irq handler * @brief RX irq handler
* *
* @param none * @param none
* *
* @return none * @return none
*/ */
_attribute_ram_code_ __attribute__((optimize("-Os"))) void rf_rx_irq_handler(void) _attribute_ram_code_ __attribute__((optimize("-Os"))) void rf_rx_irq_handler(void)
{ {
u8 *p = rf_rxBuf; u8 *p = rf_rxBuf;
u8 fAck = 0; u8 fAck = 0;
u8 fDrop = 0; u8 fDrop = 0;
s32 txTime = 0; s32 txTime = 0;
s32 txDelayUs = 0; s32 txDelayUs = 0;
ZB_RADIO_RX_DISABLE; ZB_RADIO_RX_DISABLE;
g_sysDiags.macRxIrqCnt++; g_sysDiags.macRxIrqCnt++;
#if 0 #if 0
static s32 rfRxCnt = 0; static s32 rfRxCnt = 0;
s8 rssi = ZB_RADION_PKT_RSSI_GET(p) - 110; s8 rssi = ZB_RADION_PKT_RSSI_GET(p) - 110;
T_rxRssiBuf[rfRxCnt++ & 0x3f] = rssi; T_rxRssiBuf[rfRxCnt++ & 0x3f] = rssi;
T_rxRssiPass[0]++; T_rxRssiPass[0]++;
if(rssi < RSSI_PASS_THRESHOLD){ if(rssi < RSSI_PASS_THRESHOLD){
ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf); ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf);
ZB_RADIO_RX_ENABLE; ZB_RADIO_RX_ENABLE;
return; return;
} }
T_rxRssiPass[1]++; T_rxRssiPass[1]++;
#endif #endif
/************************************************************* /*************************************************************
* rf_busyFlag & TX_BUSY, means a packet received before during csma delay call back interrupt called, * rf_busyFlag & TX_BUSY, means a packet received before during csma delay call back interrupt called,
* should drop this packet * should drop this packet
*/ */
if( (!ZB_RADIO_CRC_OK(p)) || (!ZB_RADIO_PACKET_LENGTH_OK(p)) || (rf_busyFlag&TX_BUSY) ){ if( (!ZB_RADIO_CRC_OK(p)) || (!ZB_RADIO_PACKET_LENGTH_OK(p)) || (rf_busyFlag&TX_BUSY) ){
/* diagnostics MAC layer receive error packet */ /* diagnostics MAC layer receive error packet */
g_sysDiags.macRxCrcFail++; g_sysDiags.macRxCrcFail++;
ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf); ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf);
ZB_RADIO_RX_ENABLE; ZB_RADIO_RX_ENABLE;
return; return;
} }
/* Parse necessary field to be used later */ /* Parse necessary field to be used later */
u8 len = (u8)ZB_RADIO_ACTUAL_PAYLOAD_LEN(p); u8 len = (u8)ZB_RADIO_ACTUAL_PAYLOAD_LEN(p);
u8 *macPld = p + ZB_RADIO_RX_HDR_LEN; u8 *macPld = p + ZB_RADIO_RX_HDR_LEN;
/*---------------------------------------------------------- /*----------------------------------------------------------
* Do the filter * Do the filter
*/ */
u8 *pSrcAddr = zb_macDataFilter(macPld, len, &fDrop, &fAck); u8 *pSrcAddr = zb_macDataFilter(macPld, len, &fDrop, &fAck);
if(fDrop){ if(fDrop){
/* Drop the packet and recover the DMA */ /* Drop the packet and recover the DMA */
ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf); ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf);
ZB_RADIO_RX_ENABLE; ZB_RADIO_RX_ENABLE;
return; return;
} }
/* switch to tx in advance to let the pll stable */ /* switch to tx in advance to let the pll stable */
if(macPld[0] & MAC_FCF_ACK_REQ_BIT){ if(macPld[0] & MAC_FCF_ACK_REQ_BIT){
ZB_SWTICH_TO_TXMODE(); ZB_SWTICH_TO_TXMODE();
txTime = clock_time(); txTime = clock_time();
} }
/* if don't have enough buffer, use current rxBuf, and drop it */ /* if don't have enough buffer, use current rxBuf, and drop it */
u8 *rxNextBuf = tl_getRxBuf(); u8 *rxNextBuf = tl_getRxBuf();
if(!rxNextBuf){ if(!rxNextBuf){
if(macPld[0] & MAC_FCF_ACK_REQ_BIT){ if(macPld[0] & MAC_FCF_ACK_REQ_BIT){
ZB_SWTICH_TO_RXMODE(); ZB_SWTICH_TO_RXMODE();
} }
/* diagnostics PHY to MAC queue limit */ /* diagnostics PHY to MAC queue limit */
g_sysDiags.phytoMACqueuelimitreached++; g_sysDiags.phytoMACqueuelimitreached++;
ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf); ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf);
ZB_RADIO_RX_ENABLE; ZB_RADIO_RX_ENABLE;
return; return;
} }
/* Use the backup buffer to receive next packet */ /* Use the backup buffer to receive next packet */
rf_rxBuf = rxNextBuf; rf_rxBuf = rxNextBuf;
ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf); ZB_RADIO_RX_BUF_CLEAR(rf_rxBuf);
ZB_RADIO_RX_BUF_SET(rf_rxBuf); ZB_RADIO_RX_BUF_SET(rf_rxBuf);
/*---------------------------------------------------------- /*----------------------------------------------------------
* Send ACK * Send ACK
*/ */
if(macPld[0] & MAC_FCF_ACK_REQ_BIT){ if(macPld[0] & MAC_FCF_ACK_REQ_BIT){
rf_ack_buf[ZB_RADIO_TX_HDR_LEN+2] = macPld[2]; //seqnno rf_ack_buf[ZB_RADIO_TX_HDR_LEN+2] = macPld[2]; //seqnno
rf_ack_buf[ZB_RADIO_TX_HDR_LEN] = 0x02; rf_ack_buf[ZB_RADIO_TX_HDR_LEN] = 0x02;
#if defined ZB_COORDINATOR_ROLE || defined ZB_ROUTER_ROLE #if defined ZB_COORDINATOR_ROLE || defined ZB_ROUTER_ROLE
u16 fcf = (macPld[1] << 8) | macPld[0]; // frame control u16 fcf = (macPld[1] << 8) | macPld[0]; // frame control
u8 pldOft = tl_zbMacHdrSize(fcf); u8 pldOft = tl_zbMacHdrSize(fcf);
u8 frameType = (fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_POS; u8 frameType = (fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_POS;
bool cmdDataReq = ((frameType == MAC_FRAME_COMMAND) && (macPld[pldOft] == MAC_CMD_DATA_REQUEST)); bool cmdDataReq = ((frameType == MAC_FRAME_COMMAND) && (macPld[pldOft] == MAC_CMD_DATA_REQUEST));
/* if has pending data, set the pending bit as 1 */ /* if has pending data, set the pending bit as 1 */
u8 srcAddrMode = ZB_ADDR_NO_ADDR; u8 srcAddrMode = ZB_ADDR_NO_ADDR;
if((macPld[1] & MAC_FCF_SRC_ADDR_BIT) == 0x80){ if((macPld[1] & MAC_FCF_SRC_ADDR_BIT) == 0x80){
srcAddrMode = ZB_ADDR_16BIT_DEV_OR_BROADCAST; srcAddrMode = ZB_ADDR_16BIT_DEV_OR_BROADCAST;
}else if((macPld[1] & MAC_FCF_SRC_ADDR_BIT) == 0xc0){ }else if((macPld[1] & MAC_FCF_SRC_ADDR_BIT) == 0xc0){
srcAddrMode = ZB_ADDR_64BIT_DEV; srcAddrMode = ZB_ADDR_64BIT_DEV;
} }
if(cmdDataReq && srcAddrMode){ if(cmdDataReq && srcAddrMode){
extern u8 tl_zbMacPendingDataCheck(u8 addrMode, u8 *addr, u8 send); extern u8 tl_zbMacPendingDataCheck(u8 addrMode, u8 *addr, u8 send);
if(MAC_SUCCESS == tl_zbMacPendingDataCheck(srcAddrMode, pSrcAddr, 1)){ if(MAC_SUCCESS == tl_zbMacPendingDataCheck(srcAddrMode, pSrcAddr, 1)){
rf_ack_buf[ZB_RADIO_TX_HDR_LEN] |= (1 << 4);// (rf_framePending<<4 ); rf_ack_buf[ZB_RADIO_TX_HDR_LEN] |= (1 << 4);// (rf_framePending<<4 );
} }
} }
#else #else
(void)pSrcAddr; (void)pSrcAddr;
#endif #endif
txDelayUs = (clock_time() - txTime) / S_TIMER_CLOCK_1US; txDelayUs = (clock_time() - txTime) / S_TIMER_CLOCK_1US;
if(txDelayUs < ZB_TX_WAIT_US){ if(txDelayUs < ZB_TX_WAIT_US){
WaitUs(ZB_TX_WAIT_US - txDelayUs); WaitUs(ZB_TX_WAIT_US - txDelayUs);
} }
/* wait until tx done, /* wait until tx done,
* disable tx irq here, rfMode still is RF_STATE_RX; * disable tx irq here, rfMode still is RF_STATE_RX;
* */ * */
/* clear rf interrupt mask bit*/ /* clear rf interrupt mask bit*/
ZB_RADIO_IRQ_MASK_CLR; ZB_RADIO_IRQ_MASK_CLR;
/* start to send ack */ /* start to send ack */
ZB_RADIO_TX_START(rf_ack_buf);//Manual Mode ZB_RADIO_TX_START(rf_ack_buf);//Manual Mode
/* wait until tx done or timeout */ /* wait until tx done or timeout */
u32 cur_tick = clock_time(); u32 cur_tick = clock_time();
while(!ZB_RADIO_TX_DONE && !clock_time_exceed(cur_tick, 1000)); while(!ZB_RADIO_TX_DONE && !clock_time_exceed(cur_tick, 1000));
/* clear the tx done status */ /* clear the tx done status */
ZB_RADIO_TX_DONE_CLR; ZB_RADIO_TX_DONE_CLR;
/* set interrupt mask bit again */ /* set interrupt mask bit again */
ZB_RADIO_IRQ_MASK_SET; ZB_RADIO_IRQ_MASK_SET;
/* rf is set to rx mode again */ /* rf is set to rx mode again */
ZB_SWTICH_TO_RXMODE(); ZB_SWTICH_TO_RXMODE();
} }
/* enable rf rx dma again */ /* enable rf rx dma again */
ZB_RADIO_RX_ENABLE; ZB_RADIO_RX_ENABLE;
/* zb_mac_receive_data handler */ /* zb_mac_receive_data handler */
zb_macDataRecvHander(p, macPld, len, fAck, ZB_RADIO_TIMESTAMP_GET(p), ZB_RADION_PKT_RSSI_GET(p) - 110); zb_macDataRecvHander(p, macPld, len, fAck, ZB_RADIO_TIMESTAMP_GET(p), ZB_RADION_PKT_RSSI_GET(p) - 110);
} }
/********************************************************************* /*********************************************************************
* @fn rf_tx_irq_handler * @fn rf_tx_irq_handler
* *
* @brief Tx Interrupt handler for RF module. * @brief Tx Interrupt handler for RF module.
* *
* @param none * @param none
* *
* @return none * @return none
*/ */
_attribute_ram_code_ __attribute__((optimize("-Os"))) void rf_tx_irq_handler(void) _attribute_ram_code_ __attribute__((optimize("-Os"))) void rf_tx_irq_handler(void)
{ {
rf_busyFlag &= ~TX_BUSY;//Clear TX busy flag after receive TX done signal rf_busyFlag &= ~TX_BUSY;//Clear TX busy flag after receive TX done signal
g_sysDiags.macTxIrqCnt++; g_sysDiags.macTxIrqCnt++;
rfMode = RF_STATE_RX; rfMode = RF_STATE_RX;
ZB_SWTICH_TO_RXMODE(); ZB_SWTICH_TO_RXMODE();
zb_macDataSendHander(); zb_macDataSendHander();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment