📄 demozcoordapp.c
字号:
DISABLE_WDT();
ConfigTask();
ENABLE_WDT();
// Mark that we are no longer in config mode.
appFlags.bits.bInConfigMode = FALSE;
}
// Set MAC address before initializing the stack.
// This demo application stores MAC address into flash memory at variable
// called "macLongAddr". See zNVM.c
//
// Your application may store and read MAC address from anywhere it prefers.
// Read MAC long address from nonvolatile memory.
NVMRead(&macInfo.longAddr,
(ROM void*)&macLongAddr,
sizeof(macInfo.longAddr));
// This is main Zigbee stack initialization call.
// MAC must be enabled when application is ready.
APLInit();
// We have to enable MAC separately. This way you can disable and enable as per your
// requirement.
APLEnable();
// First of all establish a network.
APLNetworkInit();
// Start with Init state.
smApp = SM_APP_INIT;
// Turn off LEDs
D1 = 0;
D2 = 0;
while(1)
{
// Toggle RA4 to indicate how long we execute this loop
LATA4 ^= 1;
// Keep watchdog happy
CLRWDT();
// This is the main stack task, responsible for Zigbee stack related functionality.
// This function must be called before all Zigbee tasks.
// Actual application task functions can be called in any order.
APLTask();
// This demo application provides two modes of operations - config and normal.
// In config mode, this coordinator will accept new devices and you can create
// binding entries.
// In normal mode, no new node will be accepted - only the ones that are
// already accepted.
// You may change this logic as per your application requirements.
switch(smApp)
{
// This is a required step - A coordinator must establish its own network
// before anything can be done.
case SM_APP_INIT:
ConsolePutROMString(startNetworkMsg);
smApp = SM_APP_INIT_RUN;
break;
case SM_APP_INIT_RUN:
// We must find an empty channel to establish network, or else
// continue scanning new channels.
if ( APLIsNetworkInitComplete() )
{
// If there was any error, report/handle it.
if ( GetLastZError() == ZCODE_NO_ERROR )
{
// We have established a network, break out from this loop and continue
// with next logic.
ConsolePutROMString(networkStartedMsg);
// Form new network now - or do it after your application requirements are met
APLNetworkForm();
smApp = SM_APP_NORMAL_START;
}
else
{
ConsolePutROMString(networkStartErrMsg);
// Actual application would want to go to sleep and/or notify user about this.
smApp = SM_APP_INIT;
}
}
break;
// Once we are in normal mode, we will not allow any new association.
case SM_APP_NORMAL_START:
// Permit new assiciation once we have established new network.
APLPermitAssociation();
// This demo binds S2 and D1
//S2Init();
//D1Init();
LEDInit();
smApp = SM_APP_NORMAL_RUN;
break;
case SM_APP_NORMAL_RUN:
// Your application tasks should be placed here.
// In this demo, we will wakeup if someone pushed a button
LEDTask();
/*if ( appFlags.bits.S2Toggled )
{
S2Task();
appFlags.bits.S2Toggled = FALSE;
}
D1Task();
BindingTask();*/
break;
}
}
}
static BOOL IsMACAddrAssigned(void)
{
// Read MAC long address from app-specific nonvolatile memory.
NVMRead(&macInfo.longAddr,
(ROM void*)&macLongAddr,
sizeof(macInfo.longAddr));
// An address is said to be invlaid if its OUI does not match with our preset OUI
if ( macInfo.longAddr.v[7] != MAC_LONG_ADDR_BYTE7 ||
macInfo.longAddr.v[6] != MAC_LONG_ADDR_BYTE6 ||
macInfo.longAddr.v[5] != MAC_LONG_ADDR_BYTE5 )
return FALSE;
else
return TRUE;
}
static void BindingTask(void)
{
// Local binding is started when both S2 and S3 are pressed.
if ( S2 == 0 && S3 == 0 )
{
// Once we user enters into local binding process,
// disable watchdog timer
DISABLE_WDT();
// Indicate that we are entering into binding task.
D1 = 1;
D2 = 1;
// Wait until one of the swithes is released.
while( S2 == 0 && S3 == 0 );
// Depending which switch is released first, we will bind either
// switch or lamp.
//
// If S2 is released first, we will attempt to bind S2
// If S3 is released first, we will attempt to bind D1
// Or else do as per terminal command.
if ( S2 == 1 && S3 == 0 )
{
// Indicate that we attempting to binding S2 EP
D1 = 0;
D2 = 1;
// Show that we are about to bind S2 EP.
ConsolePutROMString(S2BindingMsg);
// Wait for S3 to get released
while( S3 == 0 );
// Perform S2 EP binding - in ZigBee terminology switch is the source
// (i.e. sends out the data packets).
AddAsBindSource(EP_S2);
// Clear LEDs to indicate that we are done.
D1 = 0;
D2 = 0;
}
// If S2 is released first, we will attempt to bind S2
// If S3 is released first, we will attempt to bind D1
// Or else do as per terminal command.
else if ( S2 == 0 && S3 == 1 )
{
// Indicate that we are attempting to bind D1 EP
D1 = 1;
D2 = 0;
// Show that we are about to bind D1 EP.
ConsolePutROMString(D1BindingMsg);
// Wait for both S2 to get released
while( S2 == 0 );
// Perform LAMP EP binding - in ZigBee terminology lamp is the destination
// (i.e. receives the data packets only)
AddAsBindDest(EP_D1);
// Clear LEDs to indicate that we are done.
D1 = 0;
D2 = 0;
}
// Reenable once done.
ENABLE_WDT();
// Clear SW toggled flags as they would be set when user was performing binding
appFlags.bits.S2Toggled = FALSE;
}
}
// Callback to application to notify of a frame transmission.
void AppMACFrameTransmitted(void)
{
// Turn on LED to indicate activity. TMR0IF interrupt will turn it off.
// See interrupt handler.
if ( !appFlags.bits.bInConfigMode )
D2 = 1;
}
// Callback to application to notify of a frame reception
void AppMACFrameReceived(void)
{
// Turn on LED to indicate activity. TMR0IF interrupt will turn it off.
// See interrupt handler.
if ( !appFlags.bits.bInConfigMode )
D2 = 1;
}
// Callback to application to notify of an ack timeout
void AppMACFrameTimeOutOccurred(void)
{
}
BOOL AppOkayToUseChannel(BYTE channel)
{
// This demo uses all available channels
// You may check given channel against your allowable channels and return TRUE
// or FALSE as needed.
// For 2.4GHz, channel = 11 through 26.
ConsolePutROMString(nextChannelMsg);
return TRUE;
}
// Callback to application to notify if this node should be accepted to our network.
BOOL AppOkayToAcceptThisNode(LONG_ADDR *longAddr)
{
// In this demo, we would allow everyone to join our network.
// You may want to check the long address before allowing it.
return TRUE;
}
// Callback to application to noify of new node joining our network.
void AppNewNodeJoined(LONG_ADDR *nodeAddr, BOOL bIsRejoined)
{
// A new node has just joined (or rejoined).
// In this demo application, once a new node has joined, we want to save its
// association permanently into NVM.
if ( bIsRejoined == FALSE )
{
// You may want to check the nodeAddr and do something specific based
// on that node. This demo app does not any do anything special.
APLCommitTableChanges();
// Display that a new node has joined.
ConsolePutROMString(newNodeJoinedMsg);
}
else
{
// Display that a previous node has rejoined.
ConsolePutROMString(newNodeRejoinedMsg);
}
}
// Callback to application to notify that a node has left the network.
void AppNodeLeft(LONG_ADDR *nodeAddr)
{
// Display a message that a node has left the network.
ConsolePutROMString(nodeLeftMsg);
// Update our NVM table.
APLCommitTableChanges();
// Do application specific action here.
}
// Following functions are dependent on application.
// Remove it if you are not using custom binding..
void AddAsBindSource(BYTE epSource)
{
// The coordinator always has key of '0' - in neighbor table coordinator
// entry is the very first one.
customBindInfo.srcKey = 0;
// Save given EP and cluster.
sourceBindInfo.ep = epSource;
sourceBindInfo.clusterID = PICDEMZ_DEMO_CLUSTER_ID;
// Mark that we now have source information.
customBindInfo.Flags.bits.bSourceBindInfoReceived = TRUE;
// Now prepare the binding entry.
PrepareBindEntry();
}
void AddAsBindDest(BYTE epDest)
{
// The coordinator always has key of '0' - in neighbor table coordinator
// entry is the very first one.
customBindInfo.destKey = 0;
// Save given EP.
destBindInfo.ep = epDest;
// Mark that we now have destination information.
customBindInfo.Flags.bits.bDestBindInfoReceived = TRUE;
// Now prepare the binding entry.
PrepareBindEntry();
}
// This is a callback from ZDO EP#0, whenever it receives custom bind
// frames. When this function is called, a packet is already received
// and this function has to fetch and process rest of the packet.
//
// Modify or remove following custom binding function as per your requirements.
BOOL ProcessCustomBind(BYTE transID, BYTE dataLen)
{
BYTE remoteNodeKey;
BIND_INFO bindInfo;
// Before we process this packet, make sure that it contains expected
// bytes of data.
if ( dataLen != sizeof(bindInfo) )
{
ConsolePutROMString(invalidBindInfoMsg);
return FALSE;
}
// Now fetch entire bindInfo data.
APSGetArray((BYTE*)&bindInfo, sizeof(bindInfo));
if ( bindInfo.cmd == CUSTOM_BIND_SOURCE ||
bindInfo.cmd == CUSTOM_BIND_DEMO)
{
// Make sure that this source node is in our neighbor table
customBindInfo.srcKey = LookupNodeByLongAddr(&bindInfo.nodeAddr);
if ( customBindInfo.srcKey == NEIGHBOR_KEY_INVALID )
{
ConsolePutROMString(unknownSrcNodeMsg);
return FALSE;
}
else
{
ConsolePutROMString(validSrcInfoMsg);
// Save source EP #
//sourceBindInfo.ep = bindInfo.ep;
sourceBindInfo.ep = EP_LED_D;
// Remember that we have received source information.
customBindInfo.Flags.bits.bSourceBindInfoReceived = TRUE;
//=======================================
// test
sourceBindInfo.clusterID = bindInfo.clusterID;
customBindInfo.Flags.bits.bDestBindInfoReceived = TRUE;
destBindInfo.ep = EP_LED_S;
customBindInfo.destKey = 0;
PrepareBindEntry();
}
/*if ( bindInfo.cmd == CUSTOM_BIND_LED)
{
// Save remote node key
remoteNodeKey = customBindInfo.srcKey;
// First bind #6
customBindInfo.Flags.bits.bDestBindInfoReceived = TRUE;
customBindInfo.Flags.bits.bSourceBindInfoReceived = TRUE;
customBindInfo.srcKey = remoteNodeKey;
sourceBindInfo.ep = EP_LED_S;
sourceBindInfo.clusterID = PICDEMZ_LED_CLUSTER_ID;
destBindInfo.ep = EP_LED_D;
customBindInfo.destKey = 0;
PrepareBindEntry();
// Bind #8
customBindInfo.Flags.bits.bDestBindInfoReceived = TRUE;
customBindInfo.Flags.bits.bSourceBindInfoReceived = TRUE;
customBindInfo.srcKey = 0;
sourceBindInfo.ep = EP_LED_S;
sourceBindInfo.clusterID = PICDEMZ_LED_CLUSTER_ID;
destBindInfo.ep = EP_LED_D;
customBindInfo.destKey = remoteNodeKey;
PrepareBindEntry();
ConsolePutROMString(ledBindSuccessMsg);
}else*/
// Now do CUSTOM_BIND_DEMO specific processing
if ( bindInfo.cmd == CUSTOM_BIND_DEMO)
{
// In demo binding action, we will automatically bind :
// 1. S2 on remote node to D1 on coordinator
// 2. S2 on coordinator to D1 on remote node.
//
// Save remote node key
remoteNodeKey = customBindInfo.srcKey;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -