⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coordmain.c

📁 Zigbee 路由协议源代码(版本V3.0)
💻 C
字号:
/*********************************************************************

 Coordinator/RFD node based on Demo Coordinator App from Microchip


 Implements an endpoint on the coordinator that accepts 
 serial input from the console and sends this 
 endpoints on remote nodes.

 This file also contains the main() code for the RFD nodes
 as well.  

 Both coordinator and RFD nodes accept data from the serial
 port and send it to each other (RFD nodes to coordinator,
 coordinator to all bound RFD nodes).

 
 R.B.Reese (reese@ece.msstate.edu), July 2005

 ********************************************************************/

// 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


#include <string.h>

#include "zigbee.h"         // Zigbee defs
#if defined(MCHP_C18)
#include <stdio.h>
#endif

#include "config.h"
#include "msstate.h"

#include "sralloc.h"

#include "Console.h"
#include "bugfix.h"
#include "board.h"


#ifndef I_AM_END_DEVICE
#include "coord.h"
#else
#include "rfd.h"
#endif

// 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)

#if defined(ENABLE_DEBUG)
    #define BUILD_MODE  " (Debug Build)"
#else
    #define BUILD_MODE  " (Non-debug Build)"
#endif

// Various informational messages as part of configuration process.
ROM char * const startUpMsg      = "  SerialCoord/RFD V3 Demo, 28 Sep  2005\r\n";
ROM char * const menuMsg      = "1. Join Network\r\n. Enter Application\n\r  Enter (1,2,3): ";


ROM char * const resetMsg              = "******Unexpected reset occurred.******\r\n";
ROM char * const nextChannelMsg        = "Now operating in next channel...\r\n";
ROM char * const brownOutMsg           = "\r\nBrown Out reset\r\n";
ROM char * const powerOnMsg            = "\r\nPower On reset\r\n";
ROM char * const illegalState          = "\r\nIllegal State, resetting\r\n";
ROM char * const bindingTableCleared   = "Neighbor/Binding Table cleared, reseting network\n\r";
ROM char * const queryTimeout          = "Query timeout to all nodes. Resetting network\n\r";



#include "app.h"
APPFLAGS appFlags;

// Private helper functions
static void InitializeBoard(void);

#define MAX_CLEARBIND_TIME (TICK_SECOND*10) 


static void    ComApp(void);
static void    ComInit(void);

#ifndef I_AM_END_DEVICE
extern BYTE selective_join;
#endif



//these are input buffers and flags for the application code
#define INPUT_BUF_SIZE 40
volatile char buf_1[INPUT_BUF_SIZE], buf_2[INPUT_BUF_SIZE];
volatile unsigned char ebufptr,bufptr;
volatile unsigned char buf_flag, send_buffer_flag, overrun_flag;
volatile unsigned char echoptr, ebuf_flag, last_char;

void main(void){

  BYTE c, exit_flag;

  // To keep track of time.
  TICK lastTick;
  TICK S2High;    //use for clearing binding table

  APP_STATE smApp;

  // Enable watchdog
  ENABLE_WDT();

  // Clear all flags in the begining.
  appFlags.Val = 0x00;

  // Initialize the board hardware.
  InitializeBoard();

  // 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);

    // Prepare for alternating flashing LED sequence.
    D1 = 0;
    D2 = 1;
    TickInit();  //start TICK timer
    DISABLE_WDT();
    // On this error, blink LEDs.
    while(1)
    {
      lastTick = TickGet();
      while (TickGetDiff(TickGet(), lastTick) < (TICK_SECOND>>1)) {
	TickUpdate();   //update tick count
      }

      D1 ^= 1;
      D2 ^= 1;
    }
  }

  if (!POR && !BOR) {
    ConsolePutROMString(powerOnMsg);
    POR = 1; BOR = 1;
    CLRWDT();
  }

  if (POR && !BOR) {
    ConsolePutROMString(brownOutMsg);
    BOR = 1;
    CLRWDT();
  }

  ConsolePutROMString(startUpMsg);
  PrintStackConfig();

  exit_flag = 0;
  do {
    ConsolePutROMString(menuMsg);
    DISABLE_WDT();
    while (!RCIF);
    c = RCREG;
    ConsolePut(c);
    ConsolePut('\r'); ConsolePut('\n');
    ENABLE_WDT();
    if (c == '1') {
      // join Network
      appFlags.bits.bInConfigMode = TRUE;
      InitializeNetwork();
      ConsolePutROMString((ROM char *)"Network Started\r\n");
      while( !ConsoleIsPutReady() ) { CLRWDT(); };
      RESET();
    }else if (c == '2') {
      exit_flag = 1;
      ConsolePutROMString((ROM char *)"Starting App\r\n");
    }
  }
  while (!exit_flag);

  InitRxAlive();
  InitializeNetwork();

  lastTick = TickGet();

  smApp = SM_APP_NORMAL_START;


  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();
    KeepRxAlive();  

    // all network initialization work of this state machine done 
    // in InitializeNetwork
    switch(smApp) {
    case SM_APP_NORMAL_START:
      smApp = SM_APP_NORMAL_RUN;
      break;
      // this application does nothing except route
    case SM_APP_NORMAL_RUN:
      smApp = SM_APP_IDLE;
      break;
    case SM_APP_IDLE:
      // sleep or do other work
      smApp = SM_APP_NORMAL_RUN;
      break;
    }
  }
}


static void InitializeBoard(void)
{
    // This is a RS232 console - you may replace it with any console you like.
    ConsoleInit();

    // Switches S2 and S3 are on RB5 and RB4 respectively. We want interrupt-on-change
    INTCON = 0x00;

    // There is no external pull-up resistors on S2 and S3. We will use internal pull-ups.
    // The CC2420 provides SFD (Start of Frame Detect) signal on RB2. We are using
    // the falling edge of that signal to generate INT2
    // Enable PORTB internal pullups, INT2 on falling edge
    INTCON2 = 0x00;

    // Enable INT2 interrupt - SFD from CC2420 or IRQ from ZMD44101
    INTCON3 = 0xD0;

    // CC2420 I/O assignments with respect to PIC:
    // RB0 <- FIFO      (Input)
    // RB1 <- CCA       (Input - Not used in this version of stack)
    // RB2 <- SFD       (Input - Generates interrupt on falling edge)
    // RB3 <- FIFOP     (Input - Used to detect overflow)
    // RC0 -> CSn       (Output - to select CC2420 SPI slave)
    // RC1 -> VREG_EN   (Output - to enable CC2420 voltage regulator)
    // RC2 -> RESETn    (Output - to reset CC2420)
    // RC3 - > SCK      (Output - SPI Clock to CC2420)
    // RC4 <- SO        (Input - SPI data from CC2420)
    // RC5 -> SI        (Output - SPI data to CC2420)

    // Make PORTB as input - this is the RESET default
    TRISB = 0xff;

    // Set PORTC control signal direction and initial states
    // Start with CC2420 disabled and not selected
    LATC = 0xfd;

    // Set the SPI module for use by Stack
    TRISC = 0xD0;

    // Set the SPI module
    SSPSTAT = 0xC0;
    SSPCON1 = 0x20;


    // D1 and D2 are on RA0 and RA1 respectively, and CS of TC77 is on RA2.
    // Make PORTA as digital I/O.
    // The TC77 temp sensor CS is on RA2.
    ADCON1 = 0x0F;

    // Deselect TC77 (RA2)
    LATA = 0x04;

    // Make RA0, RA1, RA2 and RA4 as outputs.
    TRISA = 0xE0;

    // Set up the interrupt to read in a data packet.
    // set to capture on rising edge
    CCP2CON = 0b00000101;
    // set high priority for RX packet detection
    CCP2IP = 1;
    CCP2IF = 0;
    CCP2IE = 1;

}

#if defined(MCHP_C18)
#pragma interruptlow LowISR
void LowISR(void)
#elif defined(HITECH_C18)
    void interrupt low_priority LowISR(void)
#else
    void LowISR(void)
#endif

{
    return;
}


// NOTE: Several PICs, including the PIC18F4620 revision A3 have a RETFIE FAST/MOVFF bug
// The interruptlow keyword is used to work around the bug when using C18
// To work around the bug on PICC-18, configure the compiler to Compile for ICD
#if defined(MCHP_C18)
    #pragma interruptlow HighISR save=section(".tmpdata"),section("MATH_DATA"),PROD
    void HighISR(void)
#elif defined(HITECH_C18)
    void interrupt HighISR(void)
#else
    void HighISR(void)
#endif
{
    // This is a quick way to display MAC TX/RX status on RD1 LED.
    // TMR0IF is also used by TickUpdate, so we will let it clear the flag.
  // D2 turned on during transmission
  if ( TMR0IF )   D2 = 0;

    // Must call this so that MAC module can determine if a transmission is in progress or not.
    APL_ISR();

    // Must call this so that tick manager can update its tick count.
    TickUpdate();

    // Is this a interrupt-on-change interrupt?
    if ( RBIF == 1 )
    {
        // Clear mismatch condition and flag
        if ( S2 == 0 )
            appFlags.bits.S2Toggled = TRUE;
        if ( S3 == 0 )
            appFlags.bits.S3Toggled = TRUE;

        // Clear mis-match condition and reset the interrupt flag
        LATB = PORTB;
        RBIF = 0;

    }

    // this handles the serial data input capture 
    // two buffers are used, when a complete line is
    // recieved, it switchs to the alternate buffer
    // while the the line is sent to the remote unit(s)
    if (RCIF && RCIE) {
      // get character from serial port
      last_char = RCREG;
      // save character
      if (!buf_flag) buf_2[bufptr] = last_char;
      else buf_1[bufptr] = last_char;
      bufptr++;   //increment buffer pointer
      //ebufptr is normally a copy of bufptr except when
      // trying to send the last buffer.  send_buffer_flag freezes 
      // the ebufptr until the last buffer is sent
      if (!send_buffer_flag) ebufptr = bufptr; //echo bufptr
#if defined(STREAMING_DATA)
      //don't send until buffer fills
      if (bufptr == INPUT_BUF_SIZE ) 
#else
	//send when buffer fill or carriage return
      if ((bufptr == INPUT_BUF_SIZE) || last_char == '\r' ) 
#endif
	{
	if (send_buffer_flag) {
	  overrun_flag = 1;
	  // discard buffer by resetting pointer
	  bufptr = 1;
	} else {
	  send_buffer_flag = 1;  //use this to freeze ebufptr until buffer is echoed
	  bufptr = 1;
	  // toggler buffer flag
	  buf_flag = !buf_flag; 
	}
      }
    }

}

#if defined(MCHP_C18)
#pragma code highVector=0x08
void HighVector (void)
{
    _asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif

#if defined(MCHP_C18)
#pragma code lowhVector=0x18
void LowVector (void)
{
    _asm goto LowISR _endasm
}
#pragma code /* return to default code section */
#endif




// 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.
  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.
  D2 = 1;
}

// Callback to application to notify of an ack timeout
void AppMACFrameTimeOutOccurred(void)
{
}

// Callback to application to notify that a route discovery attempt failed.
extern void AppRouteDiscoveryFailed( SHORT_ADDR shortAddr )
{
}


//The functions that actually do the work of this application in terms
// of reading console input and then sending it to a remote node 
// are below here

#ifndef I_AM_END_DEVICE
EP_HANDLE hCoord;
#else
EP_HANDLE hRfd;
#endif

//state machine for sending data
typedef enum _SM_SEND_STATE
{
    SM_SEND_IDLE= 0,
    SM_SEND_UPDATE,
    SM_SEND_WAIT
} SM_SEND_STATE;

SM_SEND_STATE sendState;
#define MAX_SEND_RETRY_COUNT      (3)

void ComSend(void);
void ComReceive(void);

unsigned char sendRetryCount;


// State machine and retry counter for responding to 
// request for data
#if defined   (I_AM_END_DEVICE)



#define MAX_UPDATE_WAIT (TICK_SECOND*1)
// how often we should check coordinator for messages
#define MAX_QUERY_TIME (TICK_SECOND/4)

void  RFD_Request_Messages(void);

#endif


typedef enum _COMSTATE
{
    COM_NORMAL,
    COM_QUERY,
} COMSTATE;

static COMSTATE ComState;

TICK lastCoordQueryTick; //used by RFD


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -