]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/cc2420_tkn154/CC2420ReceiveP.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / chips / cc2420_tkn154 / CC2420ReceiveP.nc
index 04860924a488ddde3f10208aa7eec13e79484eb1..fddf5dd68188fa47aff9b99ea45b26ad69a970a8 100644 (file)
@@ -42,7 +42,6 @@ module CC2420ReceiveP {
   provides interface CC2420AsyncSplitControl as AsyncSplitControl; 
   provides interface CC2420Receive;
   provides interface CC2420Rx;
-/*  provides interface ReceiveIndicator as PacketIndicator;*/
 
   uses interface GeneralIO as CSN;
   uses interface GeneralIO as FIFO;
@@ -54,15 +53,12 @@ module CC2420ReceiveP {
   uses interface CC2420Strobe as SACK;
   uses interface CC2420Strobe as SFLUSHRX;
   uses interface CC2420Strobe as SRXON;
-  uses interface CC2420Strobe as SACKPEND; // JH: ACKs must have pending flag set
+  uses interface CC2420Strobe as SACKPEND; 
   uses interface CC2420Register as MDMCTRL1;
   uses interface ReferenceTime;
   uses interface FrameUtility;
   uses interface CC2420Config;
-/*  uses interface CC2420Packet;*/
-/*  uses interface CC2420PacketBody;*/
-  
-  uses interface Leds;
+  uses interface CC2420Ram as RXFIFO_RAM;
 }
 
 implementation {
@@ -70,7 +66,6 @@ implementation {
   typedef enum {
     S_STOPPED,
     S_STARTING,
-    S_STARTING_FLUSHRX,
     S_STARTED,
     S_RX_LENGTH,
     S_RX_FCF,
@@ -85,8 +80,8 @@ implementation {
     SACK_HEADER_LENGTH = 3,
   };
 
-  ieee154_reftime_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
-  ieee154_reftime_t m_timestamp;
+  ieee154_timestamp_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
+  ieee154_timestamp_t m_timestamp;
   norace bool m_timestampValid;
   
   uint8_t m_timestamp_head;
@@ -125,7 +120,6 @@ implementation {
   void flush();
   void switchToUnbufferedMode();
   void switchToBufferedMode();
-  void startingSpiReserved();
   void continueStart();
   void continueStop();
   task void stopContinueTask();
@@ -139,79 +133,45 @@ implementation {
     return SUCCESS;
   }
 
-  /***************** AsyncSplitControl ****************
-   * IMPORTANT: when AsyncSplitControl.start is called, 
-   * the radio MUST be off !
+  /***************** AsyncSplitControl ****************/
+  /* NOTE: AsyncSplitControl does not switch the state of the radio 
+   * hardware (i.e. it does not put the radio in Rx mode, this has to
+   * be done by the caller through a separate interface/component). 
    */
-  async command error_t AsyncSplitControl.start()
-  {
-    atomic {
-      if (m_state != S_STOPPED){
-        call Leds.led0On();
-        return FAIL;
-      } else {
-        m_state = S_STARTING;
-        if (call SpiResource.isOwner()){ 
-          call Leds.led0On(); // internal error (debug) !
-          startingSpiReserved();
-        }
-        if (call SpiResource.immediateRequest() == SUCCESS)
-          startingSpiReserved();
-        else
-          call SpiResource.request();        
-      }
-    }
-    return SUCCESS;
-  }
 
-  void startingSpiReserved()
+  /** 
+   * AsyncSplitControl.start should be called before radio
+   * is switched to Rx mode (or at least early enough before
+   * a packet has been received, i.e. before FIFOP changes)
+   */
+  async command error_t AsyncSplitControl.start()
   {
     atomic {
-      if (!call FIFOP.get() || call FIFO.get()){ // FIFOP is inverted
-        // there is something in RXFIFO: flush it out 
-        // the datasheet says at least one byte should 
-        // be read before flushing
-        m_state = S_STARTING_FLUSHRX;
-        call CSN.set();
-        call CSN.clr();
-        call RXFIFO.beginRead( &m_dummy, 1 ); // will continue in continueFlushStart()
-        return;
+      if ( !call FIFO.get() && !call FIFOP.get() ){
+        // RXFIFO has some data (remember: FIFOP is inverted)
+        // the problem is that this messses up the timestamping
+        // so why don't we flush here ourselves? 
+        // because we don't own the SPI...
+        return FAIL; 
       }
-    }
-    continueStart();
-  }
-
-
-  void continueFlushStart()
-  {
-    atomic {
-      call CSN.set();
-      call CSN.clr();
-      call SFLUSHRX.strobe();
-      call SFLUSHRX.strobe();
-      call CSN.set();
-    }
-    continueStart();
-  }
-  
-  void continueStart()
-  {
-    // RXFIFO is empty
-    if (!call FIFOP.get() || call FIFO.get()){
-      call Leds.led0On();
-    }
-    atomic {
+      ASSERT(m_state == S_STOPPED);
       reset_state();
       m_state = S_STARTED;
+      call InterruptFIFOP.enableFallingEdge(); // ready!
     }
-    call SpiResource.release();
-    call InterruptFIFOP.enableFallingEdge();
-    signal AsyncSplitControl.startDone(SUCCESS);
+    return SUCCESS;
   }
 
-  /***************** AsyncSplitControl ****************
+  /* AsyncSplitControl.stop:
+   *
    * IMPORTANT: when AsyncSplitControl.stop is called, 
-   * the radio MUST NOT be off !
+   * then either
+   * 1) the radio MUST still be in RxMode
+   * 2) it was never put in RxMode after  
+   *    AsyncSplitControl.start() was called
+   *
+   * => The radio may be switched off only *after* the
+   * stopDone() event was signalled.
    */
   async command error_t AsyncSplitControl.stop()
   {
@@ -222,9 +182,9 @@ implementation {
         m_stop = TRUE;
         call InterruptFIFOP.disable();
         if (!receivingPacket)
-          continueStop();
-        // else stopContinueTask will be posted after 
-        // current Rx operation is finished, because m_stop is set
+          continueStop(); // it is safe to stop now
+        // else continueStop will be called after 
+        // current Rx operation is finished
       }
     }
     return SUCCESS;
@@ -233,6 +193,9 @@ implementation {
   void continueStop()
   {
     atomic {
+      if (!m_stop){
+        return;
+      }
       m_stop = FALSE;
       m_state = S_STOPPED;
     }
@@ -241,49 +204,24 @@ implementation {
 
   task void stopContinueTask()
   {
-    if (receivingPacket){
-      call Leds.led0On();
-    }
+    ASSERT(receivingPacket != TRUE);
     call SpiResource.release(); // may fail
     atomic m_state = S_STOPPED;
     signal AsyncSplitControl.stopDone(SUCCESS);
   }
 
-  void switchToUnbufferedMode()
-  {
-    uint16_t mdmctrol1;
-    call CSN.set();
-    call CSN.clr();
-    call MDMCTRL1.read(&mdmctrol1);
-    mdmctrol1 &= ~0x03;
-    mdmctrol1 |= 0x01;
-    call MDMCTRL1.write(mdmctrol1);
-    call CSN.set();
-  }
-
-  void switchToBufferedMode()
-  {
-    uint16_t mdmctrol1;
-    call CSN.set();
-    call CSN.clr();
-    call MDMCTRL1.read(&mdmctrol1);
-    mdmctrol1 &= ~0x03;
-    call MDMCTRL1.write(mdmctrol1);
-    call CSN.set();
-  }
-
   /***************** CC2420Receive Commands ****************/
   /**
    * Start frame delimiter signifies the beginning/end of a packet
    * See the CC2420 datasheet for details.
    */
-  async command void CC2420Receive.sfd( ieee154_reftime_t *time ) {
+  async command void CC2420Receive.sfd( ieee154_timestamp_t *time ) {
     if (m_state == S_STOPPED)
       return;
     if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {
       uint8_t tail =  ( ( m_timestamp_head + m_timestamp_size ) % 
                         TIMESTAMP_QUEUE_SIZE );
-      memcpy(&m_timestamp_queue[ tail ], time, sizeof(ieee154_reftime_t) );
+      memcpy(&m_timestamp_queue[ tail ], time, sizeof(ieee154_timestamp_t) );
       m_timestamp_size++;
     }
   }
@@ -314,39 +252,12 @@ implementation {
     atomic {
       switch (m_state)
       {
-        case S_STARTING: startingSpiReserved(); break;
-        case S_STARTING_FLUSHRX: // fall through
-        case S_STOPPED: call Leds.led0On(); 
-                        call SpiResource.release(); break;
+        case S_STOPPED: ASSERT(0); break; // this should never happen!
         default: receive();
       }
     }
   }
   
-  uint8_t mhrLength(uint8_t *fcf)
-  {
-    uint8_t idCompression;
-    uint8_t len = MHR_INDEX_ADDRESS;
-    if (fcf[MHR_INDEX_FC1] & FC1_SECURITY_ENABLED)
-      return 0xFF; // not supported 
-    idCompression = (fcf[0] & FC1_PAN_ID_COMPRESSION);
-    if (fcf[MHR_INDEX_FC2] & 0x08){ // short or ext. address
-      len += 4; // pan id + short address
-      if (fcf[MHR_INDEX_FC2] & 0x04) // ext. address
-        len += 6; // diff to short address
-    }
-    if (fcf[MHR_INDEX_FC2] & 0x80){ // short or ext. address
-      len += 2;
-      if (!idCompression)
-        len += 2;
-      if (fcf[MHR_INDEX_FC2] & 0x40) // ext. address
-        len += 6; // diff to short address
-    }
-    return len;
-  }
-    
-  
   /***************** RXFIFO Events ****************/
   /**
    * We received some bytes from the SPI bus.  Process them in the context
@@ -441,9 +352,9 @@ implementation {
       }
       
       if ( m_timestamp_size ) {
-        if ( rxFrameLength > 10 ) {
+        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_reftime_t) );
+          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--;
@@ -471,8 +382,6 @@ implementation {
       waitForNextPacket();
       break;
 
-    case S_STARTING_FLUSHRX: continueFlushStart(); break;
-      
     default:
       atomic receivingPacket = FALSE;
       call CSN.set();
@@ -500,12 +409,7 @@ implementation {
     uint8_t payloadLen = ((ieee154_header_t*) m_rxFramePtr->header)->length - m_mhrLen - 2;
     ieee154_metadata_t *metadata = (ieee154_metadata_t*) m_rxFramePtr->metadata;
 
-    atomic {
-      if (m_state == S_STOPPED){
-        call Leds.led0On();
-        return;
-      }
-    }
+    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
@@ -538,8 +442,7 @@ implementation {
    */
   void beginReceive() { 
     atomic {
-      if ( m_state == S_STOPPED){
-        call Leds.led0On();
+      if (m_state == S_STOPPED || m_stop){
         return;
       }
       m_state = S_RX_LENGTH;
@@ -591,11 +494,11 @@ implementation {
    */
   void waitForNextPacket() {
     atomic {
-      receivingPacket = FALSE;
       if ( m_state == S_STOPPED) {
         call SpiResource.release();
         return;
       }
+      receivingPacket = FALSE;
       if (m_stop){
         continueStop();
         return;