INTERRUPT_FUNC spp_rf_IRQ(void)
{
BYTE flen;
BYTE enabledAndActiveInterrupt;
BYTE *ptr, *rx_frame;
BYTE ack_bytes[5];
BYTE crc;
#define fcflsb ack_bytes[0]
#define fcfmsb ack_bytes[1]
#define dstmode ack_bytes[2]
#define srcmode ack_bytes[3]
INT_GLOBAL_ENABLE(INT_OFF); //关闭全局中断
enabledAndActiveInterrupt = RFIF; //读取RF中断标志
RFIF = 0x00; //清空RF中断标志
INT_SETFLAG_RF(INT_CLR); // Clear MCU interrupt flag
enabledAndActiveInterrupt &= RFIM; //读取RF中断屏蔽(控制RF中断使能)
// 处理受到的数据
if(enabledAndActiveInterrupt & IRQ_FIFOP) //数据溢出中断
{
DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_RXRCV );
//if last packet has not been processed, we just
//read it but ignore it.
ptr = NULL; //temporary pointer
flen = RFD & 0x7f; //读数据长度(注意帧的格式)
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;
ack_bytes[1] = RFD; //LSB Frame Control Field
ack_bytes[2] = RFD; //MSB Frame Control Field
ack_bytes[3] = RFD; //dsn
ack_bytes[4] = RFD; //RSSI
crc = RFD;
//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
fcflsb = RFD;
fcfmsb = RFD;
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 = MemAlloc(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) { *ptr = RFD; 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
MemFree(rx_frame);
}
}
}
//flush any remaining bytes
do_rxflush:
ISFLUSHRX;
ISFLUSHRX;
//don't know why, but the RF flags have to be cleared AFTER a read is done.
RFIF = 0x00;
INT_SETFLAG_RF(INT_CLR); // Clear MCU interrupt flag
//don't know why, but the interrupt mask has to be set again here for some reason.
//the processor receives packets, but does not generate an interrupt
RFIM |= IRQ_FIFOP;
} //end receive interrupt (FIFOP)
// Transmission of a packet is finished. Enabling reception of ACK if required.
if(enabledAndActiveInterrupt & IRQ_TXDONE)
{
//Finished TX, do call back
DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_TXFIN );
phyTxEndCallBack();
macTxCallback();
// Clearing the tx done interrupt enable
RFIM &= ~IRQ_TXDONE;
}
usrIntCallback();
INT_GLOBAL_ENABLE(INT_ON);
#undef fcflsb
#undef fcfmsb
#undef dstmode
#undef srcmode
}
用户176826 2010-7-15 15:56