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

📄 coordmain.c

📁 这是在Microchip公司提供的源代码的Zigbee协议栈的下开发的三点网络应用程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
    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)
#define MAX_SAUPDATE_TIME (TICK_SECOND/3)

void  RFD_Request_Messages(void);

#endif


typedef enum _COMSTATE
{
    COM_NORMAL,
    COM_QUERY,
} COMSTATE;

static COMSTATE ComState;


static SHORT_ADDR rfd_sa;
static BYTE rfd_sa_received_flag;

static BYTE contacted_coordinator_flag;

TICK lastCoordQueryTick; //used by RFD
TICK lastShortAddrUpdate; //used by RFD


//initialize the Communication app
static void    ComInit(void){
  char c;

#ifdef I_AM_COORDINATOR
  
  rfd_sa.Val = 0;  // we do not know the RFD's short address yet
  rfd_sa_received_flag = 0;

#else
  // as RFD, have not contacted cooordinator yet.
  contacted_coordinator_flag = 0;

#endif




  ComState = COM_NORMAL;
  overrun_flag = 0;
  bufptr = 1;     //index into active buffer, 1st two bytes reserved
  ebufptr = 1;    //follows bufptr
  echoptr = 1;    //echo'ed char pointer, 1st two bytes reserved
  buf_flag = 0;   //selects active input buffer
  ebuf_flag = 0;   //selects active echo buffer
  send_buffer_flag = 0;
  //enable RCIF interrupt, assume USART port already configured
  // clear any characters in the input buffer
  while (RCIF) {
    c = RCREG;
  }
#if defined(DUPLEX) || defined(I_AM_END_DEVICE)
  
  RCIE = 1;  //enable RCIF interrupt
#else
  // this must the coordinator and in half-duplex mode, disable input
  CREN = 0;  
#endif

#ifndef I_AM_END_DEVICE
  hCoord = APLOpenEP( EP_COORD );   // open zigbee endpoint
#else
  hRfd = APLOpenEP( EP_RFD );   // open zigbee endpoint
#endif

  sendState = SM_SEND_IDLE;
  ConsolePutROMString((ROM char *)"Wireless Com Port Demo\r\n");
#if defined(STREAMING_DATA)
   ConsolePutROMString((ROM char *)"  Streaming data enabled, only send when buffer full\r\n");
#else
   ConsolePutROMString((ROM char *)"  Streaming data disabled, send on buffer full or carriage return\r\n");
#endif
#if defined(DUPLEX)
  ConsolePutROMString((ROM char *)"DUPLEX enabled, begin typing text after binding....\n\r");
#else
#ifndef I_AM_END_DEVICE
  ConsolePutROMString((ROM char *)"DUPLEX disabled, waiting for input....\n\r");
#else
  ConsolePutROMString((ROM char *)"DUPLEX disabled, begin typing text after binding....\n\r");
#endif
#endif

  lastCoordQueryTick = TickGet();
  lastShortAddrUpdate = TickGet();
}

// this function handles echoing of received characters to
// to the console. Once a complete line is received, it is 
// is then sent to the remote node.
// if this is an RFD, then we have to periodically
// request messages from the cooordinator
static void    ComApp(void){
  char c;

  // After APLTask() is called, MUST check for 
  //  input before attempting to send
  ComReceive();  

#ifdef I_AM_END_DEVICE
  RFD_Send_ShortAddr();
#endif
#ifdef I_AM_COORDINATOR

  if (rfd_sa_received_flag) {
    Coord_Send_ShortAddr_Ack();
  }
#endif


  switch(ComState){
  case COM_NORMAL:

    if (overrun_flag) {
      ConsolePutROMString((ROM char *)"Overrun, buffer lost\r\n");
      overrun_flag = 0;
    }
    
    //first echo any typed characters
    c = 0xff;
    while (echoptr != ebufptr) {
      if (!ebuf_flag) c = buf_2[echoptr];
      else c = buf_1[echoptr];
      if (c == '\r') {
	ConsolePut(c);
	ConsolePut((BYTE)'\n');
      }    else ConsolePut((BYTE) c);
      echoptr++;
      CLRWDT();
    }

    // if send state is not idle yet, we can't send
    if (sendState != SM_SEND_IDLE) {
      ComSend();// finish the last send
    } else {
      if (send_buffer_flag) {
	// got an entire string, send it
#ifdef I_AM_COORDINATOR
	//I am coordinator
	sendState = SM_SEND_UPDATE;
	sendRetryCount = MAX_SEND_RETRY_COUNT;
	ComSend();
#else
	//I am an RFD
	sendState = SM_SEND_UPDATE;
	sendRetryCount = MAX_SEND_RETRY_COUNT;
	ComSend();
#endif
	echoptr = 1;
	ebufptr = 1;
	send_buffer_flag = 0;
	ebuf_flag = !ebuf_flag; //change buffers
      } else {
#if defined   (I_AM_END_DEVICE) && defined DUPLEX && !defined MY_RX_IS_ALWAYS_ON_OR_SYNCED_WITH_BEACON
	//only have to query if end device
	if ( TickGetDiff(TickGet(), lastCoordQueryTick) > MAX_QUERY_TIME) {
	  ComState = COM_QUERY;
	}
#endif
      }
    }
    break;
  case COM_QUERY:  //used only by end devices
#if defined(I_AM_END_DEVICE)
    // only check for messages if duplex communication allowed
    RFD_Request_Messages();
    lastCoordQueryTick = TickGet();
#endif
    ComState = COM_NORMAL;
    break;
  }
}

//this just sends the received line to the remote node
void ComSend(void) {
  TRANS_ID    transID;
  BYTE        *dataPtr;
  BYTE        cid;
  BYTE        ep;
  SHORT_ADDR  dest_sa;

#ifndef I_AM_END_DEVICE
  cid = MSSTATE_COORDOUT_CLUSTER_ID;
  ep = EP_COORD;
  APLSetEP(hCoord);
#else
  cid = MSSTATE_RFDOUT_CLUSTER_ID;
  ep = EP_RFD;
  APLSetEP(hRfd);
#endif
  switch(sendState){
  case SM_SEND_IDLE:
    break;
  case SM_SEND_UPDATE:
    if ( APLIsPutReady() ) {
      if (!ebuf_flag) dataPtr = (BYTE *) buf_2;
      else dataPtr = (BYTE *)buf_1;
      // Write ZigBee string length
      *(dataPtr) = (echoptr-1);

#ifdef I_AM_END_DEVICE


      dest_sa.Val = 0;
      //send direct, we know the short address
      APLSendKVPDirect( transID, MY_PROFILE_ID,  cid, EP_RFD, 
			dest_sa, EP_COORD,         // dest EP and short addr
			  (echoptr), dataPtr, GENERATE_TRANS_ID,
			  TRANS_SET, TRANS_ZSTRING, AN_ATTRIBUTE,DEFAULT_RADIUS,ROUTE_DISCOVERY_SUPPRESS );

#else
      // coordinator
      if (rfd_sa.Val != 0) {
	// only send if we know the destination short address
      APLSendKVPDirect( transID, MY_PROFILE_ID,  cid, EP_COORD, 
                        rfd_sa,EP_RFD,
			(echoptr), dataPtr, GENERATE_TRANS_ID,
      			  TRANS_SET, TRANS_ZSTRING, AN_ATTRIBUTE,DEFAULT_RADIUS,ROUTE_DISCOVERY_SUPPRESS );
      }

#endif


#ifndef I_AM_END_DEVICE
      sendState = SM_SEND_IDLE;
      APLRemoveFrame();
#else	
      sendRetryCount--;
      sendState = SM_SEND_WAIT;
#endif
    }
    break;
  case SM_SEND_WAIT:
    if ( APLIsConfirmed() )
      {
	sendState = SM_SEND_IDLE;
	APLRemoveFrame();
      }
    else if ( APLIsTimedOut() )
      {
	// Remove previous frame from queue
	APLRemoveFrame();
	if ( sendRetryCount == 0 ){
	  sendState = SM_SEND_IDLE;
	  ConsolePutROMString((ROM char *)"*****String Send Failed\r\n");
	}
	else {
	  sendState = SM_SEND_UPDATE;
	  ConsolePutROMString((ROM char *)"*****Retrying String Send Failed\r\n");
	}
      }
    break;
  }
}


// this just checks for any messages that have been received
void ComReceive(void){
  WORD_VAL    attribID;
  TRANS_ID    transID;
  BYTE        transTag;
  BYTE        strLen;
  BYTE         c;
  BYTE         cid;

#ifndef I_AM_END_DEVICE
  cid = MSSTATE_RFDOUT_CLUSTER_ID;
  APLSetEP(hCoord);
#else
  cid = MSSTATE_COORDOUT_CLUSTER_ID;
  APLSetEP(hRfd);
#endif

  if ( APLIsGetReady() )   {
    BYTE    transTagType;
    BYTE    transTagData;

    //checking cluster ID is really only necessary if you
    // have multiple input clusters
    if (APLGetClusterID() == cid) {
      // Get KVP detail.
      transID = APLGet();
      transTag = APLGet();
      attribID.byte.LSB = APLGet();
      attribID.byte.MSB = APLGet();

#if defined   (I_AM_END_DEVICE)
      // have received a message from the coordinator!
      contacted_coordinator_flag  = 1;
#endif

      //      ConsolePutROMString((ROM char *)"In Com Receive\r\n");
      if (D1) D1=0;
      else D1 = 1;  //toggle LED everytime we get message from a remote unit

      // Decode the transaction type and data type fields from
      // the transcaction tag for faster access
      transTagType = transTag & TRANS_COMMAND_TYPE_MASK;
      transTagData = transTag & TRANS_DATA_TYPE_MASK;

      if(transTagType == TRANS_SET) {
	if(transTagData == TRANS_ZSTRING){
	  // First byte is ZigBee string length, get it
	  strLen = APLGet();
	  //simple sanity check on payload length
	  if (strLen < 118) {
	    // Write the whole string + CR+LF to the console
	    while(strLen--) {
	      c = APLGet();
	      ConsolePut(c);
	      if (c == '\r')ConsolePut('\n');
	    }
	  }
	} 
	else if(transTagData == TRANS_UINT16) {
#ifdef I_AM_COORDINATOR
	  // get the short address value
	  rfd_sa.byte.LSB = APLGet();
	  rfd_sa.byte.MSB = APLGet();
	  sprintf(tmpbuf,(ROM char *)"Received RFD short address: %4x\n\r",rfd_sa.Val);
	  ConsolePutString((BYTE *)tmpbuf);
	  rfd_sa_received_flag = 1;
#else
	  // this is dummy data back from the coordinator acknowledging receipt
	  // we can ignore
#endif

	}
      }
      else {
	ConsolePutROMString((ROM char *)"Unknown received msg type\r\n");
      }
    } else {
      ConsolePutROMString((ROM char *)"Unknown CLUSTER ID received, discarding\r\n");
    }
    // After processing, you must discard current data packet.
    APLDiscardRx();
  }
}


#if defined   (I_AM_COORDINATOR)

// this is a user level acknowledge
static void    Coord_Send_ShortAddr_Ack(void) {
  BYTE mybuf[2];
  SHORT_ADDR  dest_sa;
  TRANS_ID    transID;

  dest_sa.Val = 0;
  if ( APLIsPutReady() ) {
	ConsolePutROMString((ROM char *)"*****Sending Short Address Acknowledge\r\n");
	// this data is ignored by RFD
	*((BYTE *)mybuf) = 0;
	*((BYTE *)mybuf+1) = 0;
	APLSendKVPDirect( transID, MY_PROFILE_ID, MSSTATE_COORDOUT_CLUSTER_ID, EP_COORD, 
			  rfd_sa, EP_RFD,         // dest EP and short addr
			  2, mybuf, GENERATE_TRANS_ID,
			  TRANS_SET, TRANS_UINT16, AN_ATTRIBUTE,DEFAULT_RADIUS,ROUTE_DISCOVERY_SUPPRESS );
	rfd_sa_received_flag = 0;
    APLRemoveFrame();
  }
}

#endif

#if defined   (I_AM_END_DEVICE)


// this is used to send our short address to the endpoint
// on the coordinator so that they know where we live
static void  RFD_Send_ShortAddr(void){
  BYTE mybuf[2];
  SHORT_ADDR  dest_sa;
  TRANS_ID    transID;

  if (!contacted_coordinator_flag) {
    if ((TickGetDiff(TickGet(), lastShortAddrUpdate) > MAX_SAUPDATE_TIME)){
      dest_sa.Val = 0;
      if ( APLIsPutReady() ) {
	ConsolePutROMString((ROM char *)"*****Sending Short Address\r\n");
	*((BYTE *)mybuf) = macInfo.shortAddr.byte.LSB;
	*((BYTE *)mybuf+1) = macInfo.shortAddr.byte.MSB;
	// we will request an ack for this
	APLSendKVPDirect( transID, MY_PROFILE_ID,  MSSTATE_RFDOUT_CLUSTER_ID, EP_RFD, 
			  dest_sa, EP_COORD,         // dest EP and short addr
			  2, mybuf, GENERATE_TRANS_ID,
			  TRANS_SET, TRANS_UINT16, AN_ATTRIBUTE,DEFAULT_RADIUS,ROUTE_DISCOVERY_SUPPRESS );
	APLRemoveFrame();// don't wait for ACK
	lastShortAddrUpdate = TickGet();
      }
    }
  }
}


//RFD has to explicity request messages from coordinator
// when this returns true we will keep on processing
// don't bother waiting for response or ack'ing, just send it
// since we resend in a short time anyway

void  RFD_Request_Messages(void){

  APLSetEP(hRfd);
  // request messages from coord
  if (APLIsPutReady() ) {
    APLRequestMessages();
  }
}

#endif

⌨️ 快捷键说明

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