📄 evboard.c
字号:
// 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 + -