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

📄 evboard.c

📁 * "Copyright (c) 2006 Robert B. Reese ("AUTHOR")" * All rights reserved. * (R. Reese, reese@ece.
💻 C
📖 第 1 页 / 共 2 页
字号:
      // 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);
            rannum--;
         }//delay = aUnitBackoff * rannum
        //now do backoff
       start_tick = halGetMACTimer();
        while (halMACTimerNowDelta(start_tick) < delay);
      }
      //check CCA
      if (PIN_CCA)  break;
      nb++;
      be++;
      if (be > aMaxBE) be =aMaxBE;
   }while (nb <= macMaxCSMABackoffs);
  return;
}

#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;       
      }

     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;
     }  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;
      }


      phyTxStartCallBack();
     //wait for finish
      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;
      }
     //do callBacks signaling the end
     phyTxEndCallBack();
     macTxCallback();   
     DEBUG_STRING(DBG_ERR,"txpacket: Tx success\n");

halSendPacket_exit:
	// Turn interrupts back on
    

   return(return_status);
}


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]


   if (!CCP2IF) return;
   CCP2IF = 0;
    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.
    
      //select FIFO 
      SPI_ENABLE();
      FASTSPI_RX_ADDR(CC2420_RXFIFO);
      SSPBUF;
     

     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;
          phyRxCallback();
          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 + -