]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/cc2420/transmit/CC2420TransmitP.nc
Upstream commits to tos/chips/cc2420, Aug 7 2008 thru Jul 16 2009, except one.
[tinyos-2.x.git] / tos / chips / cc2420 / transmit / CC2420TransmitP.nc
index 8bd55a4ddc647dad40956445e4aa5921ab01ef0f..a8367e54c99f0342df952fd65fda1dc59baf2e5c 100644 (file)
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2005-2006 Arch Rock Corporation
+/* 
+ * Copyright (c) 2005-2006 Arch Rock Corporation 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 
 #include "CC2420.h"
+#include "CC2420TimeSyncMessage.h"
 #include "crc.h"
 #include "message.h"
 
-module CC2420TransmitP {
+module CC2420TransmitP @safe() {
 
   provides interface Init;
   provides interface StdControl;
   provides interface CC2420Transmit as Send;
   provides interface RadioBackoff;
-  provides interface RadioTimeStamping as TimeStamp;
   provides interface ReceiveIndicator as EnergyIndicator;
   provides interface ReceiveIndicator as ByteIndicator;
   
   uses interface Alarm<T32khz,uint32_t> as BackoffTimer;
   uses interface CC2420Packet;
   uses interface CC2420PacketBody;
+  uses interface PacketTimeStamp<T32khz,uint32_t>;
+  uses interface PacketTimeSyncOffset;
   uses interface GpioCapture as CaptureSFD;
   uses interface GeneralIO as CCA;
   uses interface GeneralIO as CSN;
@@ -95,7 +97,7 @@ implementation {
     CC2420_ABORT_PERIOD = 320
   };
   
-  norace message_t *m_msg;
+  norace message_t * ONE_NOK m_msg;
   
   norace bool m_cca;
   
@@ -124,7 +126,7 @@ implementation {
   
 
   /***************** Prototypes ****************/
-  error_t send( message_t *p_msg, bool cca );
+  error_t send( message_t * ONE p_msg, bool cca );
   error_t resend( bool cca );
   void loadTXFIFO();
   void attemptSend();
@@ -167,7 +169,7 @@ implementation {
 
 
   /**************** Send Commands ****************/
-  async command error_t Send.send( message_t* p_msg, bool useCca ) {
+  async command error_t Send.send( message_t* ONE p_msg, bool useCca ) {
     return send( p_msg, useCca );
   }
 
@@ -234,7 +236,12 @@ implementation {
   }
   
   
-  
+  inline uint32_t getTime32(uint16_t time)
+  {
+    uint32_t recent_time=call BackoffTimer.getNow();
+    return recent_time + (int16_t)(time - recent_time);
+  }
+
   /**
    * The CaptureSFD event is actually an interrupt from the capture pin
    * which is connected to timing circuitry and timer modules.  This
@@ -249,14 +256,32 @@ implementation {
    * would have picked up and executed had our microcontroller been fast enough.
    */
   async event void CaptureSFD.captured( uint16_t time ) {
+    uint32_t time32;
+    uint8_t sfd_state = 0;
     atomic {
+      time32 = getTime32(time);
       switch( m_state ) {
         
       case S_SFD:
         m_state = S_EFD;
         sfdHigh = TRUE;
+        // in case we got stuck in the receive SFD interrupts, we can reset
+        // the state here since we know that we are not receiving anymore
+        m_receiving = FALSE;
         call CaptureSFD.captureFallingEdge();
-        signal TimeStamp.transmittedSFD( time, m_msg );
+        call PacketTimeStamp.set(m_msg, time32);
+        if (call PacketTimeSyncOffset.isSet(m_msg)) {
+           uint8_t absOffset = sizeof(message_header_t)-sizeof(cc2420_header_t)+call PacketTimeSyncOffset.get(m_msg);
+           timesync_radio_t *timesync = (timesync_radio_t *)((nx_uint8_t*)m_msg+absOffset);
+           // set timesync event time as the offset between the event time and the SFD interrupt time (TEP  133)
+           *timesync  -= time32;
+           call CSN.clr();
+           call TXFIFO_RAM.write( absOffset, (uint8_t*)timesync, sizeof(timesync_radio_t) );
+           call CSN.set();
+           //restoring the event time to the original value
+           *timesync  += time32;
+        }
+
         if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
           // This is an ack packet, don't release the chip's SPI bus lock.
           abortSpiRelease = TRUE;
@@ -264,16 +289,11 @@ implementation {
         releaseSpiResource();
         call BackoffTimer.stop();
 
-        
-        if ( ( ( (call CC2420PacketBody.getHeader( m_msg ))->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == IEEE154_TYPE_DATA ) {
-          (call CC2420PacketBody.getMetadata( m_msg ))->time = time;
-        }
-        
         if ( call SFD.get() ) {
           break;
         }
         /** Fall Through because the next interrupt was already received */
-        
+
       case S_EFD:
         sfdHigh = FALSE;
         call CaptureSFD.captureRisingEdge();
@@ -291,27 +311,42 @@ implementation {
         /** Fall Through because the next interrupt was already received */
         
       default:
-        if ( !m_receiving ) {
+        /* this is the SFD for received messages */
+        if ( !m_receiving && sfdHigh == FALSE ) {
           sfdHigh = TRUE;
           call CaptureSFD.captureFallingEdge();
-          signal TimeStamp.receivedSFD( time );
-          call CC2420Receive.sfd( time );
+          // safe the SFD pin status for later use
+          sfd_state = call SFD.get();
+          call CC2420Receive.sfd( time32 );
           m_receiving = TRUE;
           m_prev_time = time;
           if ( call SFD.get() ) {
             // wait for the next interrupt before moving on
             return;
           }
+          // if SFD.get() = 0, then an other interrupt happened since we
+          // reconfigured CaptureSFD! Fall through
         }
         
-        sfdHigh = FALSE;
-        call CaptureSFD.captureRisingEdge();
-        m_receiving = FALSE;
-        if ( time - m_prev_time < 10 ) {
-          call CC2420Receive.sfd_dropped();
+        if ( sfdHigh == TRUE ) {
+          sfdHigh = FALSE;
+          call CaptureSFD.captureRisingEdge();
+          m_receiving = FALSE;
+          /* if sfd_state is 1, then we fell through, but at the time of
+           * saving the time stamp the SFD was still high. Thus, the timestamp
+           * is valid.
+           * if the sfd_state is 0, then either we fell through and SFD
+           * was low while we safed the time stamp, or we didn't fall through.
+           * Thus, we check for the time between the two interrupts.
+           * FIXME: Why 10 tics? Seams like some magic number...
+           */
+          if ((sfd_state == 0) && (time - m_prev_time < 10) ) {
+            call CC2420Receive.sfd_dropped();
+            if (m_msg)
+              call PacketTimeStamp.clear(m_msg);
+          }
+          break;
         }
-        break;
-      
       }
     }
   }
@@ -336,7 +371,7 @@ implementation {
     uint8_t* ack_buf;
     uint8_t length;
 
-    if ( type == IEEE154_TYPE_ACK ) {
+    if ( type == IEEE154_TYPE_ACK && m_msg) {
       ack_header = call CC2420PacketBody.getHeader( ack_msg );
       msg_header = call CC2420PacketBody.getHeader( m_msg );
 
@@ -488,7 +523,7 @@ implementation {
    * @param *p_msg Pointer to the message that needs to be sent
    * @param cca TRUE if this transmit should use clear channel assessment
    */
-  error_t send( message_t* p_msg, bool cca ) {
+  error_t send( message_t* ONE p_msg, bool cca ) {
     atomic {
       if (m_state == S_CANCEL) {
         return ECANCEL;
@@ -654,7 +689,10 @@ implementation {
     
     m_tx_power = tx_power;
     
-    call TXFIFO.write( (uint8_t*)header, header->length - 1);
+    {
+      uint8_t tmpLen __DEPUTY_UNUSED__ = header->length - 1;
+      call TXFIFO.write(TCAST(uint8_t * COUNT(tmpLen), header), header->length - 1);
+    }
   }
   
   void signalDone( error_t err ) {
@@ -663,17 +701,5 @@ implementation {
     call ChipSpiResource.attemptRelease();
     signal Send.sendDone( m_msg, err );
   }
-  
-  
-  
-  /***************** Tasks ****************/
-
-  /***************** Defaults ****************/
-  default async event void TimeStamp.transmittedSFD( uint16_t time, message_t* p_msg ) {
-  }
-  
-  default async event void TimeStamp.receivedSFD( uint16_t time ) {
-  }
-
 }