]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/cc2420/transmit/CC2420TransmitP.nc
Previously reported timestamping bug was only fixed partially: *timesync was computed...
[tinyos-2.x.git] / tos / chips / cc2420 / transmit / CC2420TransmitP.nc
index 8bd55a4ddc647dad40956445e4aa5921ab01ef0f..bbf76f09f7f41464b70c0dcb09acf34596ea5f4d 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,14 @@ implementation {
   }
   
   
-  
+  inline uint32_t time16to32(uint16_t time, uint32_t recent_time)
+  {
+    if ((recent_time&0xFFFF)<time)
+      return ((recent_time-0x10000UL)&0xFFFF0000UL)|time;
+    else
+      return (recent_time&0xFFFF0000UL)|time;
+  }
+
   /**
    * The CaptureSFD event is actually an interrupt from the capture pin
    * which is connected to timing circuitry and timer modules.  This
@@ -249,6 +258,7 @@ implementation {
    * would have picked up and executed had our microcontroller been fast enough.
    */
   async event void CaptureSFD.captured( uint16_t time ) {
+    uint32_t time32 = time16to32(time, call BackoffTimer.getNow());
     atomic {
       switch( m_state ) {
         
@@ -256,7 +266,17 @@ implementation {
         m_state = S_EFD;
         sfdHigh = TRUE;
         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();
+        }
+
         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;
@@ -266,7 +286,7 @@ implementation {
 
         
         if ( ( ( (call CC2420PacketBody.getHeader( m_msg ))->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == IEEE154_TYPE_DATA ) {
-          (call CC2420PacketBody.getMetadata( m_msg ))->time = time;
+          call PacketTimeStamp.set(m_msg, time32);
         }
         
         if ( call SFD.get() ) {
@@ -294,8 +314,7 @@ implementation {
         if ( !m_receiving ) {
           sfdHigh = TRUE;
           call CaptureSFD.captureFallingEdge();
-          signal TimeStamp.receivedSFD( time );
-          call CC2420Receive.sfd( time );
+          call CC2420Receive.sfd( time32 );
           m_receiving = TRUE;
           m_prev_time = time;
           if ( call SFD.get() ) {
@@ -309,6 +328,8 @@ implementation {
         m_receiving = FALSE;
         if ( time - m_prev_time < 10 ) {
           call CC2420Receive.sfd_dropped();
+         if (m_msg)
+           call PacketTimeStamp.clear(m_msg);
         }
         break;
       
@@ -336,7 +357,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 +509,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 +675,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 +687,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 ) {
-  }
-
 }