]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/cc2420/receive/CC2420ReceiveP.nc
Upstream commits to tos/chips/cc2420, Aug 7 2008 thru Jul 16 2009, except one.
[tinyos-2.x.git] / tos / chips / cc2420 / receive / CC2420ReceiveP.nc
index 3a440356d65f8efa1209f7f4af2452c406fe7d13..5bd4e852e54eb383c85a67d7be24b94a80e15a47 100644 (file)
  */
 
 #include "IEEE802154.h"
+#include "message.h"
+#include "AM.h"
 
-module CC2420ReceiveP {
+module CC2420ReceiveP @safe() {
 
   provides interface Init;
   provides interface StdControl;
@@ -58,7 +60,8 @@ module CC2420ReceiveP {
   uses interface CC2420Packet;
   uses interface CC2420PacketBody;
   uses interface CC2420Config;
-  
+  uses interface PacketTimeStamp<T32khz,uint32_t>;
+
   uses interface Leds;
 }
 
@@ -78,8 +81,8 @@ implementation {
     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;
@@ -95,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;
   
@@ -107,6 +110,7 @@ implementation {
   void receive();
   void waitForNextPacket();
   void flush();
+  bool passesAddressCheck(message_t * ONE msg);
   
   task void receiveDone_task();
   
@@ -122,6 +126,10 @@ 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;
@@ -142,7 +150,7 @@ implementation {
    * 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 );
@@ -191,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 ) {
@@ -277,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 ) {
@@ -321,14 +338,20 @@ 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->lqi = buf[ rxFrameLength ] & 0x7f;
-    metadata->rssi = buf[ rxFrameLength - 1 ];
-    m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data, 
-                                         rxFrameLength );
-
     atomic receivingPacket = FALSE;
     waitForNextPacket();
   }
@@ -394,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 ) {
@@ -422,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);
+  }
 }