📄 cc2420receivep.nc
字号:
atomic {
buf = (uint8_t*) &((ieee154_header_t*) m_rxFramePtr->header)->length;
rxFrameLength = ((ieee154_header_t*) m_rxFramePtr->header)->length;
switch( m_state ) {
case S_RX_LENGTH:
m_state = S_RX_FCF;
if ( rxFrameLength + 1 > m_bytes_left ) {
// Length of this packet is bigger than the RXFIFO, flush it out.
flush();
} else {
if ( !call FIFO.get() && !call FIFOP.get() ) {
//m_bytes_left -= rxFrameLength + 1;
flush();
}
//if(rxFrameLength <= MAC_PACKET_SIZE) {
if(rxFrameLength <= (sizeof(ieee154_header_t) - 1 + TOSH_DATA_LENGTH + 2)){
if(rxFrameLength > 0) {
if(rxFrameLength > SACK_HEADER_LENGTH) {
// This packet has an FCF byte plus at least one more byte to read
call RXFIFO.continueRead(buf + 1, SACK_HEADER_LENGTH);
} else {
// This is really a bad packet, skip FCF and get it out of here.
flush();
//m_state = S_RX_PAYLOAD;
//call RXFIFO.continueRead(buf + 1, rxFrameLength);
}
} else {
// Length == 0; start reading the next packet
flush();
/* atomic receivingPacket = FALSE;*/
/* call CSN.set();*/
/* call SpiResource.release();*/
/* waitForNextPacket();*/
}
} else {
// Length is too large; we have to flush the entire Rx FIFO
flush();
}
}
break;
case S_RX_FCF:
if (call FrameUtility.getMHRLength(buf[1], buf[2], &m_mhrLen) != SUCCESS ||
m_mhrLen > rxFrameLength - 2) {
// header size incorrect
flush();
break;
} else if (m_mhrLen > SACK_HEADER_LENGTH) {
m_state = S_RX_HEADER;
call RXFIFO.continueRead(buf + 1 + SACK_HEADER_LENGTH,
m_mhrLen - SACK_HEADER_LENGTH);
break;
} else {
// complete header has been read: fall through
}
// fall through
case S_RX_HEADER:
// JH: we are either using HW ACKs (normal receive mode) or don't ACK any
// packets (promiscuous mode)
// Didn't flip CSn, we're ok to continue reading.
if ((rxFrameLength - m_mhrLen - 2) > TOSH_DATA_LENGTH) // 2 for CRC
flush();
else {
m_state = S_RX_PAYLOAD;
call RXFIFO.continueRead((uint8_t*) m_rxFramePtr->data, rxFrameLength - m_mhrLen);
}
break;
case S_RX_PAYLOAD:
call CSN.set();
if(!m_missed_packets) {
// Release the SPI only if there are no more frames to download
call SpiResource.release();
}
if ( m_timestamp_size ) {
if ( rxFrameLength > 4 ) {
//((ieee154_metadata_t*) m_rxFramePtr->metadata)->timestamp = m_timestamp_queue[ m_timestamp_head ];
memcpy(&m_timestamp, &m_timestamp_queue[ m_timestamp_head ], sizeof(ieee154_timestamp_t) );
m_timestampValid = TRUE;
m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;
m_timestamp_size--;
}
} else {
/* metadata->time = 0xffff;*/
m_timestampValid = FALSE;
//((ieee154_metadata_t*) m_rxFramePtr->metadata)->timestamp = IEEE154_INVALID_TIMESTAMP;
}
// We may have received an ack that should be processed by Transmit
// buf[rxFrameLength] >> 7 checks the CRC
if ( ( m_rxFramePtr->data[ rxFrameLength - m_mhrLen - 1 ] >> 7 ) && rx_buf ) {
uint8_t type = ((ieee154_header_t*) m_rxFramePtr->header)->mhr[0] & 0x07;
/* signal CC2420Receive.receive( type, m_p_rx_buf );*/
signal CC2420Receive.receive( type, m_rxFramePtr );
/* if ( type == IEEE154_TYPE_DATA ) {*/
if ( (type != IEEE154_TYPE_ACK || call CC2420Config.isPromiscuousModeEnabled())
&& !m_stop) {
post receiveDone_task();
return;
}
}
waitForNextPacket();
break;
default:
atomic receivingPacket = FALSE;
call CSN.set();
call SpiResource.release();
if (m_stop){
continueStop();
return;
}
break;
}
}
}
async event void RXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {
}
/***************** Tasks *****************/
/**
* Fill in metadata details, pass the packet up the stack, and
* get the next packet.
*/
task void receiveDone_task() {
uint8_t payloadLen = ((ieee154_header_t*) m_rxFramePtr->header)->length - m_mhrLen - 2;
ieee154_metadata_t *metadata = (ieee154_metadata_t*) m_rxFramePtr->metadata;
atomic ASSERT(m_state != S_STOPPED);
((ieee154_header_t*) m_rxFramePtr->header)->length = m_rxFramePtr->data[payloadLen+1] & 0x7f; // temp. LQI
metadata->rssi = m_rxFramePtr->data[payloadLen];
metadata->linkQuality = ((ieee154_header_t*) m_rxFramePtr->header)->length; // copy back
((ieee154_header_t*) m_rxFramePtr->header)->length = payloadLen;
if (m_timestampValid)
metadata->timestamp = call ReferenceTime.toLocalTime(&m_timestamp);
else
metadata->timestamp = IEEE154_INVALID_TIMESTAMP;
m_rxFramePtr = signal CC2420Rx.received(m_rxFramePtr, &m_timestamp);
/* cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf );*/
/* uint8_t* buf = (uint8_t*) call CC2420PacketBody.getHeader( m_p_rx_buf );;*/
/* */
/* metadata->crc = buf[ rxFrameLength ] >> 7;*/
/* metadata->rssi = buf[ rxFrameLength - 1 ];*/
/* metadata->lqi = buf[ rxFrameLength ] & 0x7f;*/
// async event message_t* receiveDone( message_t *data );
/* m_p_rx_buf = signal Receive.receive( m_rxFramePtrm_p_rx_buf, m_p_rx_buf->data, */
/* rxFrameLength );*/
atomic receivingPacket = FALSE;
waitForNextPacket();
}
/****************** Functions ****************/
/**
* Attempt to acquire the SPI bus to receive a packet.
*/
void beginReceive() {
atomic {
if (m_state == S_STOPPED || m_stop){
return;
}
m_state = S_RX_LENGTH;
receivingPacket = TRUE;
if(call SpiResource.isOwner()) {
receive();
} else if (call SpiResource.immediateRequest() == SUCCESS) {
receive();
} else {
call SpiResource.request();
}
}
}
/**
* Flush out the Rx FIFO
*/
void flush() {
reset_state();
call CSN.set();
call CSN.clr();
call SFLUSHRX.strobe();
call SFLUSHRX.strobe();
call CSN.set();
call SpiResource.release();
waitForNextPacket();
}
/**
* The first byte of each packet is the length byte. Read in that single
* byte, and then read in the rest of the packet. The CC2420 could contain
* multiple packets that have been buffered up, so if something goes wrong,
* we necessarily want to flush out the FIFO unless we have to.
*/
void receive() {
call CSN.set();
call CSN.clr();
//call RXFIFO.beginRead( (uint8_t*)(call CC2420PacketBody.getHeader( m_p_rx_buf )), 1 );
call RXFIFO.beginRead( &((ieee154_header_t*) m_rxFramePtr->header)->length, 1 );
}
/**
* Determine if there's a packet ready to go, or if we should do nothing
* until the next packet arrives
*/
void waitForNextPacket() {
atomic {
if ( m_state == S_STOPPED) {
call SpiResource.release();
return;
}
receivingPacket = FALSE;
if (m_stop){
continueStop();
return;
}
if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) {
// A new packet is buffered up and ready to go
if ( m_missed_packets ) {
m_missed_packets--;
}
beginReceive();
} else {
// Wait for the next packet to arrive
m_state = S_STARTED;
m_missed_packets = 0;
call SpiResource.release();
}
}
}
/**
* Reset this component
*/
void reset_state() {
m_bytes_left = RXFIFO_SIZE;
atomic receivingPacket = FALSE;
m_timestamp_head = 0;
m_timestamp_size = 0;
m_missed_packets = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -