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

📄 evboard.c

📁 zigbee 协议堆栈 stack(简化协议)
💻 C
📖 第 1 页 / 共 2 页
字号:
	FASTSPI_STROBE(CC2420_SFLUSHRX);
	
    // Initialize the FIFOP external interrupt
    FIFOP_INT_INIT();
    ENABLE_FIFOP_INT();

    RESTORE_GLOBAL_INTERRUPT(intStatus);
    
	return(LRWPAN_STATUS_SUCCESS);
}

void halFlushRXFIFO(void){
	
 	BYTE intStatus;

   	SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus) ;
   	FASTSPI_STROBE(CC2420_SFLUSHRX);
   	FASTSPI_STROBE(CC2420_SFLUSHRX);
  	RESTORE_GLOBAL_INTERRUPT(intStatus);
}

//regardless of what happens here, we will try TXONCCA after this returns.
void doIEEE_backoff(void) {
	
    BYTE be, nb, tmp, rannum;
    UINT32  delay, start_tick;
  
   	be = aMinBE;
   	nb = 0;
   	
  do {
      if (be) {
        //do random delay
        tmp = be;
        //compute new delay
        delay = 1;
        
        while (tmp) {
           delay = delay << 1;  //delay = 2**be;
           tmp--;
        }
        
        rannum =  halGetRandomByte() & (delay-1); //rannum will be between 0 and delay-1
        delay = 0;
        while (rannum) {
            delay  += SYMBOLS_TO_MACTICKS(aUnitBackoffPeriod); //20 symbols...320us
            rannum--;
        }//delay = aUnitBackoff * rannum
        
        //now do backoff
        start_tick = halGetMACTimer();
        while (halMACTimerNowDelta(start_tick) < delay);
      }
      
      //check CCA
      if (CCA_IS_1) break; //...channel is clear
      nb++;
      be++;
      if (be > aMaxBE) be =aMaxBE;
   }
   while (nb <= macMaxCSMABackoffs);
   
  return;
}

//Send packet
#define TX_TIMEOUT 100   //in ms, overkill for waiting for TX to be ready
LRWPAN_STATUS_ENUM halSendPacket(BYTE flen, BYTE *frm)
{
   	WORD frameControlField;
    BOOL success;
    BYTE errflag;
    BYTE spiStatusByte;
    BYTE intStatus;
    BYTE return_status;
    UINT32 start_tick;
   	BYTE len;

    //dbgPrintPacket(frm, flen);
   	// Turn off global interrupts to avoid interference on the SPI interface
  
   	DEBUG_STRING(DBG_INFO, "TX PKT Size: ");
   	DEBUG_UINT8(DBG_INFO,flen + PACKET_FOOTER_SIZE);
   	DEBUG_STRING(DBG_INFO,"\n");
   
   	if ((flen + PACKET_FOOTER_SIZE)> 127) {
    	//packet size is too large!
     	return(LRWPAN_STATUS_PHY_TX_PKT_TOO_BIG);
   	}
  
   	return_status = LRWPAN_STATUS_SUCCESS;
    errflag = 0;
    
halSendPacket_1:

    start_tick = halGetMACTimer();
    do {
      	if ( !((FIFOP_IS_1 || SFD_IS_1))) break;
    } 
    while (halMACTimerNowDelta(start_tick) < MSECS_TO_MACTICKS(TX_TIMEOUT));
    // Wait until the transceiver is idle
    
    if  ((FIFOP_IS_1) || (SFD_IS_1)) {	
        if (!errflag) {
            //we are stuck. lets try flushing the RXFIFO, try this again
            halFlushRXFIFO();
            errflag = 1;
            goto halSendPacket_1;  
        } else {
            //give it up.
            DEBUG_STRING(DBG_ERR,"txpacket: unable to tx, stuck in receive mode\n");
            return(LRWPAN_STATUS_PHY_TX_START_FAILED);
        }
    }
   
    SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus);
    
    // Flush the TX FIFO just in case...
    FASTSPI_STROBE(CC2420_SFLUSHTX);
    RESTORE_GLOBAL_INTERRUPT(intStatus); 

    //load up the FIFO
    //total length, does not include length byte itself
    //last two bytes are the FCS bytes that are added automatically
    len = flen +  PACKET_FOOTER_SIZE;

    // Write the packet to the TX FIFO 
    SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus) ;
    FASTSPI_WRITE_FIFO((BYTE*)&len, 1);               	// Packet length   
    FASTSPI_WRITE_FIFO((BYTE*) frm, flen);  			// Payload
    RESTORE_GLOBAL_INTERRUPT(intStatus); 

    // Wait for the RSSI value to become valid
    start_tick = halGetMACTimer();
    do {
        SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus) ;
        FASTSPI_UPD_STATUS(spiStatusByte);
        RESTORE_GLOBAL_INTERRUPT(intStatus);
        if (spiStatusByte & BM(CC2420_RSSI_VALID)) break;
    }  
    while (halMACTimerNowDelta(start_tick) < MSECS_TO_MACTICKS(TX_TIMEOUT));

    if (!(spiStatusByte & BM(CC2420_RSSI_VALID)) ) {
       DEBUG_STRING(DBG_ERR,"txpacket: rssi never went valid\n");
       //this is a serious error, lets reset the radio before returning
       halResetRadio();
       return_status = LRWPAN_STATUS_PHY_TX_START_FAILED;
       goto halSendPacket_exit;
    }
	
	//CSMA-CA
    doIEEE_backoff();

	// TX begins after the CCA check has passed
    start_tick = halGetMACTimer();
    do {
        SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus) ;
		FASTSPI_STROBE(CC2420_STXONCCA);
		FASTSPI_UPD_STATUS(spiStatusByte);
        RESTORE_GLOBAL_INTERRUPT(intStatus); 
		halWaitUs(50);
	    halWaitUs(50);
	    
        if (spiStatusByte & BM(CC2420_TX_ACTIVE)) break;
    }
    while (halMACTimerNowDelta(start_tick) < MSECS_TO_MACTICKS(TX_TIMEOUT));
    
    if (! (spiStatusByte & BM(CC2420_TX_ACTIVE))) {
       DEBUG_STRING(DBG_ERR,"txpacket: TXONCCA failed to start\n");
       return_status = LRWPAN_STATUS_PHY_TX_START_FAILED;
       goto halSendPacket_exit;
    }

	// Wait for the transmission to begin before exiting (makes sure that this function cannot be called
	// a second time, and thereby cancelling the first transmission (observe the FIFOP + SFD test above).
    start_tick = halGetMACTimer();
    do {
	  	if (SFD_IS_1) break; //after SFD is transmitted
    }
    while (halMACTimerNowDelta(start_tick) < MSECS_TO_MACTICKS(TX_TIMEOUT));

    if (!(SFD_IS_1)) {
       DEBUG_STRING(DBG_ERR,"txpacket: Tx failed to start\n");
       return_status = LRWPAN_STATUS_PHY_TX_START_FAILED;
       goto halSendPacket_exit;
    }

    // Link to PHY Layer - Start
    phyTxStartCallBack();
    
    // Wait for transmission is finished
    do {
       	if (!((FIFOP_IS_1 || SFD_IS_1))) break;
    }  
    while (halMACTimerNowDelta(start_tick) < MSECS_TO_MACTICKS(TX_TIMEOUT ) );
    
    // Wait until the transceiver is idle
    if  ((FIFOP_IS_1) || (SFD_IS_1)) {
         DEBUG_STRING(DBG_ERR,"txpacket: Tx failed to end\n");
         return_status = LRWPAN_STATUS_PHY_TX_FINISH_FAILED;
         goto halSendPacket_exit;
    }
    
    // Link to PHY Layer - End
    phyTxEndCallBack();
    // Link to MAC Layer - End
    macTxCallback();
    DEBUG_STRING(DBG_ERR,"txpacket: Tx success\n");

halSendPacket_exit:

	// Turn interrupts back on
    return(return_status);
}

//Receive Packet
//Called from MAC timer every 16us - Polling FIFOP interrupt
//Not really for now...I did this via interrupt vector on PORT1 (TMote Sky)
void evbRadioIntCallback(void) {
	
   	BYTE flen;
  	BYTE enabledAndActiveInterrupt;
  	BYTE *ptr, *rx_frame;
	BYTE ack_bytes[5];
  	BYTE crc;
  	
//define alternate names for readability in this function
#define  fcflsb  ack_bytes[0]
#define  fcfmsb  ack_bytes[1]
#define  dstmode ack_bytes[2]
#define  srcmode ack_bytes[3]

/* 
 *Polling ... trying to use of interupt vector for handling receiving packets
   	if (!(P1IFG & BV(FIFO_P))) {
   		//led_blue_toggle(); 
   		return; //no FIFOP interrupt pending
   	}
   	*/
   
   	CLEAR_FIFOP_INT();
    DEBUG_CHAR(DBG_ITRACE, DBG_CHAR_RXRCV);
    //read the packet, do not have to check for overflow, because we flush the frame buffer
    //at the end of the read anyway, which clears any overflow condition.
    
    //just select FIFO
    SPI_ENABLE();
    FASTSPI_RX_ADDR(CC2420_RXFIFO);
    SPI_RXBUF;
     
	ptr = NULL; //temporary pointer
	
    // Payload length
    FASTSPI_RX(flen);
	flen &= 0x7F; // Ignore MSB
    // Ignore the packet if the length is too short
    if (flen <  LRWPAN_ACKFRAME_LENGTH) {
       goto do_rxflush;
    }

    // Otherwise, if the length is valid, then proceed with the rest of the packet
    if (flen == LRWPAN_ACKFRAME_LENGTH) {
        //this should be an ACK.
        //read the packet, do not allocate space for it
        DEBUG_CHAR(DBG_ITRACE, DBG_CHAR_ACKPKT);
        ack_bytes[0]= flen;
        //read next four bytes into the ack buffer
        FASTSPI_RX(ack_bytes[1]);  //LSB Frame Control Field
        FASTSPI_RX(ack_bytes[2]);  //MSB Frame Control Field
        FASTSPI_RX(ack_bytes[3]);  //DSN
        FASTSPI_RX(ack_bytes[4]);  //RSSI
        FASTSPI_RX(crc); 
        
	  	//check CRC
        if (crc & 0x80){
          // CRC ok, perform callback if this is an ACK
          macRxCallback(ack_bytes, ack_bytes[4]);
      	} 
    }
    else {
        // Not an ack packet, lets do some more early rejection
        // that the CC2430 seems to not do that we want to do.
        
        // read the fcflsb, fcfmsb
        FASTSPI_RX(fcflsb);  
        FASTSPI_RX(fcfmsb);
        
        if (!local_radio_flags.bits.listen_mode) {
           	//only reject if not in listen mode
           	//get the src, dst addressing modes
           	srcmode = LRWPAN_GET_SRC_ADDR(fcfmsb);
          	dstmode = LRWPAN_GET_DST_ADDR(fcfmsb);
          if ((srcmode == LRWPAN_ADDRMODE_NOADDR) && (dstmode == LRWPAN_ADDRMODE_NOADDR)) {
              //reject this packet, no addressing info
              goto do_rxflush;
          }
        }

       	if (!macRxBuffFull()) {
        	//MAC TX buffer has room
        	//allocate new memory space
        	//read the length
        	rx_frame = ISRMemAlloc(flen+1);
        	ptr = rx_frame;
      	} else {
        	//MAC RX buffer is full
        	DEBUG_CHAR(DBG_ITRACE, DBG_CHAR_MACFULL);
      	}
      	
      	// at this point, if ptr is null, then either
      	// the MAC RX buffer is full or there is  no
      	// free memory for the new frame, or the packet is
      	// going to be rejected because of addressing info.
      	// In these cases, we need to
      	// throw the RX packet away
      	if (ptr == NULL) {
        	//just flush the bytes
        	goto do_rxflush;
      	} else {
        
        //save packet, including the length
        *ptr = flen; ptr++;
        //save the fcflsb, fcfmsb bytes
        *ptr = fcflsb; ptr++; flen--;
        *ptr = fcfmsb; ptr++; flen--;
        //get the rest of the bytes
        while (flen) {  FASTSPI_RX(*ptr);  flen--; ptr++; }
        	//do RX callback
        	//check the CRC
        	if (*(ptr-1) & 0x80) {
          		//CRC good
          		//change the RSSI byte from 2's complement to unsigned number
          		*(ptr-2) = *(ptr-2) + 0x80;
          
          		// Link to PHY Layer - not needed in this implementation...empty function
          		phyRxCallback();
          		// Link to MAC Layer
          		macRxCallback(rx_frame, *(ptr-2));
        	} else {
          		// CRC bad. Free the packet
         		ISRMemFree(rx_frame);
        	}
      	}
    }

//flush any remaining bytes
do_rxflush:
       	halWaitUs(1);
       	SPI_DISABLE();
       	FASTSPI_STROBE(CC2420_SFLUSHRX);
      	FASTSPI_STROBE(CC2420_SFLUSHRX); 
}

⌨️ 快捷键说明

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