📄 demozcoordapp.c
字号:
/*********************************************************************
*
* Demo Coordinator App
*
*********************************************************************
* FileName: DemoZCoordApp.c
* Dependencies:
* Processor: PIC18
* Complier: MCC18 v1.00.50 or higher
* HITECH PICC-18 V8.10PL1 or higher
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the 揅ompany? for its PICmicro?Microcontroller is intended and
* supplied to you, the Company抯 customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN 揂S IS?CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
* HiTech PICC18 Compiler Options excluding device selection:
* -FAKELOCAL -G -Zg -E -C
*
* This is a demo Coordinator using Zigbee stack by Microchip
*
* To run this code, program it into PICDEM Z demo board and
* perform following steps:
*
* Note: This procedure is required only if you ever reprogram the boards
* Once programmed, you do not need to do this again. All information
* is stored in flash program memory.
*
* 1. When first programmed and run, board will automatically enter
* into configuration mode - RD0 will be lit to indicate config
* mode.
* 2. Connect board to PC using RS232 and open your choice of terminal
* emulation program - Hyperterminal is commonly used program.
* 3. Select 19200, 8-N-1 baud rate.
* 4. Make sure that "Echo" is enabled on your terminal.
* 5. Connect. If you do not see any menu, press any key to get the menu
* 6. Select option '1' to set node id. Use node id that is printed on
* board. This node id determiens MAC address of your board.
* The node id forms lower 16-bit of 64-bit MAC address. This application
* uses Microchip OUI to create the MAC address.
* 7. Now you would need to put board into '2' to access new associations.
* 8. At this time, you should run end device (RFD) board and put then to
* to join new network. If RFD is successfully joined, you will see
* appropriate message on coordinator terminal.
* 9. You will also need to bind RFD endpoints/cluster to your choice of node
* 10.Using RFD, initiate IN and OUT end point bind process and you will see
* that coordinator emits "bind successful' message.
* 11. Now reset coordiantor first, followed by RFD. Now you can push S2
* button and see RD1 toggle.
*
* More detailed instructions will be created in future.
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Nilesh Rajbharti 7/12/04 Original
* Nilesh Rajbharti 11/1/04 Pre-release version
********************************************************************/
// Uncomment ENABLE_DEBUG line to enable debug mode for this file.
// Or you may also globally enable debug by defining this macro
// in zigbee.h file or from compiler command-line.
#ifndef ENABLE_DEBUG
//#define ENABLE_DEBUG
#endif
// This stack was compiled and simulated using Windows compiler.
#if defined(WIN32)
#include <stdio.h>
#endif
#include <string.h>
#include "zigbee.h" // Zigbee defs
#include "zAPS.h" // For EP, MSG and KVP functions
#include "Tick.h" // Tick manager
#include "zAPL.h" // APL layer functions
#include "Debug.h" // For debug output support
#include "zdo.h" // Required because of custom binding
// Don't need to include if not using demo custom
// binding
#include "S2OnCoord.h"
#include "D1OnCoord.h"
#include "LedOnCoord.h"
#if defined(WIN32)
#include "physim.h" // Not distributed.
#endif
#define S2 RB5
#define S3 RB4
#define D1 LATA0
#define D2 LATA1
// When to update lamp status.
#define MAX_LAMP_UPDATE_PERIOD (1*TICK_SECOND)
// This defines how LEDs will be blinked when unexpected RESET is detected.
#define FATAL_ERROR_BLINK_PERIOD (TICK_SECOND/2)
// Configuration fuse bits.
// If other than 18F4620 device is used, you must define config values of your
// choice or set them via MPLAB interface.
#if defined(MCHP_C18) && defined(__18F4620)
#pragma romdata CONFIG1H = 0x300001
const rom unsigned char config1H = 0b00000110; // HSPLL oscillator
#pragma romdata CONFIG2L = 0x300002
const rom unsigned char config2L = 0b00011111; // Brown-out Reset Enabled in hardware @ 2.0V, PWRTEN disabled
#pragma romdata CONFIG2H = 0x300003
const rom unsigned char config2H = 0b00001110; // HW WD disabled, 1:128 prescaler
#pragma romdata CONFIG3H = 0x300005
const rom unsigned char config3H = 0b10000001; // PORTB digital on RESET
#pragma romdata CONFIG4L = 0x300006
const rom unsigned char config4L = 0b10000001; // DEBUG disabled,
// XINST disabled
// LVP disabled
// STVREN enabled
#pragma romdata
#elif defined(HITECH_C18) && defined(_18F4620)
// Set configuration fuses for HITECH compiler.
__CONFIG(1, 0x0600); // HSPLL oscillator
__CONFIG(2, 0x0E1F); // PWRTEN disabled, BOR enabled @ 2.0V, HW WD disabled, 1:128 prescaler
__CONFIG(3, 0x8100); // PORTB digital on RESET
__CONFIG(4, 0x0081); // DEBUG disabled,
// XINST disabled
// LVP disabled
// STVREN enabled
#endif
// A banner message that gets displayed on terminal on config startup.
#define STARTUP_MSG "ZigBee Demo Coordinator Application v1.0 (Microchip Stack for ZigBee v1.0.0)"
#if defined(ENABLE_DEBUG)
#define BUILD_MODE " (Debug Build)"
#else
#define BUILD_MODE " (Non-debug Build)"
#endif
// This menu is displayed when in configuration mode.
// A configuration mode can be entered by powering the board with S3 pushed down.
// Once the micro is programmed with new code, this application will
// automatically enter into config mode.
ROM char * const menu =
"\r\n"
"\r\n****************************************************************************"
"\r\n"STARTUP_MSG \
"\r\n Built on " __DATE__ BUILD_MODE
"\r\n****************************************************************************"
"\r\n 1: Set node ID..."
"\r\n 2: Clear Neighbor Table."
"\r\n 3: Clear Binding Table."
"\r\n 4: Change to next channel."
"\r\n 5: Transmit unmodulated signal."
"\r\n 6: Transmit random modulated signal."
"\r\n 0: Run application"
"\r\n\r\nEnter a menu choice: ";
// enums to execute menu options.
typedef enum _MENU_CMD
{
MENU_CMD_START = '0',
MENU_CMD_QUIT = '0',
MENU_CMD_SET_ID,
MENU_CMD_CLEAR_NEIGHBOR_TABLE,
MENU_CMD_CLEAR_BINDING_TABLE,
MENU_CMD_NEXT_CHANNEL,
MENU_CMD_UNMODULATED_OP,
MENU_CMD_RANDOM_OP,
MENU_CMD_STOP
} MENU_CMD;
// Various informational messages as part of configuration process.
ROM char * const testTxMsg = "\r\n\r\nNow transmitting test signal..."
"\r\nYou must reset the board to perform other action.";
ROM char * const continueMsg = "\r\nPress any key to continue...";
ROM char * const idEntryMsg = "\r\nEnter up to 4 digit long decimal board id: ";
ROM char * const exitMsg = "Now running application...\r\n";
ROM char * const invalidMACAddrMsg = "Invalid MAC address received.\r\n";
ROM char * const invalidValueMsg = "Invalid value received.\r\n";
ROM char * const permitAssocMsg = "Press S2 or any key to disallow and save associations & bindings.\r\n";
ROM char * const newNodeJoinedMsg = "A new node has just joined.\r\n";
ROM char * const newNodeRejoinedMsg = "A familiar node has just rejoined.\r\n";
ROM char * const nodeLeftMsg = "A node has left the network.\r\n";
ROM char * const resetMsg = "******Unexpected reset occurred.******\r\n";
ROM char * const macAddrNotAssignedMsg = "MAC Address is not assigned, entering Configuration mode...\r\n";
ROM char * const noNeighborsMsg = "Neighbor table is empty.\r\n";
ROM char * const noBindingsMsg = "Binding table is empty.\r\n";
ROM char * const startNetworkMsg = "Starting a new network...\r\n";
ROM char * const networkStartedMsg = "New network successfully started.\r\n";
ROM char * const networkStartErrMsg = "There was an error starting network.\r\n";
ROM char * const nextChannelMsg = "Now operating in next channel...\r\n";
ROM char * const unknownSrcNodeMsg = "Unknown source node received.\r\n";
ROM char * const validSrcInfoMsg = "Received valid source node info.\r\n";
ROM char * const invalidSrcInfoMsg = "Received invalid source binding info.\r\n";
ROM char * const unknownDestNodeMsg = "Unknown dest node received.\r\n";
ROM char * const validDestInfoMsg = "Received valid dest node info.\r\n";
ROM char * const invalidDestInfoMsg = "Received invalid dest binding info.\r\n";
ROM char * const bindingSuccessMsg = "Custom binding successful.\r\n";
ROM char * const bindingFailedMsg = "Custom binding failed.\r\n";
ROM char * const demoBindSuccessMsg = "Successfully completed quick demo setup.\r\n";
ROM char * const D1BindingMsg = "Attempting to bind D1 EP.\r\n";
ROM char * const S2BindingMsg = "Attempting to bind S2 EP.\r\n";
ROM char * const invalidBindInfoMsg = "Invalid binding info received.\r\n";
ROM char * const tc77TestingMsg = "Testing TC77...\r\n";
ROM char * const tc77ProblemMsg = "Auto test of TC77 failed.\r\n";
ROM char * const tc77TestSuccessMsg = "TC77 test successful.\r\n";
// Private variables
static union
{
struct
{
unsigned int bInConfigMode : 1;
unsigned int S2Toggled : 1;
} bits;
BYTE Val;
} appFlags;
// Data structures to hold custom bind information.
typedef struct _CUSTOM_BIND_SOURCE_INFO
{
LONG_ADDR longAddr;
BYTE ep;
BYTE clusterID;
} CUSTOM_BIND_SOURCE_INFO;
typedef struct _CUSTOM_BIND_DEST_INFO
{
LONG_ADDR longAddr;
BYTE ep;
} CUSTOM_BIND_DEST_INFO;
// Must match with RFD defs.
typedef enum _CUSTOM_BIND_ACTION
{
CUSTOM_BIND_SOURCE = 0,
CUSTOM_BIND_DEST,
CUSTOM_BIND_DEMO
} CUSTOM_BIND_ACTION;
CUSTOM_BIND_SOURCE_INFO sourceBindInfo;
CUSTOM_BIND_DEST_INFO destBindInfo;
// Custom bind information.
typedef struct _BIND_INFO
{
CUSTOM_BIND_ACTION cmd;
LONG_ADDR nodeAddr;
BYTE ep;
BYTE clusterID;
} BIND_INFO;
struct
{
union
{
struct
{
unsigned bSourceBindInfoReceived:1;
unsigned bDestBindInfoReceived:1;
} bits;
BYTE Val;
} Flags;
NEIGHBOR_KEY srcKey;
NEIGHBOR_KEY destKey;
} customBindInfo;
// Private helper functions
static void InitializeBoard(void);
static void ConfigTask(void);
static BOOL ExecuteMenuChoice(MENU_CMD choice);
static void BindingTask(void);
static void TestTC77(void);
// Custom binder function
static void PrepareBindEntry(void);
void AddAsBindSource(BYTE epSource);
void AddAsBindDest(BYTE epDest);
// Persistent MAC address, defined in "zNVM.c" file.
extern ROM LONG_ADDR macLongAddr;
extern BYTE sendBuf[20];
extern BYTE sendCount;
extern BYTE getCmd;
#define SaveMACLongAddr(a) \
NVMWrite((NVM_ADDR*)&macLongAddr, (BYTE*)a, sizeof(LONG_ADDR))
static BOOL IsMACAddrAssigned(void);
void main(void)
{
// Main state machine
enum
{
SM_APP_INIT = 0,
SM_APP_INIT_RUN,
SM_APP_NORMAL_START,
SM_APP_NORMAL_RUN
} smApp;
//RS232 cmd
sendCount = 0;
getCmd = 0;
// Enable watchdog
ENABLE_WDT();
// Clear all flags in the begining.
appFlags.Val = 0x00;
// Initialize custom binding flags.
customBindInfo.Flags.Val = 0x00;
// Initialize the board hardware.
InitializeBoard();
// This is to initialize tick manager required for Zigbee stack modules.
TickInit();
// Blink on LEDs on startup to provide visual feedback
// LEDs are turned off before main loop is started.
D1 = 1;
D2 = 1;
// This is to check some errant/programming mistakes.
if ( TO == 0 )
{
// Clear watchdog to set TO bit.
CLRWDT();
// Clear flags so that we can detect it next time.
STKPTR &= 0x3F;
RCON |= 0x1F;
// Display message on terminal.
ConsolePutROMString(resetMsg);
// Since core is going to sleep in coming lines, make sure that
// UART finishes its transmission.
while( !ConsoleIsPutReady() );
// Disable all interrupts
INTCON = 0;
// Prepare for alternating flashing LED sequence.
D1 = 0;
D2 = 1;
// On this error, blink LEDs.
while(1)
{
// This is to make sure that we don't waste battery.
// Of course at least one LED is always ON so saving would not be
// that much - actual application may do something different.
SLEEP();
NOP();
D1 ^= 1;
D2 ^= 1;
}
}
// Test on-board temperature sensor TC77 - This version does not use TC77.
// This test is done here because SPI is initialized in PHY.h
// You may change it so that SPI is initialized in main file instead of stack file.
TestTC77();
// This demo application uses S3 switch to enter into configuration mode.
// Actual application may implelement any logic to select configuratoin mode
// or may not have any - completely application dependent.
if ( S3 == 0 )
appFlags.bits.bInConfigMode = TRUE;
// If MAC long address is not assigned, enter configuration by default.
if ( !IsMACAddrAssigned() )
{
ConsolePutROMString(macAddrNotAssignedMsg);
appFlags.bits.bInConfigMode = TRUE;
}
// If neighbortable is empty, let the console know
if ( IsNeighborTableEmpty() )
ConsolePutROMString(noNeighborsMsg);
// If bindingtable is empty, let the console know
if ( IsBindingTableEmpty() )
ConsolePutROMString(noBindingsMsg);
// Enter Config mode if required
if ( appFlags.bits.bInConfigMode )
{
// Does not want to use watchdog while in config mode.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -