X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Fcc2420%2Freceive%2FCC2420ReceiveP.nc;h=5bd4e852e54eb383c85a67d7be24b94a80e15a47;hb=aa7578fd1472c62c1d22d0801fe0f55b36093bdf;hp=b1dfb86432f251444f3dc23acc70dec5271af41e;hpb=e72a6756a30fecdd80f4f1b1ee799749f1ab02a7;p=tinyos-2.x.git diff --git a/tos/chips/cc2420/receive/CC2420ReceiveP.nc b/tos/chips/cc2420/receive/CC2420ReceiveP.nc index b1dfb864..5bd4e852 100644 --- a/tos/chips/cc2420/receive/CC2420ReceiveP.nc +++ b/tos/chips/cc2420/receive/CC2420ReceiveP.nc @@ -36,7 +36,11 @@ * @version $Revision$ $Date$ */ -module CC2420ReceiveP { +#include "IEEE802154.h" +#include "message.h" +#include "AM.h" + +module CC2420ReceiveP @safe() { provides interface Init; provides interface StdControl; @@ -56,7 +60,8 @@ module CC2420ReceiveP { uses interface CC2420Packet; uses interface CC2420PacketBody; uses interface CC2420Config; - + uses interface PacketTimeStamp; + uses interface Leds; } @@ -73,11 +78,11 @@ implementation { enum { RXFIFO_SIZE = 128, TIMESTAMP_QUEUE_SIZE = 8, - FCF_LENGTH = 2, + SACK_HEADER_LENGTH = 7, }; - uint16_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ]; - + uint32_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ]; + uint8_t m_timestamp_head; uint8_t m_timestamp_size; @@ -93,7 +98,7 @@ implementation { norace uint8_t m_bytes_left; - norace message_t* m_p_rx_buf; + norace message_t* ONE_NOK m_p_rx_buf; message_t m_rx_buf; @@ -105,6 +110,7 @@ implementation { void receive(); void waitForNextPacket(); void flush(); + bool passesAddressCheck(message_t * ONE msg); task void receiveDone_task(); @@ -120,12 +126,14 @@ implementation { reset_state(); m_state = S_STARTED; atomic receivingPacket = FALSE; + /* Note: + We use the falling edge because the FIFOP polarity is reversed. + This is done in CC2420Power.startOscillator from CC2420ControlP.nc. + */ call InterruptFIFOP.enableFallingEdge(); } return SUCCESS; } - - command error_t StdControl.stop() { atomic { @@ -137,26 +145,12 @@ implementation { return SUCCESS; } - /***************** Receive Commands ****************/ - command void* Receive.getPayload(message_t* m, uint8_t* len) { - if (len != NULL) { - *len = ((uint8_t*) (call CC2420PacketBody.getHeader( m_p_rx_buf )))[0]; - } - return m->data; - } - - command uint8_t Receive.payloadLength(message_t* m) { - uint8_t* buf = (uint8_t*)(call CC2420PacketBody.getHeader( m_p_rx_buf )); - return buf[0]; - } - - /***************** CC2420Receive Commands ****************/ /** * Start frame delimiter signifies the beginning/end of a packet * See the CC2420 datasheet for details. */ - async command void CC2420Receive.sfd( uint16_t time ) { + async command void CC2420Receive.sfd( uint32_t time ) { if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) { uint8_t tail = ( ( m_timestamp_head + m_timestamp_size ) % TIMESTAMP_QUEUE_SIZE ); @@ -205,8 +199,8 @@ implementation { async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len, error_t error ) { cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf ); - cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf ); - uint8_t* buf = (uint8_t*) header; + uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t)); + uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header); rxFrameLength = buf[ 0 ]; switch( m_state ) { @@ -224,9 +218,9 @@ implementation { if(rxFrameLength <= MAC_PACKET_SIZE) { if(rxFrameLength > 0) { - if(rxFrameLength > FCF_LENGTH) { + if(rxFrameLength > SACK_HEADER_LENGTH) { // This packet has an FCF byte plus at least one more byte to read - call RXFIFO.continueRead(buf + 1, FCF_LENGTH); + call RXFIFO.continueRead(buf + 1, SACK_HEADER_LENGTH); } else { // This is really a bad packet, skip FCF and get it out of here. @@ -251,8 +245,20 @@ implementation { case S_RX_FCF: m_state = S_RX_PAYLOAD; + + /* + * The destination address check here is not completely optimized. If you + * are seeing issues with dropped acknowledgements, try removing + * the address check and decreasing SACK_HEADER_LENGTH to 2. + * The length byte and the FCF byte are the only two bytes required + * to know that the packet is valid and requested an ack. The destination + * address is useful when we want to sniff packets from other transmitters + * while acknowledging packets that were destined for our local address. + */ if(call CC2420Config.isAutoAckEnabled() && !call CC2420Config.isHwAutoAckDefault()) { if (((( header->fcf >> IEEE154_FCF_ACK_REQ ) & 0x01) == 1) + && ((header->dest == call CC2420Config.getShortAddr()) + || (header->dest == AM_BROADCAST_ADDR)) && ((( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7) == IEEE154_TYPE_DATA)) { // CSn flippage cuts off our FIFO; SACK and begin reading again call CSN.set(); @@ -260,15 +266,15 @@ implementation { call SACK.strobe(); call CSN.set(); call CSN.clr(); - call RXFIFO.beginRead(buf + 1 + FCF_LENGTH, - rxFrameLength - FCF_LENGTH); + call RXFIFO.beginRead(buf + 1 + SACK_HEADER_LENGTH, + rxFrameLength - SACK_HEADER_LENGTH); return; } } // Didn't flip CSn, we're ok to continue reading. - call RXFIFO.continueRead(buf + 1 + FCF_LENGTH, - rxFrameLength - FCF_LENGTH); + call RXFIFO.continueRead(buf + 1 + SACK_HEADER_LENGTH, + rxFrameLength - SACK_HEADER_LENGTH); break; case S_RX_PAYLOAD: @@ -279,16 +285,25 @@ implementation { call SpiResource.release(); } - if ( m_timestamp_size ) { - if ( rxFrameLength > 10 ) { - metadata->time = m_timestamp_queue[ m_timestamp_head ]; + //new packet is buffered up, or we don't have timestamp in fifo, or ack + if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() + || !m_timestamp_size + || rxFrameLength <= 10) { + call PacketTimeStamp.clear(m_p_rx_buf); + } + else { + if (m_timestamp_size==1) + call PacketTimeStamp.set(m_p_rx_buf, m_timestamp_queue[ m_timestamp_head ]); m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE; m_timestamp_size--; - } - } else { - metadata->time = 0xffff; + + if (m_timestamp_size>0) { + call PacketTimeStamp.clear(m_p_rx_buf); + m_timestamp_head = 0; + m_timestamp_size = 0; + } } - + // We may have received an ack that should be processed by Transmit // buf[rxFrameLength] >> 7 checks the CRC if ( ( buf[ rxFrameLength ] >> 7 ) && rx_buf ) { @@ -323,18 +338,24 @@ implementation { */ task void receiveDone_task() { cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf ); - uint8_t* buf = (uint8_t*) call CC2420PacketBody.getHeader( m_p_rx_buf );; + cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf); + uint8_t length = header->length; + uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t)); + uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header); + + metadata->crc = buf[ length ] >> 7; + metadata->lqi = buf[ length ] & 0x7f; + metadata->rssi = buf[ length - 1 ]; + + if (passesAddressCheck(m_p_rx_buf) && length >= CC2420_SIZE) { + m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data, + length - CC2420_SIZE); + } - metadata->crc = buf[ rxFrameLength ] >> 7; - metadata->rssi = buf[ rxFrameLength - 1 ]; - metadata->lqi = buf[ rxFrameLength ] & 0x7f; - m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data, - rxFrameLength ); - atomic receivingPacket = FALSE; waitForNextPacket(); } - + /****************** CC2420Config Events ****************/ event void CC2420Config.syncDone( error_t error ) { } @@ -396,6 +417,16 @@ implementation { } atomic receivingPacket = FALSE; + + /* + * The FIFOP pin here is high when there are 0 bytes in the RX FIFO + * and goes low as soon as there are bytes in the RX FIFO. The pin + * is inverted from what the datasheet says, and its threshold is 127. + * Whenever the FIFOP line goes low, as you can see from the interrupt + * handler elsewhere in this module, it means we received a new packet. + * If the line stays low without generating an interrupt, that means + * there's still more data to be received. + */ if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) { // A new packet is buffered up and ready to go if ( m_missed_packets ) { @@ -424,4 +455,17 @@ implementation { m_missed_packets = 0; } + /** + * @return TRUE if the given message passes address recognition + */ + bool passesAddressCheck(message_t *msg) { + cc2420_header_t *header = call CC2420PacketBody.getHeader( msg ); + + if(!(call CC2420Config.isAddressRecognitionEnabled())) { + return TRUE; + } + + return (header->dest == call CC2420Config.getShortAddr() + || header->dest == AM_BROADCAST_ADDR); + } }