Other Parts Discussed in Thread: CC2538, Z-STACK
Hi
When i enable watchdog, event of keys generate only 1 time then my endpoint does not receive any event of keys.
But when i disable the watchdog, it is work fine.
Please guide me.
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I do the test and don't see similar problem. I attach my zcl_samplelight.c for your reference.
/**************************************************************************************************
Filename: zcl_sampleLight.c
Revised: $Date: 2014-10-24 16:04:46 -0700 (Fri, 24 Oct 2014) $
Revision: $Revision: 40796 $
Description: Zigbee Cluster Library - sample device application.
Copyright 2006-2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/*********************************************************************
This application implements a ZigBee HA 1.2 Light. It can be configured as an
On/Off light, or as a dimmable light. The following flags must be defined in
the compiler's pre-defined symbols.
ZCL_ON_OFF
ZCL_LEVEL_CTRL (only if dimming functionality desired)
HOLD_AUTO_START
ZCL_EZMODE
This device supports all mandatory and optional commands/attributes for the
OnOff (0x0006) and LevelControl (0x0008) clusters.
SCREEN MODES
----------------------------------------
Main:
- SW1: Toggle local light
- SW2: Invoke EZMode
- SW4: Enable/Disable local permit join
- SW5: Go to Help screen
----------------------------------------
*********************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "ZComDef.h"
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "MT_SYS.h"
#include "nwk_util.h"
#include "zcl.h"
#include "zcl_general.h"
#include "zcl_ha.h"
#include "zcl_ezmode.h"
#include "zcl_diagnostic.h"
#include "zcl_samplelight.h"
#include "onboard.h"
#include "watchdog.h"
/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#if ( defined (ZGP_DEVICE_TARGET) || defined (ZGP_DEVICE_TARGETPLUS) \
|| defined (ZGP_DEVICE_COMBO) || defined (ZGP_DEVICE_COMBO_MIN) )
#include "zgp_translationtable.h"
#if (SUPPORTED_S_FEATURE(SUPP_ZGP_FEATURE_TRANSLATION_TABLE))
#define ZGP_AUTO_TT
#endif
#endif
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
#include "math.h"
#include "hal_timer.h"
#endif
#include "NLMEDE.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#if (defined HAL_BOARD_ZLIGHT)
#define LEVEL_MAX 0xFE
#define LEVEL_MIN 0x0
#define GAMMA_VALUE 2
#define PWM_FULL_DUTY_CYCLE 1000
#elif (defined HAL_PWM)
#define LEVEL_MAX 0xFE
#define LEVEL_MIN 0x0
#define GAMMA_VALUE 2
#define PWM_FULL_DUTY_CYCLE 100
#endif
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
byte zclSampleLight_TaskID;
uint8 zclSampleLightSeqNum;
/*********************************************************************
* GLOBAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
afAddrType_t zclSampleLight_DstAddr;
#ifdef ZCL_EZMODE
static void zclSampleLight_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
static void zclSampleLight_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData );
// register EZ-Mode with task information (timeout events, callback, etc...)
static const zclEZMode_RegisterData_t zclSampleLight_RegisterEZModeData =
{
&zclSampleLight_TaskID,
SAMPLELIGHT_EZMODE_NEXTSTATE_EVT,
SAMPLELIGHT_EZMODE_TIMEOUT_EVT,
&zclSampleLightSeqNum,
zclSampleLight_EZModeCB
};
#else
uint16 bindingInClusters[] =
{
ZCL_CLUSTER_ID_GEN_ON_OFF
#ifdef ZCL_LEVEL_CTRL
, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL
#endif
};
#define ZCLSAMPLELIGHT_BINDINGLIST (sizeof(bindingInClusters) / sizeof(bindingInClusters[0]))
#endif // ZCL_EZMODE
// Test Endpoint to allow SYS_APP_MSGs
static endPointDesc_t sampleLight_TestEp =
{
SAMPLELIGHT_ENDPOINT,
&zclSampleLight_TaskID,
(SimpleDescriptionFormat_t *)NULL, // No Simple description for this test endpoint
(afNetworkLatencyReq_t)0 // No Network Latency req
};
uint8 giLightScreenMode = LIGHT_MAINMODE; // display the main screen mode first
uint8 gPermitDuration = 0; // permit joining default to disabled
devStates_t zclSampleLight_NwkState = DEV_INIT;
#if ZCL_LEVEL_CTRL
uint8 zclSampleLight_WithOnOff; // set to TRUE if state machine should set light on/off
uint8 zclSampleLight_NewLevel; // new level when done moving
bool zclSampleLight_NewLevelUp; // is direction to new level up or down?
int32 zclSampleLight_CurrentLevel32; // current level, fixed point (e.g. 192.456)
int32 zclSampleLight_Rate32; // rate in units, fixed point (e.g. 16.123)
uint8 zclSampleLight_LevelLastLevel; // to save the Current Level before the light was turned OFF
#endif
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void zclSampleLight_HandleKeys( byte shift, byte keys );
static void zclSampleLight_BasicResetCB( void );
static void zclSampleLight_IdentifyCB( zclIdentify_t *pCmd );
static void zclSampleLight_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
static void zclSampleLight_OnOffCB( uint8 cmd );
static void zclSampleLight_ProcessIdentifyTimeChange( void );
#ifdef ZCL_LEVEL_CTRL
static void zclSampleLight_LevelControlMoveToLevelCB( zclLCMoveToLevel_t *pCmd );
static void zclSampleLight_LevelControlMoveCB( zclLCMove_t *pCmd );
static void zclSampleLight_LevelControlStepCB( zclLCStep_t *pCmd );
static void zclSampleLight_LevelControlStopCB( void );
static void zclSampleLight_DefaultMove( void );
static uint32 zclSampleLight_TimeRateHelper( uint8 newLevel );
static uint16 zclSampleLight_GetTime ( uint8 level, uint16 time );
static void zclSampleLight_MoveBasedOnRate( uint8 newLevel, uint32 rate );
static void zclSampleLight_MoveBasedOnTime( uint8 newLevel, uint16 time );
static void zclSampleLight_AdjustLightLevel( void );
#endif
// app display functions
static void zclSampleLight_LcdDisplayUpdate( void );
#ifdef LCD_SUPPORTED
static void zclSampleLight_LcdDisplayMainMode( void );
static void zclSampleLight_LcdDisplayHelpMode( void );
#endif
static void zclSampleLight_DisplayLight( void );
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
void zclSampleLight_UpdateLampLevel( uint8 level );
#endif
// Functions to process ZCL Foundation incoming Command/Response messages
static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *msg );
#ifdef ZCL_READ
static uint8 zclSampleLight_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
#endif
#ifdef ZCL_WRITE
static uint8 zclSampleLight_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
#endif
static uint8 zclSampleLight_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
#ifdef ZCL_DISCOVER
static uint8 zclSampleLight_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg );
static uint8 zclSampleLight_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg );
static uint8 zclSampleLight_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg );
#endif
/*********************************************************************
* STATUS STRINGS
*/
#ifdef LCD_SUPPORTED
const char sDeviceName[] = " Sample Light";
const char sClearLine[] = " ";
const char sSwLight[] = "SW1: ToggleLight"; // 16 chars max
const char sSwEZMode[] = "SW2: EZ-Mode";
char sSwHelp[] = "SW5: Help "; // last character is * if NWK open
const char sLightOn[] = " LIGHT ON ";
const char sLightOff[] = " LIGHT OFF";
#if ZCL_LEVEL_CTRL
char sLightLevel[] = " LEVEL ###"; // displays level 1-254
#endif
#endif
/*********************************************************************
* ZCL General Profile Callback table
*/
static zclGeneral_AppCallbacks_t zclSampleLight_CmdCallbacks =
{
zclSampleLight_BasicResetCB, // Basic Cluster Reset command
zclSampleLight_IdentifyCB, // Identify command
#ifdef ZCL_EZMODE
NULL, // Identify EZ-Mode Invoke command
NULL, // Identify Update Commission State command
#endif
NULL, // Identify Trigger Effect command
zclSampleLight_IdentifyQueryRspCB, // Identify Query Response command
zclSampleLight_OnOffCB, // On/Off cluster commands
NULL, // On/Off cluster enhanced command Off with Effect
NULL, // On/Off cluster enhanced command On with Recall Global Scene
NULL, // On/Off cluster enhanced command On with Timed Off
#ifdef ZCL_LEVEL_CTRL
zclSampleLight_LevelControlMoveToLevelCB, // Level Control Move to Level command
zclSampleLight_LevelControlMoveCB, // Level Control Move command
zclSampleLight_LevelControlStepCB, // Level Control Step command
zclSampleLight_LevelControlStopCB, // Level Control Stop command
#endif
#ifdef ZCL_GROUPS
NULL, // Group Response commands
#endif
#ifdef ZCL_SCENES
NULL, // Scene Store Request command
NULL, // Scene Recall Request command
NULL, // Scene Response command
#endif
#ifdef ZCL_ALARMS
NULL, // Alarm (Response) commands
#endif
#ifdef SE_UK_EXT
NULL, // Get Event Log command
NULL, // Publish Event Log command
#endif
NULL, // RSSI Location command
NULL // RSSI Location Response command
};
/*********************************************************************
* @fn zclSampleLight_Init
*
* @brief Initialization function for the zclGeneral layer.
*
* @param none
*
* @return none
*/
void zclSampleLight_Init( byte task_id )
{
zclSampleLight_TaskID = task_id;
// Set destination address to indirect
zclSampleLight_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
zclSampleLight_DstAddr.endPoint = 0;
zclSampleLight_DstAddr.addr.shortAddr = 0;
// This app is part of the Home Automation Profile
zclHA_Init( &zclSampleLight_SimpleDesc );
// Register the ZCL General Cluster Library callback functions
zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks );
// Register the application's attribute list
zcl_registerAttrList( SAMPLELIGHT_ENDPOINT, zclSampleLight_NumAttributes, zclSampleLight_Attrs );
// Register the Application to receive the unprocessed Foundation command/response messages
zcl_registerForMsg( zclSampleLight_TaskID );
#ifdef ZCL_DISCOVER
// Register the application's command list
zcl_registerCmdList( SAMPLELIGHT_ENDPOINT, zclCmdsArraySize, zclSampleLight_Cmds );
#endif
// Register for all key events - This app will handle all key events
RegisterForKeys( zclSampleLight_TaskID );
// Register for a test endpoint
afRegister( &sampleLight_TestEp );
#ifdef ZCL_EZMODE
// Register EZ-Mode
zcl_RegisterEZMode( &zclSampleLight_RegisterEZModeData );
// Register with the ZDO to receive Match Descriptor Responses
ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
#endif
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
HalTimer1Init( 0 );
halTimer1SetChannelDuty( WHITE_LED, 0 );
halTimer1SetChannelDuty( RED_LED, 0 );
halTimer1SetChannelDuty( BLUE_LED, 0 );
halTimer1SetChannelDuty( GREEN_LED, 0 );
// find if we are already on a network from NV_RESTORE
uint8 state;
NLME_GetRequest( nwkNwkState, 0, &state );
if ( state < NWK_ENDDEVICE )
{
// Start EZMode on Start up to avoid button press
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_START_EZMODE_EVT, 500 );
}
#if ZCL_LEVEL_CTRL
zclSampleLight_DefaultMove();
#endif
#endif // #if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
#ifdef ZCL_DIAGNOSTIC
// Register the application's callback function to read/write attribute data.
// This is only required when the attribute data format is unknown to ZCL.
zcl_registerReadWriteCB( SAMPLELIGHT_ENDPOINT, zclDiagnostic_ReadWriteAttrCB, NULL );
if ( zclDiagnostic_InitStats() == ZSuccess )
{
// Here the user could start the timer to save Diagnostics to NV
}
#endif
#ifdef LCD_SUPPORTED
HalLcdWriteString ( (char *)sDeviceName, HAL_LCD_LINE_3 );
#endif // LCD_SUPPORTED
#ifdef ZGP_AUTO_TT
zgpTranslationTable_RegisterEP ( &zclSampleLight_SimpleDesc );
#endif
WatchdogEnable( WATCHDOG_INTERVAL_32768 );
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LIGHT_WATCHDOG_EVT, 100);
}
/*********************************************************************
* @fn zclSample_event_loop
*
* @brief Event Loop Processor for zclGeneral.
*
* @param none
*
* @return none
*/
uint16 zclSampleLight_event_loop( uint8 task_id, uint16 events )
{
afIncomingMSGPacket_t *MSGpkt;
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleLight_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
#ifdef ZCL_EZMODE
case ZDO_CB_MSG:
zclSampleLight_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
#endif
case ZCL_INCOMING_MSG:
// Incoming ZCL Foundation command/response messages
zclSampleLight_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
zclSampleLight_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case ZDO_STATE_CHANGE:
zclSampleLight_NwkState = (devStates_t)(MSGpkt->hdr.status);
// now on the network
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
giLightScreenMode = LIGHT_MAINMODE;
zclSampleLight_LcdDisplayUpdate();
#ifdef ZCL_EZMODE
zcl_EZModeAction( EZMODE_ACTION_NETWORK_STARTED, NULL );
#endif // ZCL_EZMODE
}
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT )
{
if ( zclSampleLight_IdentifyTime > 0 )
zclSampleLight_IdentifyTime--;
zclSampleLight_ProcessIdentifyTimeChange();
return ( events ^ SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT );
}
if ( events & SAMPLELIGHT_MAIN_SCREEN_EVT )
{
giLightScreenMode = LIGHT_MAINMODE;
zclSampleLight_LcdDisplayUpdate();
return ( events ^ SAMPLELIGHT_MAIN_SCREEN_EVT );
}
#ifdef ZCL_EZMODE
#if (defined HAL_BOARD_ZLIGHT)
// event to start EZMode on startup with a delay
if ( events & SAMPLELIGHT_START_EZMODE_EVT )
{
// Invoke EZ-Mode
zclEZMode_InvokeData_t ezModeData;
// Invoke EZ-Mode
ezModeData.endpoint = SAMPLELIGHT_ENDPOINT; // endpoint on which to invoke EZ-Mode
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
ezModeData.onNetwork = TRUE; // node is already on the network
}
else
{
ezModeData.onNetwork = FALSE; // node is not yet on the network
}
ezModeData.initiator = FALSE; // OnOffLight is a target
ezModeData.numActiveOutClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
ezModeData.numActiveInClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
zcl_InvokeEZMode( &ezModeData );
return ( events ^ SAMPLELIGHT_START_EZMODE_EVT );
}
#endif // #if (defined HAL_BOARD_ZLIGHT)
// going on to next state
if ( events & SAMPLELIGHT_EZMODE_NEXTSTATE_EVT )
{
zcl_EZModeAction ( EZMODE_ACTION_PROCESS, NULL ); // going on to next state
return ( events ^ SAMPLELIGHT_EZMODE_NEXTSTATE_EVT );
}
// the overall EZMode timer expired, so we timed out
if ( events & SAMPLELIGHT_EZMODE_TIMEOUT_EVT )
{
zcl_EZModeAction ( EZMODE_ACTION_TIMED_OUT, NULL ); // EZ-Mode timed out
return ( events ^ SAMPLELIGHT_EZMODE_TIMEOUT_EVT );
}
#endif // ZLC_EZMODE
#ifdef ZCL_LEVEL_CTRL
if ( events & SAMPLELIGHT_LEVEL_CTRL_EVT )
{
zclSampleLight_AdjustLightLevel();
return ( events ^ SAMPLELIGHT_LEVEL_CTRL_EVT );
}
#endif
if ( events & SAMPLELIGHT_LIGHT_WATCHDOG_EVT )
{
WatchdogClear();
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LIGHT_WATCHDOG_EVT, 100);
return ( events ^ SAMPLELIGHT_LIGHT_WATCHDOG_EVT );
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn zclSampleLight_HandleKeys
*
* @brief Handles all key events for this device.
*
* @param shift - true if in shift/alt.
* @param keys - bit field for key events. Valid entries:
* HAL_KEY_SW_5
* HAL_KEY_SW_4
* HAL_KEY_SW_2
* HAL_KEY_SW_1
*
* @return none
*/
static void zclSampleLight_HandleKeys( byte shift, byte keys )
{
if ( keys & HAL_KEY_SW_1 )
{
giLightScreenMode = LIGHT_MAINMODE;
// toggle local light immediately
zclSampleLight_OnOff = zclSampleLight_OnOff ? LIGHT_OFF : LIGHT_ON;
#ifdef ZCL_LEVEL_CTRL
zclSampleLight_LevelCurrentLevel = zclSampleLight_OnOff ? zclSampleLight_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
#endif
}
if ( keys & HAL_KEY_SW_2 )
{
#if (defined HAL_BOARD_ZLIGHT)
zclSampleLight_BasicResetCB();
#else
giLightScreenMode = LIGHT_MAINMODE;
#ifdef ZCL_EZMODE
{
// Invoke EZ-Mode
zclEZMode_InvokeData_t ezModeData;
// Invoke EZ-Mode
ezModeData.endpoint = SAMPLELIGHT_ENDPOINT; // endpoint on which to invoke EZ-Mode
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
ezModeData.onNetwork = TRUE; // node is already on the network
}
else
{
ezModeData.onNetwork = FALSE; // node is not yet on the network
}
ezModeData.initiator = FALSE; // OnOffLight is a target
ezModeData.numActiveOutClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
ezModeData.numActiveInClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
zcl_InvokeEZMode( &ezModeData );
}
#else // NOT EZ-Mode
{
zAddrType_t dstAddr;
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate an End Device Bind Request, this bind request will
// only use a cluster list that is important to binding.
dstAddr.addrMode = afAddr16Bit;
dstAddr.addr.shortAddr = 0; // Coordinator makes the match
ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
SAMPLELIGHT_ENDPOINT,
ZCL_HA_PROFILE_ID,
ZCLSAMPLELIGHT_BINDINGLIST, bindingInClusters,
0, NULL, // No Outgoing clusters to bind
TRUE );
}
#endif // ZCL_EZMODE
#endif // HAL_BOARD_ZLIGHT
}
if ( keys & HAL_KEY_SW_3 )
{
NLME_SendNetworkStatus( zclSampleLight_DstAddr.addr.shortAddr,
NLME_GetShortAddr(), NWKSTAT_NONTREE_LINK_FAILURE, FALSE );
}
if ( keys & HAL_KEY_SW_4 )
{
giLightScreenMode = LIGHT_MAINMODE;
if ( ( zclSampleLight_NwkState == DEV_ZB_COORD ) ||
( zclSampleLight_NwkState == DEV_ROUTER ) )
{
zAddrType_t tmpAddr;
tmpAddr.addrMode = Addr16Bit;
tmpAddr.addr.shortAddr = NLME_GetShortAddr();
// toggle permit join
gPermitDuration = gPermitDuration ? 0 : 0xff;
// Trust Center significance is always true
ZDP_MgmtPermitJoinReq( &tmpAddr, gPermitDuration, TRUE, FALSE );
}
}
// Shift F5 does a Basic Reset (factory defaults)
if ( shift && ( keys & HAL_KEY_SW_5 ) )
{
zclSampleLight_BasicResetCB();
}
else if ( keys & HAL_KEY_SW_5 )
{
giLightScreenMode = giLightScreenMode ? LIGHT_MAINMODE : LIGHT_HELPMODE;
}
// update the display, including the light
zclSampleLight_LcdDisplayUpdate();
}
/*********************************************************************
* @fn zclSampleLight_LcdDisplayUpdate
*
* @brief Called to update the LCD display.
*
* @param none
*
* @return none
*/
void zclSampleLight_LcdDisplayUpdate( void )
{
#ifdef LCD_SUPPORTED
if ( giLightScreenMode == LIGHT_HELPMODE )
{
zclSampleLight_LcdDisplayHelpMode();
}
else
{
zclSampleLight_LcdDisplayMainMode();
}
#endif
zclSampleLight_DisplayLight();
}
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
/*********************************************************************
* @fn zclSampleLight_UpdateLampLevel
*
* @brief Update lamp level output with gamma compensation
*
* @param level
*
* @return none
*/
void zclSampleLight_UpdateLampLevel( uint8 level )
{
uint16 gammaCorrectedLevel;
// gamma correct the level
gammaCorrectedLevel = (uint16) ( pow( ( (float)level / LEVEL_MAX ), (float)GAMMA_VALUE ) * (float)LEVEL_MAX);
halTimer1SetChannelDuty(WHITE_LED, (uint16)(((uint32)gammaCorrectedLevel*PWM_FULL_DUTY_CYCLE)/LEVEL_MAX) );
}
#endif
/*********************************************************************
* @fn zclSampleLight_DisplayLight
*
* @brief Displays current state of light on LED and also on main display if supported.
*
* @param none
*
* @return none
*/
static void zclSampleLight_DisplayLight( void )
{
// set the LED1 based on light (on or off)
if ( zclSampleLight_OnOff == LIGHT_ON )
{
HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
}
else
{
HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
}
#ifdef LCD_SUPPORTED
if (giLightScreenMode == LIGHT_MAINMODE)
{
#ifdef ZCL_LEVEL_CTRL
// display current light level
if ( ( zclSampleLight_LevelCurrentLevel == ATTR_LEVEL_MIN_LEVEL ) &&
( zclSampleLight_OnOff == LIGHT_OFF ) )
{
HalLcdWriteString( (char *)sLightOff, HAL_LCD_LINE_2 );
}
else if ( ( zclSampleLight_LevelCurrentLevel >= ATTR_LEVEL_MAX_LEVEL ) ||
( zclSampleLight_LevelCurrentLevel == zclSampleLight_LevelOnLevel ) ||
( ( zclSampleLight_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT ) &&
( zclSampleLight_LevelCurrentLevel == zclSampleLight_LevelLastLevel ) ) )
{
HalLcdWriteString( (char *)sLightOn, HAL_LCD_LINE_2 );
}
else // " LEVEL ###"
{
zclHA_uint8toa( zclSampleLight_LevelCurrentLevel, &sLightLevel[10] );
HalLcdWriteString( (char *)sLightLevel, HAL_LCD_LINE_2 );
}
#else
if ( zclSampleLight_OnOff )
{
HalLcdWriteString( (char *)sLightOn, HAL_LCD_LINE_2 );
}
else
{
HalLcdWriteString( (char *)sLightOff, HAL_LCD_LINE_2 );
}
#endif // ZCL_LEVEL_CTRL
}
#endif // LCD_SUPPORTED
}
#ifdef LCD_SUPPORTED
/*********************************************************************
* @fn zclSampleLight_LcdDisplayMainMode
*
* @brief Called to display the main screen on the LCD.
*
* @param none
*
* @return none
*/
static void zclSampleLight_LcdDisplayMainMode( void )
{
// display line 1 to indicate NWK status
if ( zclSampleLight_NwkState == DEV_ZB_COORD )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZC );
}
else if ( zclSampleLight_NwkState == DEV_ROUTER )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZR );
}
else if ( zclSampleLight_NwkState == DEV_END_DEVICE )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZED );
}
// end of line 3 displays permit join status (*)
if ( gPermitDuration )
{
sSwHelp[15] = '*';
}
else
{
sSwHelp[15] = ' ';
}
HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3 );
}
/*********************************************************************
* @fn zclSampleLight_LcdDisplayHelpMode
*
* @brief Called to display the SW options on the LCD.
*
* @param none
*
* @return none
*/
static void zclSampleLight_LcdDisplayHelpMode( void )
{
HalLcdWriteString( (char *)sSwLight, HAL_LCD_LINE_1 );
HalLcdWriteString( (char *)sSwEZMode, HAL_LCD_LINE_2 );
HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3 );
}
#endif // LCD_SUPPORTED
/*********************************************************************
* @fn zclSampleLight_ProcessIdentifyTimeChange
*
* @brief Called to process any change to the IdentifyTime attribute.
*
* @param none
*
* @return none
*/
static void zclSampleLight_ProcessIdentifyTimeChange( void )
{
if ( zclSampleLight_IdentifyTime > 0 )
{
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT, 1000 );
HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
}
else
{
#ifdef ZCL_EZMODE
if ( zclSampleLight_IdentifyCommissionState & EZMODE_COMMISSION_OPERATIONAL )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
}
else
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
}
#endif
osal_stop_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT );
}
}
/*********************************************************************
* @fn zclSampleLight_BasicResetCB
*
* @brief Callback from the ZCL General Cluster Library
* to set all the Basic Cluster attributes to default values.
*
* @param none
*
* @return none
*/
static void zclSampleLight_BasicResetCB( void )
{
NLME_LeaveReq_t leaveReq;
// Set every field to 0
osal_memset( &leaveReq, 0, sizeof( NLME_LeaveReq_t ) );
// This will enable the device to rejoin the network after reset.
leaveReq.rejoin = TRUE;
// Set the NV startup option to force a "new" join.
zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
// Leave the network, and reset afterwards
if ( NLME_LeaveReq( &leaveReq ) != ZSuccess )
{
// Couldn't send out leave; prepare to reset anyway
ZDApp_LeaveReset( FALSE );
}
}
/*********************************************************************
* @fn zclSampleLight_IdentifyCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Identity Command for this application.
*
* @param srcAddr - source address and endpoint of the response message
* @param identifyTime - the number of seconds to identify yourself
*
* @return none
*/
static void zclSampleLight_IdentifyCB( zclIdentify_t *pCmd )
{
zclSampleLight_IdentifyTime = pCmd->identifyTime;
zclSampleLight_ProcessIdentifyTimeChange();
}
/*********************************************************************
* @fn zclSampleLight_IdentifyQueryRspCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Identity Query Response Command for this application.
*
* @param srcAddr - requestor's address
* @param timeout - number of seconds to identify yourself (valid for query response)
*
* @return none
*/
static void zclSampleLight_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
{
(void)pRsp;
#ifdef ZCL_EZMODE
{
zclEZMode_ActionData_t data;
data.pIdentifyQueryRsp = pRsp;
zcl_EZModeAction ( EZMODE_ACTION_IDENTIFY_QUERY_RSP, &data );
}
#endif
}
/*********************************************************************
* @fn zclSampleLight_OnOffCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an On/Off Command for this application.
*
* @param cmd - COMMAND_ON, COMMAND_OFF or COMMAND_TOGGLE
*
* @return none
*/
static void zclSampleLight_OnOffCB( uint8 cmd )
{
afIncomingMSGPacket_t *pPtr = zcl_getRawAFMsg();
zclSampleLight_DstAddr.addr.shortAddr = pPtr->srcAddr.addr.shortAddr;
// Turn on the light
if ( cmd == COMMAND_ON )
{
zclSampleLight_OnOff = LIGHT_ON;
}
// Turn off the light
else if ( cmd == COMMAND_OFF )
{
zclSampleLight_OnOff = LIGHT_OFF;
}
// Toggle the light
else if ( cmd == COMMAND_TOGGLE )
{
if ( zclSampleLight_OnOff == LIGHT_OFF )
{
zclSampleLight_OnOff = LIGHT_ON;
}
else
{
zclSampleLight_OnOff = LIGHT_OFF;
}
}
#if ZCL_LEVEL_CTRL
zclSampleLight_DefaultMove( );
#endif
// update the display
zclSampleLight_LcdDisplayUpdate( );
}
#ifdef ZCL_LEVEL_CTRL
/*********************************************************************
* @fn zclSampleLight_TimeRateHelper
*
* @brief Calculate time based on rate, and startup level state machine
*
* @param newLevel - new level for current level
*
* @return diff (directly), zclSampleLight_CurrentLevel32 and zclSampleLight_NewLevel, zclSampleLight_NewLevelUp
*/
static uint32 zclSampleLight_TimeRateHelper( uint8 newLevel )
{
uint32 diff;
uint32 newLevel32;
// remember current and new level
zclSampleLight_NewLevel = newLevel;
zclSampleLight_CurrentLevel32 = (uint32)1000 * zclSampleLight_LevelCurrentLevel;
// calculate diff
newLevel32 = (uint32)1000 * newLevel;
if ( zclSampleLight_LevelCurrentLevel > newLevel )
{
diff = zclSampleLight_CurrentLevel32 - newLevel32;
zclSampleLight_NewLevelUp = FALSE; // moving down
}
else
{
diff = newLevel32 - zclSampleLight_CurrentLevel32;
zclSampleLight_NewLevelUp = TRUE; // moving up
}
return ( diff );
}
/*********************************************************************
* @fn zclSampleLight_MoveBasedOnRate
*
* @brief Calculate time based on rate, and startup level state machine
*
* @param newLevel - new level for current level
* @param rate16 - fixed point rate (e.g. 16.123)
*
* @return none
*/
static void zclSampleLight_MoveBasedOnRate( uint8 newLevel, uint32 rate )
{
uint32 diff;
// determine how much time (in 10ths of seconds) based on the difference and rate
zclSampleLight_Rate32 = rate;
diff = zclSampleLight_TimeRateHelper( newLevel );
zclSampleLight_LevelRemainingTime = diff / rate;
if ( !zclSampleLight_LevelRemainingTime )
{
zclSampleLight_LevelRemainingTime = 1;
}
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT, 100 );
}
/*********************************************************************
* @fn zclSampleLight_MoveBasedOnTime
*
* @brief Calculate rate based on time, and startup level state machine
*
* @param newLevel - new level for current level
* @param time - in 10ths of seconds
*
* @return none
*/
static void zclSampleLight_MoveBasedOnTime( uint8 newLevel, uint16 time )
{
uint16 diff;
// determine rate (in units) based on difference and time
diff = zclSampleLight_TimeRateHelper( newLevel );
zclSampleLight_LevelRemainingTime = zclSampleLight_GetTime( newLevel, time );
zclSampleLight_Rate32 = diff / time;
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT, 100 );
}
/*********************************************************************
* @fn zclSampleLight_GetTime
*
* @brief Determine amount of time that MoveXXX will take to complete.
*
* @param level = new level to move to
* time = 0xffff=default, or 0x0000-n amount of time in tenths of seconds.
*
* @return none
*/
static uint16 zclSampleLight_GetTime( uint8 level, uint16 time )
{
// there is a hiearchy of the amount of time to use for transistioning
// check each one in turn. If none of defaults are set, then use fastest
// time possible.
if ( time == 0xFFFF )
{
// use On or Off Transition Time if set (not 0xffff)
if ( zclSampleLight_OnOff == LIGHT_ON )
{
time = zclSampleLight_LevelOffTransitionTime;
}
else
{
time = zclSampleLight_LevelOnTransitionTime;
}
// else use OnOffTransitionTime if set (not 0xffff)
if ( time == 0xFFFF )
{
time = zclSampleLight_LevelOnOffTransitionTime;
}
// else as fast as possible
if ( time == 0xFFFF )
{
time = 1;
}
}
if ( !time )
{
time = 1; // as fast as possible
}
return ( time );
}
/*********************************************************************
* @fn zclSampleLight_DefaultMove
*
* @brief We were turned on/off. Use default time to move to on or off.
*
* @param zclSampleLight_OnOff - must be set prior to calling this function.
*
* @return none
*/
static void zclSampleLight_DefaultMove( void )
{
uint8 newLevel;
uint32 rate; // fixed point decimal (3 places, eg. 16.345)
uint16 time;
// if moving to on position, move to on level
if ( zclSampleLight_OnOff )
{
if ( zclSampleLight_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT )
{
// The last Level (before going OFF) should be used)
newLevel = zclSampleLight_LevelLastLevel;
}
else
{
newLevel = zclSampleLight_LevelOnLevel;
}
time = zclSampleLight_LevelOnTransitionTime;
}
else
{
newLevel = ATTR_LEVEL_MIN_LEVEL;
if ( zclSampleLight_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT )
{
// Save the current Level before going OFF to use it when the light turns ON
// it should be back to this level
zclSampleLight_LevelLastLevel = zclSampleLight_LevelCurrentLevel;
}
time = zclSampleLight_LevelOffTransitionTime;
}
// else use OnOffTransitionTime if set (not 0xffff)
if ( time == 0xFFFF )
{
time = zclSampleLight_LevelOnOffTransitionTime;
}
// else as fast as possible
if ( time == 0xFFFF )
{
time = 1;
}
// calculate rate based on time (int 10ths) for full transition (1-254)
rate = 255000 / time; // units per tick, fixed point, 3 decimal places (e.g. 8500 = 8.5 units per tick)
// start up state machine.
zclSampleLight_WithOnOff = TRUE;
zclSampleLight_MoveBasedOnRate( newLevel, rate );
}
/*********************************************************************
* @fn zclSampleLight_AdjustLightLevel
*
* @brief Called each 10th of a second while state machine running
*
* @param none
*
* @return none
*/
static void zclSampleLight_AdjustLightLevel( void )
{
// one tick (10th of a second) less
if ( zclSampleLight_LevelRemainingTime )
{
--zclSampleLight_LevelRemainingTime;
}
// no time left, done
if ( zclSampleLight_LevelRemainingTime == 0)
{
zclSampleLight_LevelCurrentLevel = zclSampleLight_NewLevel;
}
// still time left, keep increment/decrementing
else
{
if ( zclSampleLight_NewLevelUp )
{
zclSampleLight_CurrentLevel32 += zclSampleLight_Rate32;
}
else
{
zclSampleLight_CurrentLevel32 -= zclSampleLight_Rate32;
}
zclSampleLight_LevelCurrentLevel = (uint8)( zclSampleLight_CurrentLevel32 / 1000 );
}
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
zclSampleLight_UpdateLampLevel(zclSampleLight_LevelCurrentLevel);
#endif
// also affect on/off
if ( zclSampleLight_WithOnOff )
{
if ( zclSampleLight_LevelCurrentLevel > ATTR_LEVEL_MIN_LEVEL )
{
zclSampleLight_OnOff = LIGHT_ON;
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
ENABLE_LAMP;
#endif
}
else
{
zclSampleLight_OnOff = LIGHT_OFF;
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
DISABLE_LAMP;
#endif
}
}
// display light level as we go
zclSampleLight_DisplayLight( );
// keep ticking away
if ( zclSampleLight_LevelRemainingTime )
{
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT, 100 );
}
}
/*********************************************************************
* @fn zclSampleLight_LevelControlMoveToLevelCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received a LevelControlMoveToLevel Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlMoveToLevelCB( zclLCMoveToLevel_t *pCmd )
{
zclSampleLight_WithOnOff = pCmd->withOnOff;
zclSampleLight_MoveBasedOnTime( pCmd->level, pCmd->transitionTime );
}
/*********************************************************************
* @fn zclSampleLight_LevelControlMoveCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received a LevelControlMove Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlMoveCB( zclLCMove_t *pCmd )
{
uint8 newLevel;
uint32 rate;
// convert rate from units per second to units per tick (10ths of seconds)
// and move at that right up or down
zclSampleLight_WithOnOff = pCmd->withOnOff;
if ( pCmd->moveMode == LEVEL_MOVE_UP )
{
newLevel = ATTR_LEVEL_MAX_LEVEL; // fully on
}
else
{
newLevel = ATTR_LEVEL_MIN_LEVEL; // fully off
}
rate = (uint32)100 * pCmd->rate;
zclSampleLight_MoveBasedOnRate( newLevel, rate );
}
/*********************************************************************
* @fn zclSampleLight_LevelControlStepCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an On/Off Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlStepCB( zclLCStep_t *pCmd )
{
uint8 newLevel;
// determine new level, but don't exceed boundaries
if ( pCmd->stepMode == LEVEL_MOVE_UP )
{
if ( (uint16)zclSampleLight_LevelCurrentLevel + pCmd->amount > ATTR_LEVEL_MAX_LEVEL )
{
newLevel = ATTR_LEVEL_MAX_LEVEL;
}
else
{
newLevel = zclSampleLight_LevelCurrentLevel + pCmd->amount;
}
}
else
{
if ( pCmd->amount >= zclSampleLight_LevelCurrentLevel )
{
newLevel = ATTR_LEVEL_MIN_LEVEL;
}
else
{
newLevel = zclSampleLight_LevelCurrentLevel - pCmd->amount;
}
}
// move to the new level
zclSampleLight_WithOnOff = pCmd->withOnOff;
zclSampleLight_MoveBasedOnTime( newLevel, pCmd->transitionTime );
}
/*********************************************************************
* @fn zclSampleLight_LevelControlStopCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Level Control Stop Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlStopCB( void )
{
// stop immediately
osal_stop_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT );
zclSampleLight_LevelRemainingTime = 0;
}
#endif
/******************************************************************************
*
* Functions for processing ZCL Foundation incoming Command/Response messages
*
*****************************************************************************/
/*********************************************************************
* @fn zclSampleLight_ProcessIncomingMsg
*
* @brief Process ZCL Foundation incoming message
*
* @param pInMsg - pointer to the received message
*
* @return none
*/
static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg )
{
switch ( pInMsg->zclHdr.commandID )
{
#ifdef ZCL_READ
case ZCL_CMD_READ_RSP:
zclSampleLight_ProcessInReadRspCmd( pInMsg );
break;
#endif
#ifdef ZCL_WRITE
case ZCL_CMD_WRITE_RSP:
zclSampleLight_ProcessInWriteRspCmd( pInMsg );
break;
#endif
#ifdef ZCL_REPORT
// Attribute Reporting implementation should be added here
case ZCL_CMD_CONFIG_REPORT:
// zclSampleLight_ProcessInConfigReportCmd( pInMsg );
break;
case ZCL_CMD_CONFIG_REPORT_RSP:
// zclSampleLight_ProcessInConfigReportRspCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG:
// zclSampleLight_ProcessInReadReportCfgCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG_RSP:
// zclSampleLight_ProcessInReadReportCfgRspCmd( pInMsg );
break;
case ZCL_CMD_REPORT:
// zclSampleLight_ProcessInReportCmd( pInMsg );
break;
#endif
case ZCL_CMD_DEFAULT_RSP:
zclSampleLight_ProcessInDefaultRspCmd( pInMsg );
break;
#ifdef ZCL_DISCOVER
case ZCL_CMD_DISCOVER_CMDS_RECEIVED_RSP:
zclSampleLight_ProcessInDiscCmdsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_CMDS_GEN_RSP:
zclSampleLight_ProcessInDiscCmdsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_ATTRS_RSP:
zclSampleLight_ProcessInDiscAttrsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_ATTRS_EXT_RSP:
zclSampleLight_ProcessInDiscAttrsExtRspCmd( pInMsg );
break;
#endif
default:
break;
}
if ( pInMsg->attrCmd )
osal_mem_free( pInMsg->attrCmd );
}
#ifdef ZCL_READ
/*********************************************************************
* @fn zclSampleLight_ProcessInReadRspCmd
*
* @brief Process the "Profile" Read Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
{
zclReadRspCmd_t *readRspCmd;
uint8 i;
readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
for (i = 0; i < readRspCmd->numAttr; i++)
{
// Notify the originator of the results of the original read attributes
// attempt and, for each successfull request, the value of the requested
// attribute
}
return ( TRUE );
}
#endif // ZCL_READ
#ifdef ZCL_WRITE
/*********************************************************************
* @fn zclSampleLight_ProcessInWriteRspCmd
*
* @brief Process the "Profile" Write Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
{
zclWriteRspCmd_t *writeRspCmd;
uint8 i;
writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
for ( i = 0; i < writeRspCmd->numAttr; i++ )
{
// Notify the device of the results of the its original write attributes
// command.
}
return ( TRUE );
}
#endif // ZCL_WRITE
/*********************************************************************
* @fn zclSampleLight_ProcessInDefaultRspCmd
*
* @brief Process the "Profile" Default Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
{
// zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
// Device is notified of the Default Response command.
(void)pInMsg;
return ( TRUE );
}
#ifdef ZCL_DISCOVER
/*********************************************************************
* @fn zclSampleLight_ProcessInDiscCmdsRspCmd
*
* @brief Process the Discover Commands Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverCmdsCmdRsp_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverCmdsCmdRsp_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numCmd; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
/*********************************************************************
* @fn zclSampleLight_ProcessInDiscAttrsRspCmd
*
* @brief Process the "Profile" Discover Attributes Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverAttrsRspCmd_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverAttrsRspCmd_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numAttr; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
/*********************************************************************
* @fn zclSampleLight_ProcessInDiscAttrsExtRspCmd
*
* @brief Process the "Profile" Discover Attributes Extended Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverAttrsExtRsp_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverAttrsExtRsp_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numAttr; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
#endif // ZCL_DISCOVER
#if ZCL_EZMODE
/*********************************************************************
* @fn zclSampleLight_ProcessZDOMsgs
*
* @brief Called when this node receives a ZDO/ZDP response.
*
* @param none
*
* @return status
*/
static void zclSampleLight_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
{
zclEZMode_ActionData_t data;
ZDO_MatchDescRsp_t *pMatchDescRsp;
// Let EZ-Mode know of the Simple Descriptor Response
if ( pMsg->clusterID == Match_Desc_rsp )
{
pMatchDescRsp = ZDO_ParseEPListRsp( pMsg );
data.pMatchDescRsp = pMatchDescRsp;
zcl_EZModeAction( EZMODE_ACTION_MATCH_DESC_RSP, &data );
osal_mem_free( pMatchDescRsp );
}
}
/*********************************************************************
* @fn zclSampleLight_EZModeCB
*
* @brief The Application is informed of events. This can be used to show on the UI what is
* going on during EZ-Mode steering/finding/binding.
*
* @param state - an
*
* @return none
*/
static void zclSampleLight_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData )
{
#ifdef LCD_SUPPORTED
char *pStr;
uint8 err;
#endif
// time to go into identify mode
if ( state == EZMODE_STATE_IDENTIFYING )
{
#ifdef LCD_SUPPORTED
HalLcdWriteString( "EZMode", HAL_LCD_LINE_2 );
#endif
zclSampleLight_IdentifyTime = ( EZMODE_TIME / 1000 ); // convert to seconds
zclSampleLight_ProcessIdentifyTimeChange();
}
// autoclosing, show what happened (success, cancelled, etc...)
if( state == EZMODE_STATE_AUTOCLOSE )
{
#ifdef LCD_SUPPORTED
pStr = NULL;
err = pData->sAutoClose.err;
if ( err == EZMODE_ERR_SUCCESS )
{
pStr = "EZMode: Success";
}
else if ( err == EZMODE_ERR_NOMATCH )
{
pStr = "EZMode: NoMatch"; // not a match made in heaven
}
if ( pStr )
{
if ( giLightScreenMode == LIGHT_MAINMODE )
{
HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
}
}
#endif
}
// finished, either show DstAddr/EP, or nothing (depending on success or not)
if( state == EZMODE_STATE_FINISH )
{
// turn off identify mode
zclSampleLight_IdentifyTime = 0;
zclSampleLight_ProcessIdentifyTimeChange();
#ifdef LCD_SUPPORTED
// if successful, inform user which nwkaddr/ep we bound to
pStr = NULL;
err = pData->sFinish.err;
if( err == EZMODE_ERR_SUCCESS )
{
// already stated on autoclose
}
else if ( err == EZMODE_ERR_CANCELLED )
{
pStr = "EZMode: Cancel";
}
else if ( err == EZMODE_ERR_BAD_PARAMETER )
{
pStr = "EZMode: BadParm";
}
else if ( err == EZMODE_ERR_TIMEDOUT )
{
pStr = "EZMode: TimeOut";
}
if ( pStr )
{
if ( giLightScreenMode == LIGHT_MAINMODE )
{
HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
}
}
#endif
// show main UI screen 3 seconds after binding
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_MAIN_SCREEN_EVT, 3000 );
}
}
#endif // ZCL_EZMODE
/****************************************************************************
****************************************************************************/
these are my project files.
/**************************************************************************************************
Filename: zcl_sampleLight.c
Revised: $Date: 2014-07-01 22:24:24 -0700 (Tue, 01 Jul 2014) $
Revision: $Revision: 39317 $
Description: Zigbee Cluster Library - sample device application.
Copyright 2006-2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/*********************************************************************
This application implements a ZigBee HA 1.2 Light. It can be configured as an
On/Off light, or as a dimmable light. The following flags must be defined in
the compiler's pre-defined symbols.
ZCL_ON_OFF
ZCL_LEVEL_CTRL (only if dimming functionality desired)
HOLD_AUTO_START
ZCL_EZMODE
This device supports all mandatory and optional commands/attributes for the
OnOff (0x0006) and LevelControl (0x0008) clusters.
SCREEN MODES
----------------------------------------
Main:
- SW1: Toggle local light
- SW2: Invoke EZMode
- SW4: Enable/Disable local permit join
- SW5: Go to Help screen
----------------------------------------
*********************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "ZComDef.h"
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "MT_SYS.h"
#include "zcl.h"
#include "zcl_general.h"
#include "zcl_ha.h"
#include "zcl_ezmode.h"
#include "zcl_diagnostic.h"
#include "zcl_samplelight.h"
#include "onboard.h"
/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#if ( defined (ZGP_DEVICE_TARGET) || defined (ZGP_DEVICE_TARGETPLUS) \
|| defined (ZGP_DEVICE_COMBO) || defined (ZGP_DEVICE_COMBO_MIN) )
#include "zgp_translationtable.h"
#if (SUPPORTED_S_FEATURE(SUPP_ZGP_FEATURE_TRANSLATION_TABLE))
#define ZGP_AUTO_TT
#endif
#endif
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
#include "math.h"
#include "hal_timer.h"
#endif
#include "NLMEDE.h"
#include "watchdog.h"
#include "hal_adc.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#if (defined HAL_BOARD_ZLIGHT)
#define LEVEL_MAX 0xFE
#define LEVEL_MIN 0x0
#define GAMMA_VALUE 2
#define PWM_FULL_DUTY_CYCLE 1000
#elif (defined HAL_PWM)
#define LEVEL_MAX 0xFE
#define LEVEL_MIN 0x0
#define GAMMA_VALUE 2
#define PWM_FULL_DUTY_CYCLE 100
#endif
#define LIGHT_INTERVAL_DELAY_TIME 500
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
byte zclSampleLight_TaskID;
uint8 zclSampleLightSeqNum;
byte zclSampleLight_ResetKeyPressed;
byte zclSampleLight_LightDelay;
uint16 maxSensorReadValue;
/*********************************************************************
* GLOBAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
afAddrType_t zclSampleLight_DstAddr;
#ifdef ZCL_EZMODE
static void zclSampleLight_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
static void zclSampleLight_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData );
// register EZ-Mode with task information (timeout events, callback, etc...)
static const zclEZMode_RegisterData_t zclSampleLight_RegisterEZModeData =
{
&zclSampleLight_TaskID,
SAMPLELIGHT_EZMODE_NEXTSTATE_EVT,
SAMPLELIGHT_EZMODE_TIMEOUT_EVT,
&zclSampleLightSeqNum,
zclSampleLight_EZModeCB
};
#else
uint16 bindingInClusters[] =
{
ZCL_CLUSTER_ID_GEN_ON_OFF
#ifdef ZCL_LEVEL_CTRL
, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL
#endif
};
#define ZCLSAMPLELIGHT_BINDINGLIST (sizeof(bindingInClusters) / sizeof(bindingInClusters[0]))
#endif // ZCL_EZMODE
// Test Endpoint to allow SYS_APP_MSGs
static endPointDesc_t sampleLight_TestEp =
{
SAMPLELIGHT_ENDPOINT,
&zclSampleLight_TaskID,
(SimpleDescriptionFormat_t *)NULL, // No Simple description for this test endpoint
(afNetworkLatencyReq_t)0 // No Network Latency req
};
uint8 giLightScreenMode = LIGHT_MAINMODE; // display the main screen mode first
uint8 gPermitDuration = 0; // permit joining default to disabled
devStates_t zclSampleLight_NwkState = DEV_INIT;
#if ZCL_LEVEL_CTRL
uint8 zclSampleLight_WithOnOff; // set to TRUE if state machine should set light on/off
uint8 zclSampleLight_NewLevel; // new level when done moving
bool zclSampleLight_NewLevelUp; // is direction to new level up or down?
int32 zclSampleLight_CurrentLevel32; // current level, fixed point (e.g. 192.456)
int32 zclSampleLight_Rate32; // rate in units, fixed point (e.g. 16.123)
uint8 zclSampleLight_LevelLastLevel; // to save the Current Level before the light was turned OFF
#endif
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void zclSampleLight_WatchDog_Loop(void);
static void zclSampleLight_ReadSensorCurrent(void);
static void zclSampleLight_SendSensorInformation(void);
static void zclSampleLight_HandleKeys( byte shift, byte keys );
static void zclSampleLight_BasicResetCB( void );
static void zclSampleLight_IdentifyCB( zclIdentify_t *pCmd );
static void zclSampleLight_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
static void zclSampleLight_OnOffCB( uint8 cmd );
static void zclSampleLight_ProcessIdentifyTimeChange( void );
#ifdef ZCL_LEVEL_CTRL
static void zclSampleLight_LevelControlMoveToLevelCB( zclLCMoveToLevel_t *pCmd );
static void zclSampleLight_LevelControlMoveCB( zclLCMove_t *pCmd );
static void zclSampleLight_LevelControlStepCB( zclLCStep_t *pCmd );
static void zclSampleLight_LevelControlStopCB( void );
static void zclSampleLight_DefaultMove( void );
static uint32 zclSampleLight_TimeRateHelper( uint8 newLevel );
static uint16 zclSampleLight_GetTime ( uint8 level, uint16 time );
static void zclSampleLight_MoveBasedOnRate( uint8 newLevel, uint32 rate );
static void zclSampleLight_MoveBasedOnTime( uint8 newLevel, uint16 time );
static void zclSampleLight_AdjustLightLevel( void );
#endif
// app display functions
static void zclSampleLight_LcdDisplayUpdate( void );
#ifdef LCD_SUPPORTED
static void zclSampleLight_LcdDisplayMainMode( void );
static void zclSampleLight_LcdDisplayHelpMode( void );
#endif
static void zclSampleLight_DisplayLight( void );
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
void zclSampleLight_UpdateLampLevel( uint8 level );
#endif
// Functions to process ZCL Foundation incoming Command/Response messages
static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *msg );
#ifdef ZCL_READ
static uint8 zclSampleLight_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
#endif
#ifdef ZCL_WRITE
static uint8 zclSampleLight_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
#endif
static uint8 zclSampleLight_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
#ifdef ZCL_DISCOVER
static uint8 zclSampleLight_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg );
static uint8 zclSampleLight_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg );
static uint8 zclSampleLight_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg );
#endif
/*********************************************************************
* STATUS STRINGS
*/
#ifdef LCD_SUPPORTED
const char sDeviceName[] = " Sample Light";
const char sClearLine[] = " ";
const char sSwLight[] = "SW1: ToggleLight"; // 16 chars max
const char sSwEZMode[] = "SW2: EZ-Mode";
char sSwHelp[] = "SW5: Help "; // last character is * if NWK open
const char sLightOn[] = " LIGHT ON ";
const char sLightOff[] = " LIGHT OFF";
#if ZCL_LEVEL_CTRL
char sLightLevel[] = " LEVEL ###"; // displays level 1-254
#endif
#endif
/*********************************************************************
* ZCL General Profile Callback table
*/
static zclGeneral_AppCallbacks_t zclSampleLight_CmdCallbacks =
{
zclSampleLight_BasicResetCB, // Basic Cluster Reset command
zclSampleLight_IdentifyCB, // Identify command
#ifdef ZCL_EZMODE
NULL, // Identify EZ-Mode Invoke command
NULL, // Identify Update Commission State command
#endif
NULL, // Identify Trigger Effect command
zclSampleLight_IdentifyQueryRspCB, // Identify Query Response command
zclSampleLight_OnOffCB, // On/Off cluster commands
NULL, // On/Off cluster enhanced command Off with Effect
NULL, // On/Off cluster enhanced command On with Recall Global Scene
NULL, // On/Off cluster enhanced command On with Timed Off
#ifdef ZCL_LEVEL_CTRL
zclSampleLight_LevelControlMoveToLevelCB, // Level Control Move to Level command
zclSampleLight_LevelControlMoveCB, // Level Control Move command
zclSampleLight_LevelControlStepCB, // Level Control Step command
zclSampleLight_LevelControlStopCB, // Level Control Stop command
#endif
#ifdef ZCL_GROUPS
NULL, // Group Response commands
#endif
#ifdef ZCL_SCENES
NULL, // Scene Store Request command
NULL, // Scene Recall Request command
NULL, // Scene Response command
#endif
#ifdef ZCL_ALARMS
NULL, // Alarm (Response) commands
#endif
#ifdef SE_UK_EXT
NULL, // Get Event Log command
NULL, // Publish Event Log command
#endif
NULL, // RSSI Location command
NULL // RSSI Location Response command
};
/*********************************************************************
* @fn zclSampleLight_Init
*
* @brief Initialization function for the zclGeneral layer.
*
* @param none
*
* @return none
*/
void zclSampleLight_Init( byte task_id )
{
zclSampleLight_TaskID = task_id;
// Set destination address to indirect
zclSampleLight_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
zclSampleLight_DstAddr.endPoint = 0;
zclSampleLight_DstAddr.addr.shortAddr = 0;
// This app is part of the Home Automation Profile
zclHA_Init( &zclSampleLight_SimpleDesc );
// Register the ZCL General Cluster Library callback functions
zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks );
// Register the application's attribute list
zcl_registerAttrList( SAMPLELIGHT_ENDPOINT, zclSampleLight_NumAttributes, zclSampleLight_Attrs );
// Register the Application to receive the unprocessed Foundation command/response messages
zcl_registerForMsg( zclSampleLight_TaskID );
#ifdef ZCL_DISCOVER
// Register the application's command list
zcl_registerCmdList( SAMPLELIGHT_ENDPOINT, zclCmdsArraySize, zclSampleLight_Cmds );
#endif
// Register for all key events - This app will handle all key events
RegisterForKeys( zclSampleLight_TaskID );
// Register for a test endpoint
afRegister( &sampleLight_TestEp );
#ifdef ZCL_EZMODE
// Register EZ-Mode
zcl_RegisterEZMode( &zclSampleLight_RegisterEZModeData );
// Register with the ZDO to receive Match Descriptor Responses
ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
#endif
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
HalTimer1Init( 0 );
halTimer1SetChannelDuty( WHITE_LED, 0 );
halTimer1SetChannelDuty( RED_LED, 0 );
halTimer1SetChannelDuty( BLUE_LED, 0 );
halTimer1SetChannelDuty( GREEN_LED, 0 );
// find if we are already on a network from NV_RESTORE
uint8 state;
NLME_GetRequest( nwkNwkState, 0, &state );
if ( state < NWK_ENDDEVICE )
{
// Start EZMode on Start up to avoid button press
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_START_EZMODE_EVT, 500 );
}
#if ZCL_LEVEL_CTRL
zclSampleLight_DefaultMove();
#endif
#endif // #if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
#ifdef ZCL_DIAGNOSTIC
// Register the application's callback function to read/write attribute data.
// This is only required when the attribute data format is unknown to ZCL.
zcl_registerReadWriteCB( SAMPLELIGHT_ENDPOINT, zclDiagnostic_ReadWriteAttrCB, NULL );
if ( zclDiagnostic_InitStats() == ZSuccess )
{
// Here the user could start the timer to save Diagnostics to NV
}
#endif
#ifdef LCD_SUPPORTED
HalLcdWriteString ( (char *)sDeviceName, HAL_LCD_LINE_3 );
#endif // LCD_SUPPORTED
#ifdef ZGP_AUTO_TT
zgpTranslationTable_RegisterEP ( &zclSampleLight_SimpleDesc );
#endif
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_READ_SENSOR_CURRENT_EVT, 3000 );
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_REPORT_SENSOR_INFORMATION_EVT, 1 );
HalLedBlink( HAL_LED_3, 255, 30, 1000 );
#ifdef HAMID_PM1
/* If WDT is used, this is a good place to enable it. */
WatchdogEnable( WATCHDOG_INTERVAL_32768 );
#endif
zclSampleLight_WatchDog_Loop();
}
/*********************************************************************
* @fn zclSample_event_loop
*
* @brief Event Loop Processor for zclGeneral.
*
* @param none
*
* @return none
*/
uint16 zclSampleLight_event_loop( uint8 task_id, uint16 events )
{
afIncomingMSGPacket_t *MSGpkt;
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleLight_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
#ifdef ZCL_EZMODE
case ZDO_CB_MSG:
zclSampleLight_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
#endif
case ZCL_INCOMING_MSG:
// Incoming ZCL Foundation command/response messages
zclSampleLight_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
zclSampleLight_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
osal_msg_send( zclSampleLight_TaskID+1, (uint8 *) MSGpkt );
break;
case ZDO_STATE_CHANGE:
zclSampleLight_NwkState = (devStates_t)(MSGpkt->hdr.status);
// now on the network
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
giLightScreenMode = LIGHT_MAINMODE;
zclSampleLight_LcdDisplayUpdate();
#ifdef ZCL_EZMODE
zcl_EZModeAction( EZMODE_ACTION_NETWORK_STARTED, NULL );
#endif // ZCL_EZMODE
}
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT )
{
if ( zclSampleLight_IdentifyTime > 0 )
zclSampleLight_IdentifyTime--;
zclSampleLight_ProcessIdentifyTimeChange();
return ( events ^ SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT );
}
if ( events & SAMPLELIGHT_MAIN_SCREEN_EVT )
{
giLightScreenMode = LIGHT_MAINMODE;
zclSampleLight_LcdDisplayUpdate();
return ( events ^ SAMPLELIGHT_MAIN_SCREEN_EVT );
}
#ifdef ZCL_EZMODE
#if (defined HAL_BOARD_ZLIGHT)
// event to start EZMode on startup with a delay
if ( events & SAMPLELIGHT_START_EZMODE_EVT )
{
// Invoke EZ-Mode
zclEZMode_InvokeData_t ezModeData;
// Invoke EZ-Mode
ezModeData.endpoint = SAMPLELIGHT_ENDPOINT; // endpoint on which to invoke EZ-Mode
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
ezModeData.onNetwork = TRUE; // node is already on the network
}
else
{
ezModeData.onNetwork = FALSE; // node is not yet on the network
}
ezModeData.initiator = FALSE; // OnOffLight is a target
ezModeData.numActiveOutClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
ezModeData.numActiveInClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
zcl_InvokeEZMode( &ezModeData );
return ( events ^ SAMPLELIGHT_START_EZMODE_EVT );
}
#endif // #if (defined HAL_BOARD_ZLIGHT)
// going on to next state
if ( events & SAMPLELIGHT_EZMODE_NEXTSTATE_EVT )
{
zcl_EZModeAction ( EZMODE_ACTION_PROCESS, NULL ); // going on to next state
return ( events ^ SAMPLELIGHT_EZMODE_NEXTSTATE_EVT );
}
// the overall EZMode timer expired, so we timed out
if ( events & SAMPLELIGHT_EZMODE_TIMEOUT_EVT )
{
zcl_EZModeAction ( EZMODE_ACTION_TIMED_OUT, NULL ); // EZ-Mode timed out
return ( events ^ SAMPLELIGHT_EZMODE_TIMEOUT_EVT );
}
#endif // ZLC_EZMODE
#ifdef ZCL_LEVEL_CTRL
if ( events & SAMPLELIGHT_LEVEL_CTRL_EVT )
{
zclSampleLight_AdjustLightLevel();
return ( events ^ SAMPLELIGHT_LEVEL_CTRL_EVT );
}
#endif
if ( events & SAMPLELIGHT_READ_SENSOR_CURRENT_EVT )
{
zclSampleLight_ReadSensorCurrent();
return ( events ^ SAMPLELIGHT_READ_SENSOR_CURRENT_EVT );
}
if ( events & SAMPLELIGHT_REPORT_SENSOR_INFORMATION_EVT )
{
zclSampleLight_SendSensorInformation();
return ( events ^ SAMPLELIGHT_REPORT_SENSOR_INFORMATION_EVT );
}
if ( events & SAMPLELIGHT_RESET_KEY_PRESSED_EVT )
{
if(zclSampleLight_ResetKeyPressed==1){
zclSampleLight_ResetKeyPressed=0;
HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
zclSampleLight_BasicResetCB();
}
zclSampleLight_ResetKeyPressed=0;
return ( events ^ SAMPLELIGHT_RESET_KEY_PRESSED_EVT );
}
if ( events & SAMPLELIGHT_LIGHT_DELAY_EVT )
{
zclSampleLight_LightDelay=0;
return ( events ^ SAMPLELIGHT_LIGHT_DELAY_EVT );
}
if ( events & SAMPLELIGHT_LIGHT_WATCHDOG_EVT )
{
zclSampleLight_WatchDog_Loop();
return ( events ^ SAMPLELIGHT_LIGHT_WATCHDOG_EVT );
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn zclSampleLight_HandleKeys
*
* @brief Handles all key events for this device.
*
* @return none
*/
static void zclSampleLight_WatchDog_Loop(void){
WatchdogClear();
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LIGHT_WATCHDOG_EVT, 900 );
}
/*********************************************************************
* @fn zclSampleLight_HandleKeys
*
* @brief Handles all key events for this device.
*
* @return none
*/
static void zclSampleLight_SendSensorInformation(void){
double iRMS;
int16 maxMinusOffset=maxSensorReadValue-1650;
if(maxMinusOffset<0)
maxMinusOffset=-maxMinusOffset;
iRMS=(maxMinusOffset*20);
iRMS=iRMS/1650;
iRMS=(iRMS/1.414)*1000;
uint32 power=(uint32)(iRMS*220);
maxSensorReadValue=0;
#ifdef ZCL_REPORT
afAddrType_t dstAddr1;
dstAddr1.addrMode=(afAddrMode_t)Addr16Bit;
dstAddr1.endPoint=3;
dstAddr1.addr.shortAddr=0x0;
zclReportCmd_t *rptcmd;
rptcmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
rptcmd->numAttr = 1;
rptcmd->attrList[0].attrID = ATTRID_SENSOR_CURRENT_A4;
rptcmd->attrList[0].dataType = ZCL_DATATYPE_UINT32;
rptcmd->attrList[0].attrData = (uint8*)&power;
zcl_SendReportCmd(SAMPLELIGHT_ENDPOINT, &dstAddr1, ZCL_CLUSTER_ID_GEN_ON_OFF, rptcmd,ZCL_FRAME_SERVER_CLIENT_DIR, false, zclSampleLightSeqNum );
osal_mem_free( rptcmd );
#endif
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_REPORT_SENSOR_INFORMATION_EVT, 3000 );
}
/*********************************************************************
* @fn zclSampleLight_HandleKeys
*
* @brief Handles all key events for this device.
*
* @return none
*/
static void zclSampleLight_ReadSensorCurrent(void){
uint16 value1 = HalAdcRead(HAL_ADC_CHANNEL_4,HAL_ADC_RESOLUTION_12);
float volt=(value1*3.3)/2047;
value1=(uint16)(volt*1000);
uint16 value2 = HalAdcRead(HAL_ADC_CHANNEL_4,HAL_ADC_RESOLUTION_12);
volt=(value2*3.3)/2047;
value2=(uint16)(volt*1000);
uint16 value3 = HalAdcRead(HAL_ADC_CHANNEL_4,HAL_ADC_RESOLUTION_12);
volt=(value3*3.3)/2047;
value3=(uint16)(volt*1000);
uint16 value4 = HalAdcRead(HAL_ADC_CHANNEL_4,HAL_ADC_RESOLUTION_12);
volt=(value4*3.3)/2047;
value4=(uint16)(volt*1000);
uint16 value = value1+value2+value3+value4;
value=(uint16)value/4;
if(value>maxSensorReadValue)
maxSensorReadValue=value;
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_READ_SENSOR_CURRENT_EVT, 1 );
}
/*********************************************************************
* @fn zclSampleLight_HandleKeys
*
* @brief Handles all key events for this device.
*
* @param shift - true if in shift/alt.
* @param keys - bit field for key events. Valid entries:
* HAL_KEY_SW_5
* HAL_KEY_SW_4
* HAL_KEY_SW_2
* HAL_KEY_SW_1
*
* @return none
*/
static void zclSampleLight_HandleKeys( byte shift, byte keys )
{
if ( keys & HAL_KEY_SW_1 )
{
if(zclSampleLight_LightDelay==0){
zclSampleLight_LightDelay=1;
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LIGHT_DELAY_EVT, LIGHT_INTERVAL_DELAY_TIME );
giLightScreenMode = LIGHT_MAINMODE;
// toggle local light immediately
zclSampleLight_OnOff = zclSampleLight_OnOff ? LIGHT_OFF : LIGHT_ON;
maxSensorReadValue=0;
#ifdef ZCL_LEVEL_CTRL
zclSampleLight_LevelCurrentLevel = zclSampleLight_OnOff ? zclSampleLight_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
#endif
#ifdef ZCL_REPORT
afAddrType_t dstAddr1;
dstAddr1.addrMode=(afAddrMode_t)Addr16Bit;
dstAddr1.endPoint=3;
dstAddr1.addr.shortAddr=0x0;
zclReportCmd_t *rptcmd;
rptcmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
rptcmd->numAttr = 1;
rptcmd->attrList[0].attrID = ATTRID_ON_OFF;
rptcmd->attrList[0].dataType = ZCL_DATATYPE_UINT8;
rptcmd->attrList[0].attrData = (uint8*)&zclSampleLight_OnOff;
zcl_SendReportCmd(SAMPLELIGHT_ENDPOINT, &dstAddr1,ZCL_CLUSTER_ID_GEN_ON_OFF, rptcmd,ZCL_FRAME_SERVER_CLIENT_DIR, false, zclSampleLightSeqNum );
HalLcdWriteString( "Send Report", HAL_LCD_LINE_4 );
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_MAIN_SCREEN_EVT, 3000 );
osal_mem_free( rptcmd );
#endif
}
}
if ( keys & HAL_KEY_SW_2 )
{
#if (defined HAL_BOARD_ZLIGHT)
zclSampleLight_BasicResetCB();
#else
giLightScreenMode = LIGHT_MAINMODE;
#ifdef ZCL_EZMODE
{
// Invoke EZ-Mode
zclEZMode_InvokeData_t ezModeData;
// Invoke EZ-Mode
ezModeData.endpoint = SAMPLELIGHT_ENDPOINT; // endpoint on which to invoke EZ-Mode
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
ezModeData.onNetwork = TRUE; // node is already on the network
}
else
{
ezModeData.onNetwork = FALSE; // node is not yet on the network
}
ezModeData.initiator = FALSE; // OnOffLight is a target
ezModeData.numActiveOutClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
ezModeData.numActiveInClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
zcl_InvokeEZMode( &ezModeData );
}
#else // NOT EZ-Mode
{
zAddrType_t dstAddr;
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate an End Device Bind Request, this bind request will
// only use a cluster list that is important to binding.
dstAddr.addrMode = afAddr16Bit;
dstAddr.addr.shortAddr = 0; // Coordinator makes the match
ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
SAMPLELIGHT_ENDPOINT,
ZCL_HA_PROFILE_ID,
ZCLSAMPLELIGHT_BINDINGLIST, bindingInClusters,
0, NULL, // No Outgoing clusters to bind
TRUE );
}
#endif // ZCL_EZMODE
#endif // HAL_BOARD_ZLIGHT
}
if ( keys & HAL_KEY_SW_3 )
{
if(zclSampleLight_ResetKeyPressed==0){
zclSampleLight_ResetKeyPressed=1;
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_RESET_KEY_PRESSED_EVT, 3000 );
}else{
zclSampleLight_ResetKeyPressed++;
}
}
if ( keys & HAL_KEY_SW_4 )
{
giLightScreenMode = LIGHT_MAINMODE;
if ( ( zclSampleLight_NwkState == DEV_ZB_COORD ) ||
( zclSampleLight_NwkState == DEV_ROUTER ) )
{
// toggle permit join
gPermitDuration = gPermitDuration ? 0 : 0xff;
NLME_PermitJoiningRequest( gPermitDuration );
}
}
// Shift F5 does a Basic Reset (factory defaults)
if ( shift && ( keys & HAL_KEY_SW_5 ) )
{
zclSampleLight_BasicResetCB();
}
else if ( keys & HAL_KEY_SW_5 )
{
giLightScreenMode = giLightScreenMode ? LIGHT_MAINMODE : LIGHT_HELPMODE;
}
// update the display, including the light
zclSampleLight_LcdDisplayUpdate();
}
/*********************************************************************
* @fn zclSampleLight_LcdDisplayUpdate
*
* @brief Called to update the LCD display.
*
* @param none
*
* @return none
*/
void zclSampleLight_LcdDisplayUpdate( void )
{
#ifdef LCD_SUPPORTED
if ( giLightScreenMode == LIGHT_HELPMODE )
{
zclSampleLight_LcdDisplayHelpMode();
}
else
{
zclSampleLight_LcdDisplayMainMode();
}
#endif
zclSampleLight_DisplayLight();
}
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
/*********************************************************************
* @fn zclSampleLight_UpdateLampLevel
*
* @brief Update lamp level output with gamma compensation
*
* @param level
*
* @return none
*/
void zclSampleLight_UpdateLampLevel( uint8 level )
{
uint16 gammaCorrectedLevel;
// gamma correct the level
gammaCorrectedLevel = (uint16) ( pow( ( (float)level / LEVEL_MAX ), (float)GAMMA_VALUE ) * (float)LEVEL_MAX);
halTimer1SetChannelDuty(WHITE_LED, (uint16)(((uint32)gammaCorrectedLevel*PWM_FULL_DUTY_CYCLE)/LEVEL_MAX) );
}
#endif
/*********************************************************************
* @fn zclSampleLight_DisplayLight
*
* @brief Displays current state of light on LED and also on main display if supported.
*
* @param none
*
* @return none
*/
static void zclSampleLight_DisplayLight( void )
{
// set the LED1 based on light (on or off)
if ( zclSampleLight_OnOff == LIGHT_ON )
{
HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON );
}
else
{
HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
}
#ifdef LCD_SUPPORTED
if (giLightScreenMode == LIGHT_MAINMODE)
{
#ifdef ZCL_LEVEL_CTRL
// display current light level
if ( ( zclSampleLight_LevelCurrentLevel == ATTR_LEVEL_MIN_LEVEL ) &&
( zclSampleLight_OnOff == LIGHT_OFF ) )
{
HalLcdWriteString( (char *)sLightOff, HAL_LCD_LINE_2 );
}
else if ( ( zclSampleLight_LevelCurrentLevel >= ATTR_LEVEL_MAX_LEVEL ) ||
( zclSampleLight_LevelCurrentLevel == zclSampleLight_LevelOnLevel ) ||
( ( zclSampleLight_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT ) &&
( zclSampleLight_LevelCurrentLevel == zclSampleLight_LevelLastLevel ) ) )
{
HalLcdWriteString( (char *)sLightOn, HAL_LCD_LINE_2 );
}
else // " LEVEL ###"
{
zclHA_uint8toa( zclSampleLight_LevelCurrentLevel, &sLightLevel[10] );
HalLcdWriteString( (char *)sLightLevel, HAL_LCD_LINE_2 );
}
#else
if ( zclSampleLight_OnOff )
{
HalLcdWriteString( (char *)sLightOn, HAL_LCD_LINE_2 );
}
else
{
HalLcdWriteString( (char *)sLightOff, HAL_LCD_LINE_2 );
}
#endif // ZCL_LEVEL_CTRL
}
#endif // LCD_SUPPORTED
}
#ifdef LCD_SUPPORTED
/*********************************************************************
* @fn zclSampleLight_LcdDisplayMainMode
*
* @brief Called to display the main screen on the LCD.
*
* @param none
*
* @return none
*/
static void zclSampleLight_LcdDisplayMainMode( void )
{
// display line 1 to indicate NWK status
if ( zclSampleLight_NwkState == DEV_ZB_COORD )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZC );
}
else if ( zclSampleLight_NwkState == DEV_ROUTER )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZR );
}
else if ( zclSampleLight_NwkState == DEV_END_DEVICE )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZED );
}
// end of line 3 displays permit join status (*)
if ( gPermitDuration )
{
sSwHelp[15] = '*';
}
else
{
sSwHelp[15] = ' ';
}
HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3 );
}
/*********************************************************************
* @fn zclSampleLight_LcdDisplayHelpMode
*
* @brief Called to display the SW options on the LCD.
*
* @param none
*
* @return none
*/
static void zclSampleLight_LcdDisplayHelpMode( void )
{
HalLcdWriteString( (char *)sSwLight, HAL_LCD_LINE_1 );
HalLcdWriteString( (char *)sSwEZMode, HAL_LCD_LINE_2 );
HalLcdWriteString( (char *)sSwHelp, HAL_LCD_LINE_3 );
}
#endif // LCD_SUPPORTED
/*********************************************************************
* @fn zclSampleLight_ProcessIdentifyTimeChange
*
* @brief Called to process any change to the IdentifyTime attribute.
*
* @param none
*
* @return none
*/
static void zclSampleLight_ProcessIdentifyTimeChange( void )
{
if ( zclSampleLight_IdentifyTime > 0 )
{
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT, 1000 );
HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
}
else
{
#ifdef ZCL_EZMODE
if ( zclSampleLight_IdentifyCommissionState & EZMODE_COMMISSION_OPERATIONAL )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
}
else
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
}
#endif
osal_stop_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT );
}
}
/*********************************************************************
* @fn zclSampleLight_BasicResetCB
*
* @brief Callback from the ZCL General Cluster Library
* to set all the Basic Cluster attributes to default values.
*
* @param none
*
* @return none
*/
static void zclSampleLight_BasicResetCB( void )
{
NLME_LeaveReq_t leaveReq;
// Set every field to 0
osal_memset( &leaveReq, 0, sizeof( NLME_LeaveReq_t ) );
// This will enable the device to rejoin the network after reset.
leaveReq.rejoin = TRUE;
// Set the NV startup option to force a "new" join.
zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
// Leave the network, and reset afterwards
if ( NLME_LeaveReq( &leaveReq ) != ZSuccess )
{
// Couldn't send out leave; prepare to reset anyway
ZDApp_LeaveReset( FALSE );
}
}
/*********************************************************************
* @fn zclSampleLight_IdentifyCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Identity Command for this application.
*
* @param srcAddr - source address and endpoint of the response message
* @param identifyTime - the number of seconds to identify yourself
*
* @return none
*/
static void zclSampleLight_IdentifyCB( zclIdentify_t *pCmd )
{
zclSampleLight_IdentifyTime = pCmd->identifyTime;
zclSampleLight_ProcessIdentifyTimeChange();
}
/*********************************************************************
* @fn zclSampleLight_IdentifyQueryRspCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Identity Query Response Command for this application.
*
* @param srcAddr - requestor's address
* @param timeout - number of seconds to identify yourself (valid for query response)
*
* @return none
*/
static void zclSampleLight_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
{
(void)pRsp;
#ifdef ZCL_EZMODE
{
zclEZMode_ActionData_t data;
data.pIdentifyQueryRsp = pRsp;
zcl_EZModeAction ( EZMODE_ACTION_IDENTIFY_QUERY_RSP, &data );
}
#endif
}
/*********************************************************************
* @fn zclSampleLight_OnOffCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an On/Off Command for this application.
*
* @param cmd - COMMAND_ON, COMMAND_OFF or COMMAND_TOGGLE
*
* @return none
*/
static void zclSampleLight_OnOffCB( uint8 cmd )
{
if(zclSampleLight_LightDelay==0){
zclSampleLight_LightDelay=1;
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LIGHT_DELAY_EVT, LIGHT_INTERVAL_DELAY_TIME );
// Turn on the light
if ( cmd == COMMAND_ON )
{
zclSampleLight_OnOff = LIGHT_ON;
}
// Turn off the light
else if ( cmd == COMMAND_OFF )
{
zclSampleLight_OnOff = LIGHT_OFF;
}
// Toggle the light
else if ( cmd == COMMAND_TOGGLE )
{
if ( zclSampleLight_OnOff == LIGHT_OFF )
{
zclSampleLight_OnOff = LIGHT_ON;
}
else
{
zclSampleLight_OnOff = LIGHT_OFF;
}
}
#if ZCL_LEVEL_CTRL
zclSampleLight_DefaultMove( );
#endif
// update the display
zclSampleLight_LcdDisplayUpdate( );
}
}
#ifdef ZCL_LEVEL_CTRL
/*********************************************************************
* @fn zclSampleLight_TimeRateHelper
*
* @brief Calculate time based on rate, and startup level state machine
*
* @param newLevel - new level for current level
*
* @return diff (directly), zclSampleLight_CurrentLevel32 and zclSampleLight_NewLevel, zclSampleLight_NewLevelUp
*/
static uint32 zclSampleLight_TimeRateHelper( uint8 newLevel )
{
uint32 diff;
uint32 newLevel32;
// remember current and new level
zclSampleLight_NewLevel = newLevel;
zclSampleLight_CurrentLevel32 = (uint32)1000 * zclSampleLight_LevelCurrentLevel;
// calculate diff
newLevel32 = (uint32)1000 * newLevel;
if ( zclSampleLight_LevelCurrentLevel > newLevel )
{
diff = zclSampleLight_CurrentLevel32 - newLevel32;
zclSampleLight_NewLevelUp = FALSE; // moving down
}
else
{
diff = newLevel32 - zclSampleLight_CurrentLevel32;
zclSampleLight_NewLevelUp = TRUE; // moving up
}
return ( diff );
}
/*********************************************************************
* @fn zclSampleLight_MoveBasedOnRate
*
* @brief Calculate time based on rate, and startup level state machine
*
* @param newLevel - new level for current level
* @param rate16 - fixed point rate (e.g. 16.123)
*
* @return none
*/
static void zclSampleLight_MoveBasedOnRate( uint8 newLevel, uint32 rate )
{
uint32 diff;
// determine how much time (in 10ths of seconds) based on the difference and rate
zclSampleLight_Rate32 = rate;
diff = zclSampleLight_TimeRateHelper( newLevel );
zclSampleLight_LevelRemainingTime = diff / rate;
if ( !zclSampleLight_LevelRemainingTime )
{
zclSampleLight_LevelRemainingTime = 1;
}
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT, 100 );
}
/*********************************************************************
* @fn zclSampleLight_MoveBasedOnTime
*
* @brief Calculate rate based on time, and startup level state machine
*
* @param newLevel - new level for current level
* @param time - in 10ths of seconds
*
* @return none
*/
static void zclSampleLight_MoveBasedOnTime( uint8 newLevel, uint16 time )
{
uint16 diff;
// determine rate (in units) based on difference and time
diff = zclSampleLight_TimeRateHelper( newLevel );
zclSampleLight_LevelRemainingTime = zclSampleLight_GetTime( newLevel, time );
zclSampleLight_Rate32 = diff / time;
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT, 100 );
}
/*********************************************************************
* @fn zclSampleLight_GetTime
*
* @brief Determine amount of time that MoveXXX will take to complete.
*
* @param level = new level to move to
* time = 0xffff=default, or 0x0000-n amount of time in tenths of seconds.
*
* @return none
*/
static uint16 zclSampleLight_GetTime( uint8 level, uint16 time )
{
// there is a hiearchy of the amount of time to use for transistioning
// check each one in turn. If none of defaults are set, then use fastest
// time possible.
if ( time == 0xFFFF )
{
// use On or Off Transition Time if set (not 0xffff)
if ( zclSampleLight_OnOff == LIGHT_ON )
{
time = zclSampleLight_LevelOffTransitionTime;
}
else
{
time = zclSampleLight_LevelOnTransitionTime;
}
// else use OnOffTransitionTime if set (not 0xffff)
if ( time == 0xFFFF )
{
time = zclSampleLight_LevelOnOffTransitionTime;
}
// else as fast as possible
if ( time == 0xFFFF )
{
time = 1;
}
}
if ( !time )
{
time = 1; // as fast as possible
}
return ( time );
}
/*********************************************************************
* @fn zclSampleLight_DefaultMove
*
* @brief We were turned on/off. Use default time to move to on or off.
*
* @param zclSampleLight_OnOff - must be set prior to calling this function.
*
* @return none
*/
static void zclSampleLight_DefaultMove( void )
{
uint8 newLevel;
uint32 rate; // fixed point decimal (3 places, eg. 16.345)
uint16 time;
// if moving to on position, move to on level
if ( zclSampleLight_OnOff )
{
if ( zclSampleLight_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT )
{
// The last Level (before going OFF) should be used)
newLevel = zclSampleLight_LevelLastLevel;
}
else
{
newLevel = zclSampleLight_LevelOnLevel;
}
time = zclSampleLight_LevelOnTransitionTime;
}
else
{
newLevel = ATTR_LEVEL_MIN_LEVEL;
if ( zclSampleLight_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT )
{
// Save the current Level before going OFF to use it when the light turns ON
// it should be back to this level
zclSampleLight_LevelLastLevel = zclSampleLight_LevelCurrentLevel;
}
time = zclSampleLight_LevelOffTransitionTime;
}
// else use OnOffTransitionTime if set (not 0xffff)
if ( time == 0xFFFF )
{
time = zclSampleLight_LevelOnOffTransitionTime;
}
// else as fast as possible
if ( time == 0xFFFF )
{
time = 1;
}
// calculate rate based on time (int 10ths) for full transition (1-254)
rate = 255000 / time; // units per tick, fixed point, 3 decimal places (e.g. 8500 = 8.5 units per tick)
// start up state machine.
zclSampleLight_WithOnOff = TRUE;
zclSampleLight_MoveBasedOnRate( newLevel, rate );
}
/*********************************************************************
* @fn zclSampleLight_AdjustLightLevel
*
* @brief Called each 10th of a second while state machine running
*
* @param none
*
* @return none
*/
static void zclSampleLight_AdjustLightLevel( void )
{
// one tick (10th of a second) less
if ( zclSampleLight_LevelRemainingTime )
{
--zclSampleLight_LevelRemainingTime;
}
// no time left, done
if ( zclSampleLight_LevelRemainingTime == 0)
{
zclSampleLight_LevelCurrentLevel = zclSampleLight_NewLevel;
}
// still time left, keep increment/decrementing
else
{
if ( zclSampleLight_NewLevelUp )
{
zclSampleLight_CurrentLevel32 += zclSampleLight_Rate32;
}
else
{
zclSampleLight_CurrentLevel32 -= zclSampleLight_Rate32;
}
zclSampleLight_LevelCurrentLevel = (uint8)( zclSampleLight_CurrentLevel32 / 1000 );
}
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
zclSampleLight_UpdateLampLevel(zclSampleLight_LevelCurrentLevel);
#endif
// also affect on/off
if ( zclSampleLight_WithOnOff )
{
if ( zclSampleLight_LevelCurrentLevel > ATTR_LEVEL_MIN_LEVEL )
{
zclSampleLight_OnOff = LIGHT_ON;
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
ENABLE_LAMP;
#endif
}
else
{
zclSampleLight_OnOff = LIGHT_OFF;
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
DISABLE_LAMP;
#endif
}
}
// display light level as we go
zclSampleLight_DisplayLight( );
// keep ticking away
if ( zclSampleLight_LevelRemainingTime )
{
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT, 100 );
}
}
/*********************************************************************
* @fn zclSampleLight_LevelControlMoveToLevelCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received a LevelControlMoveToLevel Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlMoveToLevelCB( zclLCMoveToLevel_t *pCmd )
{
zclSampleLight_WithOnOff = pCmd->withOnOff;
zclSampleLight_MoveBasedOnTime( pCmd->level, pCmd->transitionTime );
}
/*********************************************************************
* @fn zclSampleLight_LevelControlMoveCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received a LevelControlMove Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlMoveCB( zclLCMove_t *pCmd )
{
uint8 newLevel;
uint32 rate;
// convert rate from units per second to units per tick (10ths of seconds)
// and move at that right up or down
zclSampleLight_WithOnOff = pCmd->withOnOff;
if ( pCmd->moveMode == LEVEL_MOVE_UP )
{
newLevel = ATTR_LEVEL_MAX_LEVEL; // fully on
}
else
{
newLevel = ATTR_LEVEL_MIN_LEVEL; // fully off
}
rate = (uint32)100 * pCmd->rate;
zclSampleLight_MoveBasedOnRate( newLevel, rate );
}
/*********************************************************************
* @fn zclSampleLight_LevelControlStepCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an On/Off Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlStepCB( zclLCStep_t *pCmd )
{
uint8 newLevel;
// determine new level, but don't exceed boundaries
if ( pCmd->stepMode == LEVEL_MOVE_UP )
{
if ( (uint16)zclSampleLight_LevelCurrentLevel + pCmd->amount > ATTR_LEVEL_MAX_LEVEL )
{
newLevel = ATTR_LEVEL_MAX_LEVEL;
}
else
{
newLevel = zclSampleLight_LevelCurrentLevel + pCmd->amount;
}
}
else
{
if ( pCmd->amount >= zclSampleLight_LevelCurrentLevel )
{
newLevel = ATTR_LEVEL_MIN_LEVEL;
}
else
{
newLevel = zclSampleLight_LevelCurrentLevel - pCmd->amount;
}
}
// move to the new level
zclSampleLight_WithOnOff = pCmd->withOnOff;
zclSampleLight_MoveBasedOnTime( newLevel, pCmd->transitionTime );
}
/*********************************************************************
* @fn zclSampleLight_LevelControlStopCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Level Control Stop Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight_LevelControlStopCB( void )
{
// stop immediately
osal_stop_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_LEVEL_CTRL_EVT );
zclSampleLight_LevelRemainingTime = 0;
}
#endif
/******************************************************************************
*
* Functions for processing ZCL Foundation incoming Command/Response messages
*
*****************************************************************************/
/*********************************************************************
* @fn zclSampleLight_ProcessIncomingMsg
*
* @brief Process ZCL Foundation incoming message
*
* @param pInMsg - pointer to the received message
*
* @return none
*/
static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg )
{
switch ( pInMsg->zclHdr.commandID )
{
#ifdef ZCL_READ
case ZCL_CMD_READ_RSP:
zclSampleLight_ProcessInReadRspCmd( pInMsg );
break;
#endif
#ifdef ZCL_WRITE
case ZCL_CMD_WRITE_RSP:
zclSampleLight_ProcessInWriteRspCmd( pInMsg );
break;
#endif
#ifdef ZCL_REPORT
// Attribute Reporting implementation should be added here
case ZCL_CMD_CONFIG_REPORT:
// zclSampleLight_ProcessInConfigReportCmd( pInMsg );
break;
case ZCL_CMD_CONFIG_REPORT_RSP:
// zclSampleLight_ProcessInConfigReportRspCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG:
// zclSampleLight_ProcessInReadReportCfgCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG_RSP:
// zclSampleLight_ProcessInReadReportCfgRspCmd( pInMsg );
break;
case ZCL_CMD_REPORT:
// zclSampleLight_ProcessInReportCmd( pInMsg );
break;
#endif
case ZCL_CMD_DEFAULT_RSP:
zclSampleLight_ProcessInDefaultRspCmd( pInMsg );
break;
#ifdef ZCL_DISCOVER
case ZCL_CMD_DISCOVER_CMDS_RECEIVED_RSP:
zclSampleLight_ProcessInDiscCmdsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_CMDS_GEN_RSP:
zclSampleLight_ProcessInDiscCmdsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_ATTRS_RSP:
zclSampleLight_ProcessInDiscAttrsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_ATTRS_EXT_RSP:
zclSampleLight_ProcessInDiscAttrsExtRspCmd( pInMsg );
break;
#endif
default:
break;
}
if ( pInMsg->attrCmd )
osal_mem_free( pInMsg->attrCmd );
}
#ifdef ZCL_READ
/*********************************************************************
* @fn zclSampleLight_ProcessInReadRspCmd
*
* @brief Process the "Profile" Read Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
{
zclReadRspCmd_t *readRspCmd;
uint8 i;
readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
for (i = 0; i < readRspCmd->numAttr; i++)
{
// Notify the originator of the results of the original read attributes
// attempt and, for each successfull request, the value of the requested
// attribute
}
return ( TRUE );
}
#endif // ZCL_READ
#ifdef ZCL_WRITE
/*********************************************************************
* @fn zclSampleLight_ProcessInWriteRspCmd
*
* @brief Process the "Profile" Write Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
{
zclWriteRspCmd_t *writeRspCmd;
uint8 i;
writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
for ( i = 0; i < writeRspCmd->numAttr; i++ )
{
// Notify the device of the results of the its original write attributes
// command.
}
return ( TRUE );
}
#endif // ZCL_WRITE
/*********************************************************************
* @fn zclSampleLight_ProcessInDefaultRspCmd
*
* @brief Process the "Profile" Default Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
{
// zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
// Device is notified of the Default Response command.
(void)pInMsg;
return ( TRUE );
}
#ifdef ZCL_DISCOVER
/*********************************************************************
* @fn zclSampleLight_ProcessInDiscCmdsRspCmd
*
* @brief Process the Discover Commands Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverCmdsCmdRsp_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverCmdsCmdRsp_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numCmd; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
/*********************************************************************
* @fn zclSampleLight_ProcessInDiscAttrsRspCmd
*
* @brief Process the "Profile" Discover Attributes Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverAttrsRspCmd_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverAttrsRspCmd_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numAttr; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
/*********************************************************************
* @fn zclSampleLight_ProcessInDiscAttrsExtRspCmd
*
* @brief Process the "Profile" Discover Attributes Extended Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverAttrsExtRsp_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverAttrsExtRsp_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numAttr; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
#endif // ZCL_DISCOVER
#if ZCL_EZMODE
/*********************************************************************
* @fn zclSampleLight_ProcessZDOMsgs
*
* @brief Called when this node receives a ZDO/ZDP response.
*
* @param none
*
* @return status
*/
static void zclSampleLight_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
{
zclEZMode_ActionData_t data;
ZDO_MatchDescRsp_t *pMatchDescRsp;
// Let EZ-Mode know of the Simple Descriptor Response
if ( pMsg->clusterID == Match_Desc_rsp )
{
pMatchDescRsp = ZDO_ParseEPListRsp( pMsg );
data.pMatchDescRsp = pMatchDescRsp;
zcl_EZModeAction( EZMODE_ACTION_MATCH_DESC_RSP, &data );
osal_mem_free( pMatchDescRsp );
}
}
/*********************************************************************
* @fn zclSampleLight_EZModeCB
*
* @brief The Application is informed of events. This can be used to show on the UI what is
* going on during EZ-Mode steering/finding/binding.
*
* @param state - an
*
* @return none
*/
static void zclSampleLight_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData )
{
#ifdef LCD_SUPPORTED
char *pStr;
uint8 err;
#endif
// time to go into identify mode
if ( state == EZMODE_STATE_IDENTIFYING )
{
#ifdef LCD_SUPPORTED
HalLcdWriteString( "EZMode", HAL_LCD_LINE_2 );
#endif
zclSampleLight_IdentifyTime = ( EZMODE_TIME / 1000 ); // convert to seconds
zclSampleLight_ProcessIdentifyTimeChange();
}
// autoclosing, show what happened (success, cancelled, etc...)
if( state == EZMODE_STATE_AUTOCLOSE )
{
#ifdef LCD_SUPPORTED
pStr = NULL;
err = pData->sAutoClose.err;
if ( err == EZMODE_ERR_SUCCESS )
{
pStr = "EZMode: Success";
}
else if ( err == EZMODE_ERR_NOMATCH )
{
pStr = "EZMode: NoMatch"; // not a match made in heaven
}
if ( pStr )
{
if ( giLightScreenMode == LIGHT_MAINMODE )
{
HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
}
}
#endif
}
// finished, either show DstAddr/EP, or nothing (depending on success or not)
if( state == EZMODE_STATE_FINISH )
{
// turn off identify mode
zclSampleLight_IdentifyTime = 0;
zclSampleLight_ProcessIdentifyTimeChange();
#ifdef LCD_SUPPORTED
// if successful, inform user which nwkaddr/ep we bound to
pStr = NULL;
err = pData->sFinish.err;
if( err == EZMODE_ERR_SUCCESS )
{
// already stated on autoclose
}
else if ( err == EZMODE_ERR_CANCELLED )
{
pStr = "EZMode: Cancel";
}
else if ( err == EZMODE_ERR_BAD_PARAMETER )
{
pStr = "EZMode: BadParm";
}
else if ( err == EZMODE_ERR_TIMEDOUT )
{
pStr = "EZMode: TimeOut";
}
if ( pStr )
{
if ( giLightScreenMode == LIGHT_MAINMODE )
{
HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
}
}
#endif
// show main UI screen 3 seconds after binding
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_MAIN_SCREEN_EVT, 3000 );
}
}
#endif // ZCL_EZMODE
/****************************************************************************
****************************************************************************/
/**************************************************************************************************
Filename: zcl_samplelight_data.c
Revised: $Date: 2014-05-12 13:14:02 -0700 (Mon, 12 May 2014) $
Revision: $Revision: 38502 $
Description: Zigbee Cluster Library - sample device application.
Copyright 2006-2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "ZComDef.h"
#include "OSAL.h"
#include "AF.h"
#include "ZDConfig.h"
#include "zcl.h"
#include "zcl_general.h"
#include "zcl_ha.h"
#include "zcl_ezmode.h"
#include "zcl_poll_control.h"
#include "zcl_electrical_measurement.h"
#include "zcl_diagnostic.h"
#include "zcl_meter_identification.h"
#include "zcl_appliance_identification.h"
#include "zcl_appliance_events_alerts.h"
#include "zcl_power_profile.h"
#include "zcl_appliance_control.h"
#include "zcl_appliance_statistics.h"
#include "zcl_hvac.h"
#include "zcl_samplelight.h"
/*********************************************************************
* CONSTANTS
*/
#define SAMPLELIGHT_DEVICE_VERSION 0
#define SAMPLELIGHT_FLAGS 0
#define SAMPLELIGHT_HWVERSION 1
#define SAMPLELIGHT_ZCLVERSION 1
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
// Basic Cluster
const uint8 zclSampleLight_HWRevision = SAMPLELIGHT_HWVERSION;
const uint8 zclSampleLight_ZCLVersion = SAMPLELIGHT_ZCLVERSION;
const uint8 zclSampleLight_ManufacturerName[] = { 16, 'T','e','x','a','s','I','n','s','t','r','u','m','e','n','t','s' };
const uint8 zclSampleLight_ModelId[] = { 16, 'T','I','0','0','0','1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
const uint8 zclSampleLight_DateCode[] = { 16, '2','0','0','6','0','8','3','1',' ',' ',' ',' ',' ',' ',' ',' ' };
const uint8 zclSampleLight_PowerSource = POWER_SOURCE_MAINS_1_PHASE;
uint8 zclSampleLight_LocationDescription[17] = { 16, ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
uint8 zclSampleLight_PhysicalEnvironment = 0;
uint8 zclSampleLight_DeviceEnable = DEVICE_ENABLED;
// Identify Cluster
uint16 zclSampleLight_IdentifyTime = 0;
#ifdef ZCL_EZMODE
uint8 zclSampleLight_IdentifyCommissionState;
#endif
// On/Off Cluster
uint8 zclSampleLight_OnOff = LIGHT_OFF;
// Level Control Cluster
#ifdef ZCL_LEVEL_CTRL
uint8 zclSampleLight_LevelCurrentLevel = ATTR_LEVEL_MIN_LEVEL;
uint16 zclSampleLight_LevelRemainingTime;
uint16 zclSampleLight_LevelOnOffTransitionTime = 20;
uint8 zclSampleLight_LevelOnLevel = ATTR_LEVEL_MID_LEVEL;
uint16 zclSampleLight_LevelOnTransitionTime = 20;
uint16 zclSampleLight_LevelOffTransitionTime = 20;
uint8 zclSampleLight_LevelDefaultMoveRate = 0; // as fast as possible
#endif
#if ZCL_DISCOVER
CONST zclCommandRec_t zclSampleLight_Cmds[] =
{
{
ZCL_CLUSTER_ID_GEN_BASIC,
COMMAND_BASIC_RESET_FACT_DEFAULT,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
COMMAND_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
COMMAND_ON,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
COMMAND_TOGGLE,
CMD_DIR_SERVER_RECEIVED
},
#ifdef ZCL_LEVEL_CONTROL
,{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE_TO_LEVEL,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STEP,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STOP,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE_TO_LEVEL_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STEP_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STOP_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
}
#endif // ZCL_LEVEL_CONTROL
};
CONST uint8 zclCmdsArraySize = ( sizeof(zclSampleLight_Cmds) / sizeof(zclSampleLight_Cmds[0]) );
#endif // ZCL_DISCOVER
/*********************************************************************
* ATTRIBUTE DEFINITIONS - Uses REAL cluster IDs
*/
CONST zclAttrRec_t zclSampleLight_Attrs[] =
{
// *** General Basic Cluster Attributes ***
{
ZCL_CLUSTER_ID_GEN_BASIC, // Cluster IDs - defined in the foundation (ie. zcl.h)
{ // Attribute record
ATTRID_BASIC_HW_VERSION, // Attribute ID - Found in Cluster Library header (ie. zcl_general.h)
ZCL_DATATYPE_UINT8, // Data Type - found in zcl.h
ACCESS_CONTROL_READ, // Variable access control - found in zcl.h
(void *)&zclSampleLight_HWRevision // Pointer to attribute variable
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_ZCL_VERSION,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight_ZCLVersion
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_MANUFACTURER_NAME,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)zclSampleLight_ManufacturerName
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_MODEL_ID,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)zclSampleLight_ModelId
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_DATE_CODE,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)zclSampleLight_DateCode
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_POWER_SOURCE,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight_PowerSource
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_LOCATION_DESC,
ZCL_DATATYPE_CHAR_STR,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)zclSampleLight_LocationDescription
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_PHYSICAL_ENV,
ZCL_DATATYPE_UINT8,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&zclSampleLight_PhysicalEnvironment
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_DEVICE_ENABLED,
ZCL_DATATYPE_BOOLEAN,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&zclSampleLight_DeviceEnable
}
},
#ifdef ZCL_IDENTIFY
// *** Identify Cluster Attribute ***
{
ZCL_CLUSTER_ID_GEN_IDENTIFY,
{ // Attribute record
ATTRID_IDENTIFY_TIME,
ZCL_DATATYPE_UINT16,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&zclSampleLight_IdentifyTime
}
},
#ifdef ZCL_EZMODE
// *** Identify Cluster Attribute ***
{
ZCL_CLUSTER_ID_GEN_IDENTIFY,
{ // Attribute record
ATTRID_IDENTIFY_COMMISSION_STATE,
ZCL_DATATYPE_UINT8,
(ACCESS_CONTROL_READ),
(void *)&zclSampleLight_IdentifyCommissionState
}
},
#endif // ZCL_EZMODE
#endif
// *** On/Off Cluster Attributes ***
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
{ // Attribute record
ATTRID_ON_OFF,
ZCL_DATATYPE_BOOLEAN,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight_OnOff
}
}
#ifdef ZCL_LEVEL_CTRL
, {
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_CURRENT_LEVEL,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight_LevelCurrentLevel
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_REMAINING_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight_LevelRemainingTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_ON_OFF_TRANSITION_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight_LevelOnOffTransitionTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_ON_LEVEL,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight_LevelOnLevel
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_ON_TRANSITION_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight_LevelOnTransitionTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_OFF_TRANSITION_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight_LevelOffTransitionTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_DEFAULT_MOVE_RATE,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight_LevelDefaultMoveRate
}
}
#endif
#ifdef ZCL_DIAGNOSTIC
, {
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NUMBER_OF_RESETS,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PERSISTENT_MEMORY_WRITES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_RX_BCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_BCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_RX_UCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_UCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_UCAST_RETRY,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_UCAST_FAIL,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_RX_BCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_BCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_RX_UCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_UCAST_SUCCESS,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_UCAST_RETRY,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_UCAST_FAIL,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_ROUTE_DISC_INITIATED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NEIGHBOR_ADDED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NEIGHBOR_REMOVED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NEIGHBOR_STALE,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_JOIN_INDICATION,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_CHILD_MOVED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NWK_FC_FAILURE,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_FC_FAILURE,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_UNAUTHORIZED_KEY,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NWK_DECRYPT_FAILURES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_DECRYPT_FAILURES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PACKET_BUFFER_ALLOCATE_FAILURES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_RELAYED_UCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PHY_TO_MAC_QUEUE_LIMIT_REACHED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PACKET_VALIDATE_DROP_COUNT,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_AVERAGE_MAC_RETRY_PER_APS_MESSAGE_SENT,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_LAST_MESSAGE_LQI,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_LAST_MESSAGE_RSSI,
ZCL_DATATYPE_INT8,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
#endif // ZCL_DIAGNOSTIC
};
uint8 CONST zclSampleLight_NumAttributes = ( sizeof(zclSampleLight_Attrs) / sizeof(zclSampleLight_Attrs[0]) );
/*********************************************************************
* SIMPLE DESCRIPTOR
*/
// This is the Cluster ID List and should be filled with Application
// specific cluster IDs.
const cId_t zclSampleLight_InClusterList[] =
{
ZCL_CLUSTER_ID_GEN_BASIC,
ZCL_CLUSTER_ID_GEN_IDENTIFY,
ZCL_CLUSTER_ID_GEN_GROUPS,
ZCL_CLUSTER_ID_GEN_SCENES,
ZCL_CLUSTER_ID_GEN_ON_OFF
#ifdef ZCL_LEVEL_CTRL
, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL
#endif
};
// work-around for compiler bug... IAR can't calculate size of array with #if options.
#ifdef ZCL_LEVEL_CTRL
#define ZCLSAMPLELIGHT_MAX_INCLUSTERS 6
#else
#define ZCLSAMPLELIGHT_MAX_INCLUSTERS 5
#endif
const cId_t zclSampleLight_OutClusterList[] =
{
ZCL_CLUSTER_ID_GEN_BASIC
};
#define ZCLSAMPLELIGHT_MAX_OUTCLUSTERS (sizeof(zclSampleLight_OutClusterList) / sizeof(zclSampleLight_OutClusterList[0]))
SimpleDescriptionFormat_t zclSampleLight_SimpleDesc =
{
SAMPLELIGHT_ENDPOINT, // int Endpoint;
ZCL_HA_PROFILE_ID, // uint16 AppProfId;
#ifdef ZCL_LEVEL_CTRL
ZCL_HA_DEVICEID_DIMMABLE_LIGHT, // uint16 AppDeviceId;
#else
ZCL_HA_DEVICEID_ON_OFF_LIGHT, // uint16 AppDeviceId;
#endif
SAMPLELIGHT_DEVICE_VERSION, // int AppDevVer:4;
SAMPLELIGHT_FLAGS, // int AppFlags:4;
ZCLSAMPLELIGHT_MAX_INCLUSTERS, // byte AppNumInClusters;
(cId_t *)zclSampleLight_InClusterList, // byte *pAppInClusterList;
ZCLSAMPLELIGHT_MAX_OUTCLUSTERS, // byte AppNumInClusters;
(cId_t *)zclSampleLight_OutClusterList // byte *pAppInClusterList;
};
/*********************************************************************
* GLOBAL FUNCTIONS
*/
/*********************************************************************
* LOCAL FUNCTIONS
*/
/****************************************************************************
****************************************************************************/
/**************************************************************************************************
Filename: zcl_sampleLight.c
Revised: $Date: 2014-07-01 22:24:24 -0700 (Tue, 01 Jul 2014) $
Revision: $Revision: 39317 $
Description: Zigbee Cluster Library - sample device application.
Copyright 2006-2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/*********************************************************************
This application implements a ZigBee HA 1.2 Light. It can be configured as an
On/Off light, or as a dimmable light. The following flags must be defined in
the compiler's pre-defined symbols.
ZCL_ON_OFF
ZCL_LEVEL_CTRL (only if dimming functionality desired)
HOLD_AUTO_START
ZCL_EZMODE
This device supports all mandatory and optional commands/attributes for the
OnOff (0x0006) and LevelControl (0x0008) clusters.
SCREEN MODES
----------------------------------------
Main:
- SW1: Toggle local light
- SW2: Invoke EZMode
- SW4: Enable/Disable local permit join
- SW5: Go to Help screen
----------------------------------------
*********************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "ZComDef.h"
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "MT_SYS.h"
#include "zcl.h"
#include "zcl_general.h"
#include "zcl_ha.h"
#include "zcl_ezmode.h"
#include "zcl_diagnostic.h"
#include "zcl_samplelight1.h"
#include "onboard.h"
/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#if ( defined (ZGP_DEVICE_TARGET) || defined (ZGP_DEVICE_TARGETPLUS) \
|| defined (ZGP_DEVICE_COMBO) || defined (ZGP_DEVICE_COMBO_MIN) )
#include "zgp_translationtable.h"
#if (SUPPORTED_S_FEATURE(SUPP_ZGP_FEATURE_TRANSLATION_TABLE))
#define ZGP_AUTO_TT
#endif
#endif
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
#include "math.h"
#include "hal_timer.h"
#endif
#include "NLMEDE.h"
#include "hal_adc.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#if (defined HAL_BOARD_ZLIGHT)
#define LEVEL_MAX 0xFE
#define LEVEL_MIN 0x0
#define GAMMA_VALUE 2
#define PWM_FULL_DUTY_CYCLE 1000
#elif (defined HAL_PWM)
#define LEVEL_MAX 0xFE
#define LEVEL_MIN 0x0
#define GAMMA_VALUE 2
#define PWM_FULL_DUTY_CYCLE 100
#endif
#define LIGHT1_INTERVAL_DELAY_TIME 500
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
byte zclSampleLight1_TaskID;
uint8 zclSampleLight1SeqNum;
byte zclSampleLight1_LightDelay;
uint16 maxSensorReadValue1;
/*********************************************************************
* GLOBAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
afAddrType_t zclSampleLight1_DstAddr;
#ifdef ZCL_EZMODE
static void zclSampleLight1_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
static void zclSampleLight1_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData );
// register EZ-Mode with task information (timeout events, callback, etc...)
static const zclEZMode_RegisterData_t zclSampleLight1_RegisterEZModeData =
{
&zclSampleLight1_TaskID,
SAMPLELIGHT1_EZMODE_NEXTSTATE_EVT,
SAMPLELIGHT1_EZMODE_TIMEOUT_EVT,
&zclSampleLight1SeqNum,
zclSampleLight1_EZModeCB
};
#else
uint16 bindingInClusters1[] =
{
ZCL_CLUSTER_ID_GEN_ON_OFF
#ifdef ZCL_LEVEL_CTRL
, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL
#endif
};
#define ZCLSAMPLELIGHT1_BINDINGLIST (sizeof(bindingInClusters1) / sizeof(bindingInClusters1[0]))
#endif // ZCL_EZMODE
// Test Endpoint to allow SYS_APP_MSGs
static endPointDesc_t sampleLight1_TestEp =
{
SAMPLELIGHT1_ENDPOINT,
&zclSampleLight1_TaskID,
(SimpleDescriptionFormat_t *)NULL, // No Simple description for this test endpoint
(afNetworkLatencyReq_t)0 // No Network Latency req
};
uint8 giLightScreenMode1 = LIGHT1_MAINMODE; // display the main screen mode first
uint8 gPermitDuration1 = 0; // permit joining default to disabled
devStates_t zclSampleLight1_NwkState = DEV_INIT;
#if ZCL_LEVEL_CTRL
uint8 zclSampleLight1_WithOnOff; // set to TRUE if state machine should set light on/off
uint8 zclSampleLight1_NewLevel; // new level when done moving
bool zclSampleLight1_NewLevelUp; // is direction to new level up or down?
int32 zclSampleLight1_CurrentLevel32; // current level, fixed point (e.g. 192.456)
int32 zclSampleLight1_Rate32; // rate in units, fixed point (e.g. 16.123)
uint8 zclSampleLight1_LevelLastLevel; // to save the Current Level before the light was turned OFF
#endif
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void zclSampleLight1_ReadSensorCurrent(void);
static void zclSampleLight1_SendSensorInformation(void);
static void zclSampleLight1_HandleKeys( byte shift, byte keys );
static void zclSampleLight1_BasicResetCB( void );
static void zclSampleLight1_IdentifyCB( zclIdentify_t *pCmd );
static void zclSampleLight1_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
static void zclSampleLight1_OnOffCB( uint8 cmd );
static void zclSampleLight1_ProcessIdentifyTimeChange( void );
#ifdef ZCL_LEVEL_CTRL
static void zclSampleLight1_LevelControlMoveToLevelCB( zclLCMoveToLevel_t *pCmd );
static void zclSampleLight1_LevelControlMoveCB( zclLCMove_t *pCmd );
static void zclSampleLight1_LevelControlStepCB( zclLCStep_t *pCmd );
static void zclSampleLight1_LevelControlStopCB( void );
static void zclSampleLight1_DefaultMove( void );
static uint32 zclSampleLight1_TimeRateHelper( uint8 newLevel );
static uint16 zclSampleLight1_GetTime ( uint8 level, uint16 time );
static void zclSampleLight1_MoveBasedOnRate( uint8 newLevel, uint32 rate );
static void zclSampleLight1_MoveBasedOnTime( uint8 newLevel, uint16 time );
static void zclSampleLight1_AdjustLightLevel( void );
#endif
// app display functions
static void zclSampleLight1_LcdDisplayUpdate( void );
#ifdef LCD_SUPPORTED
static void zclSampleLight1_LcdDisplayMainMode( void );
static void zclSampleLight1_LcdDisplayHelpMode( void );
#endif
static void zclSampleLight1_DisplayLight( void );
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
void zclSampleLight1_UpdateLampLevel( uint8 level );
#endif
// Functions to process ZCL Foundation incoming Command/Response messages
static void zclSampleLight1_ProcessIncomingMsg( zclIncomingMsg_t *msg );
#ifdef ZCL_READ
static uint8 zclSampleLight1_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
#endif
#ifdef ZCL_WRITE
static uint8 zclSampleLight1_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
#endif
static uint8 zclSampleLight1_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
#ifdef ZCL_DISCOVER
static uint8 zclSampleLight1_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg );
static uint8 zclSampleLight1_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg );
static uint8 zclSampleLight1_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg );
#endif
/*********************************************************************
* STATUS STRINGS
*/
#ifdef LCD_SUPPORTED
const char ssDeviceName[] = " Sample Light";
const char ssClearLine[] = " ";
const char ssSwLight[] = "SW1: ToggleLight"; // 16 chars max
const char ssSwEZMode[] = "SW2: EZ-Mode";
char ssSwHelp[] = "SW5: Help "; // last character is * if NWK open
const char ssLightOn[] = " LIGHT ON ";
const char ssLightOff[] = " LIGHT OFF";
#if ZCL_LEVEL_CTRL
char ssLightLevel[] = " LEVEL ###"; // displays level 1-254
#endif
#endif
/*********************************************************************
* ZCL General Profile Callback table
*/
static zclGeneral_AppCallbacks_t zclSampleLight1_CmdCallbacks =
{
zclSampleLight1_BasicResetCB, // Basic Cluster Reset command
zclSampleLight1_IdentifyCB, // Identify command
#ifdef ZCL_EZMODE
NULL, // Identify EZ-Mode Invoke command
NULL, // Identify Update Commission State command
#endif
NULL, // Identify Trigger Effect command
zclSampleLight1_IdentifyQueryRspCB, // Identify Query Response command
zclSampleLight1_OnOffCB, // On/Off cluster commands
NULL, // On/Off cluster enhanced command Off with Effect
NULL, // On/Off cluster enhanced command On with Recall Global Scene
NULL, // On/Off cluster enhanced command On with Timed Off
#ifdef ZCL_LEVEL_CTRL
zclSampleLight1_LevelControlMoveToLevelCB, // Level Control Move to Level command
zclSampleLight1_LevelControlMoveCB, // Level Control Move command
zclSampleLight1_LevelControlStepCB, // Level Control Step command
zclSampleLight1_LevelControlStopCB, // Level Control Stop command
#endif
#ifdef ZCL_GROUPS
NULL, // Group Response commands
#endif
#ifdef ZCL_SCENES
NULL, // Scene Store Request command
NULL, // Scene Recall Request command
NULL, // Scene Response command
#endif
#ifdef ZCL_ALARMS
NULL, // Alarm (Response) commands
#endif
#ifdef SE_UK_EXT
NULL, // Get Event Log command
NULL, // Publish Event Log command
#endif
NULL, // RSSI Location command
NULL // RSSI Location Response command
};
/*********************************************************************
* @fn zclSampleLight1_Init
*
* @brief Initialization function for the zclGeneral layer.
*
* @param none
*
* @return none
*/
void zclSampleLight1_Init( byte task_id )
{
zclSampleLight1_TaskID = task_id;
// Set destination address to indirect
zclSampleLight1_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
zclSampleLight1_DstAddr.endPoint = 0;
zclSampleLight1_DstAddr.addr.shortAddr = 0;
// This app is part of the Home Automation Profile
zclHA_Init( &zclSampleLight1_SimpleDesc );
// Register the ZCL General Cluster Library callback functions
zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT1_ENDPOINT, &zclSampleLight1_CmdCallbacks );
// Register the application's attribute list
zcl_registerAttrList( SAMPLELIGHT1_ENDPOINT, zclSampleLight1_NumAttributes, zclSampleLight1_Attrs );
// Register the Application to receive the unprocessed Foundation command/response messages
zcl_registerForMsg( zclSampleLight1_TaskID );
#ifdef ZCL_DISCOVER
// Register the application's command list
zcl_registerCmdList( SAMPLELIGHT1_ENDPOINT, zclCmdsArraySize, zclSampleLight1_Cmds );
#endif
// Register for all key events - This app will handle all key events
RegisterForKeys( zclSampleLight1_TaskID );
// Register for a test endpoint
afRegister( &sampleLight1_TestEp );
#ifdef ZCL_EZMODE
// Register EZ-Mode
zcl_RegisterEZMode( &zclSampleLight1_RegisterEZModeData );
// Register with the ZDO to receive Match Descriptor Responses
ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
#endif
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
HalTimer1Init( 0 );
halTimer1SetChannelDuty( WHITE_LED, 0 );
halTimer1SetChannelDuty( RED_LED, 0 );
halTimer1SetChannelDuty( BLUE_LED, 0 );
halTimer1SetChannelDuty( GREEN_LED, 0 );
// find if we are already on a network from NV_RESTORE
uint8 state;
NLME_GetRequest( nwkNwkState, 0, &state );
if ( state < NWK_ENDDEVICE )
{
// Start EZMode on Start up to avoid button press
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_START_EZMODE_EVT, 500 );
}
#if ZCL_LEVEL_CTRL
zclSampleLight1_DefaultMove();
#endif
#endif // #if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
#ifdef ZCL_DIAGNOSTIC
// Register the application's callback function to read/write attribute data.
// This is only required when the attribute data format is unknown to ZCL.
zcl_registerReadWriteCB( SAMPLELIGHT1_ENDPOINT, zclDiagnostic_ReadWriteAttrCB, NULL );
if ( zclDiagnostic_InitStats() == ZSuccess )
{
// Here the user could start the timer to save Diagnostics to NV
}
#endif
#ifdef LCD_SUPPORTED
HalLcdWriteString ( (char *)ssDeviceName, HAL_LCD_LINE_3 );
#endif // LCD_SUPPORTED
#ifdef ZGP_AUTO_TT
zgpTranslationTable_RegisterEP ( &zclSampleLight1_SimpleDesc );
#endif
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_READ_SENSOR_CURRENT_EVT, 3000 );
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_REPORT_SENSOR_INFORMATION_EVT, 1 );
HalLedBlink( HAL_LED_3, 255, 30, 1000 );
}
/*********************************************************************
* @fn zclSample_event_loop
*
* @brief Event Loop Processor for zclGeneral.
*
* @param none
*
* @return none
*/
uint16 zclSampleLight1_event_loop( uint8 task_id, uint16 events )
{
afIncomingMSGPacket_t *MSGpkt;
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleLight1_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
#ifdef ZCL_EZMODE
case ZDO_CB_MSG:
zclSampleLight1_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
#endif
case ZCL_INCOMING_MSG:
// Incoming ZCL Foundation command/response messages
zclSampleLight1_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
zclSampleLight1_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case ZDO_STATE_CHANGE:
zclSampleLight1_NwkState = (devStates_t)(MSGpkt->hdr.status);
// now on the network
if ( (zclSampleLight1_NwkState == DEV_ZB_COORD) ||
(zclSampleLight1_NwkState == DEV_ROUTER) ||
(zclSampleLight1_NwkState == DEV_END_DEVICE) )
{
giLightScreenMode1 = LIGHT1_MAINMODE;
zclSampleLight1_LcdDisplayUpdate();
#ifdef ZCL_EZMODE
zcl_EZModeAction( EZMODE_ACTION_NETWORK_STARTED, NULL );
#endif // ZCL_EZMODE
}
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & SAMPLELIGHT1_IDENTIFY_TIMEOUT_EVT )
{
if ( zclSampleLight1_IdentifyTime > 0 )
zclSampleLight1_IdentifyTime--;
zclSampleLight1_ProcessIdentifyTimeChange();
return ( events ^ SAMPLELIGHT1_IDENTIFY_TIMEOUT_EVT );
}
if ( events & SAMPLELIGHT1_MAIN_SCREEN_EVT )
{
giLightScreenMode1 = LIGHT1_MAINMODE;
zclSampleLight1_LcdDisplayUpdate();
return ( events ^ SAMPLELIGHT1_MAIN_SCREEN_EVT );
}
#ifdef ZCL_EZMODE
#if (defined HAL_BOARD_ZLIGHT)
// event to start EZMode on startup with a delay
if ( events & SAMPLELIGHT1_START_EZMODE_EVT )
{
// Invoke EZ-Mode
zclEZMode_InvokeData_t ezModeData;
// Invoke EZ-Mode
ezModeData.endpoint = SAMPLELIGHT1_ENDPOINT; // endpoint on which to invoke EZ-Mode
if ( (zclSampleLight1_NwkState == DEV_ZB_COORD) ||
(zclSampleLight1_NwkState == DEV_ROUTER) ||
(zclSampleLight1_NwkState == DEV_END_DEVICE) )
{
ezModeData.onNetwork = TRUE; // node is already on the network
}
else
{
ezModeData.onNetwork = FALSE; // node is not yet on the network
}
ezModeData.initiator = FALSE; // OnOffLight is a target
ezModeData.numActiveOutClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
ezModeData.numActiveInClusters = 0;
ezModeData.pActiveOutClusterIDs = NULL;
zcl_InvokeEZMode( &ezModeData );
return ( events ^ SAMPLELIGHT1_START_EZMODE_EVT );
}
#endif // #if (defined HAL_BOARD_ZLIGHT)
// going on to next state
if ( events & SAMPLELIGHT1_EZMODE_NEXTSTATE_EVT )
{
zcl_EZModeAction ( EZMODE_ACTION_PROCESS, NULL ); // going on to next state
return ( events ^ SAMPLELIGHT1_EZMODE_NEXTSTATE_EVT );
}
// the overall EZMode timer expired, so we timed out
if ( events & SAMPLELIGHT1_EZMODE_TIMEOUT_EVT )
{
zcl_EZModeAction ( EZMODE_ACTION_TIMED_OUT, NULL ); // EZ-Mode timed out
return ( events ^ SAMPLELIGHT1_EZMODE_TIMEOUT_EVT );
}
#endif // ZLC_EZMODE
#ifdef ZCL_LEVEL_CTRL
if ( events & SAMPLELIGHT1_LEVEL_CTRL_EVT )
{
zclSampleLight1_AdjustLightLevel();
return ( events ^ SAMPLELIGHT1_LEVEL_CTRL_EVT );
}
#endif
if ( events & SAMPLELIGHT1_READ_SENSOR_CURRENT_EVT )
{
zclSampleLight1_ReadSensorCurrent();
return ( events ^ SAMPLELIGHT1_READ_SENSOR_CURRENT_EVT );
}
if ( events & SAMPLELIGHT1_REPORT_SENSOR_INFORMATION_EVT )
{
zclSampleLight1_SendSensorInformation();
return ( events ^ SAMPLELIGHT1_REPORT_SENSOR_INFORMATION_EVT );
}
if ( events & SAMPLELIGHT1_LIGHT_DELAY_EVT )
{
zclSampleLight1_LightDelay=0;
return ( events ^ SAMPLELIGHT1_LIGHT_DELAY_EVT );
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn zclSampleLight_HandleKeys
*
* @brief Handles all key events for this device.
*
* @return none
*/
static void zclSampleLight1_SendSensorInformation(void){
double iRMS;
int16 maxMinusOffset=maxSensorReadValue1-1650;
if(maxMinusOffset<0)
maxMinusOffset=-maxMinusOffset;
iRMS=(maxMinusOffset*20);
iRMS=iRMS/1650;
iRMS=(iRMS/1.414)*1000;
uint32 power=(uint32)(iRMS*220);
maxSensorReadValue1=0;
#ifdef ZCL_REPORT
afAddrType_t dstAddr1;
dstAddr1.addrMode=(afAddrMode_t)Addr16Bit;
dstAddr1.endPoint=3;
dstAddr1.addr.shortAddr=0x0;
zclReportCmd_t *rptcmd;
rptcmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
rptcmd->numAttr = 1;
rptcmd->attrList[0].attrID = ATTRID_SENSOR_CURRENT_A5;
rptcmd->attrList[0].dataType = ZCL_DATATYPE_UINT16;
rptcmd->attrList[0].attrData = (uint8*)&power;
zcl_SendReportCmd(SAMPLELIGHT1_ENDPOINT, &dstAddr1, ZCL_CLUSTER_ID_GEN_ON_OFF, rptcmd,ZCL_FRAME_SERVER_CLIENT_DIR, false, zclSampleLight1SeqNum );
osal_mem_free( rptcmd );
#endif
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_REPORT_SENSOR_INFORMATION_EVT, 3000 );
}
/*********************************************************************
* @fn zclSampleLight_HandleKeys
*
* @brief Handles all key events for this device.
*
* @return none
*/
static void zclSampleLight1_ReadSensorCurrent(void){
uint16 value1 = HalAdcRead(HAL_ADC_CHANNEL_5,HAL_ADC_RESOLUTION_12);
float volt=(value1*3.3)/2047;
value1=(uint16)(volt*1000);
uint16 value2 = HalAdcRead(HAL_ADC_CHANNEL_5,HAL_ADC_RESOLUTION_12);
volt=(value2*3.3)/2047;
value2=(uint16)(volt*1000);
uint16 value3 = HalAdcRead(HAL_ADC_CHANNEL_5,HAL_ADC_RESOLUTION_12);
volt=(value3*3.3)/2047;
value3=(uint16)(volt*1000);
uint16 value4 = HalAdcRead(HAL_ADC_CHANNEL_5,HAL_ADC_RESOLUTION_12);
volt=(value4*3.3)/2047;
value4=(uint16)(volt*1000);
uint16 value = value1+value2+value3+value4;
value=(uint16)value/4;
if(value>maxSensorReadValue1)
maxSensorReadValue1=value;
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_READ_SENSOR_CURRENT_EVT, 1 );
}
/*********************************************************************
* @fn zclSampleLight1_HandleKeys
*
* @brief Handles all key events for this device.
*
* @param shift - true if in shift/alt.
* @param keys - bit field for key events. Valid entries:
* HAL_KEY_SW_5
* HAL_KEY_SW_4
* HAL_KEY_SW_2
* HAL_KEY_SW_1
*
* @return none
*/
static void zclSampleLight1_HandleKeys( byte shift, byte keys )
{
if ( keys & HAL_KEY_SW_2 )
{
if(zclSampleLight1_LightDelay==0){
zclSampleLight1_LightDelay=1;
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_LIGHT_DELAY_EVT, LIGHT1_INTERVAL_DELAY_TIME );
giLightScreenMode1 = LIGHT1_MAINMODE;
// toggle local light immediately
zclSampleLight1_OnOff = zclSampleLight1_OnOff ? LIGHT1_OFF : LIGHT1_ON;
maxSensorReadValue1=0;
#ifdef ZCL_LEVEL_CTRL
zclSampleLight1_LevelCurrentLevel = zclSampleLight1_OnOff ? zclSampleLight1_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
#endif
#ifdef ZCL_REPORT
afAddrType_t dstAddr1;
dstAddr1.addrMode=(afAddrMode_t)Addr16Bit;
dstAddr1.endPoint=3;
dstAddr1.addr.shortAddr=0x0;
zclReportCmd_t *rptcmd;
rptcmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
rptcmd->numAttr = 1;
rptcmd->attrList[0].attrID = ATTRID_ON_OFF;
rptcmd->attrList[0].dataType = ZCL_DATATYPE_UINT8;
rptcmd->attrList[0].attrData = (uint8*)&zclSampleLight1_OnOff;
zcl_SendReportCmd(SAMPLELIGHT1_ENDPOINT, &dstAddr1,ZCL_CLUSTER_ID_GEN_ON_OFF, rptcmd,ZCL_FRAME_SERVER_CLIENT_DIR, false, zclSampleLight1SeqNum );
HalLcdWriteString( "Send Report", HAL_LCD_LINE_4 );
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_MAIN_SCREEN_EVT, 3000 );
osal_mem_free( rptcmd );
#endif
}
}
if ( keys & HAL_KEY_SW_4 )
{
giLightScreenMode1 = LIGHT1_MAINMODE;
if ( ( zclSampleLight1_NwkState == DEV_ZB_COORD ) ||
( zclSampleLight1_NwkState == DEV_ROUTER ) )
{
// toggle permit join
gPermitDuration1 = gPermitDuration1 ? 0 : 0xff;
NLME_PermitJoiningRequest( gPermitDuration1 );
}
}
// Shift F5 does a Basic Reset (factory defaults)
if ( shift && ( keys & HAL_KEY_SW_5 ) )
{
zclSampleLight1_BasicResetCB();
}
else if ( keys & HAL_KEY_SW_5 )
{
giLightScreenMode1 = giLightScreenMode1 ? LIGHT1_MAINMODE : LIGHT1_HELPMODE;
}
// update the display, including the light
zclSampleLight1_LcdDisplayUpdate();
}
/*********************************************************************
* @fn zclSampleLight1_LcdDisplayUpdate
*
* @brief Called to update the LCD display.
*
* @param none
*
* @return none
*/
void zclSampleLight1_LcdDisplayUpdate( void )
{
#ifdef LCD_SUPPORTED
if ( giLightScreenMode1 == LIGHT1_HELPMODE )
{
zclSampleLight1_LcdDisplayHelpMode();
}
else
{
zclSampleLight1_LcdDisplayMainMode();
}
#endif
zclSampleLight1_DisplayLight();
}
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
/*********************************************************************
* @fn zclSampleLight1_UpdateLampLevel
*
* @brief Update lamp level output with gamma compensation
*
* @param level
*
* @return none
*/
void zclSampleLight1_UpdateLampLevel( uint8 level )
{
uint16 gammaCorrectedLevel;
// gamma correct the level
gammaCorrectedLevel = (uint16) ( pow( ( (float)level / LEVEL_MAX ), (float)GAMMA_VALUE ) * (float)LEVEL_MAX);
halTimer1SetChannelDuty(WHITE_LED, (uint16)(((uint32)gammaCorrectedLevel*PWM_FULL_DUTY_CYCLE)/LEVEL_MAX) );
}
#endif
/*********************************************************************
* @fn zclSampleLight1_DisplayLight
*
* @brief Displays current state of light on LED and also on main display if supported.
*
* @param none
*
* @return none
*/
static void zclSampleLight1_DisplayLight( void )
{
// set the LED1 based on light (on or off)
if ( zclSampleLight1_OnOff == LIGHT1_ON )
{
HalLedSet ( HAL_LED_2, HAL_LED_MODE_ON );
}
else
{
HalLedSet ( HAL_LED_2, HAL_LED_MODE_OFF );
}
#ifdef LCD_SUPPORTED
if (giLightScreenMode1 == LIGHT1_MAINMODE)
{
#ifdef ZCL_LEVEL_CTRL
// display current light level
if ( ( zclSampleLight1_LevelCurrentLevel == ATTR_LEVEL_MIN_LEVEL ) &&
( zclSampleLight1_OnOff == LIGHT1_OFF ) )
{
HalLcdWriteString( (char *)ssLightOff, HAL_LCD_LINE_2 );
}
else if ( ( zclSampleLight1_LevelCurrentLevel >= ATTR_LEVEL_MAX_LEVEL ) ||
( zclSampleLight1_LevelCurrentLevel == zclSampleLight1_LevelOnLevel ) ||
( ( zclSampleLight1_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT ) &&
( zclSampleLight1_LevelCurrentLevel == zclSampleLight1_LevelLastLevel ) ) )
{
HalLcdWriteString( (char *)ssLightOn, HAL_LCD_LINE_2 );
}
else // " LEVEL ###"
{
zclHA_uint8toa( zclSampleLight1_LevelCurrentLevel, &ssLightLevel[10] );
HalLcdWriteString( (char *)ssLightLevel, HAL_LCD_LINE_2 );
}
#else
if ( zclSampleLight1_OnOff )
{
HalLcdWriteString( (char *)ssLightOn, HAL_LCD_LINE_2 );
}
else
{
HalLcdWriteString( (char *)ssLightOff, HAL_LCD_LINE_2 );
}
#endif // ZCL_LEVEL_CTRL
}
#endif // LCD_SUPPORTED
}
#ifdef LCD_SUPPORTED
/*********************************************************************
* @fn zclSampleLight1_LcdDisplayMainMode
*
* @brief Called to display the main screen on the LCD.
*
* @param none
*
* @return none
*/
static void zclSampleLight1_LcdDisplayMainMode( void )
{
// display line 1 to indicate NWK status
if ( zclSampleLight1_NwkState == DEV_ZB_COORD )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZC );
}
else if ( zclSampleLight1_NwkState == DEV_ROUTER )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZR );
}
else if ( zclSampleLight1_NwkState == DEV_END_DEVICE )
{
zclHA_LcdStatusLine1( ZCL_HA_STATUSLINE_ZED );
}
// end of line 3 displays permit join status (*)
if ( gPermitDuration1 )
{
ssSwHelp[15] = '*';
}
else
{
ssSwHelp[15] = ' ';
}
HalLcdWriteString( (char *)ssSwHelp, HAL_LCD_LINE_3 );
}
/*********************************************************************
* @fn zclSampleLight1_LcdDisplayHelpMode
*
* @brief Called to display the SW options on the LCD.
*
* @param none
*
* @return none
*/
static void zclSampleLight1_LcdDisplayHelpMode( void )
{
HalLcdWriteString( (char *)ssSwLight, HAL_LCD_LINE_1 );
HalLcdWriteString( (char *)ssSwEZMode, HAL_LCD_LINE_2 );
HalLcdWriteString( (char *)ssSwHelp, HAL_LCD_LINE_3 );
}
#endif // LCD_SUPPORTED
/*********************************************************************
* @fn zclSampleLight1_ProcessIdentifyTimeChange
*
* @brief Called to process any change to the IdentifyTime attribute.
*
* @param none
*
* @return none
*/
static void zclSampleLight1_ProcessIdentifyTimeChange( void )
{
if ( zclSampleLight1_IdentifyTime > 0 )
{
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_IDENTIFY_TIMEOUT_EVT, 1000 );
HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
}
else
{
#ifdef ZCL_EZMODE
if ( zclSampleLight1_IdentifyCommissionState & EZMODE_COMMISSION_OPERATIONAL )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
}
else
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
}
#endif
osal_stop_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_IDENTIFY_TIMEOUT_EVT );
}
}
/*********************************************************************
* @fn zclSampleLight1_BasicResetCB
*
* @brief Callback from the ZCL General Cluster Library
* to set all the Basic Cluster attributes to default values.
*
* @param none
*
* @return none
*/
static void zclSampleLight1_BasicResetCB( void )
{
NLME_LeaveReq_t leaveReq;
// Set every field to 0
osal_memset( &leaveReq, 0, sizeof( NLME_LeaveReq_t ) );
// This will enable the device to rejoin the network after reset.
leaveReq.rejoin = TRUE;
// Set the NV startup option to force a "new" join.
zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
// Leave the network, and reset afterwards
if ( NLME_LeaveReq( &leaveReq ) != ZSuccess )
{
// Couldn't send out leave; prepare to reset anyway
ZDApp_LeaveReset( FALSE );
}
}
/*********************************************************************
* @fn zclSampleLight1_IdentifyCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Identity Command for this application.
*
* @param srcAddr - source address and endpoint of the response message
* @param identifyTime - the number of seconds to identify yourself
*
* @return none
*/
static void zclSampleLight1_IdentifyCB( zclIdentify_t *pCmd )
{
zclSampleLight1_IdentifyTime = pCmd->identifyTime;
zclSampleLight1_ProcessIdentifyTimeChange();
}
/*********************************************************************
* @fn zclSampleLight1_IdentifyQueryRspCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Identity Query Response Command for this application.
*
* @param srcAddr - requestor's address
* @param timeout - number of seconds to identify yourself (valid for query response)
*
* @return none
*/
static void zclSampleLight1_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
{
(void)pRsp;
#ifdef ZCL_EZMODE
{
zclEZMode_ActionData_t data;
data.pIdentifyQueryRsp = pRsp;
zcl_EZModeAction ( EZMODE_ACTION_IDENTIFY_QUERY_RSP, &data );
}
#endif
}
/*********************************************************************
* @fn zclSampleLight1_OnOffCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an On/Off Command for this application.
*
* @param cmd - COMMAND_ON, COMMAND_OFF or COMMAND_TOGGLE
*
* @return none
*/
static void zclSampleLight1_OnOffCB( uint8 cmd )
{
if(zclSampleLight1_LightDelay==0){
zclSampleLight1_LightDelay=1;
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_LIGHT_DELAY_EVT, LIGHT1_INTERVAL_DELAY_TIME );
// Turn on the light
if ( cmd == COMMAND_ON )
{
zclSampleLight1_OnOff = LIGHT1_ON;
}
// Turn off the light
else if ( cmd == COMMAND_OFF )
{
zclSampleLight1_OnOff = LIGHT1_OFF;
}
// Toggle the light
else if ( cmd == COMMAND_TOGGLE )
{
if ( zclSampleLight1_OnOff == LIGHT1_OFF )
{
zclSampleLight1_OnOff = LIGHT1_ON;
}
else
{
zclSampleLight1_OnOff = LIGHT1_OFF;
}
}
#if ZCL_LEVEL_CTRL
zclSampleLight1_DefaultMove( );
#endif
// update the display
zclSampleLight1_LcdDisplayUpdate( );
}
}
#ifdef ZCL_LEVEL_CTRL
/*********************************************************************
* @fn zclSampleLight1_TimeRateHelper
*
* @brief Calculate time based on rate, and startup level state machine
*
* @param newLevel - new level for current level
*
* @return diff (directly), zclSampleLight1_CurrentLevel32 and zclSampleLight1_NewLevel, zclSampleLight1_NewLevelUp
*/
static uint32 zclSampleLight1_TimeRateHelper( uint8 newLevel )
{
uint32 diff;
uint32 newLevel32;
// remember current and new level
zclSampleLight1_NewLevel = newLevel;
zclSampleLight1_CurrentLevel32 = (uint32)1000 * zclSampleLight1_LevelCurrentLevel;
// calculate diff
newLevel32 = (uint32)1000 * newLevel;
if ( zclSampleLight1_LevelCurrentLevel > newLevel )
{
diff = zclSampleLight1_CurrentLevel32 - newLevel32;
zclSampleLight1_NewLevelUp = FALSE; // moving down
}
else
{
diff = newLevel32 - zclSampleLight1_CurrentLevel32;
zclSampleLight1_NewLevelUp = TRUE; // moving up
}
return ( diff );
}
/*********************************************************************
* @fn zclSampleLight1_MoveBasedOnRate
*
* @brief Calculate time based on rate, and startup level state machine
*
* @param newLevel - new level for current level
* @param rate16 - fixed point rate (e.g. 16.123)
*
* @return none
*/
static void zclSampleLight1_MoveBasedOnRate( uint8 newLevel, uint32 rate )
{
uint32 diff;
// determine how much time (in 10ths of seconds) based on the difference and rate
zclSampleLight1_Rate32 = rate;
diff = zclSampleLight1_TimeRateHelper( newLevel );
zclSampleLight1_LevelRemainingTime = diff / rate;
if ( !zclSampleLight1_LevelRemainingTime )
{
zclSampleLight1_LevelRemainingTime = 1;
}
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_LEVEL_CTRL_EVT, 100 );
}
/*********************************************************************
* @fn zclSampleLight1_MoveBasedOnTime
*
* @brief Calculate rate based on time, and startup level state machine
*
* @param newLevel - new level for current level
* @param time - in 10ths of seconds
*
* @return none
*/
static void zclSampleLight1_MoveBasedOnTime( uint8 newLevel, uint16 time )
{
uint16 diff;
// determine rate (in units) based on difference and time
diff = zclSampleLight1_TimeRateHelper( newLevel );
zclSampleLight1_LevelRemainingTime = zclSampleLight1_GetTime( newLevel, time );
zclSampleLight1_Rate32 = diff / time;
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_LEVEL_CTRL_EVT, 100 );
}
/*********************************************************************
* @fn zclSampleLight1_GetTime
*
* @brief Determine amount of time that MoveXXX will take to complete.
*
* @param level = new level to move to
* time = 0xffff=default, or 0x0000-n amount of time in tenths of seconds.
*
* @return none
*/
static uint16 zclSampleLight1_GetTime( uint8 level, uint16 time )
{
// there is a hiearchy of the amount of time to use for transistioning
// check each one in turn. If none of defaults are set, then use fastest
// time possible.
if ( time == 0xFFFF )
{
// use On or Off Transition Time if set (not 0xffff)
if ( zclSampleLight1_OnOff == LIGHT1_ON )
{
time = zclSampleLight1_LevelOffTransitionTime;
}
else
{
time = zclSampleLight1_LevelOnTransitionTime;
}
// else use OnOffTransitionTime if set (not 0xffff)
if ( time == 0xFFFF )
{
time = zclSampleLight1_LevelOnOffTransitionTime;
}
// else as fast as possible
if ( time == 0xFFFF )
{
time = 1;
}
}
if ( !time )
{
time = 1; // as fast as possible
}
return ( time );
}
/*********************************************************************
* @fn zclSampleLight1_DefaultMove
*
* @brief We were turned on/off. Use default time to move to on or off.
*
* @param zclSampleLight1_OnOff - must be set prior to calling this function.
*
* @return none
*/
static void zclSampleLight1_DefaultMove( void )
{
uint8 newLevel;
uint32 rate; // fixed point decimal (3 places, eg. 16.345)
uint16 time;
// if moving to on position, move to on level
if ( zclSampleLight1_OnOff )
{
if ( zclSampleLight1_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT )
{
// The last Level (before going OFF) should be used)
newLevel = zclSampleLight1_LevelLastLevel;
}
else
{
newLevel = zclSampleLight1_LevelOnLevel;
}
time = zclSampleLight1_LevelOnTransitionTime;
}
else
{
newLevel = ATTR_LEVEL_MIN_LEVEL;
if ( zclSampleLight1_LevelOnLevel == ATTR_LEVEL_ON_LEVEL_NO_EFFECT )
{
// Save the current Level before going OFF to use it when the light turns ON
// it should be back to this level
zclSampleLight1_LevelLastLevel = zclSampleLight1_LevelCurrentLevel;
}
time = zclSampleLight1_LevelOffTransitionTime;
}
// else use OnOffTransitionTime if set (not 0xffff)
if ( time == 0xFFFF )
{
time = zclSampleLight1_LevelOnOffTransitionTime;
}
// else as fast as possible
if ( time == 0xFFFF )
{
time = 1;
}
// calculate rate based on time (int 10ths) for full transition (1-254)
rate = 255000 / time; // units per tick, fixed point, 3 decimal places (e.g. 8500 = 8.5 units per tick)
// start up state machine.
zclSampleLight1_WithOnOff = TRUE;
zclSampleLight1_MoveBasedOnRate( newLevel, rate );
}
/*********************************************************************
* @fn zclSampleLight1_AdjustLightLevel
*
* @brief Called each 10th of a second while state machine running
*
* @param none
*
* @return none
*/
static void zclSampleLight1_AdjustLightLevel( void )
{
// one tick (10th of a second) less
if ( zclSampleLight1_LevelRemainingTime )
{
--zclSampleLight1_LevelRemainingTime;
}
// no time left, done
if ( zclSampleLight1_LevelRemainingTime == 0)
{
zclSampleLight1_LevelCurrentLevel = zclSampleLight1_NewLevel;
}
// still time left, keep increment/decrementing
else
{
if ( zclSampleLight1_NewLevelUp )
{
zclSampleLight1_CurrentLevel32 += zclSampleLight1_Rate32;
}
else
{
zclSampleLight1_CurrentLevel32 -= zclSampleLight1_Rate32;
}
zclSampleLight1_LevelCurrentLevel = (uint8)( zclSampleLight1_CurrentLevel32 / 1000 );
}
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
zclSampleLight1_UpdateLampLevel(zclSampleLight1_LevelCurrentLevel);
#endif
// also affect on/off
if ( zclSampleLight1_WithOnOff )
{
if ( zclSampleLight1_LevelCurrentLevel > ATTR_LEVEL_MIN_LEVEL )
{
zclSampleLight1_OnOff = LIGHT1_ON;
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
ENABLE_LAMP;
#endif
}
else
{
zclSampleLight1_OnOff = LIGHT1_OFF;
#if (defined HAL_BOARD_ZLIGHT) || (defined HAL_PWM)
DISABLE_LAMP;
#endif
}
}
// display light level as we go
zclSampleLight1_DisplayLight( );
// keep ticking away
if ( zclSampleLight1_LevelRemainingTime )
{
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_LEVEL_CTRL_EVT, 100 );
}
}
/*********************************************************************
* @fn zclSampleLight1_LevelControlMoveToLevelCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received a LevelControlMoveToLevel Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight1_LevelControlMoveToLevelCB( zclLCMoveToLevel_t *pCmd )
{
zclSampleLight1_WithOnOff = pCmd->withOnOff;
zclSampleLight1_MoveBasedOnTime( pCmd->level, pCmd->transitionTime );
}
/*********************************************************************
* @fn zclSampleLight1_LevelControlMoveCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received a LevelControlMove Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight1_LevelControlMoveCB( zclLCMove_t *pCmd )
{
uint8 newLevel;
uint32 rate;
// convert rate from units per second to units per tick (10ths of seconds)
// and move at that right up or down
zclSampleLight1_WithOnOff = pCmd->withOnOff;
if ( pCmd->moveMode == LEVEL_MOVE_UP )
{
newLevel = ATTR_LEVEL_MAX_LEVEL; // fully on
}
else
{
newLevel = ATTR_LEVEL_MIN_LEVEL; // fully off
}
rate = (uint32)100 * pCmd->rate;
zclSampleLight1_MoveBasedOnRate( newLevel, rate );
}
/*********************************************************************
* @fn zclSampleLight1_LevelControlStepCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an On/Off Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight1_LevelControlStepCB( zclLCStep_t *pCmd )
{
uint8 newLevel;
// determine new level, but don't exceed boundaries
if ( pCmd->stepMode == LEVEL_MOVE_UP )
{
if ( (uint16)zclSampleLight1_LevelCurrentLevel + pCmd->amount > ATTR_LEVEL_MAX_LEVEL )
{
newLevel = ATTR_LEVEL_MAX_LEVEL;
}
else
{
newLevel = zclSampleLight1_LevelCurrentLevel + pCmd->amount;
}
}
else
{
if ( pCmd->amount >= zclSampleLight1_LevelCurrentLevel )
{
newLevel = ATTR_LEVEL_MIN_LEVEL;
}
else
{
newLevel = zclSampleLight1_LevelCurrentLevel - pCmd->amount;
}
}
// move to the new level
zclSampleLight1_WithOnOff = pCmd->withOnOff;
zclSampleLight1_MoveBasedOnTime( newLevel, pCmd->transitionTime );
}
/*********************************************************************
* @fn zclSampleLight1_LevelControlStopCB
*
* @brief Callback from the ZCL General Cluster Library when
* it received an Level Control Stop Command for this application.
*
* @param pCmd - ZigBee command parameters
*
* @return none
*/
static void zclSampleLight1_LevelControlStopCB( void )
{
// stop immediately
osal_stop_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_LEVEL_CTRL_EVT );
zclSampleLight1_LevelRemainingTime = 0;
}
#endif
/******************************************************************************
*
* Functions for processing ZCL Foundation incoming Command/Response messages
*
*****************************************************************************/
/*********************************************************************
* @fn zclSampleLight1_ProcessIncomingMsg
*
* @brief Process ZCL Foundation incoming message
*
* @param pInMsg - pointer to the received message
*
* @return none
*/
static void zclSampleLight1_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg )
{
switch ( pInMsg->zclHdr.commandID )
{
#ifdef ZCL_READ
case ZCL_CMD_READ_RSP:
zclSampleLight1_ProcessInReadRspCmd( pInMsg );
break;
#endif
#ifdef ZCL_WRITE
case ZCL_CMD_WRITE_RSP:
zclSampleLight1_ProcessInWriteRspCmd( pInMsg );
break;
#endif
#ifdef ZCL_REPORT
// Attribute Reporting implementation should be added here
case ZCL_CMD_CONFIG_REPORT:
// zclSampleLight1_ProcessInConfigReportCmd( pInMsg );
break;
case ZCL_CMD_CONFIG_REPORT_RSP:
// zclSampleLight1_ProcessInConfigReportRspCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG:
// zclSampleLight1_ProcessInReadReportCfgCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG_RSP:
// zclSampleLight1_ProcessInReadReportCfgRspCmd( pInMsg );
break;
case ZCL_CMD_REPORT:
// zclSampleLight1_ProcessInReportCmd( pInMsg );
break;
#endif
case ZCL_CMD_DEFAULT_RSP:
zclSampleLight1_ProcessInDefaultRspCmd( pInMsg );
break;
#ifdef ZCL_DISCOVER
case ZCL_CMD_DISCOVER_CMDS_RECEIVED_RSP:
zclSampleLight1_ProcessInDiscCmdsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_CMDS_GEN_RSP:
zclSampleLight1_ProcessInDiscCmdsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_ATTRS_RSP:
zclSampleLight1_ProcessInDiscAttrsRspCmd( pInMsg );
break;
case ZCL_CMD_DISCOVER_ATTRS_EXT_RSP:
zclSampleLight1_ProcessInDiscAttrsExtRspCmd( pInMsg );
break;
#endif
default:
break;
}
if ( pInMsg->attrCmd )
osal_mem_free( pInMsg->attrCmd );
}
#ifdef ZCL_READ
/*********************************************************************
* @fn zclSampleLight1_ProcessInReadRspCmd
*
* @brief Process the "Profile" Read Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight1_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
{
zclReadRspCmd_t *readRspCmd;
uint8 i;
readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
for (i = 0; i < readRspCmd->numAttr; i++)
{
// Notify the originator of the results of the original read attributes
// attempt and, for each successfull request, the value of the requested
// attribute
}
return ( TRUE );
}
#endif // ZCL_READ
#ifdef ZCL_WRITE
/*********************************************************************
* @fn zclSampleLight1_ProcessInWriteRspCmd
*
* @brief Process the "Profile" Write Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight1_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
{
zclWriteRspCmd_t *writeRspCmd;
uint8 i;
writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
for ( i = 0; i < writeRspCmd->numAttr; i++ )
{
// Notify the device of the results of the its original write attributes
// command.
}
return ( TRUE );
}
#endif // ZCL_WRITE
/*********************************************************************
* @fn zclSampleLight1_ProcessInDefaultRspCmd
*
* @brief Process the "Profile" Default Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight1_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
{
// zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
// Device is notified of the Default Response command.
(void)pInMsg;
return ( TRUE );
}
#ifdef ZCL_DISCOVER
/*********************************************************************
* @fn zclSampleLight1_ProcessInDiscCmdsRspCmd
*
* @brief Process the Discover Commands Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight1_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverCmdsCmdRsp_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverCmdsCmdRsp_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numCmd; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
/*********************************************************************
* @fn zclSampleLight1_ProcessInDiscAttrsRspCmd
*
* @brief Process the "Profile" Discover Attributes Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight1_ProcessInDiscAttrsRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverAttrsRspCmd_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverAttrsRspCmd_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numAttr; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
/*********************************************************************
* @fn zclSampleLight1_ProcessInDiscAttrsExtRspCmd
*
* @brief Process the "Profile" Discover Attributes Extended Response Command
*
* @param pInMsg - incoming message to process
*
* @return none
*/
static uint8 zclSampleLight1_ProcessInDiscAttrsExtRspCmd( zclIncomingMsg_t *pInMsg )
{
zclDiscoverAttrsExtRsp_t *discoverRspCmd;
uint8 i;
discoverRspCmd = (zclDiscoverAttrsExtRsp_t *)pInMsg->attrCmd;
for ( i = 0; i < discoverRspCmd->numAttr; i++ )
{
// Device is notified of the result of its attribute discovery command.
}
return ( TRUE );
}
#endif // ZCL_DISCOVER
#if ZCL_EZMODE
/*********************************************************************
* @fn zclSampleLight1_ProcessZDOMsgs
*
* @brief Called when this node receives a ZDO/ZDP response.
*
* @param none
*
* @return status
*/
static void zclSampleLight1_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
{
zclEZMode_ActionData_t data;
ZDO_MatchDescRsp_t *pMatchDescRsp;
// Let EZ-Mode know of the Simple Descriptor Response
if ( pMsg->clusterID == Match_Desc_rsp )
{
pMatchDescRsp = ZDO_ParseEPListRsp( pMsg );
data.pMatchDescRsp = pMatchDescRsp;
zcl_EZModeAction( EZMODE_ACTION_MATCH_DESC_RSP, &data );
osal_mem_free( pMatchDescRsp );
}
}
/*********************************************************************
* @fn zclSampleLight1_EZModeCB
*
* @brief The Application is informed of events. This can be used to show on the UI what is
* going on during EZ-Mode steering/finding/binding.
*
* @param state - an
*
* @return none
*/
static void zclSampleLight1_EZModeCB( zlcEZMode_State_t state, zclEZMode_CBData_t *pData )
{
#ifdef LCD_SUPPORTED
char *pStr;
uint8 err;
#endif
// time to go into identify mode
if ( state == EZMODE_STATE_IDENTIFYING )
{
#ifdef LCD_SUPPORTED
HalLcdWriteString( "EZMode", HAL_LCD_LINE_2 );
#endif
zclSampleLight1_IdentifyTime = ( EZMODE_TIME / 1000 ); // convert to seconds
zclSampleLight1_ProcessIdentifyTimeChange();
}
// autoclosing, show what happened (success, cancelled, etc...)
if( state == EZMODE_STATE_AUTOCLOSE )
{
#ifdef LCD_SUPPORTED
pStr = NULL;
err = pData->sAutoClose.err;
if ( err == EZMODE_ERR_SUCCESS )
{
pStr = "EZMode: Success";
}
else if ( err == EZMODE_ERR_NOMATCH )
{
pStr = "EZMode: NoMatch"; // not a match made in heaven
}
if ( pStr )
{
if ( giLightScreenMode1 == LIGHT1_MAINMODE )
{
HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
}
}
#endif
}
// finished, either show DstAddr/EP, or nothing (depending on success or not)
if( state == EZMODE_STATE_FINISH )
{
// turn off identify mode
zclSampleLight1_IdentifyTime = 0;
zclSampleLight1_ProcessIdentifyTimeChange();
#ifdef LCD_SUPPORTED
// if successful, inform user which nwkaddr/ep we bound to
pStr = NULL;
err = pData->sFinish.err;
if( err == EZMODE_ERR_SUCCESS )
{
// already stated on autoclose
}
else if ( err == EZMODE_ERR_CANCELLED )
{
pStr = "EZMode: Cancel";
}
else if ( err == EZMODE_ERR_BAD_PARAMETER )
{
pStr = "EZMode: BadParm";
}
else if ( err == EZMODE_ERR_TIMEDOUT )
{
pStr = "EZMode: TimeOut";
}
if ( pStr )
{
if ( giLightScreenMode1 == LIGHT1_MAINMODE )
{
HalLcdWriteString ( pStr, HAL_LCD_LINE_2 );
}
}
#endif
// show main UI screen 3 seconds after binding
osal_start_timerEx( zclSampleLight1_TaskID, SAMPLELIGHT1_MAIN_SCREEN_EVT, 3000 );
}
}
#endif // ZCL_EZMODE
/****************************************************************************
****************************************************************************/
/**************************************************************************************************
Filename: zcl_samplelight_data.c
Revised: $Date: 2014-05-12 13:14:02 -0700 (Mon, 12 May 2014) $
Revision: $Revision: 38502 $
Description: Zigbee Cluster Library - sample device application.
Copyright 2006-2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "ZComDef.h"
#include "OSAL.h"
#include "AF.h"
#include "ZDConfig.h"
#include "zcl.h"
#include "zcl_general.h"
#include "zcl_ha.h"
#include "zcl_ezmode.h"
#include "zcl_poll_control.h"
#include "zcl_electrical_measurement.h"
#include "zcl_diagnostic.h"
#include "zcl_meter_identification.h"
#include "zcl_appliance_identification.h"
#include "zcl_appliance_events_alerts.h"
#include "zcl_power_profile.h"
#include "zcl_appliance_control.h"
#include "zcl_appliance_statistics.h"
#include "zcl_hvac.h"
#include "zcl_samplelight1.h"
/*********************************************************************
* CONSTANTS
*/
#define SAMPLELIGHT1_DEVICE_VERSION 0
#define SAMPLELIGHT1_FLAGS 0
#define SAMPLELIGHT1_HWVERSION 1
#define SAMPLELIGHT1_ZCLVERSION 1
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
// Basic Cluster
const uint8 zclSampleLight1_HWRevision = SAMPLELIGHT1_HWVERSION;
const uint8 zclSampleLight1_ZCLVersion = SAMPLELIGHT1_ZCLVERSION;
const uint8 zclSampleLight1_ManufacturerName[] = { 16, 'T','e','x','a','s','I','n','s','t','r','u','m','e','n','t','s' };
const uint8 zclSampleLight1_ModelId[] = { 16, 'T','I','0','0','0','1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
const uint8 zclSampleLight1_DateCode[] = { 16, '2','0','0','6','0','8','3','1',' ',' ',' ',' ',' ',' ',' ',' ' };
const uint8 zclSampleLight1_PowerSource = POWER_SOURCE_MAINS_1_PHASE;
uint8 zclSampleLight1_LocationDescription[17] = { 16, ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
uint8 zclSampleLight1_PhysicalEnvironment = 0;
uint8 zclSampleLight1_DeviceEnable = DEVICE_ENABLED;
// Identify Cluster
uint16 zclSampleLight1_IdentifyTime = 0;
#ifdef ZCL_EZMODE
uint8 zclSampleLight1_IdentifyCommissionState;
#endif
// On/Off Cluster
uint8 zclSampleLight1_OnOff = LIGHT1_OFF;
// Level Control Cluster
#ifdef ZCL_LEVEL_CTRL
uint8 zclSampleLight1_LevelCurrentLevel = ATTR_LEVEL_MIN_LEVEL;
uint16 zclSampleLight1_LevelRemainingTime;
uint16 zclSampleLight1_LevelOnOffTransitionTime = 20;
uint8 zclSampleLight1_LevelOnLevel = ATTR_LEVEL_MID_LEVEL;
uint16 zclSampleLight1_LevelOnTransitionTime = 20;
uint16 zclSampleLight1_LevelOffTransitionTime = 20;
uint8 zclSampleLight1_LevelDefaultMoveRate = 0; // as fast as possible
#endif
#if ZCL_DISCOVER
CONST zclCommandRec_t zclSampleLight1_Cmds[] =
{
{
ZCL_CLUSTER_ID_GEN_BASIC,
COMMAND_BASIC_RESET_FACT_DEFAULT,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
COMMAND_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
COMMAND_ON,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
COMMAND_TOGGLE,
CMD_DIR_SERVER_RECEIVED
},
#ifdef ZCL_LEVEL_CONTROL
,{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE_TO_LEVEL,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STEP,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STOP,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE_TO_LEVEL_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_MOVE_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STEP_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
COMMAND_LEVEL_STOP_WITH_ON_OFF,
CMD_DIR_SERVER_RECEIVED
}
#endif // ZCL_LEVEL_CONTROL
};
CONST uint8 zclCmdsArraySize = ( sizeof(zclSampleLight1_Cmds) / sizeof(zclSampleLight1_Cmds[0]) );
#endif // ZCL_DISCOVER
/*********************************************************************
* ATTRIBUTE DEFINITIONS - Uses REAL cluster IDs
*/
CONST zclAttrRec_t zclSampleLight1_Attrs[] =
{
// *** General Basic Cluster Attributes ***
{
ZCL_CLUSTER_ID_GEN_BASIC, // Cluster IDs - defined in the foundation (ie. zcl.h)
{ // Attribute record
ATTRID_BASIC_HW_VERSION, // Attribute ID - Found in Cluster Library header (ie. zcl_general.h)
ZCL_DATATYPE_UINT8, // Data Type - found in zcl.h
ACCESS_CONTROL_READ, // Variable access control - found in zcl.h
(void *)&zclSampleLight1_HWRevision // Pointer to attribute variable
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_ZCL_VERSION,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight1_ZCLVersion
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_MANUFACTURER_NAME,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)zclSampleLight1_ManufacturerName
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_MODEL_ID,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)zclSampleLight1_ModelId
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_DATE_CODE,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)zclSampleLight1_DateCode
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_POWER_SOURCE,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight1_PowerSource
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_LOCATION_DESC,
ZCL_DATATYPE_CHAR_STR,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)zclSampleLight1_LocationDescription
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_PHYSICAL_ENV,
ZCL_DATATYPE_UINT8,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&zclSampleLight1_PhysicalEnvironment
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{ // Attribute record
ATTRID_BASIC_DEVICE_ENABLED,
ZCL_DATATYPE_BOOLEAN,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&zclSampleLight1_DeviceEnable
}
},
#ifdef ZCL_IDENTIFY
// *** Identify Cluster Attribute ***
{
ZCL_CLUSTER_ID_GEN_IDENTIFY,
{ // Attribute record
ATTRID_IDENTIFY_TIME,
ZCL_DATATYPE_UINT16,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&zclSampleLight1_IdentifyTime
}
},
#ifdef ZCL_EZMODE
// *** Identify Cluster Attribute ***
{
ZCL_CLUSTER_ID_GEN_IDENTIFY,
{ // Attribute record
ATTRID_IDENTIFY_COMMISSION_STATE,
ZCL_DATATYPE_UINT8,
(ACCESS_CONTROL_READ),
(void *)&zclSampleLight1_IdentifyCommissionState
}
},
#endif // ZCL_EZMODE
#endif
// *** On/Off Cluster Attributes ***
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
{ // Attribute record
ATTRID_ON_OFF,
ZCL_DATATYPE_BOOLEAN,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight1_OnOff
}
}
#ifdef ZCL_LEVEL_CTRL
, {
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_CURRENT_LEVEL,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight1_LevelCurrentLevel
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_REMAINING_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
(void *)&zclSampleLight1_LevelRemainingTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_ON_OFF_TRANSITION_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight1_LevelOnOffTransitionTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_ON_LEVEL,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight1_LevelOnLevel
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_ON_TRANSITION_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight1_LevelOnTransitionTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_OFF_TRANSITION_TIME,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight1_LevelOffTransitionTime
}
},
{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
{ // Attribute record
ATTRID_LEVEL_DEFAULT_MOVE_RATE,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE,
(void *)&zclSampleLight1_LevelDefaultMoveRate
}
}
#endif
#ifdef ZCL_DIAGNOSTIC
, {
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NUMBER_OF_RESETS,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PERSISTENT_MEMORY_WRITES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_RX_BCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_BCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_RX_UCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_UCAST,
ZCL_DATATYPE_UINT32,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_UCAST_RETRY,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_MAC_TX_UCAST_FAIL,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_RX_BCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_BCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_RX_UCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_UCAST_SUCCESS,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_UCAST_RETRY,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_TX_UCAST_FAIL,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_ROUTE_DISC_INITIATED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NEIGHBOR_ADDED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NEIGHBOR_REMOVED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NEIGHBOR_STALE,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_JOIN_INDICATION,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_CHILD_MOVED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NWK_FC_FAILURE,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_FC_FAILURE,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_UNAUTHORIZED_KEY,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_NWK_DECRYPT_FAILURES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_APS_DECRYPT_FAILURES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PACKET_BUFFER_ALLOCATE_FAILURES,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_RELAYED_UCAST,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PHY_TO_MAC_QUEUE_LIMIT_REACHED,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_PACKET_VALIDATE_DROP_COUNT,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_AVERAGE_MAC_RETRY_PER_APS_MESSAGE_SENT,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_LAST_MESSAGE_LQI,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
{
ZCL_CLUSTER_ID_HA_DIAGNOSTIC,
{ // Attribute record
ATTRID_DIAGNOSTIC_LAST_MESSAGE_RSSI,
ZCL_DATATYPE_INT8,
ACCESS_CONTROL_READ,
NULL // Use application's callback to Read this attribute
}
},
#endif // ZCL_DIAGNOSTIC
};
uint8 CONST zclSampleLight1_NumAttributes = ( sizeof(zclSampleLight1_Attrs) / sizeof(zclSampleLight1_Attrs[0]) );
/*********************************************************************
* SIMPLE DESCRIPTOR
*/
// This is the Cluster ID List and should be filled with Application
// specific cluster IDs.
const cId_t zclSampleLight1_InClusterList[] =
{
ZCL_CLUSTER_ID_GEN_BASIC,
ZCL_CLUSTER_ID_GEN_IDENTIFY,
ZCL_CLUSTER_ID_GEN_GROUPS,
ZCL_CLUSTER_ID_GEN_SCENES,
ZCL_CLUSTER_ID_GEN_ON_OFF
#ifdef ZCL_LEVEL_CTRL
, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL
#endif
};
// work-around for compiler bug... IAR can't calculate size of array with #if options.
#ifdef ZCL_LEVEL_CTRL
#define ZCLSAMPLELIGHT1_MAX_INCLUSTERS 6
#else
#define ZCLSAMPLELIGHT1_MAX_INCLUSTERS 5
#endif
const cId_t zclSampleLight1_OutClusterList[] =
{
ZCL_CLUSTER_ID_GEN_BASIC
};
#define ZCLSAMPLELIGHT1_MAX_OUTCLUSTERS (sizeof(zclSampleLight1_OutClusterList) / sizeof(zclSampleLight1_OutClusterList[0]))
SimpleDescriptionFormat_t zclSampleLight1_SimpleDesc =
{
SAMPLELIGHT1_ENDPOINT, // int Endpoint;
ZCL_HA_PROFILE_ID, // uint16 AppProfId;
#ifdef ZCL_LEVEL_CTRL
ZCL_HA_DEVICEID_DIMMABLE_LIGHT, // uint16 AppDeviceId;
#else
ZCL_HA_DEVICEID_ON_OFF_LIGHT, // uint16 AppDeviceId;
#endif
SAMPLELIGHT1_DEVICE_VERSION, // int AppDevVer:4;
SAMPLELIGHT1_FLAGS, // int AppFlags:4;
ZCLSAMPLELIGHT1_MAX_INCLUSTERS, // byte AppNumInClusters;
(cId_t *)zclSampleLight1_InClusterList, // byte *pAppInClusterList;
ZCLSAMPLELIGHT1_MAX_OUTCLUSTERS, // byte AppNumInClusters;
(cId_t *)zclSampleLight1_OutClusterList // byte *pAppInClusterList;
};
/*********************************************************************
* GLOBAL FUNCTIONS
*/
/*********************************************************************
* LOCAL FUNCTIONS
*/
/****************************************************************************
****************************************************************************/
Maybe you can try the following workaround:
Just change the define for the display buffer in lcd_dogm128_6.h
from
#define LCD_BYTES 1024 // Number of bytes needed in LCD buffer
to
#define LCD_BYTES 1025 // Number of bytes needed in LCD buffer
Increasing this buffer will fix overwriting the first byte of the nex variable in RAM after Display update routine. Seems there is a problem with the indexing there.
I`ve had the same issue here with the per test software for cc2538dk using ccs 6.0.
Best regards
Christian